From d2180270010cf78884c973b3260ec957496f0db6 Mon Sep 17 00:00:00 2001 From: Lecky Lao Date: Thu, 20 Aug 2020 05:02:14 +1000 Subject: [PATCH 01/19] adding curve gauge mapping; adding curve gauge connector; remove trailing spaces; --- contracts/connectors/curve_gauge.sol | 199 ++++++++++++++++++++++ contracts/mapping/curve_gauge_mapping.sol | 95 +++++++++++ contracts/mapping/staking.sol | 2 +- 3 files changed, 295 insertions(+), 1 deletion(-) create mode 100644 contracts/connectors/curve_gauge.sol create mode 100644 contracts/mapping/curve_gauge_mapping.sol diff --git a/contracts/connectors/curve_gauge.sol b/contracts/connectors/curve_gauge.sol new file mode 100644 index 0000000..82131d4 --- /dev/null +++ b/contracts/connectors/curve_gauge.sol @@ -0,0 +1,199 @@ +pragma solidity ^0.6.0; + +// import files from common directory +import { Stores } from "../common/stores.sol"; +import { DSMath } from "../common/math.sol"; +import { TokenInterface } from "../common/interfaces.sol"; + +interface IGauge { + function claim_rewards() external; + function deposit(uint256 value) external; + function withdraw(uint256 value) external; + function lp_token() external view returns(address token); + function rewarded_token() external view returns(address token); + function crv_token() external view returns(address token); + function balanceOf(address user) external view returns(uint256 amt); +} + +interface IMintor{ + function mint(address gauge) external; +} + +interface CurveGaugeMapping { + function gaugeMapping(bytes32) external view returns(address gaugeAddress); +} + +contract GaugeHelper is DSMath, Stores{ + function getCurveGaugeMappingAddr() internal virtual view returns (address){ + // Change this to the deployed address + return 0x0000000000000000000000000000000000000000; + } + + function getCurveMintorAddr() internal virtual view returns (address){ + return 0xd061D61a4d941c39E5453435B6345Dc261C2fcE0; + } + + /** + * @dev Convert String to bytes32. + */ + function stringToBytes32(string memory str) internal pure returns (bytes32 result) { + require(bytes(str).length != 0, "string-empty"); + // solium-disable-next-line security/no-inline-assembly + assembly { + result := mload(add(str, 32)) + } + } +} + +contract CurveGauge is GaugeHelper { + event LogDeposit( + string indexed gaugePoolName, + uint amount, + uint getId, + uint setId + ); + + event LogWithdraw( + string indexed gaugePoolName, + uint amount, + uint getId, + uint setId, + uint setIdCRVReward, + uint setIdReward + ); + + event LogClaimedReward( + string indexed gaugePoolName, + uint setId, + uint setIdReward + ); + + struct Balances{ + uint intialCRVBal; + uint intialRewardBal; + uint finalCRVBal; + uint finalRewardBal; + uint crvRewardAmt; + uint rewardAmt; + } + + /** + * @dev Deposit Cruve LP Token. + * @param gaugePoolName Curve gauge pool name. + * @param amt deposit amount. + * @param getId Get token amount at this ID from `InstaMemory` Contract. + * @param setId Set token amount at this ID in `InstaMemory` Contract. + */ + function deposit( + string calldata gaugePoolName, + uint amt, + uint getId, + uint setId + ) external payable { + uint _amt = getUint(getId, amt); + CurveGaugeMapping curveGaugeMapping = CurveGaugeMapping(getCurveGaugeMappingAddr()); + address curveGaugeAddr = curveGaugeMapping.gaugeMapping(bytes32(stringToBytes32(gaugePoolName))); + require(curveGaugeAddr != address(0), "wrong-gauge-pool-name"); + IGauge gauge = IGauge(curveGaugeAddr); + TokenInterface lp_token = TokenInterface(address(gauge.lp_token())); + + _amt = _amt == uint(-1) ? lp_token.balanceOf(address(this)) : _amt; + lp_token.approve(address(curveGaugeAddr), _amt); + gauge.deposit(_amt); + setUint(setId, _amt); + + emit LogDeposit(gaugePoolName, _amt, getId, setId); + bytes32 _eventCode = keccak256("LogDeposit(string,uint256,uint256,uint256)"); + bytes memory _eventParam = abi.encode(gaugePoolName, _amt, getId, setId); + emitEvent(_eventCode, _eventParam); + } + + /** + * @dev Withdraw LP Token. + * @param gaugePoolName gauge pool name. + * @param amt LP token amount. + * @param getId Get token amount at this ID from `InstaMemory` Contract. + * @param setId Set token amount at this ID in `InstaMemory` Contract. + * @param setIdCRVReward Set CRV token reward amount at this ID in `InstaMemory` Contract. + * @param setIdReward Set reward amount at this ID in `InstaMemory` Contract. + */ + function withdraw( + string calldata gaugePoolName, + uint amt, + uint getId, + uint setId, + uint setIdCRVReward, + uint setIdReward + ) external payable { + uint _amt = getUint(getId, amt); + CurveGaugeMapping curveGaugeMapping = CurveGaugeMapping(getCurveGaugeMappingAddr()); + address curveGaugeAddr = curveGaugeMapping.gaugeMapping(bytes32(stringToBytes32(gaugePoolName))); + require(curveGaugeAddr != address(0), "wrong-gauge-pool-name"); + IGauge gauge = IGauge(curveGaugeAddr); + TokenInterface lp_token = TokenInterface(address(gauge.lp_token())); + TokenInterface crv_token = TokenInterface(address(gauge.crv_token())); + TokenInterface rewarded_token = TokenInterface(address(gauge.rewarded_token())); + IMintor mintor = IMintor(getCurveMintorAddr()); + Balances memory balances; + + _amt = _amt == uint(-1) ? lp_token.balanceOf(address(this)) : _amt; + balances.intialCRVBal = crv_token.balanceOf(address(this)); + balances.intialRewardBal = rewarded_token.balanceOf(address(this)); + mintor.mint(curveGaugeAddr); + gauge.withdraw(_amt); + balances.finalCRVBal = crv_token.balanceOf(address(this)); + balances.finalRewardBal = rewarded_token.balanceOf(address(this)); + balances.crvRewardAmt = sub(balances.finalCRVBal, balances.intialCRVBal); + balances.rewardAmt = sub(balances.finalRewardBal, balances.intialRewardBal); + + setUint(setId, _amt); + setUint(setIdCRVReward, balances.crvRewardAmt); + setUint(setIdReward, balances.rewardAmt); + + emit LogWithdraw(gaugePoolName, _amt, getId, setId, setIdCRVReward, setIdReward); + bytes32 _eventCodeWithdraw = keccak256("LogWithdraw(string,uint256,uint256,uint256,uint256,uint256)"); + bytes memory _eventParamWithdraw = abi.encode(gaugePoolName, _amt, getId, setId, setIdCRVReward, setIdReward); + emitEvent(_eventCodeWithdraw, _eventParamWithdraw); + } + + /** + * @dev Claim Reward. + * @param gaugePoolName gauge pool name. + * @param setId Set CRV reward amount at this ID in `InstaMemory` Contract. + * @param setIdReward Set token reward amount at this ID in `InstaMemory` Contract. + */ + function claimReward( + string calldata gaugePoolName, + uint setId, + uint setIdReward + ) external payable { + CurveGaugeMapping curveGaugeMapping = CurveGaugeMapping(getCurveGaugeMappingAddr()); + address curveGaugeAddr = curveGaugeMapping.gaugeMapping(bytes32(stringToBytes32(gaugePoolName))); + require(curveGaugeAddr != address(0), "wrong-gauge-pool-name"); + IMintor mintor = IMintor(getCurveMintorAddr()); + IGauge gauge = IGauge(curveGaugeAddr); + TokenInterface crv_token = TokenInterface(address(gauge.crv_token())); + TokenInterface rewarded_token = TokenInterface(address(gauge.rewarded_token())); + Balances memory balances; + + balances.intialCRVBal = crv_token.balanceOf(address(this)); + balances.intialRewardBal = rewarded_token.balanceOf(address(this)); + mintor.mint(curveGaugeAddr); + balances.finalCRVBal = crv_token.balanceOf(address(this)); + balances.finalRewardBal = rewarded_token.balanceOf(address(this)); + balances.crvRewardAmt = sub(balances.finalCRVBal, balances.intialCRVBal); + balances.rewardAmt = sub(balances.finalRewardBal, balances.intialRewardBal); + + setUint(setId, balances.crvRewardAmt); + setUint(setIdReward, balances.rewardAmt); + + emit LogClaimedReward(gaugePoolName, setId, setIdReward); + bytes32 _eventCode = keccak256("LogClaimedReward(string,uint256,uint256,uint256)"); + bytes memory _eventParam = abi.encode(gaugePoolName, setId, setIdReward); + emitEvent(_eventCode, _eventParam); + } +} + +contract ConnectCurveGauge is CurveGauge { + string public name = "Curve-Gauge-v1.0"; +} diff --git a/contracts/mapping/curve_gauge_mapping.sol b/contracts/mapping/curve_gauge_mapping.sol new file mode 100644 index 0000000..7e79625 --- /dev/null +++ b/contracts/mapping/curve_gauge_mapping.sol @@ -0,0 +1,95 @@ +pragma solidity ^0.6.0; +pragma experimental ABIEncoderV2; + +interface ConnectorsInterface { + function chief(address) external view returns (bool); +} + +interface IndexInterface { + function master() external view returns (address); +} + +contract BytesHelper { + /** + * @dev Convert String to bytes32. + */ + function stringToBytes32(string memory str) internal pure returns (bytes32 result) { + require(bytes(str).length != 0, "String-Empty"); + // solium-disable-next-line security/no-inline-assembly + assembly { + result := mload(add(str, 32)) + } + } + + function bytes32ToString(bytes32 _bytes32) internal pure returns (string memory) { + bytes32 _temp; + uint count; + for (uint256 i; i < 32; i++) { + _temp = _bytes32[i]; + if( _temp != bytes32(0)) { + count += 1; + } + } + bytes memory bytesArray = new bytes(count); + for (uint256 i; i < count; i++) { + bytesArray[i] = (_bytes32[i]); + } + return (string(bytesArray)); + } +} + +contract Helpers is BytesHelper { + address public constant connectors = 0xD6A602C01a023B98Ecfb29Df02FBA380d3B21E0c; + address public constant instaIndex = 0x2971AdFa57b20E5a416aE5a708A8655A9c74f723; + uint public version = 1; + + mapping (bytes32 => address) public gaugeMapping; + + event LogAddGaugeMapping( + string gaugeName, + address gaugeAddress + ); + + event LogRemoveGaugeMapping( + string gaugeName, + address gaugeAddress + ); + + modifier isChief virtual { + require( + ConnectorsInterface(connectors).chief(msg.sender) || + IndexInterface(instaIndex).master() == msg.sender, "not-Chief"); + _; + } + + function addGaugeMapping( + string memory gaugeName, + address gaugeAddress + ) public isChief { + require(gaugeAddress != address(0), "gaugeAddress-not-vaild"); + require(bytes(gaugeName).length <= 32, "Length-exceeds"); + bytes32 gaugeType = stringToBytes32(gaugeName); + require(gaugeMapping[gaugeType] == address(0), "gaugePool-already-added"); + + gaugeMapping[gaugeType] = gaugeAddress; + + emit LogAddGaugeMapping(gaugeName, gaugeAddress); + } + + function removeGaugeMapping(string memory gaugeName, address gaugeAddress) public isChief { + require(gaugeAddress != address(0), "gaugeAddress-not-vaild"); + bytes32 gaugeType = stringToBytes32(gaugeName); + require(gaugeMapping[gaugeType] == gaugeAddress, "different-gauge-pool"); + + delete gaugeMapping[gaugeType]; + + emit LogRemoveGaugeMapping( + gaugeName, + gaugeAddress + ); + } +} + +contract CurveGaugeMapping is Helpers { + string constant public name = "Curve-Gauge-Mapping-v1"; +} diff --git a/contracts/mapping/staking.sol b/contracts/mapping/staking.sol index 94419b4..f2ee950 100644 --- a/contracts/mapping/staking.sol +++ b/contracts/mapping/staking.sol @@ -40,6 +40,7 @@ contract BytesHelper { return (string(bytesArray)); } } + contract Helpers is BytesHelper { address public constant connectors = 0xD6A602C01a023B98Ecfb29Df02FBA380d3B21E0c; address public constant instaIndex = 0x2971AdFa57b20E5a416aE5a708A8655A9c74f723; @@ -112,7 +113,6 @@ contract Helpers is BytesHelper { } } - contract InstaStakingMapping is Helpers { string constant public name = "Staking-Mapping-v1"; } From be23d7bba8a21c30eb046bda01dc27e2c90b4641 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Thu, 20 Aug 2020 00:55:47 +0530 Subject: [PATCH 02/19] Fixed stack too deep error --- contracts/connectors/curve_gauge.sol | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/contracts/connectors/curve_gauge.sol b/contracts/connectors/curve_gauge.sol index 82131d4..cad896c 100644 --- a/contracts/connectors/curve_gauge.sol +++ b/contracts/connectors/curve_gauge.sol @@ -126,20 +126,18 @@ contract CurveGauge is GaugeHelper { uint setIdReward ) external payable { uint _amt = getUint(getId, amt); - CurveGaugeMapping curveGaugeMapping = CurveGaugeMapping(getCurveGaugeMappingAddr()); - address curveGaugeAddr = curveGaugeMapping.gaugeMapping(bytes32(stringToBytes32(gaugePoolName))); + address curveGaugeAddr = CurveGaugeMapping(getCurveGaugeMappingAddr()) + .gaugeMapping(bytes32(stringToBytes32(gaugePoolName))); require(curveGaugeAddr != address(0), "wrong-gauge-pool-name"); IGauge gauge = IGauge(curveGaugeAddr); - TokenInterface lp_token = TokenInterface(address(gauge.lp_token())); TokenInterface crv_token = TokenInterface(address(gauge.crv_token())); TokenInterface rewarded_token = TokenInterface(address(gauge.rewarded_token())); - IMintor mintor = IMintor(getCurveMintorAddr()); Balances memory balances; - _amt = _amt == uint(-1) ? lp_token.balanceOf(address(this)) : _amt; + _amt = _amt == uint(-1) ? TokenInterface(address(gauge.lp_token())).balanceOf(address(this)) : _amt; balances.intialCRVBal = crv_token.balanceOf(address(this)); balances.intialRewardBal = rewarded_token.balanceOf(address(this)); - mintor.mint(curveGaugeAddr); + IMintor(getCurveMintorAddr()).mint(curveGaugeAddr); gauge.withdraw(_amt); balances.finalCRVBal = crv_token.balanceOf(address(this)); balances.finalRewardBal = rewarded_token.balanceOf(address(this)); @@ -150,6 +148,11 @@ contract CurveGauge is GaugeHelper { setUint(setIdCRVReward, balances.crvRewardAmt); setUint(setIdReward, balances.rewardAmt); + emitLogWithdraw(gaugePoolName, _amt, getId, setId, setIdCRVReward, setIdReward); + + } + + function emitLogWithdraw(string memory gaugePoolName, uint _amt, uint getId, uint setId, uint setIdCRVReward, uint setIdReward) internal { emit LogWithdraw(gaugePoolName, _amt, getId, setId, setIdCRVReward, setIdReward); bytes32 _eventCodeWithdraw = keccak256("LogWithdraw(string,uint256,uint256,uint256,uint256,uint256)"); bytes memory _eventParamWithdraw = abi.encode(gaugePoolName, _amt, getId, setId, setIdCRVReward, setIdReward); From b4feb0467de7fa7b4a8eac5087d02a6295fe2ef4 Mon Sep 17 00:00:00 2001 From: Lecky Lao Date: Thu, 20 Aug 2020 05:37:44 +1000 Subject: [PATCH 03/19] added event and function overloading for withdraw and claimReward --- contracts/connectors/curve_gauge.sol | 87 +++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) diff --git a/contracts/connectors/curve_gauge.sol b/contracts/connectors/curve_gauge.sol index cad896c..3433232 100644 --- a/contracts/connectors/curve_gauge.sol +++ b/contracts/connectors/curve_gauge.sol @@ -62,12 +62,25 @@ contract CurveGauge is GaugeHelper { uint setIdReward ); + event LogWithdraw( + string indexed gaugePoolName, + uint amount, + uint getId, + uint setId, + uint setIdCRVReward + ); + event LogClaimedReward( string indexed gaugePoolName, uint setId, uint setIdReward ); + event LogClaimedReward( + string indexed gaugePoolName, + uint setId + ); + struct Balances{ uint intialCRVBal; uint intialRewardBal; @@ -149,7 +162,6 @@ contract CurveGauge is GaugeHelper { setUint(setIdReward, balances.rewardAmt); emitLogWithdraw(gaugePoolName, _amt, getId, setId, setIdCRVReward, setIdReward); - } function emitLogWithdraw(string memory gaugePoolName, uint _amt, uint getId, uint setId, uint setIdCRVReward, uint setIdReward) internal { @@ -195,6 +207,79 @@ contract CurveGauge is GaugeHelper { bytes memory _eventParam = abi.encode(gaugePoolName, setId, setIdReward); emitEvent(_eventCode, _eventParam); } + + /** + * @dev Withdraw LP Token. + * @param gaugePoolName gauge pool name. + * @param amt LP token amount. + * @param getId Get token amount at this ID from `InstaMemory` Contract. + * @param setId Set token amount at this ID in `InstaMemory` Contract. + * @param setIdCRVReward Set CRV token reward amount at this ID in `InstaMemory` Contract. + */ + function withdraw( + string calldata gaugePoolName, + uint amt, + uint getId, + uint setId, + uint setIdCRVReward + ) external payable { + uint _amt = getUint(getId, amt); + address curveGaugeAddr = CurveGaugeMapping(getCurveGaugeMappingAddr()) + .gaugeMapping(bytes32(stringToBytes32(gaugePoolName))); + require(curveGaugeAddr != address(0), "wrong-gauge-pool-name"); + IGauge gauge = IGauge(curveGaugeAddr); + TokenInterface crv_token = TokenInterface(address(gauge.crv_token())); + Balances memory balances; + + _amt = _amt == uint(-1) ? TokenInterface(address(gauge.lp_token())).balanceOf(address(this)) : _amt; + balances.intialCRVBal = crv_token.balanceOf(address(this)); + IMintor(getCurveMintorAddr()).mint(curveGaugeAddr); + gauge.withdraw(_amt); + balances.finalCRVBal = crv_token.balanceOf(address(this)); + balances.crvRewardAmt = sub(balances.finalCRVBal, balances.intialCRVBal); + + setUint(setId, _amt); + setUint(setIdCRVReward, balances.crvRewardAmt); + + emitLogWithdraw(gaugePoolName, _amt, getId, setId, setIdCRVReward); + } + + function emitLogWithdraw(string memory gaugePoolName, uint _amt, uint getId, uint setId, uint setIdCRVReward) internal { + emit LogWithdraw(gaugePoolName, _amt, getId, setId, setIdCRVReward); + bytes32 _eventCodeWithdraw = keccak256("LogWithdraw(string,uint256,uint256,uint256,uint256)"); + bytes memory _eventParamWithdraw = abi.encode(gaugePoolName, _amt, getId, setId, setIdCRVReward); + emitEvent(_eventCodeWithdraw, _eventParamWithdraw); + } + + /** + * @dev Claim Reward. + * @param gaugePoolName gauge pool name. + * @param setId Set CRV reward amount at this ID in `InstaMemory` Contract. + */ + function claimReward( + string calldata gaugePoolName, + uint setId + ) external payable { + CurveGaugeMapping curveGaugeMapping = CurveGaugeMapping(getCurveGaugeMappingAddr()); + address curveGaugeAddr = curveGaugeMapping.gaugeMapping(bytes32(stringToBytes32(gaugePoolName))); + require(curveGaugeAddr != address(0), "wrong-gauge-pool-name"); + IMintor mintor = IMintor(getCurveMintorAddr()); + IGauge gauge = IGauge(curveGaugeAddr); + TokenInterface crv_token = TokenInterface(address(gauge.crv_token())); + Balances memory balances; + + balances.intialCRVBal = crv_token.balanceOf(address(this)); + mintor.mint(curveGaugeAddr); + balances.finalCRVBal = crv_token.balanceOf(address(this)); + balances.crvRewardAmt = sub(balances.finalCRVBal, balances.intialCRVBal); + + setUint(setId, balances.crvRewardAmt); + + emit LogClaimedReward(gaugePoolName, setId); + bytes32 _eventCode = keccak256("LogClaimedReward(string,uint256,uint256)"); + bytes memory _eventParam = abi.encode(gaugePoolName, setId); + emitEvent(_eventCode, _eventParam); + } } contract ConnectCurveGauge is CurveGauge { From 0c1355fdd3b39fdf7f191f898e8f7ffbd97571b2 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Thu, 20 Aug 2020 01:34:02 +0530 Subject: [PATCH 04/19] added new lines --- contracts/connectors/curve_gauge.sol | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/contracts/connectors/curve_gauge.sol b/contracts/connectors/curve_gauge.sol index 3433232..dc50f66 100644 --- a/contracts/connectors/curve_gauge.sol +++ b/contracts/connectors/curve_gauge.sol @@ -113,6 +113,7 @@ contract CurveGauge is GaugeHelper { _amt = _amt == uint(-1) ? lp_token.balanceOf(address(this)) : _amt; lp_token.approve(address(curveGaugeAddr), _amt); gauge.deposit(_amt); + setUint(setId, _amt); emit LogDeposit(gaugePoolName, _amt, getId, setId); @@ -148,12 +149,16 @@ contract CurveGauge is GaugeHelper { Balances memory balances; _amt = _amt == uint(-1) ? TokenInterface(address(gauge.lp_token())).balanceOf(address(this)) : _amt; + balances.intialCRVBal = crv_token.balanceOf(address(this)); balances.intialRewardBal = rewarded_token.balanceOf(address(this)); + IMintor(getCurveMintorAddr()).mint(curveGaugeAddr); gauge.withdraw(_amt); + balances.finalCRVBal = crv_token.balanceOf(address(this)); balances.finalRewardBal = rewarded_token.balanceOf(address(this)); + balances.crvRewardAmt = sub(balances.finalCRVBal, balances.intialCRVBal); balances.rewardAmt = sub(balances.finalRewardBal, balances.intialRewardBal); @@ -196,6 +201,7 @@ contract CurveGauge is GaugeHelper { mintor.mint(curveGaugeAddr); balances.finalCRVBal = crv_token.balanceOf(address(this)); balances.finalRewardBal = rewarded_token.balanceOf(address(this)); + balances.crvRewardAmt = sub(balances.finalCRVBal, balances.intialCRVBal); balances.rewardAmt = sub(balances.finalRewardBal, balances.intialRewardBal); From 5afef3d9f0104f0f1f5d74f45ee75a6a120d417a Mon Sep 17 00:00:00 2001 From: Lecky Lao Date: Thu, 20 Aug 2020 15:37:36 +1000 Subject: [PATCH 05/19] added amount and rewardAmt for LogClaimedReward; fixing withdraw -1 to use gauge.balance_Of; moving same name functions together; removing setId from withdraw event; --- contracts/connectors/curve_gauge.sol | 189 +++++++++++++++------------ 1 file changed, 109 insertions(+), 80 deletions(-) diff --git a/contracts/connectors/curve_gauge.sol b/contracts/connectors/curve_gauge.sol index 3433232..b31ff84 100644 --- a/contracts/connectors/curve_gauge.sol +++ b/contracts/connectors/curve_gauge.sol @@ -72,12 +72,15 @@ contract CurveGauge is GaugeHelper { event LogClaimedReward( string indexed gaugePoolName, + uint amount, + uint rewardAmt, uint setId, uint setIdReward ); event LogClaimedReward( string indexed gaugePoolName, + uint amount, uint setId ); @@ -122,7 +125,48 @@ contract CurveGauge is GaugeHelper { } /** - * @dev Withdraw LP Token. + * @dev Withdraw LP Token and claim CRV reward. + * @param gaugePoolName gauge pool name. + * @param amt LP token amount. + * @param getId Get token amount at this ID from `InstaMemory` Contract. + * @param setId Set token amount at this ID in `InstaMemory` Contract. + * @param setIdCRVReward Set CRV token reward amount at this ID in `InstaMemory` Contract. + */ + function withdraw( + string calldata gaugePoolName, + uint amt, + uint getId, + uint setId, + uint setIdCRVReward + ) external payable { + uint _amt = getUint(getId, amt); + address curveGaugeAddr = CurveGaugeMapping(getCurveGaugeMappingAddr()) + .gaugeMapping(bytes32(stringToBytes32(gaugePoolName))); + require(curveGaugeAddr != address(0), "wrong-gauge-pool-name"); + IGauge gauge = IGauge(curveGaugeAddr); + TokenInterface crv_token = TokenInterface(address(gauge.crv_token())); + Balances memory balances; + + _amt = _amt == uint(-1) ? TokenInterface(address(gauge.lp_token())).balanceOf(address(this)) : _amt; + balances.intialCRVBal = crv_token.balanceOf(address(this)); + IMintor(getCurveMintorAddr()).mint(curveGaugeAddr); + gauge.withdraw(_amt); + balances.finalCRVBal = crv_token.balanceOf(address(this)); + balances.crvRewardAmt = sub(balances.finalCRVBal, balances.intialCRVBal); + + setUint(setId, _amt); + setUint(setIdCRVReward, balances.crvRewardAmt); + + emit LogClaimedReward(gaugePoolName, balances.crvRewardAmt, setId); + bytes32 _eventCode = keccak256("LogClaimedReward(string,uint256,uint256)"); + bytes memory _eventParam = abi.encode(gaugePoolName, balances.crvRewardAmt, setId); + emitEvent(_eventCode, _eventParam); + + emitLogWithdraw(gaugePoolName, _amt, getId, setId); + } + + /** + * @dev Withdraw LP Token and claim both CRV and Reward token. * @param gaugePoolName gauge pool name. * @param amt LP token amount. * @param getId Get token amount at this ID from `InstaMemory` Contract. @@ -147,7 +191,7 @@ contract CurveGauge is GaugeHelper { TokenInterface rewarded_token = TokenInterface(address(gauge.rewarded_token())); Balances memory balances; - _amt = _amt == uint(-1) ? TokenInterface(address(gauge.lp_token())).balanceOf(address(this)) : _amt; + _amt = _amt == uint(-1) ? gauge.balanceOf(address(this)) : _amt; balances.intialCRVBal = crv_token.balanceOf(address(this)); balances.intialRewardBal = rewarded_token.balanceOf(address(this)); IMintor(getCurveMintorAddr()).mint(curveGaugeAddr); @@ -161,18 +205,74 @@ contract CurveGauge is GaugeHelper { setUint(setIdCRVReward, balances.crvRewardAmt); setUint(setIdReward, balances.rewardAmt); - emitLogWithdraw(gaugePoolName, _amt, getId, setId, setIdCRVReward, setIdReward); + emit LogClaimedReward(gaugePoolName, balances.crvRewardAmt, setId, balances.rewardAmt, setIdReward); + bytes32 _eventCode = keccak256("LogClaimedReward(string,uint256,uint256,uint256,uint256)"); + bytes memory _eventParam = abi.encode(gaugePoolName, balances.crvRewardAmt, setId, balances.rewardAmt, setIdReward)); + emitEvent(_eventCode, _eventParam); + + emitLogWithdraw(gaugePoolName, _amt, getId, setId); } - function emitLogWithdraw(string memory gaugePoolName, uint _amt, uint getId, uint setId, uint setIdCRVReward, uint setIdReward) internal { - emit LogWithdraw(gaugePoolName, _amt, getId, setId, setIdCRVReward, setIdReward); - bytes32 _eventCodeWithdraw = keccak256("LogWithdraw(string,uint256,uint256,uint256,uint256,uint256)"); - bytes memory _eventParamWithdraw = abi.encode(gaugePoolName, _amt, getId, setId, setIdCRVReward, setIdReward); + /** + * @dev emit LogWithdraw event with CRV Reward + * @param gaugePoolName gauge pool name. + * @param amt LP token amount. + * @param getId Get token amount at this ID from `InstaMemory` Contract. + * @param setId Set token amount at this ID in `InstaMemory` Contract. + */ + function emitLogWithdraw(string memory gaugePoolName, uint _amt, uint getId, uint setId) internal { + emit LogWithdraw(gaugePoolName, _amt, getId, setId); + bytes32 _eventCodeWithdraw = keccak256("LogWithdraw(string,uint256,uint256,uint256)"); + bytes memory _eventParamWithdraw = abi.encode(gaugePoolName, _amt, getId, setId); emitEvent(_eventCodeWithdraw, _eventParamWithdraw); } /** - * @dev Claim Reward. + * @dev emit LogWithdraw event with CRV Reward and reward token + * @param gaugePoolName gauge pool name. + * @param amt LP token amount. + * @param getId Get token amount at this ID from `InstaMemory` Contract. + * @param setId Set token amount at this ID in `InstaMemory` Contract. + */ + function emitLogWithdraw(string memory gaugePoolName, uint _amt, uint getId, uint setId) internal { + emit LogWithdraw(gaugePoolName, _amt, getId, setId); + bytes32 _eventCodeWithdraw = keccak256("LogWithdraw(string,uint256,uint256,uint256)"); + bytes memory _eventParamWithdraw = abi.encode(gaugePoolName, _amt, getId, setId); + emitEvent(_eventCodeWithdraw, _eventParamWithdraw); + } + + /** + * @dev Claim CRV Reward. + * @param gaugePoolName gauge pool name. + * @param setId Set CRV reward amount at this ID in `InstaMemory` Contract. + */ + function claimReward( + string calldata gaugePoolName, + uint setId + ) external payable { + CurveGaugeMapping curveGaugeMapping = CurveGaugeMapping(getCurveGaugeMappingAddr()); + address curveGaugeAddr = curveGaugeMapping.gaugeMapping(bytes32(stringToBytes32(gaugePoolName))); + require(curveGaugeAddr != address(0), "wrong-gauge-pool-name"); + IMintor mintor = IMintor(getCurveMintorAddr()); + IGauge gauge = IGauge(curveGaugeAddr); + TokenInterface crv_token = TokenInterface(address(gauge.crv_token())); + Balances memory balances; + + balances.intialCRVBal = crv_token.balanceOf(address(this)); + mintor.mint(curveGaugeAddr); + balances.finalCRVBal = crv_token.balanceOf(address(this)); + balances.crvRewardAmt = sub(balances.finalCRVBal, balances.intialCRVBal); + + setUint(setId, balances.crvRewardAmt); + + emit LogClaimedReward(gaugePoolName, setId); + bytes32 _eventCode = keccak256("LogClaimedReward(string,uint256,uint256)"); + bytes memory _eventParam = abi.encode(gaugePoolName, setId); + emitEvent(_eventCode, _eventParam); + } + + /** + * @dev Claim CRV Reward with Staked Reward token * @param gaugePoolName gauge pool name. * @param setId Set CRV reward amount at this ID in `InstaMemory` Contract. * @param setIdReward Set token reward amount at this ID in `InstaMemory` Contract. @@ -208,80 +308,9 @@ contract CurveGauge is GaugeHelper { emitEvent(_eventCode, _eventParam); } - /** - * @dev Withdraw LP Token. - * @param gaugePoolName gauge pool name. - * @param amt LP token amount. - * @param getId Get token amount at this ID from `InstaMemory` Contract. - * @param setId Set token amount at this ID in `InstaMemory` Contract. - * @param setIdCRVReward Set CRV token reward amount at this ID in `InstaMemory` Contract. - */ - function withdraw( - string calldata gaugePoolName, - uint amt, - uint getId, - uint setId, - uint setIdCRVReward - ) external payable { - uint _amt = getUint(getId, amt); - address curveGaugeAddr = CurveGaugeMapping(getCurveGaugeMappingAddr()) - .gaugeMapping(bytes32(stringToBytes32(gaugePoolName))); - require(curveGaugeAddr != address(0), "wrong-gauge-pool-name"); - IGauge gauge = IGauge(curveGaugeAddr); - TokenInterface crv_token = TokenInterface(address(gauge.crv_token())); - Balances memory balances; - - _amt = _amt == uint(-1) ? TokenInterface(address(gauge.lp_token())).balanceOf(address(this)) : _amt; - balances.intialCRVBal = crv_token.balanceOf(address(this)); - IMintor(getCurveMintorAddr()).mint(curveGaugeAddr); - gauge.withdraw(_amt); - balances.finalCRVBal = crv_token.balanceOf(address(this)); - balances.crvRewardAmt = sub(balances.finalCRVBal, balances.intialCRVBal); - - setUint(setId, _amt); - setUint(setIdCRVReward, balances.crvRewardAmt); - - emitLogWithdraw(gaugePoolName, _amt, getId, setId, setIdCRVReward); - } - - function emitLogWithdraw(string memory gaugePoolName, uint _amt, uint getId, uint setId, uint setIdCRVReward) internal { - emit LogWithdraw(gaugePoolName, _amt, getId, setId, setIdCRVReward); - bytes32 _eventCodeWithdraw = keccak256("LogWithdraw(string,uint256,uint256,uint256,uint256)"); - bytes memory _eventParamWithdraw = abi.encode(gaugePoolName, _amt, getId, setId, setIdCRVReward); - emitEvent(_eventCodeWithdraw, _eventParamWithdraw); - } - - /** - * @dev Claim Reward. - * @param gaugePoolName gauge pool name. - * @param setId Set CRV reward amount at this ID in `InstaMemory` Contract. - */ - function claimReward( - string calldata gaugePoolName, - uint setId - ) external payable { - CurveGaugeMapping curveGaugeMapping = CurveGaugeMapping(getCurveGaugeMappingAddr()); - address curveGaugeAddr = curveGaugeMapping.gaugeMapping(bytes32(stringToBytes32(gaugePoolName))); - require(curveGaugeAddr != address(0), "wrong-gauge-pool-name"); - IMintor mintor = IMintor(getCurveMintorAddr()); - IGauge gauge = IGauge(curveGaugeAddr); - TokenInterface crv_token = TokenInterface(address(gauge.crv_token())); - Balances memory balances; - - balances.intialCRVBal = crv_token.balanceOf(address(this)); - mintor.mint(curveGaugeAddr); - balances.finalCRVBal = crv_token.balanceOf(address(this)); - balances.crvRewardAmt = sub(balances.finalCRVBal, balances.intialCRVBal); - - setUint(setId, balances.crvRewardAmt); - - emit LogClaimedReward(gaugePoolName, setId); - bytes32 _eventCode = keccak256("LogClaimedReward(string,uint256,uint256)"); - bytes memory _eventParam = abi.encode(gaugePoolName, setId); - emitEvent(_eventCode, _eventParam); - } } contract ConnectCurveGauge is CurveGauge { string public name = "Curve-Gauge-v1.0"; } + From 8518f72e37385b6c321602f55bd29db0e902d7be Mon Sep 17 00:00:00 2001 From: Lecky Lao Date: Thu, 20 Aug 2020 16:09:38 +1000 Subject: [PATCH 06/19] fixed compiling issues; --- contracts/connectors/curve_gauge.sol | 48 +++++++--------------------- 1 file changed, 12 insertions(+), 36 deletions(-) diff --git a/contracts/connectors/curve_gauge.sol b/contracts/connectors/curve_gauge.sol index b31ff84..ef4ed14 100644 --- a/contracts/connectors/curve_gauge.sol +++ b/contracts/connectors/curve_gauge.sol @@ -57,17 +57,7 @@ contract CurveGauge is GaugeHelper { string indexed gaugePoolName, uint amount, uint getId, - uint setId, - uint setIdCRVReward, - uint setIdReward - ); - - event LogWithdraw( - string indexed gaugePoolName, - uint amount, - uint getId, - uint setId, - uint setIdCRVReward + uint setId ); event LogClaimedReward( @@ -157,9 +147,9 @@ contract CurveGauge is GaugeHelper { setUint(setId, _amt); setUint(setIdCRVReward, balances.crvRewardAmt); - emit LogClaimedReward(gaugePoolName, balances.crvRewardAmt, setId); + emit LogClaimedReward(gaugePoolName, balances.crvRewardAmt, setIdCRVReward); bytes32 _eventCode = keccak256("LogClaimedReward(string,uint256,uint256)"); - bytes memory _eventParam = abi.encode(gaugePoolName, balances.crvRewardAmt, setId); + bytes memory _eventParam = abi.encode(gaugePoolName, balances.crvRewardAmt, setIdCRVReward); emitEvent(_eventCode, _eventParam); emitLogWithdraw(gaugePoolName, _amt, getId, setId); @@ -205,32 +195,18 @@ contract CurveGauge is GaugeHelper { setUint(setIdCRVReward, balances.crvRewardAmt); setUint(setIdReward, balances.rewardAmt); - emit LogClaimedReward(gaugePoolName, balances.crvRewardAmt, setId, balances.rewardAmt, setIdReward); + emit LogClaimedReward(gaugePoolName, balances.crvRewardAmt, setIdCRVReward, balances.rewardAmt, setIdReward); bytes32 _eventCode = keccak256("LogClaimedReward(string,uint256,uint256,uint256,uint256)"); - bytes memory _eventParam = abi.encode(gaugePoolName, balances.crvRewardAmt, setId, balances.rewardAmt, setIdReward)); + bytes memory _eventParam = abi.encode(gaugePoolName, balances.crvRewardAmt, setIdCRVReward, balances.rewardAmt, setIdReward); emitEvent(_eventCode, _eventParam); emitLogWithdraw(gaugePoolName, _amt, getId, setId); } /** - * @dev emit LogWithdraw event with CRV Reward + * @dev emit LogWithdraw event * @param gaugePoolName gauge pool name. - * @param amt LP token amount. - * @param getId Get token amount at this ID from `InstaMemory` Contract. - * @param setId Set token amount at this ID in `InstaMemory` Contract. - */ - function emitLogWithdraw(string memory gaugePoolName, uint _amt, uint getId, uint setId) internal { - emit LogWithdraw(gaugePoolName, _amt, getId, setId); - bytes32 _eventCodeWithdraw = keccak256("LogWithdraw(string,uint256,uint256,uint256)"); - bytes memory _eventParamWithdraw = abi.encode(gaugePoolName, _amt, getId, setId); - emitEvent(_eventCodeWithdraw, _eventParamWithdraw); - } - - /** - * @dev emit LogWithdraw event with CRV Reward and reward token - * @param gaugePoolName gauge pool name. - * @param amt LP token amount. + * @param _amt LP token amount. * @param getId Get token amount at this ID from `InstaMemory` Contract. * @param setId Set token amount at this ID in `InstaMemory` Contract. */ @@ -265,9 +241,9 @@ contract CurveGauge is GaugeHelper { setUint(setId, balances.crvRewardAmt); - emit LogClaimedReward(gaugePoolName, setId); + emit LogClaimedReward(gaugePoolName, balances.crvRewardAmt, setId); bytes32 _eventCode = keccak256("LogClaimedReward(string,uint256,uint256)"); - bytes memory _eventParam = abi.encode(gaugePoolName, setId); + bytes memory _eventParam = abi.encode(gaugePoolName, balances.crvRewardAmt, setId); emitEvent(_eventCode, _eventParam); } @@ -302,9 +278,9 @@ contract CurveGauge is GaugeHelper { setUint(setId, balances.crvRewardAmt); setUint(setIdReward, balances.rewardAmt); - emit LogClaimedReward(gaugePoolName, setId, setIdReward); - bytes32 _eventCode = keccak256("LogClaimedReward(string,uint256,uint256,uint256)"); - bytes memory _eventParam = abi.encode(gaugePoolName, setId, setIdReward); + emit LogClaimedReward(gaugePoolName, balances.crvRewardAmt, setId, balances.rewardAmt, setIdReward); + bytes32 _eventCode = keccak256("LogClaimedReward(string,uint256,uint256,uint256,uint256)"); + bytes memory _eventParam = abi.encode(gaugePoolName, balances.crvRewardAmt, setId, balances.rewardAmt, setIdReward); emitEvent(_eventCode, _eventParam); } From a2b929a794775f03b1a37a16cdf7c0d5d96615f9 Mon Sep 17 00:00:00 2001 From: Lecky Lao Date: Thu, 20 Aug 2020 23:01:45 +1000 Subject: [PATCH 07/19] fixing another withdraw amt balanceOf issue --- contracts/connectors/curve_gauge.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/connectors/curve_gauge.sol b/contracts/connectors/curve_gauge.sol index ef4ed14..0c67c3e 100644 --- a/contracts/connectors/curve_gauge.sol +++ b/contracts/connectors/curve_gauge.sol @@ -137,7 +137,7 @@ contract CurveGauge is GaugeHelper { TokenInterface crv_token = TokenInterface(address(gauge.crv_token())); Balances memory balances; - _amt = _amt == uint(-1) ? TokenInterface(address(gauge.lp_token())).balanceOf(address(this)) : _amt; + _amt = _amt == uint(-1) ? gauge.balanceOf(address(this)) : _amt; balances.intialCRVBal = crv_token.balanceOf(address(this)); IMintor(getCurveMintorAddr()).mint(curveGaugeAddr); gauge.withdraw(_amt); From 0f9e5f69f1732092e63ec72b50d35508855b1fdf Mon Sep 17 00:00:00 2001 From: Lecky Lao Date: Fri, 21 Aug 2020 00:30:29 +1000 Subject: [PATCH 08/19] changed CurveGaugeMapping to use GaugeData to include gaugeAddress and rewardToken; removed function overload for withdraw and claim by using curveGaugeData; --- contracts/connectors/curve_gauge.sol | 182 +++++++++------------- contracts/mapping/curve_gauge_mapping.sol | 22 ++- 2 files changed, 86 insertions(+), 118 deletions(-) diff --git a/contracts/connectors/curve_gauge.sol b/contracts/connectors/curve_gauge.sol index 0c67c3e..1276f5a 100644 --- a/contracts/connectors/curve_gauge.sol +++ b/contracts/connectors/curve_gauge.sol @@ -1,4 +1,5 @@ pragma solidity ^0.6.0; +pragma experimental ABIEncoderV2; // import files from common directory import { Stores } from "../common/stores.sol"; @@ -19,8 +20,14 @@ interface IMintor{ function mint(address gauge) external; } -interface CurveGaugeMapping { - function gaugeMapping(bytes32) external view returns(address gaugeAddress); +interface ICurveGaugeMapping { + + struct GaugeData { + address gaugeAddress; + bool rewardToken; + } + + function gaugeMapping(bytes32) external view returns(GaugeData memory); } contract GaugeHelper is DSMath, Stores{ @@ -97,14 +104,14 @@ contract CurveGauge is GaugeHelper { uint setId ) external payable { uint _amt = getUint(getId, amt); - CurveGaugeMapping curveGaugeMapping = CurveGaugeMapping(getCurveGaugeMappingAddr()); - address curveGaugeAddr = curveGaugeMapping.gaugeMapping(bytes32(stringToBytes32(gaugePoolName))); - require(curveGaugeAddr != address(0), "wrong-gauge-pool-name"); - IGauge gauge = IGauge(curveGaugeAddr); + ICurveGaugeMapping curveGaugeMapping = ICurveGaugeMapping(getCurveGaugeMappingAddr()); + ICurveGaugeMapping.GaugeData memory curveGaugeData = curveGaugeMapping.gaugeMapping(bytes32(stringToBytes32(gaugePoolName))); + require(curveGaugeData.gaugeAddress != address(0), "wrong-gauge-pool-name"); + IGauge gauge = IGauge(curveGaugeData.gaugeAddress); TokenInterface lp_token = TokenInterface(address(gauge.lp_token())); _amt = _amt == uint(-1) ? lp_token.balanceOf(address(this)) : _amt; - lp_token.approve(address(curveGaugeAddr), _amt); + lp_token.approve(address(curveGaugeData.gaugeAddress), _amt); gauge.deposit(_amt); setUint(setId, _amt); @@ -114,47 +121,6 @@ contract CurveGauge is GaugeHelper { emitEvent(_eventCode, _eventParam); } - /** - * @dev Withdraw LP Token and claim CRV reward. - * @param gaugePoolName gauge pool name. - * @param amt LP token amount. - * @param getId Get token amount at this ID from `InstaMemory` Contract. - * @param setId Set token amount at this ID in `InstaMemory` Contract. - * @param setIdCRVReward Set CRV token reward amount at this ID in `InstaMemory` Contract. - */ - function withdraw( - string calldata gaugePoolName, - uint amt, - uint getId, - uint setId, - uint setIdCRVReward - ) external payable { - uint _amt = getUint(getId, amt); - address curveGaugeAddr = CurveGaugeMapping(getCurveGaugeMappingAddr()) - .gaugeMapping(bytes32(stringToBytes32(gaugePoolName))); - require(curveGaugeAddr != address(0), "wrong-gauge-pool-name"); - IGauge gauge = IGauge(curveGaugeAddr); - TokenInterface crv_token = TokenInterface(address(gauge.crv_token())); - Balances memory balances; - - _amt = _amt == uint(-1) ? gauge.balanceOf(address(this)) : _amt; - balances.intialCRVBal = crv_token.balanceOf(address(this)); - IMintor(getCurveMintorAddr()).mint(curveGaugeAddr); - gauge.withdraw(_amt); - balances.finalCRVBal = crv_token.balanceOf(address(this)); - balances.crvRewardAmt = sub(balances.finalCRVBal, balances.intialCRVBal); - - setUint(setId, _amt); - setUint(setIdCRVReward, balances.crvRewardAmt); - - emit LogClaimedReward(gaugePoolName, balances.crvRewardAmt, setIdCRVReward); - bytes32 _eventCode = keccak256("LogClaimedReward(string,uint256,uint256)"); - bytes memory _eventParam = abi.encode(gaugePoolName, balances.crvRewardAmt, setIdCRVReward); - emitEvent(_eventCode, _eventParam); - - emitLogWithdraw(gaugePoolName, _amt, getId, setId); - } - /** * @dev Withdraw LP Token and claim both CRV and Reward token. * @param gaugePoolName gauge pool name. @@ -173,34 +139,46 @@ contract CurveGauge is GaugeHelper { uint setIdReward ) external payable { uint _amt = getUint(getId, amt); - address curveGaugeAddr = CurveGaugeMapping(getCurveGaugeMappingAddr()) - .gaugeMapping(bytes32(stringToBytes32(gaugePoolName))); - require(curveGaugeAddr != address(0), "wrong-gauge-pool-name"); - IGauge gauge = IGauge(curveGaugeAddr); + ICurveGaugeMapping curveGaugeMapping = ICurveGaugeMapping(getCurveGaugeMappingAddr()); + ICurveGaugeMapping.GaugeData memory curveGaugeData = curveGaugeMapping.gaugeMapping(bytes32(stringToBytes32(gaugePoolName))); + require(curveGaugeData.gaugeAddress != address(0), "wrong-gauge-pool-name"); + IGauge gauge = IGauge(curveGaugeData.gaugeAddress); TokenInterface crv_token = TokenInterface(address(gauge.crv_token())); - TokenInterface rewarded_token = TokenInterface(address(gauge.rewarded_token())); Balances memory balances; _amt = _amt == uint(-1) ? gauge.balanceOf(address(this)) : _amt; balances.intialCRVBal = crv_token.balanceOf(address(this)); - balances.intialRewardBal = rewarded_token.balanceOf(address(this)); - IMintor(getCurveMintorAddr()).mint(curveGaugeAddr); - gauge.withdraw(_amt); - balances.finalCRVBal = crv_token.balanceOf(address(this)); - balances.finalRewardBal = rewarded_token.balanceOf(address(this)); - balances.crvRewardAmt = sub(balances.finalCRVBal, balances.intialCRVBal); - balances.rewardAmt = sub(balances.finalRewardBal, balances.intialRewardBal); + if(curveGaugeData.rewardToken == true){ + TokenInterface rewarded_token = TokenInterface(address(gauge.rewarded_token())); + balances.intialRewardBal = rewarded_token.balanceOf(address(this)); + } + + IMintor(getCurveMintorAddr()).mint(curveGaugeData.gaugeAddress); + gauge.withdraw(_amt); + + balances.finalCRVBal = crv_token.balanceOf(address(this)); + balances.crvRewardAmt = sub(balances.finalCRVBal, balances.intialCRVBal); setUint(setId, _amt); setUint(setIdCRVReward, balances.crvRewardAmt); - setUint(setIdReward, balances.rewardAmt); - - emit LogClaimedReward(gaugePoolName, balances.crvRewardAmt, setIdCRVReward, balances.rewardAmt, setIdReward); - bytes32 _eventCode = keccak256("LogClaimedReward(string,uint256,uint256,uint256,uint256)"); - bytes memory _eventParam = abi.encode(gaugePoolName, balances.crvRewardAmt, setIdCRVReward, balances.rewardAmt, setIdReward); - emitEvent(_eventCode, _eventParam); emitLogWithdraw(gaugePoolName, _amt, getId, setId); + + if(curveGaugeData.rewardToken == true){ + TokenInterface rewarded_token = TokenInterface(address(gauge.rewarded_token())); + balances.finalRewardBal = rewarded_token.balanceOf(address(this)); + balances.rewardAmt = sub(balances.finalRewardBal, balances.intialRewardBal); + setUint(setIdReward, balances.rewardAmt); + emit LogClaimedReward(gaugePoolName, balances.crvRewardAmt, setIdCRVReward, balances.rewardAmt, setIdReward); + bytes32 _eventCode = keccak256("LogClaimedReward(string,uint256,uint256,uint256,uint256)"); + bytes memory _eventParam = abi.encode(gaugePoolName, balances.crvRewardAmt, setIdCRVReward, balances.rewardAmt, setIdReward); + emitEvent(_eventCode, _eventParam); + }else{ + emit LogClaimedReward(gaugePoolName, balances.crvRewardAmt, setIdCRVReward); + bytes32 _eventCode = keccak256("LogClaimedReward(string,uint256,uint256"); + bytes memory _eventParam = abi.encode(gaugePoolName, balances.crvRewardAmt, setIdCRVReward); + emitEvent(_eventCode, _eventParam); + } } /** @@ -217,36 +195,6 @@ contract CurveGauge is GaugeHelper { emitEvent(_eventCodeWithdraw, _eventParamWithdraw); } - /** - * @dev Claim CRV Reward. - * @param gaugePoolName gauge pool name. - * @param setId Set CRV reward amount at this ID in `InstaMemory` Contract. - */ - function claimReward( - string calldata gaugePoolName, - uint setId - ) external payable { - CurveGaugeMapping curveGaugeMapping = CurveGaugeMapping(getCurveGaugeMappingAddr()); - address curveGaugeAddr = curveGaugeMapping.gaugeMapping(bytes32(stringToBytes32(gaugePoolName))); - require(curveGaugeAddr != address(0), "wrong-gauge-pool-name"); - IMintor mintor = IMintor(getCurveMintorAddr()); - IGauge gauge = IGauge(curveGaugeAddr); - TokenInterface crv_token = TokenInterface(address(gauge.crv_token())); - Balances memory balances; - - balances.intialCRVBal = crv_token.balanceOf(address(this)); - mintor.mint(curveGaugeAddr); - balances.finalCRVBal = crv_token.balanceOf(address(this)); - balances.crvRewardAmt = sub(balances.finalCRVBal, balances.intialCRVBal); - - setUint(setId, balances.crvRewardAmt); - - emit LogClaimedReward(gaugePoolName, balances.crvRewardAmt, setId); - bytes32 _eventCode = keccak256("LogClaimedReward(string,uint256,uint256)"); - bytes memory _eventParam = abi.encode(gaugePoolName, balances.crvRewardAmt, setId); - emitEvent(_eventCode, _eventParam); - } - /** * @dev Claim CRV Reward with Staked Reward token * @param gaugePoolName gauge pool name. @@ -258,30 +206,42 @@ contract CurveGauge is GaugeHelper { uint setId, uint setIdReward ) external payable { - CurveGaugeMapping curveGaugeMapping = CurveGaugeMapping(getCurveGaugeMappingAddr()); - address curveGaugeAddr = curveGaugeMapping.gaugeMapping(bytes32(stringToBytes32(gaugePoolName))); - require(curveGaugeAddr != address(0), "wrong-gauge-pool-name"); + ICurveGaugeMapping curveGaugeMapping = ICurveGaugeMapping(getCurveGaugeMappingAddr()); + ICurveGaugeMapping.GaugeData memory curveGaugeData = curveGaugeMapping.gaugeMapping(bytes32(stringToBytes32(gaugePoolName))); + require(curveGaugeData.gaugeAddress != address(0), "wrong-gauge-pool-name"); IMintor mintor = IMintor(getCurveMintorAddr()); - IGauge gauge = IGauge(curveGaugeAddr); + IGauge gauge = IGauge(curveGaugeData.gaugeAddress); TokenInterface crv_token = TokenInterface(address(gauge.crv_token())); - TokenInterface rewarded_token = TokenInterface(address(gauge.rewarded_token())); Balances memory balances; + if(curveGaugeData.rewardToken == true){ + TokenInterface rewarded_token = TokenInterface(address(gauge.rewarded_token())); + balances.intialRewardBal = rewarded_token.balanceOf(address(this)); + } + balances.intialCRVBal = crv_token.balanceOf(address(this)); - balances.intialRewardBal = rewarded_token.balanceOf(address(this)); - mintor.mint(curveGaugeAddr); + + mintor.mint(curveGaugeData.gaugeAddress); + balances.finalCRVBal = crv_token.balanceOf(address(this)); - balances.finalRewardBal = rewarded_token.balanceOf(address(this)); balances.crvRewardAmt = sub(balances.finalCRVBal, balances.intialCRVBal); - balances.rewardAmt = sub(balances.finalRewardBal, balances.intialRewardBal); - setUint(setId, balances.crvRewardAmt); - setUint(setIdReward, balances.rewardAmt); - emit LogClaimedReward(gaugePoolName, balances.crvRewardAmt, setId, balances.rewardAmt, setIdReward); - bytes32 _eventCode = keccak256("LogClaimedReward(string,uint256,uint256,uint256,uint256)"); - bytes memory _eventParam = abi.encode(gaugePoolName, balances.crvRewardAmt, setId, balances.rewardAmt, setIdReward); - emitEvent(_eventCode, _eventParam); + if(curveGaugeData.rewardToken == true){ + TokenInterface rewarded_token = TokenInterface(address(gauge.rewarded_token())); + balances.finalRewardBal = rewarded_token.balanceOf(address(this)); + balances.rewardAmt = sub(balances.finalRewardBal, balances.intialRewardBal); + setUint(setIdReward, balances.rewardAmt); + emit LogClaimedReward(gaugePoolName, balances.crvRewardAmt, setId, balances.rewardAmt, setIdReward); + bytes32 _eventCode = keccak256("LogClaimedReward(string,uint256,uint256,uint256,uint256)"); + bytes memory _eventParam = abi.encode(gaugePoolName, balances.crvRewardAmt, setId, balances.rewardAmt, setIdReward); + emitEvent(_eventCode, _eventParam); + }else{ + emit LogClaimedReward(gaugePoolName, balances.crvRewardAmt, setId); + bytes32 _eventCode = keccak256("LogClaimedReward(string,uint256,uint256"); + bytes memory _eventParam = abi.encode(gaugePoolName, balances.crvRewardAmt, setId); + emitEvent(_eventCode, _eventParam); + } } } diff --git a/contracts/mapping/curve_gauge_mapping.sol b/contracts/mapping/curve_gauge_mapping.sol index 7e79625..cd6b14f 100644 --- a/contracts/mapping/curve_gauge_mapping.sol +++ b/contracts/mapping/curve_gauge_mapping.sol @@ -43,11 +43,17 @@ contract Helpers is BytesHelper { address public constant instaIndex = 0x2971AdFa57b20E5a416aE5a708A8655A9c74f723; uint public version = 1; - mapping (bytes32 => address) public gaugeMapping; + mapping (bytes32 => GaugeData) public gaugeMapping; + + struct GaugeData { + address gaugeAddress; + bool rewardToken; + } event LogAddGaugeMapping( string gaugeName, - address gaugeAddress + address gaugeAddress, + bool rewardToken ); event LogRemoveGaugeMapping( @@ -64,22 +70,24 @@ contract Helpers is BytesHelper { function addGaugeMapping( string memory gaugeName, - address gaugeAddress + address gaugeAddress, + bool rewardToken ) public isChief { require(gaugeAddress != address(0), "gaugeAddress-not-vaild"); require(bytes(gaugeName).length <= 32, "Length-exceeds"); bytes32 gaugeType = stringToBytes32(gaugeName); - require(gaugeMapping[gaugeType] == address(0), "gaugePool-already-added"); + require(gaugeMapping[gaugeType].gaugeAddress == address(0), "gaugePool-already-added"); - gaugeMapping[gaugeType] = gaugeAddress; + gaugeMapping[gaugeType].gaugeAddress = gaugeAddress; + gaugeMapping[gaugeType].rewardToken = rewardToken; - emit LogAddGaugeMapping(gaugeName, gaugeAddress); + emit LogAddGaugeMapping(gaugeName, gaugeAddress, rewardToken); } function removeGaugeMapping(string memory gaugeName, address gaugeAddress) public isChief { require(gaugeAddress != address(0), "gaugeAddress-not-vaild"); bytes32 gaugeType = stringToBytes32(gaugeName); - require(gaugeMapping[gaugeType] == gaugeAddress, "different-gauge-pool"); + require(gaugeMapping[gaugeType].gaugeAddress == gaugeAddress, "different-gauge-pool"); delete gaugeMapping[gaugeType]; From 8a9ce14a9d1a85f2e82f6ec2b05b0725dfd88f50 Mon Sep 17 00:00:00 2001 From: Lecky Lao Date: Fri, 21 Aug 2020 01:53:33 +1000 Subject: [PATCH 09/19] added test for CurveGauge; added ABI for CurveGauge; added MockCurveGauge and MockCurveGaugeMapping; --- contracts/tests/MockCurveGauge.sol | 27 ++++ contracts/tests/MockCurveGaugeMapping.sol | 7 + test/CurveGauge.js | 149 ++++++++++++++++++++++ test/abi/curveGauge.json | 1 + 4 files changed, 184 insertions(+) create mode 100644 contracts/tests/MockCurveGauge.sol create mode 100644 contracts/tests/MockCurveGaugeMapping.sol create mode 100644 test/CurveGauge.js create mode 100644 test/abi/curveGauge.json diff --git a/contracts/tests/MockCurveGauge.sol b/contracts/tests/MockCurveGauge.sol new file mode 100644 index 0000000..c42896a --- /dev/null +++ b/contracts/tests/MockCurveGauge.sol @@ -0,0 +1,27 @@ +pragma solidity ^0.6.0; +pragma experimental ABIEncoderV2; + +import { ConnectCurveGauge } from "../connectors/curve_gauge.sol"; + +contract MockCurveGauge is ConnectCurveGauge{ + address public curveMintorAddr; + address public curveGaugeMappingAddr; + + constructor(address _curveMintorAddr, address _curveGaugeMappingAddr) public { + curveMintorAddr = _curveMintorAddr; + curveGaugeMappingAddr = _curveGaugeMappingAddr; + } + + function emitEvent(bytes32 eventCode, bytes memory eventData) override internal {} + + function getCurveGaugeMappingAddr() override internal view returns (address) { + return curveGaugeMappingAddr; + } + + function getCurveMintorAddr() override internal view returns (address) { + return curveMintorAddr; + } + + function setUint(uint setId, uint val) override internal {} +} + diff --git a/contracts/tests/MockCurveGaugeMapping.sol b/contracts/tests/MockCurveGaugeMapping.sol new file mode 100644 index 0000000..0996e6b --- /dev/null +++ b/contracts/tests/MockCurveGaugeMapping.sol @@ -0,0 +1,7 @@ +pragma solidity ^0.6.0; + +import { CurveGaugeMapping } from "../mapping/curve_gauge_mapping.sol"; + +contract MockCurveGaugeMapping is CurveGaugeMapping { + modifier isChief override {_;} +} diff --git a/test/CurveGauge.js b/test/CurveGauge.js new file mode 100644 index 0000000..1677caf --- /dev/null +++ b/test/CurveGauge.js @@ -0,0 +1,149 @@ +const { + BN, // Big Number support + expectEvent, // Assertions for emitted events + expectRevert, // Assertions for transactions that should fail + balance, + ether +} = require('@openzeppelin/test-helpers'); + +const MockContract = artifacts.require("MockContract"); +const MockCurveGauge = artifacts.require('MockCurveGauge'); +const MockCurveGaugeMapping = artifacts.require('MockCurveGaugeMapping'); +const erc20ABI = require("./abi/erc20.js"); +const gaugeABI = require("./abi/curveGauge.json"); + +contract("ConnectCurveGauge", async accounts => { + const [sender, receiver] = accounts; + let mock, mockCurveGauge, mockCurveGaugeMapping; + + before(async function () { + mock = await MockContract.new(); + mockCurveGaugeMapping = await MockCurveGaugeMapping.new(); + mockCurveGauge = await MockCurveGauge.new(mock.address, mockCurveGaugeMapping.address); + // lp_token = new web3.eth.Contract(erc20ABI, mock.address); + curveGauge = new web3.eth.Contract(gaugeABI, mock.address) + // mocking lp_token + let lp_token = await curveGauge.methods.lp_token().encodeABI(); + await mock.givenMethodReturnAddress(lp_token, mock.address); + // mocking crv_token + let crv_token = await curveGauge.methods.crv_token().encodeABI(); + await mock.givenMethodReturnAddress(crv_token, mock.address); + // mocking rewarded_token + let rewarded_token = await curveGauge.methods.rewarded_token().encodeABI(); + await mock.givenMethodReturnAddress(rewarded_token, mock.address); + + mockCurveGaugeMapping.addGaugeMapping('compound', mock.address, false); + mockCurveGaugeMapping.addGaugeMapping('susd', mock.address, true); + }) + + it('can deposit into compound gauge', async function() { + const tx = await mockCurveGauge.deposit( + "compound", + 10000000, + 0, + 0 + ) + expectEvent(tx, "LogDeposit", { + amount: "10000000", + getId: "0", + setId: "0" + }); + }); + + it('can claim reward from compound gauge', async function() { + const tx = await mockCurveGauge.claimReward( + "compound", + 0, + 0 + ) + expectEvent(tx, "LogClaimedReward"); + }); + + it('can withdraw from compound gauge', async function() { + const tx = await mockCurveGauge.withdraw( + "compound", + 10000000, + 0, + 0, + 0, + 0 + ) + expectEvent(tx, "LogClaimedReward"); + expectEvent(tx, "LogWithdraw", { + amount: "10000000", + getId: "0", + setId: "0" + }); + }); + + it('can deposit into susd gauge', async function() { + const tx = await mockCurveGauge.deposit( + "susd", + 10000000, + 0, + 0 + ) + expectEvent(tx, "LogDeposit", { + amount: "10000000", + getId: "0", + setId: "0" + }); + }); + + it('can claim reward from susd gauge', async function() { + const tx = await mockCurveGauge.claimReward( + "susd", + 0, + 0 + ) + expectEvent(tx, "LogClaimedReward"); + }); + + it('can withdraw from susd gauge', async function() { + const tx = await mockCurveGauge.withdraw( + "susd", + 10000000, + 0, + 0, + 0, + 0 + ) + expectEvent(tx, "LogClaimedReward"); + expectEvent(tx, "LogWithdraw", { + amount: "10000000", + getId: "0", + setId: "0" + }); + }); + + it('cannot deposit into unknown gauge', async function() { + const tx = mockCurveGauge.deposit( + "unknown", + 10000000, + 0, + 0 + ) + await expectRevert(tx, "wrong-gauge-pool-name") + }); + + it('cannot claim reward from unknown gauge', async function() { + const tx = mockCurveGauge.claimReward( + "unknown", + 0, + 0 + ) + await expectRevert(tx, "wrong-gauge-pool-name") + }); + + it('cannot withdraw from unknown gauge', async function() { + const tx = mockCurveGauge.withdraw( + "unknown", + 10000000, + 0, + 0, + 0, + 0 + ) + await expectRevert(tx, "wrong-gauge-pool-name") + }); +}) diff --git a/test/abi/curveGauge.json b/test/abi/curveGauge.json new file mode 100644 index 0000000..7123d81 --- /dev/null +++ b/test/abi/curveGauge.json @@ -0,0 +1 @@ +[{"name":"Deposit","inputs":[{"type":"address","name":"provider","indexed":true},{"type":"uint256","name":"value","indexed":false}],"anonymous":false,"type":"event"},{"name":"Withdraw","inputs":[{"type":"address","name":"provider","indexed":true},{"type":"uint256","name":"value","indexed":false}],"anonymous":false,"type":"event"},{"name":"UpdateLiquidityLimit","inputs":[{"type":"address","name":"user","indexed":false},{"type":"uint256","name":"original_balance","indexed":false},{"type":"uint256","name":"original_supply","indexed":false},{"type":"uint256","name":"working_balance","indexed":false},{"type":"uint256","name":"working_supply","indexed":false}],"anonymous":false,"type":"event"},{"outputs":[],"inputs":[{"type":"address","name":"lp_addr"},{"type":"address","name":"_minter"},{"type":"address","name":"_reward_contract"},{"type":"address","name":"_rewarded_token"}],"stateMutability":"nonpayable","type":"constructor"},{"name":"user_checkpoint","outputs":[{"type":"bool","name":""}],"inputs":[{"type":"address","name":"addr"}],"stateMutability":"nonpayable","type":"function","gas":2311984},{"name":"claimable_tokens","outputs":[{"type":"uint256","name":""}],"inputs":[{"type":"address","name":"addr"}],"stateMutability":"nonpayable","type":"function","gas":2231138},{"name":"claimable_reward","outputs":[{"type":"uint256","name":""}],"inputs":[{"type":"address","name":"addr"}],"stateMutability":"view","type":"function","gas":7300},{"name":"kick","outputs":[],"inputs":[{"type":"address","name":"addr"}],"stateMutability":"nonpayable","type":"function","gas":2317383},{"name":"set_approve_deposit","outputs":[],"inputs":[{"type":"address","name":"addr"},{"type":"bool","name":"can_deposit"}],"stateMutability":"nonpayable","type":"function","gas":35826},{"name":"deposit","outputs":[],"inputs":[{"type":"uint256","name":"_value"}],"stateMutability":"nonpayable","type":"function"},{"name":"deposit","outputs":[],"inputs":[{"type":"uint256","name":"_value"},{"type":"address","name":"addr"}],"stateMutability":"nonpayable","type":"function"},{"name":"withdraw","outputs":[],"inputs":[{"type":"uint256","name":"_value"}],"stateMutability":"nonpayable","type":"function"},{"name":"withdraw","outputs":[],"inputs":[{"type":"uint256","name":"_value"},{"type":"bool","name":"claim_rewards"}],"stateMutability":"nonpayable","type":"function"},{"name":"claim_rewards","outputs":[],"inputs":[],"stateMutability":"nonpayable","type":"function"},{"name":"claim_rewards","outputs":[],"inputs":[{"type":"address","name":"addr"}],"stateMutability":"nonpayable","type":"function"},{"name":"integrate_checkpoint","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2387},{"name":"minter","outputs":[{"type":"address","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":1511},{"name":"crv_token","outputs":[{"type":"address","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":1541},{"name":"lp_token","outputs":[{"type":"address","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":1571},{"name":"controller","outputs":[{"type":"address","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":1601},{"name":"voting_escrow","outputs":[{"type":"address","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":1631},{"name":"balanceOf","outputs":[{"type":"uint256","name":""}],"inputs":[{"type":"address","name":"arg0"}],"stateMutability":"view","type":"function","gas":1815},{"name":"totalSupply","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":1691},{"name":"future_epoch_time","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":1721},{"name":"approved_to_deposit","outputs":[{"type":"bool","name":""}],"inputs":[{"type":"address","name":"arg0"},{"type":"address","name":"arg1"}],"stateMutability":"view","type":"function","gas":2059},{"name":"working_balances","outputs":[{"type":"uint256","name":""}],"inputs":[{"type":"address","name":"arg0"}],"stateMutability":"view","type":"function","gas":1935},{"name":"working_supply","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":1811},{"name":"period","outputs":[{"type":"int128","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":1841},{"name":"period_timestamp","outputs":[{"type":"uint256","name":""}],"inputs":[{"type":"uint256","name":"arg0"}],"stateMutability":"view","type":"function","gas":1980},{"name":"integrate_inv_supply","outputs":[{"type":"uint256","name":""}],"inputs":[{"type":"uint256","name":"arg0"}],"stateMutability":"view","type":"function","gas":2010},{"name":"integrate_inv_supply_of","outputs":[{"type":"uint256","name":""}],"inputs":[{"type":"address","name":"arg0"}],"stateMutability":"view","type":"function","gas":2085},{"name":"integrate_checkpoint_of","outputs":[{"type":"uint256","name":""}],"inputs":[{"type":"address","name":"arg0"}],"stateMutability":"view","type":"function","gas":2115},{"name":"integrate_fraction","outputs":[{"type":"uint256","name":""}],"inputs":[{"type":"address","name":"arg0"}],"stateMutability":"view","type":"function","gas":2145},{"name":"inflation_rate","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2021},{"name":"reward_contract","outputs":[{"type":"address","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2051},{"name":"rewarded_token","outputs":[{"type":"address","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2081},{"name":"reward_integral","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2111},{"name":"reward_integral_for","outputs":[{"type":"uint256","name":""}],"inputs":[{"type":"address","name":"arg0"}],"stateMutability":"view","type":"function","gas":2295},{"name":"rewards_for","outputs":[{"type":"uint256","name":""}],"inputs":[{"type":"address","name":"arg0"}],"stateMutability":"view","type":"function","gas":2325},{"name":"claimed_rewards_for","outputs":[{"type":"uint256","name":""}],"inputs":[{"type":"address","name":"arg0"}],"stateMutability":"view","type":"function","gas":2355}] From 058fc7d8f577fa22f28bd416de29bb406855c2f7 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Thu, 20 Aug 2020 21:46:41 +0530 Subject: [PATCH 10/19] Code refactoring --- contracts/connectors/curve_gauge.sol | 82 +++++++++++----------------- 1 file changed, 33 insertions(+), 49 deletions(-) diff --git a/contracts/connectors/curve_gauge.sol b/contracts/connectors/curve_gauge.sol index 1276f5a..371b1d1 100644 --- a/contracts/connectors/curve_gauge.sol +++ b/contracts/connectors/curve_gauge.sol @@ -52,7 +52,7 @@ contract GaugeHelper is DSMath, Stores{ } } -contract CurveGauge is GaugeHelper { +contract CurveGaugeEvent is GaugeHelper { event LogDeposit( string indexed gaugePoolName, uint amount, @@ -75,12 +75,22 @@ contract CurveGauge is GaugeHelper { uint setIdReward ); - event LogClaimedReward( - string indexed gaugePoolName, - uint amount, - uint setId - ); + function emitLogWithdraw(string memory gaugePoolName, uint _amt, uint getId, uint setId) internal { + emit LogWithdraw(gaugePoolName, _amt, getId, setId); + bytes32 _eventCodeWithdraw = keccak256("LogWithdraw(string,uint256,uint256,uint256)"); + bytes memory _eventParamWithdraw = abi.encode(gaugePoolName, _amt, getId, setId); + emitEvent(_eventCodeWithdraw, _eventParamWithdraw); + } + function emitLogClaimedReward(string memory gaugePoolName, uint crvAmt, uint rewardAmt, uint setIdCrv, uint setIdReward) internal { + emit LogClaimedReward(gaugePoolName, crvAmt, rewardAmt, setIdCrv, setIdReward); + bytes32 _eventCode = keccak256("LogClaimedReward(string,uint256,uint256,uint256,uint256)"); + bytes memory _eventParam = abi.encode(gaugePoolName, crvAmt, rewardAmt, setIdCrv, setIdReward); + emitEvent(_eventCode, _eventParam); + } +} + +contract CurveGauge is CurveGaugeEvent { struct Balances{ uint intialCRVBal; uint intialRewardBal; @@ -105,7 +115,9 @@ contract CurveGauge is GaugeHelper { ) external payable { uint _amt = getUint(getId, amt); ICurveGaugeMapping curveGaugeMapping = ICurveGaugeMapping(getCurveGaugeMappingAddr()); - ICurveGaugeMapping.GaugeData memory curveGaugeData = curveGaugeMapping.gaugeMapping(bytes32(stringToBytes32(gaugePoolName))); + ICurveGaugeMapping.GaugeData memory curveGaugeData = curveGaugeMapping.gaugeMapping( + bytes32(stringToBytes32(gaugePoolName) + )); require(curveGaugeData.gaugeAddress != address(0), "wrong-gauge-pool-name"); IGauge gauge = IGauge(curveGaugeData.gaugeAddress); TokenInterface lp_token = TokenInterface(address(gauge.lp_token())); @@ -127,7 +139,7 @@ contract CurveGauge is GaugeHelper { * @param amt LP token amount. * @param getId Get token amount at this ID from `InstaMemory` Contract. * @param setId Set token amount at this ID in `InstaMemory` Contract. - * @param setIdCRVReward Set CRV token reward amount at this ID in `InstaMemory` Contract. + * @param setIdCrv Set CRV token reward amount at this ID in `InstaMemory` Contract. * @param setIdReward Set reward amount at this ID in `InstaMemory` Contract. */ function withdraw( @@ -135,7 +147,7 @@ contract CurveGauge is GaugeHelper { uint amt, uint getId, uint setId, - uint setIdCRVReward, + uint setIdCrv, uint setIdReward ) external payable { uint _amt = getUint(getId, amt); @@ -144,13 +156,14 @@ contract CurveGauge is GaugeHelper { require(curveGaugeData.gaugeAddress != address(0), "wrong-gauge-pool-name"); IGauge gauge = IGauge(curveGaugeData.gaugeAddress); TokenInterface crv_token = TokenInterface(address(gauge.crv_token())); + TokenInterface rewarded_token; Balances memory balances; _amt = _amt == uint(-1) ? gauge.balanceOf(address(this)) : _amt; balances.intialCRVBal = crv_token.balanceOf(address(this)); - if(curveGaugeData.rewardToken == true){ - TokenInterface rewarded_token = TokenInterface(address(gauge.rewarded_token())); + if (curveGaugeData.rewardToken) { + rewarded_token = TokenInterface(address(gauge.rewarded_token())); balances.intialRewardBal = rewarded_token.balanceOf(address(this)); } @@ -160,39 +173,17 @@ contract CurveGauge is GaugeHelper { balances.finalCRVBal = crv_token.balanceOf(address(this)); balances.crvRewardAmt = sub(balances.finalCRVBal, balances.intialCRVBal); setUint(setId, _amt); - setUint(setIdCRVReward, balances.crvRewardAmt); + setUint(setIdCrv, balances.crvRewardAmt); emitLogWithdraw(gaugePoolName, _amt, getId, setId); - if(curveGaugeData.rewardToken == true){ - TokenInterface rewarded_token = TokenInterface(address(gauge.rewarded_token())); + if (curveGaugeData.rewardToken) { balances.finalRewardBal = rewarded_token.balanceOf(address(this)); balances.rewardAmt = sub(balances.finalRewardBal, balances.intialRewardBal); setUint(setIdReward, balances.rewardAmt); - emit LogClaimedReward(gaugePoolName, balances.crvRewardAmt, setIdCRVReward, balances.rewardAmt, setIdReward); - bytes32 _eventCode = keccak256("LogClaimedReward(string,uint256,uint256,uint256,uint256)"); - bytes memory _eventParam = abi.encode(gaugePoolName, balances.crvRewardAmt, setIdCRVReward, balances.rewardAmt, setIdReward); - emitEvent(_eventCode, _eventParam); - }else{ - emit LogClaimedReward(gaugePoolName, balances.crvRewardAmt, setIdCRVReward); - bytes32 _eventCode = keccak256("LogClaimedReward(string,uint256,uint256"); - bytes memory _eventParam = abi.encode(gaugePoolName, balances.crvRewardAmt, setIdCRVReward); - emitEvent(_eventCode, _eventParam); } - } - /** - * @dev emit LogWithdraw event - * @param gaugePoolName gauge pool name. - * @param _amt LP token amount. - * @param getId Get token amount at this ID from `InstaMemory` Contract. - * @param setId Set token amount at this ID in `InstaMemory` Contract. - */ - function emitLogWithdraw(string memory gaugePoolName, uint _amt, uint getId, uint setId) internal { - emit LogWithdraw(gaugePoolName, _amt, getId, setId); - bytes32 _eventCodeWithdraw = keccak256("LogWithdraw(string,uint256,uint256,uint256)"); - bytes memory _eventParamWithdraw = abi.encode(gaugePoolName, _amt, getId, setId); - emitEvent(_eventCodeWithdraw, _eventParamWithdraw); + emitLogClaimedReward(gaugePoolName, balances.crvRewardAmt, balances.rewardAmt, setIdCrv, setIdReward); } /** @@ -212,10 +203,11 @@ contract CurveGauge is GaugeHelper { IMintor mintor = IMintor(getCurveMintorAddr()); IGauge gauge = IGauge(curveGaugeData.gaugeAddress); TokenInterface crv_token = TokenInterface(address(gauge.crv_token())); + TokenInterface rewarded_token; Balances memory balances; - if(curveGaugeData.rewardToken == true){ - TokenInterface rewarded_token = TokenInterface(address(gauge.rewarded_token())); + if (curveGaugeData.rewardToken) { + rewarded_token = TokenInterface(address(gauge.rewarded_token())); balances.intialRewardBal = rewarded_token.balanceOf(address(this)); } @@ -227,21 +219,13 @@ contract CurveGauge is GaugeHelper { balances.crvRewardAmt = sub(balances.finalCRVBal, balances.intialCRVBal); setUint(setId, balances.crvRewardAmt); - if(curveGaugeData.rewardToken == true){ - TokenInterface rewarded_token = TokenInterface(address(gauge.rewarded_token())); + if(curveGaugeData.rewardToken){ balances.finalRewardBal = rewarded_token.balanceOf(address(this)); balances.rewardAmt = sub(balances.finalRewardBal, balances.intialRewardBal); setUint(setIdReward, balances.rewardAmt); - emit LogClaimedReward(gaugePoolName, balances.crvRewardAmt, setId, balances.rewardAmt, setIdReward); - bytes32 _eventCode = keccak256("LogClaimedReward(string,uint256,uint256,uint256,uint256)"); - bytes memory _eventParam = abi.encode(gaugePoolName, balances.crvRewardAmt, setId, balances.rewardAmt, setIdReward); - emitEvent(_eventCode, _eventParam); - }else{ - emit LogClaimedReward(gaugePoolName, balances.crvRewardAmt, setId); - bytes32 _eventCode = keccak256("LogClaimedReward(string,uint256,uint256"); - bytes memory _eventParam = abi.encode(gaugePoolName, balances.crvRewardAmt, setId); - emitEvent(_eventCode, _eventParam); } + + emitLogClaimedReward(gaugePoolName, balances.crvRewardAmt, balances.rewardAmt, setId, setIdReward); } } From b2a31a24c71fab46ac1f476e1671519ad420c1f2 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Thu, 20 Aug 2020 21:51:54 +0530 Subject: [PATCH 11/19] Minor edits --- contracts/connectors/curve_gauge.sol | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/contracts/connectors/curve_gauge.sol b/contracts/connectors/curve_gauge.sol index 371b1d1..75fc9f2 100644 --- a/contracts/connectors/curve_gauge.sol +++ b/contracts/connectors/curve_gauge.sol @@ -124,7 +124,9 @@ contract CurveGauge is CurveGaugeEvent { _amt = _amt == uint(-1) ? lp_token.balanceOf(address(this)) : _amt; lp_token.approve(address(curveGaugeData.gaugeAddress), _amt); + gauge.deposit(_amt); + setUint(setId, _amt); emit LogDeposit(gaugePoolName, _amt, getId, setId); @@ -152,7 +154,9 @@ contract CurveGauge is CurveGaugeEvent { ) external payable { uint _amt = getUint(getId, amt); ICurveGaugeMapping curveGaugeMapping = ICurveGaugeMapping(getCurveGaugeMappingAddr()); - ICurveGaugeMapping.GaugeData memory curveGaugeData = curveGaugeMapping.gaugeMapping(bytes32(stringToBytes32(gaugePoolName))); + ICurveGaugeMapping.GaugeData memory curveGaugeData = curveGaugeMapping.gaugeMapping( + bytes32(stringToBytes32(gaugePoolName)) + ); require(curveGaugeData.gaugeAddress != address(0), "wrong-gauge-pool-name"); IGauge gauge = IGauge(curveGaugeData.gaugeAddress); TokenInterface crv_token = TokenInterface(address(gauge.crv_token())); @@ -172,17 +176,17 @@ contract CurveGauge is CurveGaugeEvent { balances.finalCRVBal = crv_token.balanceOf(address(this)); balances.crvRewardAmt = sub(balances.finalCRVBal, balances.intialCRVBal); + setUint(setId, _amt); setUint(setIdCrv, balances.crvRewardAmt); - emitLogWithdraw(gaugePoolName, _amt, getId, setId); - if (curveGaugeData.rewardToken) { balances.finalRewardBal = rewarded_token.balanceOf(address(this)); balances.rewardAmt = sub(balances.finalRewardBal, balances.intialRewardBal); setUint(setIdReward, balances.rewardAmt); } + emitLogWithdraw(gaugePoolName, _amt, getId, setId); emitLogClaimedReward(gaugePoolName, balances.crvRewardAmt, balances.rewardAmt, setIdCrv, setIdReward); } @@ -198,7 +202,9 @@ contract CurveGauge is CurveGaugeEvent { uint setIdReward ) external payable { ICurveGaugeMapping curveGaugeMapping = ICurveGaugeMapping(getCurveGaugeMappingAddr()); - ICurveGaugeMapping.GaugeData memory curveGaugeData = curveGaugeMapping.gaugeMapping(bytes32(stringToBytes32(gaugePoolName))); + ICurveGaugeMapping.GaugeData memory curveGaugeData = curveGaugeMapping.gaugeMapping( + bytes32(stringToBytes32(gaugePoolName)) + ); require(curveGaugeData.gaugeAddress != address(0), "wrong-gauge-pool-name"); IMintor mintor = IMintor(getCurveMintorAddr()); IGauge gauge = IGauge(curveGaugeData.gaugeAddress); @@ -217,6 +223,7 @@ contract CurveGauge is CurveGaugeEvent { balances.finalCRVBal = crv_token.balanceOf(address(this)); balances.crvRewardAmt = sub(balances.finalCRVBal, balances.intialCRVBal); + setUint(setId, balances.crvRewardAmt); if(curveGaugeData.rewardToken){ From 8e5f68efbd74f78ef5b6ba268fd0089e25690c92 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Thu, 20 Aug 2020 21:57:37 +0530 Subject: [PATCH 12/19] Removed not used function --- contracts/mapping/curve_gauge_mapping.sol | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/contracts/mapping/curve_gauge_mapping.sol b/contracts/mapping/curve_gauge_mapping.sol index cd6b14f..22863d1 100644 --- a/contracts/mapping/curve_gauge_mapping.sol +++ b/contracts/mapping/curve_gauge_mapping.sol @@ -20,22 +20,6 @@ contract BytesHelper { result := mload(add(str, 32)) } } - - function bytes32ToString(bytes32 _bytes32) internal pure returns (string memory) { - bytes32 _temp; - uint count; - for (uint256 i; i < 32; i++) { - _temp = _bytes32[i]; - if( _temp != bytes32(0)) { - count += 1; - } - } - bytes memory bytesArray = new bytes(count); - for (uint256 i; i < count; i++) { - bytesArray[i] = (_bytes32[i]); - } - return (string(bytesArray)); - } } contract Helpers is BytesHelper { From 73a5eee1fd7f657f704023e2abd4f7a1eea1fc07 Mon Sep 17 00:00:00 2001 From: Lecky Lao Date: Fri, 21 Aug 2020 03:38:51 +1000 Subject: [PATCH 13/19] added addGaugeMappings into curveGaugeMapping to add multiple mappings; added test for that; --- contracts/mapping/curve_gauge_mapping.sol | 11 +++++++++++ contracts/tests/MockCurveGaugeMapping.sol | 1 + test/CurveGauge.js | 9 +++++++-- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/contracts/mapping/curve_gauge_mapping.sol b/contracts/mapping/curve_gauge_mapping.sol index cd6b14f..6a10759 100644 --- a/contracts/mapping/curve_gauge_mapping.sol +++ b/contracts/mapping/curve_gauge_mapping.sol @@ -68,6 +68,17 @@ contract Helpers is BytesHelper { _; } + function addGaugeMappings( + string[] memory gaugeNames, + address[] memory gaugeAddresses, + bool[] memory rewardTokens + ) public isChief { + require(gaugeNames.length == gaugeAddresses.length && gaugeAddresses.length == rewardTokens.length, "length-not-match"); + for (uint32 i; i < gaugeNames.length; i++) { + addGaugeMapping(gaugeNames[i], gaugeAddresses[i], rewardTokens[i]); + } + } + function addGaugeMapping( string memory gaugeName, address gaugeAddress, diff --git a/contracts/tests/MockCurveGaugeMapping.sol b/contracts/tests/MockCurveGaugeMapping.sol index 0996e6b..c80852c 100644 --- a/contracts/tests/MockCurveGaugeMapping.sol +++ b/contracts/tests/MockCurveGaugeMapping.sol @@ -1,4 +1,5 @@ pragma solidity ^0.6.0; +pragma experimental ABIEncoderV2; import { CurveGaugeMapping } from "../mapping/curve_gauge_mapping.sol"; diff --git a/test/CurveGauge.js b/test/CurveGauge.js index 1677caf..96c2d26 100644 --- a/test/CurveGauge.js +++ b/test/CurveGauge.js @@ -32,8 +32,8 @@ contract("ConnectCurveGauge", async accounts => { let rewarded_token = await curveGauge.methods.rewarded_token().encodeABI(); await mock.givenMethodReturnAddress(rewarded_token, mock.address); - mockCurveGaugeMapping.addGaugeMapping('compound', mock.address, false); - mockCurveGaugeMapping.addGaugeMapping('susd', mock.address, true); + await mockCurveGaugeMapping.addGaugeMapping('compound', mock.address, false); + await mockCurveGaugeMapping.addGaugeMapping('susd', mock.address, true); }) it('can deposit into compound gauge', async function() { @@ -146,4 +146,9 @@ contract("ConnectCurveGauge", async accounts => { ) await expectRevert(tx, "wrong-gauge-pool-name") }); + + it('can add multiple gauge mappings', async function() { + const tx = await mockCurveGaugeMapping.addGaugeMappings(['sbtc'], [mock.address], [true]); + expectEvent(tx, "LogAddGaugeMapping"); + }); }) From acfa6d2d3676fa7f065b361ef800206f1d702050 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Fri, 21 Aug 2020 03:49:49 +0530 Subject: [PATCH 14/19] Added constructor in mapping --- contracts/tests/curve_staking.prod.sol | 310 +++++++++++++++++++++++++ 1 file changed, 310 insertions(+) create mode 100644 contracts/tests/curve_staking.prod.sol diff --git a/contracts/tests/curve_staking.prod.sol b/contracts/tests/curve_staking.prod.sol new file mode 100644 index 0000000..ccb1148 --- /dev/null +++ b/contracts/tests/curve_staking.prod.sol @@ -0,0 +1,310 @@ +pragma solidity ^0.6.0; + +interface TokenInterface { + function approve(address, uint256) external; + function transfer(address, uint) external; + function transferFrom(address, address, uint) external; + function deposit() external payable; + function withdraw(uint) external; + function balanceOf(address) external view returns (uint); + function decimals() external view returns (uint); +} + +interface MemoryInterface { + function getUint(uint id) external returns (uint num); + function setUint(uint id, uint val) external; +} + +interface EventInterface { + function emitEvent(uint connectorType, uint connectorID, bytes32 eventCode, bytes calldata eventData) external; +} + +contract Stores { + /** + * @dev Return memory variable address + */ + function getMemoryAddr() internal pure returns (address) { + return 0x8a5419CfC711B2343c17a6ABf4B2bAFaBb06957F; // InstaMemory Address + } + + /** + * @dev Return InstaEvent Address. + */ + function getEventAddr() internal pure returns (address) { + return 0x2af7ea6Cb911035f3eb1ED895Cb6692C39ecbA97; // InstaEvent Address + } + + /** + * @dev Get Uint value from InstaMemory Contract. + */ + function getUint(uint getId, uint val) internal returns (uint returnVal) { + returnVal = getId == 0 ? val : MemoryInterface(getMemoryAddr()).getUint(getId); + } + + /** + * @dev Set Uint value in InstaMemory Contract. + */ + function setUint(uint setId, uint val) virtual internal { + if (setId != 0) MemoryInterface(getMemoryAddr()).setUint(setId, val); + } + + /** + * @dev emit event on event contract + */ + function emitEvent(bytes32 eventCode, bytes memory eventData) virtual internal { + (uint model, uint id) = connectorID(); + EventInterface(getEventAddr()).emitEvent(model, id, eventCode, eventData); + } + + /** + * @dev Connector Details - needs to be changed before deployment + */ + function connectorID() public view returns(uint model, uint id) { + (model, id) = (1, 39); + } + +} + +/** + * @dev Wrappers over Solidity's arithmetic operations with added overflow + * checks. + * + * Arithmetic operations in Solidity wrap on overflow. This can easily result + * in bugs, because programmers usually assume that an overflow raises an + * error, which is the standard behavior in high level programming languages. + * `SafeMath` restores this intuition by reverting the transaction when an + * operation overflows. + * + * Using this library instead of the unchecked operations eliminates an entire + * class of bugs, so it's recommended to use it always. + */ +library SafeMath { + /** + * @dev Returns the addition of two unsigned integers, reverting on + * overflow. + * + * Counterpart to Solidity's `+` operator. + * + * Requirements: + * + * - Addition cannot overflow. + */ + function add(uint256 a, uint256 b) internal pure returns (uint256) { + uint256 c = a + b; + require(c >= a, "SafeMath: addition overflow"); + + return c; + } + + /** + * @dev Returns the subtraction of two unsigned integers, reverting on + * overflow (when the result is negative). + * + * Counterpart to Solidity's `-` operator. + * + * Requirements: + * + * - Subtraction cannot overflow. + */ + function sub(uint256 a, uint256 b) internal pure returns (uint256) { + return sub(a, b, "SafeMath: subtraction overflow"); + } + + /** + * @dev Returns the subtraction of two unsigned integers, reverting with custom message on + * overflow (when the result is negative). + * + * Counterpart to Solidity's `-` operator. + * + * Requirements: + * + * - Subtraction cannot overflow. + */ + function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + require(b <= a, errorMessage); + uint256 c = a - b; + + return c; + } + + /** + * @dev Returns the multiplication of two unsigned integers, reverting on + * overflow. + * + * Counterpart to Solidity's `*` operator. + * + * Requirements: + * + * - Multiplication cannot overflow. + */ + function mul(uint256 a, uint256 b) internal pure returns (uint256) { + // Gas optimization: this is cheaper than requiring 'a' not being zero, but the + // benefit is lost if 'b' is also tested. + // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 + if (a == 0) { + return 0; + } + + uint256 c = a * b; + require(c / a == b, "SafeMath: multiplication overflow"); + + return c; + } + + /** + * @dev Returns the integer division of two unsigned integers. Reverts on + * division by zero. The result is rounded towards zero. + * + * Counterpart to Solidity's `/` operator. Note: this function uses a + * `revert` opcode (which leaves remaining gas untouched) while Solidity + * uses an invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * + * - The divisor cannot be zero. + */ + function div(uint256 a, uint256 b) internal pure returns (uint256) { + return div(a, b, "SafeMath: division by zero"); + } + + /** + * @dev Returns the integer division of two unsigned integers. Reverts with custom message on + * division by zero. The result is rounded towards zero. + * + * Counterpart to Solidity's `/` operator. Note: this function uses a + * `revert` opcode (which leaves remaining gas untouched) while Solidity + * uses an invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * + * - The divisor cannot be zero. + */ + function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + require(b > 0, errorMessage); + uint256 c = a / b; + // assert(a == b * c + a % b); // There is no case in which this doesn't hold + + return c; + } + + /** + * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), + * Reverts when dividing by zero. + * + * Counterpart to Solidity's `%` operator. This function uses a `revert` + * opcode (which leaves remaining gas untouched) while Solidity uses an + * invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * + * - The divisor cannot be zero. + */ + function mod(uint256 a, uint256 b) internal pure returns (uint256) { + return mod(a, b, "SafeMath: modulo by zero"); + } + + /** + * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), + * Reverts with custom message when dividing by zero. + * + * Counterpart to Solidity's `%` operator. This function uses a `revert` + * opcode (which leaves remaining gas untouched) while Solidity uses an + * invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * + * - The divisor cannot be zero. + */ + function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + require(b != 0, errorMessage); + return a % b; + } +} + +contract DSMath { + uint constant WAD = 10 ** 18; + uint constant RAY = 10 ** 27; + + function add(uint x, uint y) internal pure returns (uint z) { + z = SafeMath.add(x, y); + } + + function sub(uint x, uint y) internal virtual pure returns (uint z) { + z = SafeMath.sub(x, y); + } + + function mul(uint x, uint y) internal pure returns (uint z) { + z = SafeMath.mul(x, y); + } + + function div(uint x, uint y) internal pure returns (uint z) { + z = SafeMath.div(x, y); + } + + function wmul(uint x, uint y) internal pure returns (uint z) { + z = SafeMath.add(SafeMath.mul(x, y), WAD / 2) / WAD; + } + + function wdiv(uint x, uint y) internal pure returns (uint z) { + z = SafeMath.add(SafeMath.mul(x, WAD), y / 2) / y; + } + + function rdiv(uint x, uint y) internal pure returns (uint z) { + z = SafeMath.add(SafeMath.mul(x, RAY), y / 2) / y; + } + + function rmul(uint x, uint y) internal pure returns (uint z) { + z = SafeMath.add(SafeMath.mul(x, y), RAY / 2) / RAY; + } + +} + +interface ICurve { + function claim(address addr) external; +} + +contract CurveVestingHelpers is Stores, DSMath { + /** + * @dev Return Curve Token Address + */ + function getCurveTokenAddr() internal pure returns (address) { + return 0xD533a949740bb3306d119CC777fa900bA034cd52; + } + + /** + * @dev Return Curve Vesting Address + */ + function getCurveVestingAddr() internal pure returns (address) { + return 0x575CCD8e2D300e2377B43478339E364000318E2c; + } +} + +contract CurveVestingProtocol is CurveVestingHelpers { + event LogClaim(address account, uint256 claimAmount, uint256 getId, uint256 setId); + + /** + * @dev Claim Curve DAO Token. + * @param getId Get token amount at this ID from `InstaMemory` Contract. + * @param setId Set token amount at this ID in `InstaMemory` Contract. + */ + function claim(uint getId, uint setId) external{ + TokenInterface curveTokenContract = TokenInterface(getCurveTokenAddr()); + + uint initialCurveBal = curveTokenContract.balanceOf(address(this)); + ICurve(getCurveVestingAddr()).claim(address(this)); + uint finalCurveBal = curveTokenContract.balanceOf(address(this)); + + uint claimedAmt = sub(finalCurveBal, initialCurveBal); + + setUint(setId, claimedAmt); + + emit LogClaim(address(this), claimedAmt, getId, setId); + bytes32 _eventCode = keccak256("LogClaim(address,uint256,uint256,uint256)"); + bytes memory _eventParam = abi.encode(address(this), claimedAmt, getId, setId); + emitEvent(_eventCode, _eventParam); + } +} + +contract ConnectCurveVesting is CurveVestingProtocol { + string public name = "Curve-vesting-v1"; +} From e3bebae9b6820d8c43427c67ef4b1e2121d07327 Mon Sep 17 00:00:00 2001 From: Thrilok kumar Date: Fri, 21 Aug 2020 03:53:38 +0530 Subject: [PATCH 15/19] Delete curve_staking.prod.sol --- contracts/tests/curve_staking.prod.sol | 310 ------------------------- 1 file changed, 310 deletions(-) delete mode 100644 contracts/tests/curve_staking.prod.sol diff --git a/contracts/tests/curve_staking.prod.sol b/contracts/tests/curve_staking.prod.sol deleted file mode 100644 index ccb1148..0000000 --- a/contracts/tests/curve_staking.prod.sol +++ /dev/null @@ -1,310 +0,0 @@ -pragma solidity ^0.6.0; - -interface TokenInterface { - function approve(address, uint256) external; - function transfer(address, uint) external; - function transferFrom(address, address, uint) external; - function deposit() external payable; - function withdraw(uint) external; - function balanceOf(address) external view returns (uint); - function decimals() external view returns (uint); -} - -interface MemoryInterface { - function getUint(uint id) external returns (uint num); - function setUint(uint id, uint val) external; -} - -interface EventInterface { - function emitEvent(uint connectorType, uint connectorID, bytes32 eventCode, bytes calldata eventData) external; -} - -contract Stores { - /** - * @dev Return memory variable address - */ - function getMemoryAddr() internal pure returns (address) { - return 0x8a5419CfC711B2343c17a6ABf4B2bAFaBb06957F; // InstaMemory Address - } - - /** - * @dev Return InstaEvent Address. - */ - function getEventAddr() internal pure returns (address) { - return 0x2af7ea6Cb911035f3eb1ED895Cb6692C39ecbA97; // InstaEvent Address - } - - /** - * @dev Get Uint value from InstaMemory Contract. - */ - function getUint(uint getId, uint val) internal returns (uint returnVal) { - returnVal = getId == 0 ? val : MemoryInterface(getMemoryAddr()).getUint(getId); - } - - /** - * @dev Set Uint value in InstaMemory Contract. - */ - function setUint(uint setId, uint val) virtual internal { - if (setId != 0) MemoryInterface(getMemoryAddr()).setUint(setId, val); - } - - /** - * @dev emit event on event contract - */ - function emitEvent(bytes32 eventCode, bytes memory eventData) virtual internal { - (uint model, uint id) = connectorID(); - EventInterface(getEventAddr()).emitEvent(model, id, eventCode, eventData); - } - - /** - * @dev Connector Details - needs to be changed before deployment - */ - function connectorID() public view returns(uint model, uint id) { - (model, id) = (1, 39); - } - -} - -/** - * @dev Wrappers over Solidity's arithmetic operations with added overflow - * checks. - * - * Arithmetic operations in Solidity wrap on overflow. This can easily result - * in bugs, because programmers usually assume that an overflow raises an - * error, which is the standard behavior in high level programming languages. - * `SafeMath` restores this intuition by reverting the transaction when an - * operation overflows. - * - * Using this library instead of the unchecked operations eliminates an entire - * class of bugs, so it's recommended to use it always. - */ -library SafeMath { - /** - * @dev Returns the addition of two unsigned integers, reverting on - * overflow. - * - * Counterpart to Solidity's `+` operator. - * - * Requirements: - * - * - Addition cannot overflow. - */ - function add(uint256 a, uint256 b) internal pure returns (uint256) { - uint256 c = a + b; - require(c >= a, "SafeMath: addition overflow"); - - return c; - } - - /** - * @dev Returns the subtraction of two unsigned integers, reverting on - * overflow (when the result is negative). - * - * Counterpart to Solidity's `-` operator. - * - * Requirements: - * - * - Subtraction cannot overflow. - */ - function sub(uint256 a, uint256 b) internal pure returns (uint256) { - return sub(a, b, "SafeMath: subtraction overflow"); - } - - /** - * @dev Returns the subtraction of two unsigned integers, reverting with custom message on - * overflow (when the result is negative). - * - * Counterpart to Solidity's `-` operator. - * - * Requirements: - * - * - Subtraction cannot overflow. - */ - function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { - require(b <= a, errorMessage); - uint256 c = a - b; - - return c; - } - - /** - * @dev Returns the multiplication of two unsigned integers, reverting on - * overflow. - * - * Counterpart to Solidity's `*` operator. - * - * Requirements: - * - * - Multiplication cannot overflow. - */ - function mul(uint256 a, uint256 b) internal pure returns (uint256) { - // Gas optimization: this is cheaper than requiring 'a' not being zero, but the - // benefit is lost if 'b' is also tested. - // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 - if (a == 0) { - return 0; - } - - uint256 c = a * b; - require(c / a == b, "SafeMath: multiplication overflow"); - - return c; - } - - /** - * @dev Returns the integer division of two unsigned integers. Reverts on - * division by zero. The result is rounded towards zero. - * - * Counterpart to Solidity's `/` operator. Note: this function uses a - * `revert` opcode (which leaves remaining gas untouched) while Solidity - * uses an invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - * - The divisor cannot be zero. - */ - function div(uint256 a, uint256 b) internal pure returns (uint256) { - return div(a, b, "SafeMath: division by zero"); - } - - /** - * @dev Returns the integer division of two unsigned integers. Reverts with custom message on - * division by zero. The result is rounded towards zero. - * - * Counterpart to Solidity's `/` operator. Note: this function uses a - * `revert` opcode (which leaves remaining gas untouched) while Solidity - * uses an invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - * - The divisor cannot be zero. - */ - function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { - require(b > 0, errorMessage); - uint256 c = a / b; - // assert(a == b * c + a % b); // There is no case in which this doesn't hold - - return c; - } - - /** - * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), - * Reverts when dividing by zero. - * - * Counterpart to Solidity's `%` operator. This function uses a `revert` - * opcode (which leaves remaining gas untouched) while Solidity uses an - * invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - * - The divisor cannot be zero. - */ - function mod(uint256 a, uint256 b) internal pure returns (uint256) { - return mod(a, b, "SafeMath: modulo by zero"); - } - - /** - * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), - * Reverts with custom message when dividing by zero. - * - * Counterpart to Solidity's `%` operator. This function uses a `revert` - * opcode (which leaves remaining gas untouched) while Solidity uses an - * invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - * - The divisor cannot be zero. - */ - function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { - require(b != 0, errorMessage); - return a % b; - } -} - -contract DSMath { - uint constant WAD = 10 ** 18; - uint constant RAY = 10 ** 27; - - function add(uint x, uint y) internal pure returns (uint z) { - z = SafeMath.add(x, y); - } - - function sub(uint x, uint y) internal virtual pure returns (uint z) { - z = SafeMath.sub(x, y); - } - - function mul(uint x, uint y) internal pure returns (uint z) { - z = SafeMath.mul(x, y); - } - - function div(uint x, uint y) internal pure returns (uint z) { - z = SafeMath.div(x, y); - } - - function wmul(uint x, uint y) internal pure returns (uint z) { - z = SafeMath.add(SafeMath.mul(x, y), WAD / 2) / WAD; - } - - function wdiv(uint x, uint y) internal pure returns (uint z) { - z = SafeMath.add(SafeMath.mul(x, WAD), y / 2) / y; - } - - function rdiv(uint x, uint y) internal pure returns (uint z) { - z = SafeMath.add(SafeMath.mul(x, RAY), y / 2) / y; - } - - function rmul(uint x, uint y) internal pure returns (uint z) { - z = SafeMath.add(SafeMath.mul(x, y), RAY / 2) / RAY; - } - -} - -interface ICurve { - function claim(address addr) external; -} - -contract CurveVestingHelpers is Stores, DSMath { - /** - * @dev Return Curve Token Address - */ - function getCurveTokenAddr() internal pure returns (address) { - return 0xD533a949740bb3306d119CC777fa900bA034cd52; - } - - /** - * @dev Return Curve Vesting Address - */ - function getCurveVestingAddr() internal pure returns (address) { - return 0x575CCD8e2D300e2377B43478339E364000318E2c; - } -} - -contract CurveVestingProtocol is CurveVestingHelpers { - event LogClaim(address account, uint256 claimAmount, uint256 getId, uint256 setId); - - /** - * @dev Claim Curve DAO Token. - * @param getId Get token amount at this ID from `InstaMemory` Contract. - * @param setId Set token amount at this ID in `InstaMemory` Contract. - */ - function claim(uint getId, uint setId) external{ - TokenInterface curveTokenContract = TokenInterface(getCurveTokenAddr()); - - uint initialCurveBal = curveTokenContract.balanceOf(address(this)); - ICurve(getCurveVestingAddr()).claim(address(this)); - uint finalCurveBal = curveTokenContract.balanceOf(address(this)); - - uint claimedAmt = sub(finalCurveBal, initialCurveBal); - - setUint(setId, claimedAmt); - - emit LogClaim(address(this), claimedAmt, getId, setId); - bytes32 _eventCode = keccak256("LogClaim(address,uint256,uint256,uint256)"); - bytes memory _eventParam = abi.encode(address(this), claimedAmt, getId, setId); - emitEvent(_eventCode, _eventParam); - } -} - -contract ConnectCurveVesting is CurveVestingProtocol { - string public name = "Curve-vesting-v1"; -} From ee5000da1b25c623fe14c482731fc789b077c722 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Fri, 21 Aug 2020 03:54:01 +0530 Subject: [PATCH 16/19] Added constructor in mapping gauge --- contracts/mapping/curve_gauge_mapping.sol | 37 +++++++++++++++-------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/contracts/mapping/curve_gauge_mapping.sol b/contracts/mapping/curve_gauge_mapping.sol index 69b0210..f9c78cf 100644 --- a/contracts/mapping/curve_gauge_mapping.sol +++ b/contracts/mapping/curve_gauge_mapping.sol @@ -52,22 +52,11 @@ contract Helpers is BytesHelper { _; } - function addGaugeMappings( - string[] memory gaugeNames, - address[] memory gaugeAddresses, - bool[] memory rewardTokens - ) public isChief { - require(gaugeNames.length == gaugeAddresses.length && gaugeAddresses.length == rewardTokens.length, "length-not-match"); - for (uint32 i; i < gaugeNames.length; i++) { - addGaugeMapping(gaugeNames[i], gaugeAddresses[i], rewardTokens[i]); - } - } - - function addGaugeMapping( + function _addGaugeMapping( string memory gaugeName, address gaugeAddress, bool rewardToken - ) public isChief { + ) internal { require(gaugeAddress != address(0), "gaugeAddress-not-vaild"); require(bytes(gaugeName).length <= 32, "Length-exceeds"); bytes32 gaugeType = stringToBytes32(gaugeName); @@ -79,6 +68,17 @@ contract Helpers is BytesHelper { emit LogAddGaugeMapping(gaugeName, gaugeAddress, rewardToken); } + function addGaugeMappings( + string[] memory gaugeNames, + address[] memory gaugeAddresses, + bool[] memory rewardTokens + ) public isChief { + require(gaugeNames.length == gaugeAddresses.length && gaugeAddresses.length == rewardTokens.length, "length-not-match"); + for (uint32 i; i < gaugeNames.length; i++) { + _addGaugeMapping(gaugeNames[i], gaugeAddresses[i], rewardTokens[i]); + } + } + function removeGaugeMapping(string memory gaugeName, address gaugeAddress) public isChief { require(gaugeAddress != address(0), "gaugeAddress-not-vaild"); bytes32 gaugeType = stringToBytes32(gaugeName); @@ -95,4 +95,15 @@ contract Helpers is BytesHelper { contract CurveGaugeMapping is Helpers { string constant public name = "Curve-Gauge-Mapping-v1"; + + constructor ( + string[] memory gaugeNames, + address[] memory gaugeAddresses, + bool[] memory rewardTokens + ) public { + require(gaugeNames.length == gaugeAddresses.length && gaugeAddresses.length == rewardTokens.length, "length-not-match"); + for (uint32 i; i < gaugeNames.length; i++) { + _addGaugeMapping(gaugeNames[i], gaugeAddresses[i], rewardTokens[i]); + } + } } From 321b66a8615c273b3e3c77dbbf53e9e7e2e91e64 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Fri, 21 Aug 2020 03:54:16 +0530 Subject: [PATCH 17/19] Minor edits --- contracts/connectors/curve_gauge.sol | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/contracts/connectors/curve_gauge.sol b/contracts/connectors/curve_gauge.sol index 75fc9f2..7fe21ef 100644 --- a/contracts/connectors/curve_gauge.sol +++ b/contracts/connectors/curve_gauge.sol @@ -139,8 +139,8 @@ contract CurveGauge is CurveGaugeEvent { * @dev Withdraw LP Token and claim both CRV and Reward token. * @param gaugePoolName gauge pool name. * @param amt LP token amount. - * @param getId Get token amount at this ID from `InstaMemory` Contract. - * @param setId Set token amount at this ID in `InstaMemory` Contract. + * @param getId Get LP token amount at this ID from `InstaMemory` Contract. + * @param setId Set LP token amount at this ID in `InstaMemory` Contract. * @param setIdCrv Set CRV token reward amount at this ID in `InstaMemory` Contract. * @param setIdReward Set reward amount at this ID in `InstaMemory` Contract. */ @@ -234,7 +234,6 @@ contract CurveGauge is CurveGaugeEvent { emitLogClaimedReward(gaugePoolName, balances.crvRewardAmt, balances.rewardAmt, setId, setIdReward); } - } contract ConnectCurveGauge is CurveGauge { From baaaf4ad883770851855f8c7ae8cebcc76ae2835 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Sat, 22 Aug 2020 09:32:46 +0530 Subject: [PATCH 18/19] Fixed test cases --- contracts/tests/MockCurveGaugeMapping.sol | 6 ++++++ test/CurveGauge.js | 9 ++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/contracts/tests/MockCurveGaugeMapping.sol b/contracts/tests/MockCurveGaugeMapping.sol index c80852c..0aa52ae 100644 --- a/contracts/tests/MockCurveGaugeMapping.sol +++ b/contracts/tests/MockCurveGaugeMapping.sol @@ -4,5 +4,11 @@ pragma experimental ABIEncoderV2; import { CurveGaugeMapping } from "../mapping/curve_gauge_mapping.sol"; contract MockCurveGaugeMapping is CurveGaugeMapping { + constructor( + string[] memory gaugeNames, + address[] memory gaugeAddresses, + bool[] memory rewardTokens + ) public CurveGaugeMapping(gaugeNames, gaugeAddresses, rewardTokens) { + } modifier isChief override {_;} } diff --git a/test/CurveGauge.js b/test/CurveGauge.js index 96c2d26..e9ef1c5 100644 --- a/test/CurveGauge.js +++ b/test/CurveGauge.js @@ -18,7 +18,10 @@ contract("ConnectCurveGauge", async accounts => { before(async function () { mock = await MockContract.new(); - mockCurveGaugeMapping = await MockCurveGaugeMapping.new(); + let names = ["compound", "susd"] + let poolAddress = [mock.address, mock.address] + let rewardArr = [false, true] + mockCurveGaugeMapping = await MockCurveGaugeMapping.new(names, poolAddress, rewardArr); mockCurveGauge = await MockCurveGauge.new(mock.address, mockCurveGaugeMapping.address); // lp_token = new web3.eth.Contract(erc20ABI, mock.address); curveGauge = new web3.eth.Contract(gaugeABI, mock.address) @@ -32,8 +35,8 @@ contract("ConnectCurveGauge", async accounts => { let rewarded_token = await curveGauge.methods.rewarded_token().encodeABI(); await mock.givenMethodReturnAddress(rewarded_token, mock.address); - await mockCurveGaugeMapping.addGaugeMapping('compound', mock.address, false); - await mockCurveGaugeMapping.addGaugeMapping('susd', mock.address, true); + // await mockCurveGaugeMapping.addGaugeMapping('compound', mock.address, false); + // await mockCurveGaugeMapping.addGaugeMapping('susd', mock.address, true); }) it('can deposit into compound gauge', async function() { From 32ba4e8f328e49527a4a6cd2c4ce58eecc6da1cc Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Sun, 23 Aug 2020 02:22:23 +0530 Subject: [PATCH 19/19] Added gauge mapping address --- contracts/connectors/curve_gauge.sol | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/contracts/connectors/curve_gauge.sol b/contracts/connectors/curve_gauge.sol index 7fe21ef..7fd1745 100644 --- a/contracts/connectors/curve_gauge.sol +++ b/contracts/connectors/curve_gauge.sol @@ -32,8 +32,7 @@ interface ICurveGaugeMapping { contract GaugeHelper is DSMath, Stores{ function getCurveGaugeMappingAddr() internal virtual view returns (address){ - // Change this to the deployed address - return 0x0000000000000000000000000000000000000000; + return 0x1C800eF1bBfE3b458969226A96c56B92a069Cc92; } function getCurveMintorAddr() internal virtual view returns (address){