UNPKG

@gooddollar/goodcontracts

Version:
1,004 lines (1,003 loc) 1.52 MB
{ "contractName": "IConsensus", "abi": [ { "inputs": [ { "internalType": "address", "name": "_validator", "type": "address" } ], "name": "delegate", "outputs": [], "stateMutability": "payable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "_validator", "type": "address" }, { "internalType": "uint256", "name": "_amount", "type": "uint256" } ], "name": "withdraw", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "_address", "type": "address" }, { "internalType": "address", "name": "_validator", "type": "address" } ], "name": "delegatedAmount", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "_address", "type": "address" } ], "name": "stakeAmount", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" } ], "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_validator\",\"type\":\"address\"}],\"name\":\"delegate\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_validator\",\"type\":\"address\"}],\"name\":\"delegatedAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"stakeAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_validator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"delegate(address)\":{\"details\":\"delegate to a validator\",\"params\":{\"_validator\":\"the address of the validator msg.sender is delegating to\"}},\"withdraw(address,uint256)\":{\"details\":\"Function to be called when a delegator whishes to withdraw some of his staked funds for a validator\",\"params\":{\"_amount\":\"the amount msg.sender wishes to withdraw from the contract\",\"_validator\":\"the address of the validator msg.sender has delegating to\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"/Users/hadar/workspace/GoodDollar/GoodBootstrap/packages/contracts/upgradables/contracts/staking/FuseStakingV3.sol\":\"IConsensus\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"/Users/hadar/workspace/GoodDollar/GoodBootstrap/packages/contracts/upgradables/contracts/Interfaces.sol\":{\"keccak256\":\"0xe501727b0e5e15fe639129ab4b1abc59a14ebd3ddd05bb7056ac4fc26a8f3ee7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://90d8797740cfd3933ae849f3144e30f9133a55b26634b3efefa8206cd91f62d8\",\"dweb:/ipfs/QmYLeetoyiPej9acnGzjLLwgVnEg4d2Eg1Xb4k3A1mJqj6\"]},\"/Users/hadar/workspace/GoodDollar/GoodBootstrap/packages/contracts/upgradables/contracts/staking/FuseStakingV3.sol\":{\"keccak256\":\"0x499a7548bed80359f337b487318cb2fa04f5ba0fd2c6776b8beabf6349f04997\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2a1a9e5394281cf86fef8bcd6e88193de1d8b86c3dafc506994f271c1e3314d1\",\"dweb:/ipfs/QmUYRzxjhSY9Yd2BRuqHMNMxBtzsZDASBPxXxZa33L8jMC\"]},\"/Users/hadar/workspace/GoodDollar/GoodBootstrap/packages/contracts/upgradables/contracts/utils/DSMath.sol\":{\"keccak256\":\"0x064e3a362de2b979b6afd9d9b00ef9682b61d3a2560f53a18535c36e5dacf57d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d86b2691be131202255756be3509685b4b00b65469577caba7d90d0a54be47f6\",\"dweb:/ipfs/QmP2MBv2YTd257qSv6TJmxmSwTcP4zDC3M51TjmL8Mv7xQ\"]},\"@openzeppelin/contracts-upgradeable/GSN/ContextUpgradeable.sol\":{\"keccak256\":\"0xbbf8a21b9a66c48d45ff771b8563c6df19ba451d63dfb8380a865c1e1f29d1a0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://062688aac76e27ab50157a9d645700cf92e3c0d51d3d860be1d2e1a0c04a87d0\",\"dweb:/ipfs/QmfXxppWAiSTeH8YNn2EtMPDgzrLeJ5rjRq8knEbje88mX\"]},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"keccak256\":\"0xe422bf8bc61fe71acb27de4631400cdbb9b532df4de4f255eab093ac356f9745\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7c2e5ed663c9df8fd44b624cfef92a703803cc72cf356c96e69a6e88c5ce082d\",\"dweb:/ipfs/QmdtPLYhopn3L14o6TCJkwH28o91do8JriAxpFYt67NWGB\"]},\"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\":{\"keccak256\":\"0xe9ecc18d06bcc5aa48c40a98333540248b6c1c18ecb6262329c06d3f0cbb45ae\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8a81bcbe4f867a4eaf7ec375508a9901ea7517b9854c9a542c242050beda5127\",\"dweb:/ipfs/QmS499VRDhAgMg1pK96PiyRpP3gJZzzMcoNBbe8AV3JNw3\"]},\"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\":{\"keccak256\":\"0xae7044b7c89ed74327b0979ae6f317c65d87b8d17a42d0c62d698d77d5de5511\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d676c978d8ecee5c4510f045b747d94f3a1381e39feb870d2675d5b6d45a371b\",\"dweb:/ipfs/QmUAokuHWPVAf14QkhPtSdYFyNa8HVje9CBEzwCcxH3xkP\"]}},\"version\":1}", "bytecode": "0x", "deployedBytecode": "0x", "immutableReferences": {}, "sourceMap": "", "deployedSourceMap": "", "source": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6;\npragma experimental ABIEncoderV2;\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"../utils/DSMath.sol\";\n\nimport \"../Interfaces.sol\";\n\ninterface IConsensus {\n\t/**\n\t * @dev delegate to a validator\n\t * @param _validator the address of the validator msg.sender is delegating to\n\t */\n\tfunction delegate(address _validator) external payable;\n\n\t/**\n\t * @dev Function to be called when a delegator whishes to withdraw some of his staked funds for a validator\n\t * @param _validator the address of the validator msg.sender has delegating to\n\t * @param _amount the amount msg.sender wishes to withdraw from the contract\n\t */\n\tfunction withdraw(address _validator, uint256 _amount) external;\n\n\tfunction delegatedAmount(address _address, address _validator)\n\t\texternal\n\t\tview\n\t\treturns (uint256);\n\n\tfunction stakeAmount(address _address) external view returns (uint256);\n}\n\ncontract FuseStakingV3 is Initializable, OwnableUpgradeable, DSMath {\n\tusing SafeMathUpgradeable for uint256;\n\n\tmapping(address => uint256) public stakers;\n\taddress[] public validators;\n\n\tIConsensus public consensus;\n\n\tUniswap public uniswap;\n\tGoodDollar public GD;\n\tUBIScheme public ubischeme;\n\tUniswapFactory public uniswapFactory;\n\tUniswapPair public uniswapPair;\n\n\tuint256 public lastDayCollected; //ubi day from ubischeme\n\n\tuint256 public stakeBackRatio;\n\tuint256 public maxSlippageRatio;\n\tuint256 public keeperFeeRatio;\n\tuint256 public RATIO_BASE;\n\tuint256 public communityPoolRatio; //out of G$ bought how much should goto pool\n\n\tuint256 communityPoolBalance;\n\tuint256 pendingFuseEarnings; //earnings not used because of slippage\n\n\tevent UBICollected(\n\t\tuint256 indexed currentDay,\n\t\tuint256 ubi, //G$ sent to ubischeme\n\t\tuint256 communityPool, //G$ added to pool\n\t\tuint256 gdBought, //actual G$ we got out of swapping stakingRewards + pendingFuseEarnings\n\t\tuint256 stakingRewards, //rewards earned since previous collection,\n\t\tuint256 pendingFuseEarnings, //new balance of fuse pending to be swapped for G$\n\t\taddress keeper,\n\t\tuint256 keeperGDFee\n\t);\n\n\t/**\n\t * @dev initialize\n\t */\n\tfunction initialize() public initializer {\n\t\t__Ownable_init_unchained();\n\t\tconsensus = IConsensus(\n\t\t\taddress(0x3014ca10b91cb3D0AD85fEf7A3Cb95BCAc9c0f79)\n\t\t);\n\t\tvalidators.push(address(0xcb876A393F05a6677a8a029f1C6D7603B416C0A6));\n\t}\n\n\tfunction upgrade0() public {\n\t\tif (RATIO_BASE == 0) {\n\t\t\tstakeBackRatio = 33333; //%33\n\t\t\tcommunityPoolRatio = 33333; //%33\n\t\t\tmaxSlippageRatio = 3000; //3%\n\t\t\tkeeperFeeRatio = 30; //0.03%\n\t\t\tRATIO_BASE = 100000; //100%\n\t\t}\n\t}\n\n\tfunction upgrade1(\n\t\taddress _gd,\n\t\taddress _ubischeme,\n\t\taddress _uniswap\n\t) public {\n\t\tif (address(uniswapPair) == address(0)) {\n\t\t\tuniswap = Uniswap(\n\t\t\t\t_uniswap == address(0)\n\t\t\t\t\t? 0xFB76e9E7d88E308aB530330eD90e84a952570319\n\t\t\t\t\t: _uniswap\n\t\t\t);\n\t\t\tGD = GoodDollar(_gd);\n\t\t\tubischeme = UBIScheme(_ubischeme);\n\n\t\t\tuniswapFactory = UniswapFactory(uniswap.factory());\n\t\t\tuniswapPair = UniswapPair(\n\t\t\t\tuniswapFactory.getPair(uniswap.WETH(), _gd)\n\t\t\t);\n\t\t\tupgrade0();\n\t\t}\n\t}\n\n\tfunction stake() public payable returns (bool) {\n\t\treturn stake(address(0));\n\t}\n\n\tfunction stake(address _validator) public payable returns (bool) {\n\t\trequire(msg.value > 0, \"stake must be > 0\");\n\t\trequire(validators.length > 0, \"no approved validators\");\n\t\tbool found;\n\t\tfor (\n\t\t\tuint256 i = 0;\n\t\t\t_validator != address(0) && i < validators.length;\n\t\t\ti++\n\t\t) {\n\t\t\tif (validators[i] != _validator) {\n\t\t\t\tfound = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\trequire(\n\t\t\t_validator == address(0) || found,\n\t\t\t\"validator not in approved list\"\n\t\t);\n\n\t\tbool staked = stakeNextValidator(msg.value, _validator);\n\t\tstakers[msg.sender] = stakers[msg.sender].add(msg.value);\n\t\treturn staked;\n\t}\n\n\tfunction balanceOf(address _owner) public view returns (uint256) {\n\t\treturn stakers[_owner];\n\t}\n\n\tfunction withdraw(uint256 _value) public returns (uint256) {\n\t\tuint256 effectiveBalance = balance(); //use only undelegated funds\n\t\tuint256 toWithdraw = _value == 0 ? stakers[msg.sender] : _value;\n\t\tuint256 toCollect = toWithdraw;\n\t\trequire(\n\t\t\ttoWithdraw > 0 && toWithdraw <= stakers[msg.sender],\n\t\t\t\"invalid withdraw amount\"\n\t\t);\n\t\tuint256 perValidator = _value.div(validators.length);\n\t\tfor (uint256 i = 0; i < validators.length; i++) {\n\t\t\tuint256 cur =\n\t\t\t\tconsensus.delegatedAmount(address(this), validators[i]);\n\t\t\tif (cur == 0) continue;\n\t\t\tif (cur <= perValidator) {\n\t\t\t\tundelegateWithCatch(validators[i], cur);\n\t\t\t\ttoCollect = toCollect.sub(cur);\n\t\t\t} else {\n\t\t\t\tundelegateWithCatch(validators[i], perValidator);\n\t\t\t\ttoCollect = toCollect.sub(perValidator);\n\t\t\t}\n\t\t\tif (toCollect == 0) break;\n\t\t}\n\n\t\teffectiveBalance = balance().sub(effectiveBalance); //use only undelegated funds\n\n\t\t// in case some funds where not withdrawn\n\t\tif (toWithdraw > effectiveBalance) {\n\t\t\ttoWithdraw = effectiveBalance;\n\t\t}\n\n\t\tstakers[msg.sender] = stakers[msg.sender].sub(toWithdraw);\n\t\tif (toWithdraw > 0) payable(msg.sender).transfer(toWithdraw);\n\t\treturn toWithdraw;\n\t}\n\n\tfunction stakeNextValidator(uint256 _value, address _validator)\n\t\tinternal\n\t\treturns (bool)\n\t{\n\t\tif (validators.length == 0) return false;\n\t\tif (_validator != address(0)) {\n\t\t\tconsensus.delegate{ value: _value }(_validator);\n\t\t\treturn true;\n\t\t}\n\n\t\tuint256 perValidator =\n\t\t\ttotalDelegated().add(_value).div(validators.length);\n\t\tuint256 left = _value;\n\t\tfor (uint256 i = 0; i < validators.length && left > 0; i++) {\n\t\t\tuint256 cur =\n\t\t\t\tconsensus.delegatedAmount(address(this), validators[i]);\n\n\t\t\tif (cur < perValidator) {\n\t\t\t\tuint256 toDelegate = perValidator.sub(cur);\n\t\t\t\ttoDelegate = toDelegate < left ? toDelegate : left;\n\t\t\t\tconsensus.delegate{ value: toDelegate }(validators[i]);\n\t\t\t\tleft = left.sub(toDelegate);\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tfunction addValidator(address _v) public onlyOwner {\n\t\tvalidators.push(_v);\n\t}\n\n\tfunction totalDelegated() public view returns (uint256) {\n\t\tuint256 total = 0;\n\t\tfor (uint256 i = 0; i < validators.length; i++) {\n\t\t\tuint256 cur =\n\t\t\t\tconsensus.delegatedAmount(address(this), validators[i]);\n\t\t\ttotal = total.add(cur);\n\t\t}\n\t\treturn total;\n\t}\n\n\tfunction removeValidator(address _validator) public onlyOwner {\n\t\tuint256 delegated =\n\t\t\tconsensus.delegatedAmount(address(this), _validator);\n\t\tif (delegated > 0) {\n\t\t\tuint256 prevBalance = balance();\n\t\t\tundelegateWithCatch(_validator, delegated);\n\n\t\t\t// wasnt withdrawn because validator needs to be taken of active validators\n\t\t\tif (balance() == prevBalance) {\n\t\t\t\t// pendingValidators.push(_validator);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tfor (uint256 i = 0; i < validators.length; i++) {\n\t\t\tif (validators[i] == _validator) {\n\t\t\t\tif (i < validators.length - 1)\n\t\t\t\t\tvalidators[i] = validators[validators.length - 1];\n\t\t\t\tvalidators.pop();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction collectUBIInterest() public {\n\t\tuint256 curDay = ubischeme.currentDay();\n\t\trequire(\n\t\t\tcurDay != lastDayCollected,\n\t\t\t\"can collect only once in a ubi cycle\"\n\t\t);\n\n\t\tuint256 earnings = balance() - pendingFuseEarnings;\n\t\trequire(pendingFuseEarnings + earnings > 0, \"no earnings to collect\");\n\n\t\tlastDayCollected = curDay;\n\t\tuint256 fuseUBI =\n\t\t\tearnings.mul(RATIO_BASE - stakeBackRatio).div(RATIO_BASE);\n\t\tuint256 stakeBack = earnings - fuseUBI;\n\n\t\tuint256[] memory fuseswapResult =\n\t\t\t_buyGD(fuseUBI.add(pendingFuseEarnings)); //buy GD with X% of earnings\n\t\tpendingFuseEarnings = fuseUBI.add(pendingFuseEarnings).sub(\n\t\t\tfuseswapResult[0]\n\t\t);\n\t\tstakeNextValidator(stakeBack, address(0)); //stake back the rest of the earnings\n\n\t\tuint256 gdBought = fuseswapResult[1];\n\t\tuint256 keeperFee = gdBought.mul(keeperFeeRatio).div(RATIO_BASE);\n\t\tif (keeperFee > 0) GD.transfer(msg.sender, keeperFee);\n\n\t\tuint256 communityPoolContribution =\n\t\t\tgdBought\n\t\t\t\t.sub(keeperFee) //subtract fee\n\t\t\t\t.mul(communityPoolRatio) // * ommunityPoolRatio\n\t\t\t\t.div(RATIO_BASE); // = G$ after fee * communityPoolRatio%\n\n\t\tuint256 ubiAfterFeeAndPool = gdBought.sub(communityPoolContribution);\n\n\t\tGD.transfer(address(ubischeme), ubiAfterFeeAndPool); //transfer to ubischeme\n\t\tcommunityPoolBalance = communityPoolBalance.add(\n\t\t\tcommunityPoolContribution\n\t\t);\n\n\t\temit UBICollected(\n\t\t\tcurDay,\n\t\t\tubiAfterFeeAndPool,\n\t\t\tcommunityPoolContribution,\n\t\t\tgdBought,\n\t\t\tearnings,\n\t\t\tpendingFuseEarnings,\n\t\t\tmsg.sender,\n\t\t\tkeeperFee\n\t\t);\n\t}\n\n\t/**\n\t * @dev internal method to buy GD from fuseswap\n\t * @param _value fuse to be sold\n\t * @return uniswap coversion results uint256[2]\n\t */\n\tfunction _buyGD(uint256 _value) internal returns (uint256[] memory) {\n\t\t//buy from uniwasp\n\t\trequire(_value > 0, \"buy value should be > 0\");\n\t\tuint256 maxFuse = calcMaxFuseWithSlippage(_value);\n\t\taddress[] memory path = new address[](2);\n\t\tpath[1] = address(GD);\n\t\tpath[0] = uniswap.WETH();\n\t\treturn\n\t\t\tuniswap.swapExactETHForTokens{ value: maxFuse }(\n\t\t\t\t0,\n\t\t\t\tpath,\n\t\t\t\taddress(this),\n\t\t\t\tnow\n\t\t\t);\n\t}\n\n\tfunction calcMaxFuseWithSlippage(uint256 _value)\n\t\tpublic\n\t\tview\n\t\treturns (uint256)\n\t{\n\t\t(uint256 r_fuse, uint256 r_gd, ) = uniswapPair.getReserves();\n\n\t\treturn calcMaxFuseWithSlippage(r_fuse, r_gd, _value);\n\t}\n\n\t/**\n\t * uniswap amountOut helper\n\t */\n\tfunction getAmountOut(\n\t\tuint256 _amountIn,\n\t\tuint256 _reserveIn,\n\t\tuint256 _reserveOut\n\t) internal pure returns (uint256 amountOut) {\n\t\tuint256 amountInWithFee = _amountIn.mul(997);\n\t\tuint256 numerator = amountInWithFee.mul(_reserveOut);\n\t\tuint256 denominator = _reserveIn.mul(1000).add(amountInWithFee);\n\t\tamountOut = numerator / denominator;\n\t}\n\n\t/**\n\t * @dev use binary search to find quantity that will result with slippage < maxSlippageRatio\n\t */\n\tfunction calcMaxFuseWithSlippage(\n\t\tuint256 r_fuse,\n\t\tuint256 r_gd,\n\t\tuint256 _value\n\t) public view returns (uint256) {\n\t\tuint256 start = 0;\n\t\tuint256 end = _value.div(1e18); //save iterations by moving precision to whole Fuse quantity\n\t\tuint256 curPriceWei = uint256(100).mul(r_fuse) / r_gd; //uniswap quote formula UniswapV2Library.sol\n\t\tuint256 maxPriceWei =\n\t\t\tcurPriceWei.mul(RATIO_BASE.add(maxSlippageRatio)).div(RATIO_BASE);\n\t\tuint256 fuseAmount = _value;\n\n\t\t//Iterate while start not meets end\n\t\twhile (start <= end) {\n\t\t\t// Find the mid index\n\t\t\tuint256 midQuantityWei = start.add(end).mul(1e18).div(2); //restore quantity precision\n\t\t\tif (midQuantityWei == 0) break;\n\t\t\tuint256 gdForQuantity = getAmountOut(midQuantityWei, r_fuse, r_gd);\n\t\t\tuint256 priceForQuantityWei =\n\t\t\t\trdiv(midQuantityWei, gdForQuantity.mul(1e16)).div(1e9);\n\n\t\t\tif (priceForQuantityWei <= maxPriceWei) {\n\t\t\t\tstart = midQuantityWei.div(1e18) + 1; //reduce precision to whole quantity div 1e18\n\t\t\t\tfuseAmount = midQuantityWei;\n\t\t\t} else end = midQuantityWei.div(1e18) - 1; //reduce precision to whole quantity div 1e18\n\t\t}\n\n\t\treturn fuseAmount;\n\t}\n\n\tfunction undelegateWithCatch(address _validator, uint256 _amount)\n\t\tinternal\n\t\treturns (bool)\n\t{\n\t\ttry consensus.withdraw(_validator, _amount) {\n\t\t\treturn true;\n\t\t} catch Error(\n\t\t\tstring memory /*reason*/\n\t\t) {\n\t\t\t// This is executed in case\n\t\t\t// revert was called inside getData\n\t\t\t// and a reason string was provided.\n\t\t\treturn false;\n\t\t} catch (\n\t\t\tbytes memory /*lowLevelData*/\n\t\t) {\n\t\t\t// This is executed in case revert() was used\n\t\t\t// or there was a failing assertion, division\n\t\t\t// by zero, etc. inside getData.\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tfunction balance() internal view returns (uint256) {\n\t\treturn payable(address(this)).balance;\n\t}\n\n\treceive() external payable {}\n}\n", "sourcePath": "/Users/hadar/workspace/GoodDollar/GoodBootstrap/packages/contracts/upgradables/contracts/staking/FuseStakingV3.sol", "ast": { "absolutePath": "/Users/hadar/workspace/GoodDollar/GoodBootstrap/packages/contracts/upgradables/contracts/staking/FuseStakingV3.sol", "exportedSymbols": { "FuseStakingV3": [ 7377 ], "IConsensus": [ 6164 ] }, "id": 7378, "license": "MIT", "nodeType": "SourceUnit", "nodes": [ { "id": 6127, "literals": [ "solidity", ">=", "0.6" ], "nodeType": "PragmaDirective", "src": "33:22:10" }, { "id": 6128, "literals": [ "experimental", "ABIEncoderV2" ], "nodeType": "PragmaDirective", "src": "56:33:10" }, { "absolutePath": "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol", "file": "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol", "id": 6129, "nodeType": "ImportDirective", "scope": 7378, "sourceUnit": 8212, "src": "90:69:10", "symbolAliases": [], "unitAlias": "" }, { "absolutePath": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol", "file": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol", "id": 6130, "nodeType": "ImportDirective", "scope": 7378, "sourceUnit": 7874, "src": "160:75:10", "symbolAliases": [], "unitAlias": "" }, { "absolutePath": "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol", "file": "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol", "id": 6131, "nodeType": "ImportDirective", "scope": 7378, "sourceUnit": 8141, "src": "236:74:10", "symbolAliases": [], "unitAlias": "" }, { "absolutePath": "/Users/hadar/workspace/GoodDollar/GoodBootstrap/packages/contracts/upgradables/contracts/utils/DSMath.sol", "file": "../utils/DSMath.sol", "id": 6132, "nodeType": "ImportDirective", "scope": 7378, "sourceUnit": 7699, "src": "312:29:10", "symbolAliases": [], "unitAlias": "" }, { "absolutePath": "/Users/hadar/workspace/GoodDollar/GoodBootstrap/packages/contracts/upgradables/contracts/Interfaces.sol", "file": "../Interfaces.sol", "id": 6133, "nodeType": "ImportDirective", "scope": 7378, "sourceUnit": 552, "src": "343:27:10", "symbolAliases": [], "unitAlias": "" }, { "abstract": false, "baseContracts": [], "contractDependencies": [], "contractKind": "interface", "documentation": null, "fullyImplemented": false, "id": 6164, "linearizedBaseContracts": [ 6164 ], "name": "IConsensus", "nodeType": "ContractDefinition", "nodes": [ { "body": null, "documentation": { "id": 6134, "nodeType": "StructuredDocumentation", "src": "396:120:10", "text": " @dev delegate to a validator\n @param _validator the address of the validator msg.sender is delegating to" }, "functionSelector": "5c19a95c", "id": 6139, "implemented": false, "kind": "function", "modifiers": [], "name": "delegate", "nodeType": "FunctionDefinition", "overrides": null, "parameters": { "id": 6137, "nodeType": "ParameterList", "parameters": [ { "constant": false, "id": 6136, "mutability": "mutable", "name": "_validator", "nodeType": "VariableDeclaration", "overrides": null, "scope": 6139, "src": "536:18:10", "stateVariable": false, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_address", "typeString": "address" }, "typeName": { "id": 6135, "name": "address", "nodeType": "ElementaryTypeName", "src": "536:7:10", "stateMutability": "nonpayable", "typeDescriptions": { "typeIdentifier": "t_address", "typeString": "address" } }, "value": null, "visibility": "internal" } ], "src": "535:20:10" }, "returnParameters": { "id": 6138, "nodeType": "ParameterList", "parameters": [], "src": "572:0:10" }, "scope": 6164, "src": "518:55:10", "stateMutability": "payable", "virtual": false, "visibility": "external" }, { "body": null, "documentation": { "id": 6140, "nodeType": "StructuredDocumentation", "src": "576:275:10", "text": " @dev Function to be called when a delegator whishes to withdraw some of his staked funds for a validator\n @param _validator the address of the validator msg.sender has delegating to\n @param _amount the amount msg.sender wishes to withdraw from the contract" }, "functionSelector": "f3fef3a3", "id": 6147, "implemented": false, "kind": "function", "modifiers": [], "name": "withdraw", "nodeType": "FunctionDefinition", "overrides": null, "parameters": { "id": 6145, "nodeType": "ParameterList", "parameters": [ { "constant": false, "id": 6142, "mutability": "mutable", "name": "_validator", "nodeType": "VariableDeclaration", "overrides": null, "scope": 6147, "src": "871:18:10", "stateVariable": false, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_address", "typeString": "address" }, "typeName": { "id": 6141, "name": "address", "nodeType": "ElementaryTypeName", "src": "871:7:10", "stateMutability": "nonpayable", "typeDescriptions": { "typeIdentifier": "t_address", "typeString": "address" } }, "value": null, "visibility": "internal" }, { "constant": false, "id": 6144, "mutability": "mutable", "name": "_amount", "nodeType": "VariableDeclaration", "overrides": null, "scope": 6147, "src": "891:15:10", "stateVariable": false, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, "typeName": { "id": 6143, "name": "uint256", "nodeType": "ElementaryTypeName", "src": "891:7:10", "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } }, "value": null, "visibility": "internal" } ], "src": "870:37:10" }, "returnParameters": { "id": 6146, "nodeType": "ParameterList", "parameters": [], "src": "916:0:10" }, "scope": 6164, "src": "853:64:10", "stateMutability": "nonpayable", "virtual": false, "visibility": "external" }, { "body": null, "documentation": null, "functionSelector": "21429e60", "id": 6156, "implemented": false, "kind": "function", "modifiers": [], "name": "delegatedAmount", "nodeType": "FunctionDefinition", "overrides": null, "parameters": { "id": 6152, "nodeType": "ParameterList", "parameters": [ { "constant": false, "id": 6149, "mutability": "mutable", "name": "_address", "nodeType": "VariableDeclaration", "overrides": null, "scope": 6156, "src": "945:16:10", "stateVariable": false, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_address", "typeString": "address" }, "typeName": { "id": 6148, "name": "address", "nodeType": "ElementaryTypeName", "src": "945:7:10", "stateMutability": "nonpayable", "typeDescriptions": { "typeIdentifier": "t_address", "typeString": "address" } }, "value": null, "visibility": "internal" }, { "constant": false, "id": 6151, "mutability": "mutable", "name": "_validator", "nodeType": "VariableDeclaration", "overrides": null, "scope": 6156, "src": "963:18:10", "stateVariable": false, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_address", "typeString": "address" }, "typeName": { "id": 6150, "name": "address", "nodeType": "ElementaryTypeName", "src": "963:7:10", "stateMutability": "nonpayable", "typeDescriptions": { "typeIdentifier": "t_address", "typeString": "address" } }, "value": null, "visibility": "internal" } ], "src": "944:38:10" }, "returnParameters": { "id": 6155, "nodeType": "ParameterList", "parameters": [ { "constant": false, "id": 6154, "mutability": "mutable", "name": "", "nodeType": "VariableDeclaration", "overrides": null, "scope": 6156, "src": "1012:7:10", "stateVariable": false, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, "typeName": { "id": 6153, "name": "uint256", "nodeType": "ElementaryTypeName", "src": "1012:7:10", "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } }, "value": null, "visibility": "internal" } ], "src": "1011:9:10" }, "scope": 6164, "src": "920:101:10", "stateMutability": "view", "virtual": false, "visibility": "external" }, { "body": null, "documentation": null, "functionSelector": "bf135267", "id": 6163, "implemented": false, "kind": "function", "modifiers": [], "name": "stakeAmount", "nodeType": "FunctionDefinition", "overrides": null, "parameters": { "id": 6159, "nodeType": "ParameterList", "parameters": [ { "constant": false, "id": 6158, "mutability": "mutable", "name": "_address", "nodeType": "VariableDeclaration", "overrides": null, "scope": 6163, "src": "1045:16:10", "stateVariable": false, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_address", "typeString": "address" }, "typeName": { "id": 6157, "name": "address", "nodeType": "ElementaryTypeName", "src": "1045:7:10", "stateMutability": "nonpayable", "typeDescriptions": { "typeIdentifier": "t_address", "typeString": "address" } }, "value": null, "visibility": "internal" } ], "src": "1044:18:10" }, "returnParameters": { "id": 6162, "nodeType": "ParameterList", "parameters": [ { "constant": false, "id": 6161, "mutability": "mutable", "name": "", "nodeType": "VariableDeclaration", "overrides": null, "scope": 6163, "src": "1086:7:10", "stateVariable": false, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, "typeName": { "id": 6160, "name": "uint256", "nodeType": "ElementaryTypeName", "src": "1086:7:10", "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } }, "value": null, "visibility": "internal" } ], "src": "1085:9:10" }, "scope": 6164, "src": "1024:71:10", "stateMutability": "view", "virtual": false, "visibility": "external" } ], "scope": 7378, "src": "372:725:10" }, { "abstract": false, "baseContracts": [ { "arguments": null, "baseName": { "contractScope": null, "id": 6165, "name": "Initializable", "nodeType": "UserDefinedTypeName", "referencedDeclaration": 8211, "src": "1125:13:10", "typeDescriptions": { "typeIdentifier": "t_contract$_Initializable_$8211", "typeString": "contract Initializable" } }, "id": 6166, "nodeType": "InheritanceSpecifier", "src": "1125:13:10" }, { "arguments": null, "baseName": { "contractScope": null, "id": 6167, "name": "OwnableUpgradeable", "nodeType": "UserDefinedTypeName", "referencedDeclaration": 7873, "src": "1140:18:10", "typeDescriptions": { "typeIdentifier": "t_contract$_OwnableUpgradeable_$7873", "typeString": "contract OwnableUpgradeable" } }, "id": 6168, "nodeType": "InheritanceSpecifier", "src": "1140:18:10" }, { "arguments": null, "baseName": { "contractScope": null, "id": 6169, "name": "DSMath", "nodeType": "UserDefinedTypeName", "referencedDeclaration": 7698, "src": "1160:6:10", "typeDescriptions": { "typeIdentifier": "t_contract$_DSMath_$7698", "typeString": "contract DSMath" } }, "id": 6170, "nodeType": "InheritanceSpecifier", "src": "1160:6:10" } ], "contractDependencies": [ 7698, 7743, 7873, 8211 ], "contractKind": "contract", "documentation": null, "fullyImplemented": true, "id": 7377, "linearizedBaseContracts": [ 7377, 7698, 7873, 7743, 8211 ], "name": "FuseStakingV3", "nodeType": "ContractDefinition", "nodes": [ { "id": 6173, "libraryName": { "contractScope": null, "id": 6171, "name": "SafeMathUpgradeable", "nodeType": "UserDefinedTypeName", "referencedDeclaration": 8140, "src": "1176:19:10", "typeDescriptions": { "typeIdentifier": "t_contract$_SafeMathUpgradeable_$8140", "typeString": "library SafeMathUpgradeable" } }, "nodeType": "UsingForDirective", "src": "1170:38:10", "typeName": { "id": 6172, "name": "uint256", "nodeType": "ElementaryTypeName", "src": "1200:7:10", "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } } }, { "constant": false, "functionSelector": "9168ae72", "id": 6177, "mutability": "mutable", "name": "stakers", "nodeType": "VariableDeclaration", "overrides": null, "scope": 7377, "src": "1211:42:10", "stateVariable": true, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", "typeString": "mapping(address => uint256)" }, "typeName": { "id": 6176, "keyType": { "id": 6174, "name": "address", "nodeType": "ElementaryTypeName", "src": "1219:7:10", "typeDescriptions": { "typeIdentifier": "t_address", "typeString": "address" } }, "nodeType": "Mapping", "src": "1211:27:10", "typeDescriptions": { "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", "typeString": "mapping(address => uint256)" }, "valueType": { "id": 6175, "name": "uint256", "nodeType": "ElementaryTypeName", "src": "1230:7:10", "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } } }, "value": null, "visibility": "public" }, { "constant": false, "functionSelector": "35aa2e44", "id": 6180, "mutability": "mutable", "name": "validators", "nodeType": "VariableDeclaration", "overrides": null, "scope": 7377, "src": "1256:27:10", "stateVariable": true, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_array$_t_address_$dyn_storage", "typeString": "address[]" }, "typeName": { "baseType": { "id": 6178, "name": "address", "nodeType": "ElementaryTypeName", "src": "1256:7:10", "stateMutability": "nonpayable", "typeDescriptions": { "typeIdentifier": "t_address", "typeString": "address" } }, "id": 6179, "length": null, "nodeType": "ArrayTypeName", "src": "1256:9:10", "typeDescriptions": { "typeIdentifier": "t_array$_t_address_$dyn_storage_ptr", "typeString": "address[]" } }, "value": null, "visibility": "public" }, { "constant": false, "functionSelector": "8ef3f761", "id": 6182, "mutability": "mutable", "name": "consensus", "nodeType": "VariableDeclaration", "overrides": null, "scope": 7377, "src": "1287:27:10", "stateVariable": true, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_contract$_IConsensus_$6164", "typeString": "contract IConsensus" }, "typeName": { "contractScope": null, "id": 6181, "name": "IConsensus", "nodeType": "UserDefinedTypeName", "referencedDeclaration": 6164, "src": "1287:10:10", "typeDescriptions": { "typeIdentifier": "t_contract$_IConsensus_$6164", "typeString": "contract IConsensus" } }, "value": null, "visibility": "public" }, { "constant": false, "functionSelector": "2681f7e4", "id": 6184, "mutability": "mutable", "name": "uniswap", "nodeType": "VariableDeclaration", "overrides": null, "scope": 7377, "src": "1318:22:10", "stateVariable": true, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_contract$_Uniswap_$444", "typeString": "contract Uniswap" }, "typeName": { "contractScope": null, "id": 6183, "name": "Uniswap", "nodeType": "UserDefinedTypeName", "referencedDeclaration": 444, "src": "1318:7:10", "typeDescriptions": { "typeIdentifier": "t_contract$_Uniswap_$444", "typeString": "contract Uniswap" } }, "value": null, "visibility": "public" }, { "constant": false, "functionSelector": "3fb1ccf1", "id": 6186, "mutability": "mutable", "name": "GD", "nodeType": "VariableDeclaration", "overrides": null, "scope": 7377, "src": "1343:20:10", "stateVariable": true, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_contract$_GoodDollar_$330", "typeString": "contract GoodDollar" }, "typeName": { "contractScope": null, "id": 6185, "name": "GoodDollar", "nodeType": "UserDefinedTypeName", "referencedDeclaration": 330, "src": "1343:10:10", "typeDescriptions": { "typeIdentifier": "t_contract$_GoodDollar_$330", "typeString": "contract GoodDollar" } }, "value": null, "visibility": "public" }, { "constant": false, "functionSelector": "81028f67", "id": 6188, "mutability": "mutable", "name": "ubischeme", "nodeType": "VariableDeclaration", "overrides": null, "scope": 7377, "src": "1366:26:10", "stateVariable": true, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_contract$_UBIScheme_$519", "typeString": "contract UBIScheme" }, "typeName": { "contractScope": null, "id": 6187, "name": "UBIScheme", "nodeType": "UserDefinedTypeName", "referencedDeclaration": 519, "src": "1366:9:10", "typeDescriptions": { "typeIdentifier": "t_contract$_UBIScheme_$519", "typeString": "contract UBIScheme" } }, "value": null, "visibility": "public" }, { "constant": false, "functionSelector": "8bdb2afa", "id": 6190, "mutability": "mutable", "name": "uniswapFactory", "nodeType": "VariableDeclaration", "overrides": null, "scope": 7377, "src": "1395:36:10", "stateVariable": true, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_contract$_UniswapFactory_$454", "typeString": "contract UniswapFactory" }, "typeName": { "contractScope": null, "id": 6189, "name": "UniswapFactory", "nodeType": "UserDefinedTypeName", "referencedDeclaration": 454, "src": "1395:14:10", "typeDescriptions": { "typeIdentifier": "t_contract$_UniswapFactory_$454", "typeString": "contract UniswapFactory" } }, "value": null, "visibility": "public" }, { "constant": false, "functionSelector": "c816841b", "id": 6192, "mutability": "mutable", "name": "uniswapPair", "nodeType": "VariableDeclaration", "overrides": null, "scope": 7377, "src": "1434:30:10", "stateVariable": true, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_contract$_UniswapPair_$469", "typeString": "contract UniswapPair" }, "typeName": { "contractScope": null, "id": 6191, "name": "UniswapPair", "nodeType": "UserDefinedTypeName", "referencedDeclaration": 469, "src": "1434:11:10", "typeDescriptions": { "typeIdentifier": "t_contract$_UniswapPair_$469", "typeString": "contract UniswapPair" } }, "value": null, "visibility": "public" }, { "constant": false, "functionSelector": "8918c4a2", "id": 6194, "mutability": "mutable", "name": "lastDayCollected", "nodeType": "VariableDeclaration", "overrides": null, "scope": 7377, "src": "1468:31:10", "stateVariable": true, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, "typeName": { "id": 6193, "name": "uint256", "nodeType": "ElementaryTypeName", "src": "1468:7:10", "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } }, "value": null, "visibility": "public" }, { "constant": false, "functionSelector": "6021a9d5", "id": 6196, "mutability": "mutable", "name": "stakeBackRatio", "nodeType": "VariableDeclaration", "overrides": null, "scope": 7377, "src": "1528:29:10", "stateVariable": true, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, "typeName": { "id": 6195, "name": "uint256", "nodeType": "ElementaryTypeName", "src": "1528:7:10", "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } }, "value": null, "visibility": "public" }, { "constant": false, "functionSelector": "04d26ebf", "id": 6198, "mutability": "mutable", "name": "maxSlippageRatio", "nodeType": "VariableDeclaration", "overrides": null, "scope": 7377, "src": "1560:31:10", "stateVariable": true, "storageLocation": "default", "typeDescriptions": {