@gooddollar/goodcontracts
Version:
GoodDollar Contracts
1,004 lines (1,003 loc) • 1.52 MB
JSON
{
"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": {