From 39f640312e4c24b444b240397c3c311de74a4132 Mon Sep 17 00:00:00 2001 From: 0xKChau Date: Mon, 17 Jan 2022 02:11:00 +0800 Subject: [PATCH 01/13] Fix bond page issue --- src/abi/ftmTestnet/RedeemHelper.json | 233 +++ src/abi/rinkeby/.chainId | 1 + src/abi/rinkeby/BrickFraxBondDepository.json | 1269 +++++++++++++ src/abi/rinkeby/Distributor.json | 545 ++++++ src/abi/rinkeby/FRAX.json | 738 ++++++++ src/abi/rinkeby/FraxBondDepository.json | 1269 +++++++++++++ src/abi/rinkeby/OlympusBondingCalculator.json | 147 ++ src/abi/rinkeby/OlympusERC20Token.json | 745 ++++++++ src/abi/rinkeby/OlympusStaking.json | 743 ++++++++ src/abi/rinkeby/OlympusTreasury.json | 1682 +++++++++++++++++ src/abi/rinkeby/RedeemHelper.json | 233 +++ src/abi/rinkeby/StakingHelper.json | 98 + src/abi/rinkeby/StakingWarmup.json | 103 + src/abi/rinkeby/WrappedToken.json | 560 ++++++ .../rinkeby/WrappedTokenBondDepository.json | 1253 ++++++++++++ src/abi/rinkeby/sOlympus.json | 1092 +++++++++++ .../77788eae31d169a831f4a6df224e3de9.json | 53 + .../778fd7df05b9b5e245a90ea93cf9b329.json | 59 + .../80205d7caa85cf7d901b88f836b16309.json | 38 + .../8d3774b312edc15e04c44a56a82de7d8.json | 83 + .../bbf3f95bcfbd20e9e9f7857af806cde4.json | 35 + .../c9b246e9781a79119b50bb31bf7fa5c6.json | 35 + .../d0f6f5ddb1e2301823073d2aeed57f8f.json | 35 + .../fb3b81c61761bcfb33ca99488ac60a1b.json | 38 + src/abi/rinkeby/wOHM.json | 685 +++++++ src/constants.ts | 33 +- src/helpers/AllBonds.ts | 16 +- src/helpers/index.tsx | 2 +- src/slices/AccountSlice.ts | 56 +- src/slices/BondSlice.ts | 51 +- src/slices/StakeThunk.ts | 8 +- src/slices/WrapThunk.ts | 2 +- src/views/Stake/Stake.tsx | 4 +- .../TreasuryDashboard/TreasuryDashboard.jsx | 4 +- .../TreasuryDashboard/TreasuryDashboard.tsx | 4 +- .../components/Graph/Graph.js | 2 +- src/views/Wrap/Wrap.jsx | 14 +- 37 files changed, 11867 insertions(+), 101 deletions(-) create mode 100644 src/abi/ftmTestnet/RedeemHelper.json create mode 100644 src/abi/rinkeby/.chainId create mode 100644 src/abi/rinkeby/BrickFraxBondDepository.json create mode 100644 src/abi/rinkeby/Distributor.json create mode 100644 src/abi/rinkeby/FRAX.json create mode 100644 src/abi/rinkeby/FraxBondDepository.json create mode 100644 src/abi/rinkeby/OlympusBondingCalculator.json create mode 100644 src/abi/rinkeby/OlympusERC20Token.json create mode 100644 src/abi/rinkeby/OlympusStaking.json create mode 100644 src/abi/rinkeby/OlympusTreasury.json create mode 100644 src/abi/rinkeby/RedeemHelper.json create mode 100644 src/abi/rinkeby/StakingHelper.json create mode 100644 src/abi/rinkeby/StakingWarmup.json create mode 100644 src/abi/rinkeby/WrappedToken.json create mode 100644 src/abi/rinkeby/WrappedTokenBondDepository.json create mode 100644 src/abi/rinkeby/sOlympus.json create mode 100644 src/abi/rinkeby/solcInputs/77788eae31d169a831f4a6df224e3de9.json create mode 100644 src/abi/rinkeby/solcInputs/778fd7df05b9b5e245a90ea93cf9b329.json create mode 100644 src/abi/rinkeby/solcInputs/80205d7caa85cf7d901b88f836b16309.json create mode 100644 src/abi/rinkeby/solcInputs/8d3774b312edc15e04c44a56a82de7d8.json create mode 100644 src/abi/rinkeby/solcInputs/bbf3f95bcfbd20e9e9f7857af806cde4.json create mode 100644 src/abi/rinkeby/solcInputs/c9b246e9781a79119b50bb31bf7fa5c6.json create mode 100644 src/abi/rinkeby/solcInputs/d0f6f5ddb1e2301823073d2aeed57f8f.json create mode 100644 src/abi/rinkeby/solcInputs/fb3b81c61761bcfb33ca99488ac60a1b.json create mode 100644 src/abi/rinkeby/wOHM.json diff --git a/src/abi/ftmTestnet/RedeemHelper.json b/src/abi/ftmTestnet/RedeemHelper.json new file mode 100644 index 0000000000..d3d9d2ad04 --- /dev/null +++ b/src/abi/ftmTestnet/RedeemHelper.json @@ -0,0 +1,233 @@ +{ + "address": "0x952A2D7BE42E04FCC622e4beB4c59d3AD4Ffbe4F", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipPulled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipPushed", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_bond", + "type": "address" + } + ], + "name": "addBondContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "bonds", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "policy", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pullManagement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner_", + "type": "address" + } + ], + "name": "pushManagement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "bool", + "name": "_stake", + "type": "bool" + } + ], + "name": "redeemAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + } + ], + "name": "removeBondContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceManagement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x36773d99e840b21def9f549aa62b8f961e0026c65f496e429a6e8a792e7101db", + "receipt": { + "to": null, + "from": "0xA38F4E6718EdCF023a1d032a2193848CB932c8e3", + "contractAddress": "0x952A2D7BE42E04FCC622e4beB4c59d3AD4Ffbe4F", + "transactionIndex": 0, + "gasUsed": "801122", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x000016f900001bae1e540d4bd1ebeaa56488d364ef8a76ee439d2ae93891ac39", + "transactionHash": "0x36773d99e840b21def9f549aa62b8f961e0026c65f496e429a6e8a792e7101db", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 6563009, + "transactionHash": "0x36773d99e840b21def9f549aa62b8f961e0026c65f496e429a6e8a792e7101db", + "address": "0x952A2D7BE42E04FCC622e4beB4c59d3AD4Ffbe4F", + "topics": [ + "0xea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000a38f4e6718edcf023a1d032a2193848cb932c8e3" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x000016f900001bae1e540d4bd1ebeaa56488d364ef8a76ee439d2ae93891ac39" + } + ], + "blockNumber": 6563009, + "cumulativeGasUsed": "801122", + "status": 1, + "byzantium": true + }, + "args": [], + "solcInputHash": "8d3774b312edc15e04c44a56a82de7d8", + "metadata": "{\"compiler\":{\"version\":\"0.7.5+commit.eb77ed08\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipPulled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipPushed\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bond\",\"type\":\"address\"}],\"name\":\"addBondContract\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bonds\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"policy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pullManagement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner_\",\"type\":\"address\"}],\"name\":\"pushManagement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_stake\",\"type\":\"bool\"}],\"name\":\"redeemAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"removeBondContract\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceManagement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/RedeemHelper.sol\":\"RedeemHelper\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/RedeemHelper.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-or-later\\npragma solidity 0.7.5;\\n\\ninterface IOwnable {\\n function policy() external view returns (address);\\n\\n function renounceManagement() external;\\n \\n function pushManagement( address newOwner_ ) external;\\n \\n function pullManagement() external;\\n}\\n\\ncontract Ownable is IOwnable {\\n\\n address internal _owner;\\n address internal _newOwner;\\n\\n event OwnershipPushed(address indexed previousOwner, address indexed newOwner);\\n event OwnershipPulled(address indexed previousOwner, address indexed newOwner);\\n\\n constructor () {\\n _owner = msg.sender;\\n emit OwnershipPushed( address(0), _owner );\\n }\\n\\n function policy() public view override returns (address) {\\n return _owner;\\n }\\n\\n modifier onlyPolicy() {\\n require( _owner == msg.sender, \\\"Ownable: caller is not the owner\\\" );\\n _;\\n }\\n\\n function renounceManagement() public virtual override onlyPolicy() {\\n emit OwnershipPushed( _owner, address(0) );\\n _owner = address(0);\\n }\\n\\n function pushManagement( address newOwner_ ) public virtual override onlyPolicy() {\\n require( newOwner_ != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipPushed( _owner, newOwner_ );\\n _newOwner = newOwner_;\\n }\\n \\n function pullManagement() public virtual override {\\n require( msg.sender == _newOwner, \\\"Ownable: must be new owner to pull\\\");\\n emit OwnershipPulled( _owner, _newOwner );\\n _owner = _newOwner;\\n }\\n}\\n\\ninterface IBond {\\n function redeem( address _recipient, bool _stake ) external returns ( uint );\\n function pendingPayoutFor( address _depositor ) external view returns ( uint pendingPayout_ );\\n}\\n\\ncontract RedeemHelper is Ownable {\\n\\n address[] public bonds;\\n\\n function redeemAll( address _recipient, bool _stake ) external {\\n for( uint i = 0; i < bonds.length; i++ ) {\\n if ( bonds[i] != address(0) ) {\\n if ( IBond( bonds[i] ).pendingPayoutFor( _recipient ) > 0 ) {\\n IBond( bonds[i] ).redeem( _recipient, _stake );\\n }\\n }\\n }\\n }\\n\\n function addBondContract( address _bond ) external onlyPolicy() {\\n require( _bond != address(0) );\\n bonds.push( _bond );\\n }\\n\\n function removeBondContract( uint _index ) external onlyPolicy() {\\n bonds[ _index ] = address(0);\\n }\\n}\",\"keccak256\":\"0x63054884c30b69052cc99139e062a9e801f4eef74142cbb776295e6aad579a1a\",\"license\":\"AGPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a3610d15806100db6000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c806346f68ee91161005b57806346f68ee91461015f5780635a96ac0a146101a35780635f1c17c0146101ad578063b1e59ab71461020557610088565b80630505c8c91461008d578063089208d8146100c15780630a6d1860146100cb57806346aed74e1461010f575b600080fd5b610095610233565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100c961025c565b005b61010d600480360360208110156100e157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506103db565b005b61015d6004803603604081101561012557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080351515906020019092919050505061053c565b005b6101a16004803603602081101561017557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610792565b005b6101ab610997565b005b6101d9600480360360208110156101c357600080fd5b8101908080359060200190929190505050610b3d565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102316004803603602081101561021b57600080fd5b8101908080359060200190929190505050610b7c565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461031d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461049c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156104d657600080fd5b6002819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60005b60028054905081101561078d57600073ffffffffffffffffffffffffffffffffffffffff166002828154811061057157fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610780576000600282815481106105c657fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166301b88ee8856040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561065757600080fd5b505afa15801561066b573d6000803e3d6000fd5b505050506040513d602081101561068157600080fd5b8101908080519060200190929190505050111561077f57600281815481106106a557fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631feed31f84846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff168152602001821515815260200192505050602060405180830381600087803b15801561074257600080fd5b505af1158015610756573d6000803e3d6000fd5b505050506040513d602081101561076c57600080fd5b8101908080519060200190929190505050505b5b808060010191505061053f565b505050565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610853576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156108d9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180610c986026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a380600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180610cbe6022913960400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167faa151555690c956fc3ea32f106bb9f119b5237a061eaa8557cff3e51e3792c8d60405160405180910390a3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60028181548110610b4d57600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610c3d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060028281548110610c4c57fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a206d757374206265206e6577206f776e657220746f2070756c6ca26469706673582212208fcc9c74d1b99bbd630564fd21bafb64a29f4cee164be7ccaaf4503253ae80fc64736f6c63430007050033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100885760003560e01c806346f68ee91161005b57806346f68ee91461015f5780635a96ac0a146101a35780635f1c17c0146101ad578063b1e59ab71461020557610088565b80630505c8c91461008d578063089208d8146100c15780630a6d1860146100cb57806346aed74e1461010f575b600080fd5b610095610233565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100c961025c565b005b61010d600480360360208110156100e157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506103db565b005b61015d6004803603604081101561012557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080351515906020019092919050505061053c565b005b6101a16004803603602081101561017557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610792565b005b6101ab610997565b005b6101d9600480360360208110156101c357600080fd5b8101908080359060200190929190505050610b3d565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102316004803603602081101561021b57600080fd5b8101908080359060200190929190505050610b7c565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461031d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461049c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156104d657600080fd5b6002819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60005b60028054905081101561078d57600073ffffffffffffffffffffffffffffffffffffffff166002828154811061057157fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610780576000600282815481106105c657fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166301b88ee8856040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561065757600080fd5b505afa15801561066b573d6000803e3d6000fd5b505050506040513d602081101561068157600080fd5b8101908080519060200190929190505050111561077f57600281815481106106a557fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631feed31f84846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff168152602001821515815260200192505050602060405180830381600087803b15801561074257600080fd5b505af1158015610756573d6000803e3d6000fd5b505050506040513d602081101561076c57600080fd5b8101908080519060200190929190505050505b5b808060010191505061053f565b505050565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610853576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156108d9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180610c986026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a380600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180610cbe6022913960400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167faa151555690c956fc3ea32f106bb9f119b5237a061eaa8557cff3e51e3792c8d60405160405180910390a3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60028181548110610b4d57600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610c3d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060028281548110610c4c57fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a206d757374206265206e6577206f776e657220746f2070756c6ca26469706673582212208fcc9c74d1b99bbd630564fd21bafb64a29f4cee164be7ccaaf4503253ae80fc64736f6c63430007050033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 8447, + "contract": "contracts/RedeemHelper.sol:RedeemHelper", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 8449, + "contract": "contracts/RedeemHelper.sol:RedeemHelper", + "label": "_newOwner", + "offset": 0, + "slot": "1", + "type": "t_address" + }, + { + "astId": 8594, + "contract": "contracts/RedeemHelper.sol:RedeemHelper", + "label": "bonds", + "offset": 0, + "slot": "2", + "type": "t_array(t_address)dyn_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_address)dyn_storage": { + "base": "t_address", + "encoding": "dynamic_array", + "label": "address[]", + "numberOfBytes": "32" + } + } + } + } \ No newline at end of file diff --git a/src/abi/rinkeby/.chainId b/src/abi/rinkeby/.chainId new file mode 100644 index 0000000000..bf0d87ab1b --- /dev/null +++ b/src/abi/rinkeby/.chainId @@ -0,0 +1 @@ +4 \ No newline at end of file diff --git a/src/abi/rinkeby/BrickFraxBondDepository.json b/src/abi/rinkeby/BrickFraxBondDepository.json new file mode 100644 index 0000000000..0034733f10 --- /dev/null +++ b/src/abi/rinkeby/BrickFraxBondDepository.json @@ -0,0 +1,1269 @@ +{ + "address": "0x1cB859d5e17e785BB41e1BDe5A1FC962BfEE8A5e", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_OHM", + "type": "address" + }, + { + "internalType": "address", + "name": "_principle", + "type": "address" + }, + { + "internalType": "address", + "name": "_treasury", + "type": "address" + }, + { + "internalType": "address", + "name": "_DAO", + "type": "address" + }, + { + "internalType": "address", + "name": "_bondCalculator", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "deposit", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "payout", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "expires", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "priceInUSD", + "type": "uint256" + } + ], + "name": "BondCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "priceInUSD", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "internalPrice", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "debtRatio", + "type": "uint256" + } + ], + "name": "BondPriceChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "payout", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "remaining", + "type": "uint256" + } + ], + "name": "BondRedeemed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "initialBCV", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newBCV", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "adjustment", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bool", + "name": "addition", + "type": "bool" + } + ], + "name": "ControlVariableAdjustment", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipPulled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipPushed", + "type": "event" + }, + { + "inputs": [], + "name": "DAO", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "OHM", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "adjustment", + "outputs": [ + { + "internalType": "bool", + "name": "add", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "rate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "target", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "buffer", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastTime", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bondCalculator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "bondInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "payout", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "vesting", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "pricePaid", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bondPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "price_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bondPriceInUSD", + "outputs": [ + { + "internalType": "uint256", + "name": "price_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "debtDecay", + "outputs": [ + { + "internalType": "uint256", + "name": "decay_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "debtRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "debtRatio_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxPrice", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_depositor", + "type": "address" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_controlVariable", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_vestingTerm", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_minimumPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxPayout", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_fee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_initialDebt", + "type": "uint256" + } + ], + "name": "initializeBondTerms", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isLiquidityBond", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastDecay", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxPayout", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + } + ], + "name": "payoutFor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_depositor", + "type": "address" + } + ], + "name": "pendingPayoutFor", + "outputs": [ + { + "internalType": "uint256", + "name": "pendingPayout_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_depositor", + "type": "address" + } + ], + "name": "percentVestedFor", + "outputs": [ + { + "internalType": "uint256", + "name": "percentVested_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "policy", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "principle", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pullManagement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner_", + "type": "address" + } + ], + "name": "pushManagement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "recoverLostToken", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "bool", + "name": "_stake", + "type": "bool" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceManagement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_addition", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "_increment", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_target", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_buffer", + "type": "uint256" + } + ], + "name": "setAdjustment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum OlympusBondDepository.PARAMETER", + "name": "_parameter", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "_input", + "type": "uint256" + } + ], + "name": "setBondTerms", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_staking", + "type": "address" + }, + { + "internalType": "bool", + "name": "_helper", + "type": "bool" + } + ], + "name": "setStaking", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "staking", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stakingHelper", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "standardizedDebtRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "terms", + "outputs": [ + { + "internalType": "uint256", + "name": "controlVariable", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "vestingTerm", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minimumPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPayout", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxDebt", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "treasury", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "useHelper", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x014ec8986b37b0eb9110a0101f020926b1535850acb625c21ad786b923dfcc73", + "receipt": { + "to": null, + "from": "0xA38F4E6718EdCF023a1d032a2193848CB932c8e3", + "contractAddress": "0x1cB859d5e17e785BB41e1BDe5A1FC962BfEE8A5e", + "transactionIndex": 34, + "gasUsed": "3731149", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000400000200000000000000040000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000004000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000020000000000020002000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x94a32de361b950e9d0d87c495e6cd351deccce42d3229de6f21693e23144b5ef", + "transactionHash": "0x014ec8986b37b0eb9110a0101f020926b1535850acb625c21ad786b923dfcc73", + "logs": [ + { + "transactionIndex": 34, + "blockNumber": 9969767, + "transactionHash": "0x014ec8986b37b0eb9110a0101f020926b1535850acb625c21ad786b923dfcc73", + "address": "0x1cB859d5e17e785BB41e1BDe5A1FC962BfEE8A5e", + "topics": [ + "0xea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000a38f4e6718edcf023a1d032a2193848cb932c8e3" + ], + "data": "0x", + "logIndex": 33, + "blockHash": "0x94a32de361b950e9d0d87c495e6cd351deccce42d3229de6f21693e23144b5ef" + } + ], + "blockNumber": 9969767, + "cumulativeGasUsed": "5754649", + "status": 1, + "byzantium": true + }, + "args": [ + "0x9bb5E7183e6259183f8E79876eCC0228738C95F6", + "0x088ce658Db1AB9e8B0BD62d75964Ac8f88f27aeA", + "0x1e0AD0F8DDFF84FDc938373E9aa66b8d994ea066", + "0xA38F4E6718EdCF023a1d032a2193848CB932c8e3", + "0x03E82c27761DaaA69852cF5238Bc2597a14592cd" + ], + "solcInputHash": "bbf3f95bcfbd20e9e9f7857af806cde4", + "metadata": "{\"compiler\":{\"version\":\"0.7.5+commit.eb77ed08\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_OHM\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_principle\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_DAO\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_bondCalculator\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"deposit\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"payout\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"expires\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"priceInUSD\",\"type\":\"uint256\"}],\"name\":\"BondCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"priceInUSD\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"internalPrice\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"debtRatio\",\"type\":\"uint256\"}],\"name\":\"BondPriceChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payout\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remaining\",\"type\":\"uint256\"}],\"name\":\"BondRedeemed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"initialBCV\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBCV\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"adjustment\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"addition\",\"type\":\"bool\"}],\"name\":\"ControlVariableAdjustment\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipPulled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipPushed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DAO\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OHM\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"adjustment\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"add\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"rate\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"target\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"buffer\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lastTime\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bondCalculator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bondInfo\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"payout\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"vesting\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lastTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"pricePaid\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bondPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"price_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bondPriceInUSD\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"price_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentDebt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"debtDecay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"decay_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"debtRatio\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"debtRatio_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_depositor\",\"type\":\"address\"}],\"name\":\"deposit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_controlVariable\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_vestingTerm\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_minimumPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxPayout\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxDebt\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_initialDebt\",\"type\":\"uint256\"}],\"name\":\"initializeBondTerms\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isLiquidityBond\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastDecay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxPayout\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"payoutFor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_depositor\",\"type\":\"address\"}],\"name\":\"pendingPayoutFor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"pendingPayout_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_depositor\",\"type\":\"address\"}],\"name\":\"percentVestedFor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"percentVested_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"policy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"principle\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pullManagement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner_\",\"type\":\"address\"}],\"name\":\"pushManagement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"recoverLostToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_stake\",\"type\":\"bool\"}],\"name\":\"redeem\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceManagement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_addition\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"_increment\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_target\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_buffer\",\"type\":\"uint256\"}],\"name\":\"setAdjustment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enum OlympusBondDepository.PARAMETER\",\"name\":\"_parameter\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"_input\",\"type\":\"uint256\"}],\"name\":\"setBondTerms\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_staking\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_helper\",\"type\":\"bool\"}],\"name\":\"setStaking\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"staking\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stakingHelper\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"standardizedDebtRatio\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"terms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"controlVariable\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"vestingTerm\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minimumPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPayout\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxDebt\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalDebt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useHelper\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"bondPrice()\":{\"returns\":{\"price_\":\"uint\"}},\"bondPriceInUSD()\":{\"returns\":{\"price_\":\"uint\"}},\"currentDebt()\":{\"returns\":{\"_0\":\"uint\"}},\"debtDecay()\":{\"returns\":{\"decay_\":\"uint\"}},\"debtRatio()\":{\"returns\":{\"debtRatio_\":\"uint\"}},\"deposit(uint256,uint256,address)\":{\"params\":{\"_amount\":\"uint\",\"_depositor\":\"address\",\"_maxPrice\":\"uint\"},\"returns\":{\"_0\":\"uint\"}},\"initializeBondTerms(uint256,uint256,uint256,uint256,uint256,uint256,uint256)\":{\"params\":{\"_controlVariable\":\"uint\",\"_fee\":\"uint\",\"_initialDebt\":\"uint\",\"_maxDebt\":\"uint\",\"_maxPayout\":\"uint\",\"_minimumPrice\":\"uint\",\"_vestingTerm\":\"uint\"}},\"maxPayout()\":{\"returns\":{\"_0\":\"uint\"}},\"payoutFor(uint256)\":{\"params\":{\"_value\":\"uint\"},\"returns\":{\"_0\":\"uint\"}},\"pendingPayoutFor(address)\":{\"params\":{\"_depositor\":\"address\"},\"returns\":{\"pendingPayout_\":\"uint\"}},\"percentVestedFor(address)\":{\"params\":{\"_depositor\":\"address\"},\"returns\":{\"percentVested_\":\"uint\"}},\"recoverLostToken(address)\":{\"returns\":{\"_0\":\"bool\"}},\"redeem(address,bool)\":{\"params\":{\"_recipient\":\"address\",\"_stake\":\"bool\"},\"returns\":{\"_0\":\"uint\"}},\"setAdjustment(bool,uint256,uint256,uint256)\":{\"params\":{\"_addition\":\"bool\",\"_buffer\":\"uint\",\"_increment\":\"uint\",\"_target\":\"uint\"}},\"setBondTerms(uint8,uint256)\":{\"params\":{\"_input\":\"uint\",\"_parameter\":\"PARAMETER\"}},\"setStaking(address,bool)\":{\"params\":{\"_helper\":\"bool\",\"_staking\":\"address\"}},\"standardizedDebtRatio()\":{\"returns\":{\"_0\":\"uint\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"bondPrice()\":{\"notice\":\"calculate current bond premium\"},\"bondPriceInUSD()\":{\"notice\":\"converts bond price to DAI value\"},\"currentDebt()\":{\"notice\":\"calculate debt factoring in decay\"},\"debtDecay()\":{\"notice\":\"amount to decay total debt by\"},\"debtRatio()\":{\"notice\":\"calculate current ratio of debt to OHM supply\"},\"deposit(uint256,uint256,address)\":{\"notice\":\"deposit bond\"},\"initializeBondTerms(uint256,uint256,uint256,uint256,uint256,uint256,uint256)\":{\"notice\":\"initializes bond parameters\"},\"maxPayout()\":{\"notice\":\"determine maximum bond size\"},\"payoutFor(uint256)\":{\"notice\":\"calculate interest due for new bond\"},\"pendingPayoutFor(address)\":{\"notice\":\"calculate amount of OHM available for claim by depositor\"},\"percentVestedFor(address)\":{\"notice\":\"calculate how far into vesting a depositor is\"},\"recoverLostToken(address)\":{\"notice\":\"allow anyone to send lost tokens (excluding principle or OHM) to the DAO\"},\"redeem(address,bool)\":{\"notice\":\"redeem bond for user\"},\"setAdjustment(bool,uint256,uint256,uint256)\":{\"notice\":\"set control variable adjustment\"},\"setBondTerms(uint8,uint256)\":{\"notice\":\"set parameters for new bonds\"},\"setStaking(address,bool)\":{\"notice\":\"set contract for auto stake\"},\"standardizedDebtRatio()\":{\"notice\":\"debt ratio in same terms for reserve or liquidity bonds\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/BondDepository.sol\":\"OlympusBondDepository\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/BondDepository.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-or-later\\npragma solidity 0.7.5;\\n\\ninterface IOwnable {\\n function policy() external view returns (address);\\n\\n function renounceManagement() external;\\n \\n function pushManagement( address newOwner_ ) external;\\n \\n function pullManagement() external;\\n}\\n\\ncontract Ownable is IOwnable {\\n\\n address internal _owner;\\n address internal _newOwner;\\n\\n event OwnershipPushed(address indexed previousOwner, address indexed newOwner);\\n event OwnershipPulled(address indexed previousOwner, address indexed newOwner);\\n\\n constructor () {\\n _owner = msg.sender;\\n emit OwnershipPushed( address(0), _owner );\\n }\\n\\n function policy() public view override returns (address) {\\n return _owner;\\n }\\n\\n modifier onlyPolicy() {\\n require( _owner == msg.sender, \\\"Ownable: caller is not the owner\\\" );\\n _;\\n }\\n\\n function renounceManagement() public virtual override onlyPolicy() {\\n emit OwnershipPushed( _owner, address(0) );\\n _owner = address(0);\\n }\\n\\n function pushManagement( address newOwner_ ) public virtual override onlyPolicy() {\\n require( newOwner_ != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipPushed( _owner, newOwner_ );\\n _newOwner = newOwner_;\\n }\\n \\n function pullManagement() public virtual override {\\n require( msg.sender == _newOwner, \\\"Ownable: must be new owner to pull\\\");\\n emit OwnershipPulled( _owner, _newOwner );\\n _owner = _newOwner;\\n }\\n}\\n\\nlibrary SafeMath {\\n\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n return c;\\n }\\n\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n\\n function sqrrt(uint256 a) internal pure returns (uint c) {\\n if (a > 3) {\\n c = a;\\n uint b = add( div( a, 2), 1 );\\n while (b < c) {\\n c = b;\\n b = div( add( div( a, b ), b), 2 );\\n }\\n } else if (a != 0) {\\n c = 1;\\n }\\n }\\n}\\n\\nlibrary Address {\\n\\n function isContract(address account) internal view returns (bool) {\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return _functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n if (returndata.length > 0) {\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n\\n function addressToString(address _address) internal pure returns(string memory) {\\n bytes32 _bytes = bytes32(uint256(_address));\\n bytes memory HEX = \\\"0123456789abcdef\\\";\\n bytes memory _addr = new bytes(42);\\n\\n _addr[0] = '0';\\n _addr[1] = 'x';\\n\\n for(uint256 i = 0; i < 20; i++) {\\n _addr[2+i*2] = HEX[uint8(_bytes[i + 12] >> 4)];\\n _addr[3+i*2] = HEX[uint8(_bytes[i + 12] & 0x0f)];\\n }\\n\\n return string(_addr);\\n\\n }\\n}\\n\\ninterface IERC20 {\\n function decimals() external view returns (uint8);\\n\\n function totalSupply() external view returns (uint256);\\n\\n function balanceOf(address account) external view returns (uint256);\\n\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\\nabstract contract ERC20 is IERC20 {\\n\\n using SafeMath for uint256;\\n\\n // TODO comment actual hash value.\\n bytes32 constant private ERC20TOKEN_ERC1820_INTERFACE_ID = keccak256( \\\"ERC20Token\\\" );\\n \\n mapping (address => uint256) internal _balances;\\n\\n mapping (address => mapping (address => uint256)) internal _allowances;\\n\\n uint256 internal _totalSupply;\\n\\n string internal _name;\\n \\n string internal _symbol;\\n \\n uint8 internal _decimals;\\n\\n constructor (string memory name_, string memory symbol_, uint8 decimals_) {\\n _name = name_;\\n _symbol = symbol_;\\n _decimals = decimals_;\\n }\\n\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n function symbol() public view returns (string memory) {\\n return _symbol;\\n }\\n\\n function decimals() public view override returns (uint8) {\\n return _decimals;\\n }\\n\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(msg.sender, recipient, amount);\\n return true;\\n }\\n\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(msg.sender, spender, amount);\\n return true;\\n }\\n\\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\n return true;\\n }\\n\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\\n return true;\\n }\\n\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(sender, recipient, amount);\\n }\\n\\n function _mint(address account_, uint256 ammount_) internal virtual {\\n require(account_ != address(0), \\\"ERC20: mint to the zero address\\\");\\n _beforeTokenTransfer(address( this ), account_, ammount_);\\n _totalSupply = _totalSupply.add(ammount_);\\n _balances[account_] = _balances[account_].add(ammount_);\\n emit Transfer(address( this ), account_, ammount_);\\n }\\n\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(account, address(0), amount);\\n }\\n\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n function _beforeTokenTransfer( address from_, address to_, uint256 amount_ ) internal virtual { }\\n}\\n\\ninterface IERC2612Permit {\\n\\n function permit(\\n address owner,\\n address spender,\\n uint256 amount,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n function nonces(address owner) external view returns (uint256);\\n}\\n\\nlibrary Counters {\\n using SafeMath for uint256;\\n\\n struct Counter {\\n\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n counter._value += 1;\\n }\\n\\n function decrement(Counter storage counter) internal {\\n counter._value = counter._value.sub(1);\\n }\\n}\\n\\nabstract contract ERC20Permit is ERC20, IERC2612Permit {\\n using Counters for Counters.Counter;\\n\\n mapping(address => Counters.Counter) private _nonces;\\n\\n // keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\\n\\n bytes32 public DOMAIN_SEPARATOR;\\n\\n constructor() {\\n uint256 chainID;\\n assembly {\\n chainID := chainid()\\n }\\n\\n DOMAIN_SEPARATOR = keccak256(\\n abi.encode(\\n keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"),\\n keccak256(bytes(name())),\\n keccak256(bytes(\\\"1\\\")), // Version\\n chainID,\\n address(this)\\n )\\n );\\n }\\n\\n function permit(\\n address owner,\\n address spender,\\n uint256 amount,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"Permit: expired deadline\\\");\\n\\n bytes32 hashStruct =\\n keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, amount, _nonces[owner].current(), deadline));\\n\\n bytes32 _hash = keccak256(abi.encodePacked(uint16(0x1901), DOMAIN_SEPARATOR, hashStruct));\\n\\n address signer = ecrecover(_hash, v, r, s);\\n require(signer != address(0) && signer == owner, \\\"ZeroSwapPermit: Invalid signature\\\");\\n\\n _nonces[owner].increment();\\n _approve(owner, spender, amount);\\n }\\n\\n function nonces(address owner) public view override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n}\\n\\nlibrary SafeERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n\\n require((value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\\nlibrary FullMath {\\n function fullMul(uint256 x, uint256 y) private pure returns (uint256 l, uint256 h) {\\n uint256 mm = mulmod(x, y, uint256(-1));\\n l = x * y;\\n h = mm - l;\\n if (mm < l) h -= 1;\\n }\\n\\n function fullDiv(\\n uint256 l,\\n uint256 h,\\n uint256 d\\n ) private pure returns (uint256) {\\n uint256 pow2 = d & -d;\\n d /= pow2;\\n l /= pow2;\\n l += h * ((-pow2) / pow2 + 1);\\n uint256 r = 1;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n return l * r;\\n }\\n\\n function mulDiv(\\n uint256 x,\\n uint256 y,\\n uint256 d\\n ) internal pure returns (uint256) {\\n (uint256 l, uint256 h) = fullMul(x, y);\\n uint256 mm = mulmod(x, y, d);\\n if (mm > l) h -= 1;\\n l -= mm;\\n require(h < d, 'FullMath::mulDiv: overflow');\\n return fullDiv(l, h, d);\\n }\\n}\\n\\nlibrary FixedPoint {\\n\\n struct uq112x112 {\\n uint224 _x;\\n }\\n\\n struct uq144x112 {\\n uint256 _x;\\n }\\n\\n uint8 private constant RESOLUTION = 112;\\n uint256 private constant Q112 = 0x10000000000000000000000000000;\\n uint256 private constant Q224 = 0x100000000000000000000000000000000000000000000000000000000;\\n uint256 private constant LOWER_MASK = 0xffffffffffffffffffffffffffff; // decimal of UQ*x112 (lower 112 bits)\\n\\n function decode(uq112x112 memory self) internal pure returns (uint112) {\\n return uint112(self._x >> RESOLUTION);\\n }\\n\\n function decode112with18(uq112x112 memory self) internal pure returns (uint) {\\n\\n return uint(self._x) / 5192296858534827;\\n }\\n\\n function fraction(uint256 numerator, uint256 denominator) internal pure returns (uq112x112 memory) {\\n require(denominator > 0, 'FixedPoint::fraction: division by zero');\\n if (numerator == 0) return FixedPoint.uq112x112(0);\\n\\n if (numerator <= uint144(-1)) {\\n uint256 result = (numerator << RESOLUTION) / denominator;\\n require(result <= uint224(-1), 'FixedPoint::fraction: overflow');\\n return uq112x112(uint224(result));\\n } else {\\n uint256 result = FullMath.mulDiv(numerator, Q112, denominator);\\n require(result <= uint224(-1), 'FixedPoint::fraction: overflow');\\n return uq112x112(uint224(result));\\n }\\n }\\n}\\n\\ninterface ITreasury {\\n function deposit( uint _amount, address _token, uint _profit ) external returns ( bool );\\n function valueOf( address _token, uint _amount ) external view returns ( uint value_ );\\n}\\n\\ninterface IBondCalculator {\\n function valuation( address _LP, uint _amount ) external view returns ( uint );\\n function markdown( address _LP ) external view returns ( uint );\\n}\\n\\ninterface IStaking {\\n function stake( uint _amount, address _recipient ) external returns ( bool );\\n}\\n\\ninterface IStakingHelper {\\n function stake( uint _amount, address _recipient ) external;\\n}\\n\\ncontract OlympusBondDepository is Ownable {\\n\\n using FixedPoint for *;\\n using SafeERC20 for IERC20;\\n using SafeMath for uint;\\n\\n\\n\\n\\n /* ======== EVENTS ======== */\\n\\n event BondCreated( uint deposit, uint indexed payout, uint indexed expires, uint indexed priceInUSD );\\n event BondRedeemed( address indexed recipient, uint payout, uint remaining );\\n event BondPriceChanged( uint indexed priceInUSD, uint indexed internalPrice, uint indexed debtRatio );\\n event ControlVariableAdjustment( uint initialBCV, uint newBCV, uint adjustment, bool addition );\\n\\n\\n\\n\\n /* ======== STATE VARIABLES ======== */\\n\\n address public immutable OHM; // token given as payment for bond\\n address public immutable principle; // token used to create bond\\n address public immutable treasury; // mints OHM when receives principle\\n address public immutable DAO; // receives profit share from bond\\n\\n bool public immutable isLiquidityBond; // LP and Reserve bonds are treated slightly different\\n address public immutable bondCalculator; // calculates value of LP tokens\\n\\n address public staking; // to auto-stake payout\\n address public stakingHelper; // to stake and claim if no staking warmup\\n bool public useHelper;\\n\\n Terms public terms; // stores terms for new bonds\\n Adjust public adjustment; // stores adjustment to BCV data\\n\\n mapping( address => Bond ) public bondInfo; // stores bond information for depositors\\n\\n uint public totalDebt; // total value of outstanding bonds; used for pricing\\n uint public lastDecay; // reference block timestamp for debt decay\\n\\n\\n\\n\\n /* ======== STRUCTS ======== */\\n\\n // Info for creating new bonds\\n struct Terms {\\n uint controlVariable; // scaling variable for price\\n uint vestingTerm; // in seconds\\n uint minimumPrice; // vs principle value\\n uint maxPayout; // in thousandths of a %. i.e. 500 = 0.5%\\n uint fee; // as % of bond payout, in hundreths. ( 500 = 5% = 0.05 for every 1 paid)\\n uint maxDebt; // 9 decimal debt ratio, max % total supply created as debt\\n }\\n\\n // Info for bond holder\\n struct Bond {\\n uint payout; // OHM remaining to be paid\\n uint vesting; // Blocks left to vest\\n uint lastTime; // Last interaction\\n uint pricePaid; // In DAI, for front end viewing\\n }\\n\\n // Info for incremental adjustments to control variable\\n struct Adjust {\\n bool add; // addition or subtraction\\n uint rate; // increment\\n uint target; // BCV when adjustment finished\\n uint buffer; // minimum length (in seconds) between adjustments\\n uint lastTime; // time when last adjustment made\\n }\\n\\n\\n\\n\\n /* ======== INITIALIZATION ======== */\\n\\n constructor ( \\n address _OHM,\\n address _principle,\\n address _treasury, \\n address _DAO, \\n address _bondCalculator\\n ) {\\n require( _OHM != address(0) );\\n OHM = _OHM;\\n require( _principle != address(0) );\\n principle = _principle;\\n require( _treasury != address(0) );\\n treasury = _treasury;\\n require( _DAO != address(0) );\\n DAO = _DAO;\\n // bondCalculator should be address(0) if not LP bond\\n bondCalculator = _bondCalculator;\\n isLiquidityBond = ( _bondCalculator != address(0) );\\n }\\n\\n /**\\n * @notice initializes bond parameters\\n * @param _controlVariable uint\\n * @param _vestingTerm uint\\n * @param _minimumPrice uint\\n * @param _maxPayout uint\\n * @param _fee uint\\n * @param _maxDebt uint\\n * @param _initialDebt uint\\n */\\n function initializeBondTerms( \\n uint _controlVariable, \\n uint _vestingTerm,\\n uint _minimumPrice,\\n uint _maxPayout,\\n uint _fee,\\n uint _maxDebt,\\n uint _initialDebt\\n ) external onlyPolicy() {\\n require( terms.controlVariable == 0, \\\"Bonds must be initialized from 0\\\" );\\n terms = Terms ({\\n controlVariable: _controlVariable,\\n vestingTerm: _vestingTerm,\\n minimumPrice: _minimumPrice,\\n maxPayout: _maxPayout,\\n fee: _fee,\\n maxDebt: _maxDebt\\n });\\n totalDebt = _initialDebt;\\n lastDecay = block.timestamp;\\n }\\n\\n\\n\\n\\n /* ======== POLICY FUNCTIONS ======== */\\n\\n enum PARAMETER { VESTING, PAYOUT, FEE, DEBT }\\n /**\\n * @notice set parameters for new bonds\\n * @param _parameter PARAMETER\\n * @param _input uint\\n */\\n function setBondTerms ( PARAMETER _parameter, uint _input ) external onlyPolicy() {\\n if ( _parameter == PARAMETER.VESTING ) { // 0\\n require( _input >= 129600, \\\"Vesting must be longer than 36 hours\\\" );\\n terms.vestingTerm = _input;\\n } else if ( _parameter == PARAMETER.PAYOUT ) { // 1\\n require( _input <= 1000, \\\"Payout cannot be above 1 percent\\\" );\\n terms.maxPayout = _input;\\n } else if ( _parameter == PARAMETER.FEE ) { // 2\\n require( _input <= 10000, \\\"DAO fee cannot exceed payout\\\" );\\n terms.fee = _input;\\n } else if ( _parameter == PARAMETER.DEBT ) { // 3\\n terms.maxDebt = _input;\\n }\\n }\\n\\n /**\\n * @notice set control variable adjustment\\n * @param _addition bool\\n * @param _increment uint\\n * @param _target uint\\n * @param _buffer uint\\n */\\n function setAdjustment ( \\n bool _addition,\\n uint _increment, \\n uint _target,\\n uint _buffer \\n ) external onlyPolicy() {\\n require( _increment <= terms.controlVariable.mul( 25 ).div( 1000 ), \\\"Increment too large\\\" );\\n\\n adjustment = Adjust({\\n add: _addition,\\n rate: _increment,\\n target: _target,\\n buffer: _buffer,\\n lastTime: block.timestamp\\n });\\n }\\n\\n /**\\n * @notice set contract for auto stake\\n * @param _staking address\\n * @param _helper bool\\n */\\n function setStaking( address _staking, bool _helper ) external onlyPolicy() {\\n require( _staking != address(0) );\\n if ( _helper ) {\\n useHelper = true;\\n stakingHelper = _staking;\\n } else {\\n useHelper = false;\\n staking = _staking;\\n }\\n }\\n\\n\\n \\n\\n /* ======== USER FUNCTIONS ======== */\\n\\n /**\\n * @notice deposit bond\\n * @param _amount uint\\n * @param _maxPrice uint\\n * @param _depositor address\\n * @return uint\\n */\\n function deposit( \\n uint _amount, \\n uint _maxPrice,\\n address _depositor\\n ) external returns ( uint ) {\\n require( _depositor != address(0), \\\"Invalid address\\\" );\\n\\n decayDebt();\\n require( totalDebt <= terms.maxDebt, \\\"Max capacity reached\\\" );\\n \\n uint priceInUSD = bondPriceInUSD(); // Stored in bond info\\n uint nativePrice = _bondPrice();\\n\\n require( _maxPrice >= nativePrice, \\\"Slippage limit: more than max price\\\" ); // slippage protection\\n\\n uint value = ITreasury( treasury ).valueOf( principle, _amount );\\n uint payout = payoutFor( value ); // payout to bonder is computed\\n\\n require( payout >= 10000000, \\\"Bond too small\\\" ); // must be > 0.01 OHM ( underflow protection )\\n require( payout <= maxPayout(), \\\"Bond too large\\\"); // size protection because there is no slippage\\n\\n // profits are calculated\\n uint fee = payout.mul( terms.fee ).div( 10000 );\\n uint profit = value.sub( payout ).sub( fee );\\n\\n /**\\n principle is transferred in\\n approved and\\n deposited into the treasury, returning (_amount - profit) OHM\\n */\\n IERC20( principle ).safeTransferFrom( msg.sender, address(this), _amount );\\n IERC20( principle ).approve( address( treasury ), _amount );\\n ITreasury( treasury ).deposit( _amount, principle, profit );\\n \\n if ( fee != 0 ) { // fee is transferred to dao \\n IERC20( OHM ).safeTransfer( DAO, fee ); \\n }\\n \\n // total debt is increased\\n totalDebt = totalDebt.add( value ); \\n \\n // depositor info is stored\\n bondInfo[ _depositor ] = Bond({ \\n payout: bondInfo[ _depositor ].payout.add( payout ),\\n vesting: terms.vestingTerm,\\n lastTime: block.timestamp,\\n pricePaid: priceInUSD\\n });\\n\\n // indexed events are emitted\\n emit BondCreated( _amount, payout, block.timestamp.add( terms.vestingTerm ), priceInUSD );\\n emit BondPriceChanged( bondPriceInUSD(), _bondPrice(), debtRatio() );\\n\\n adjust(); // control variable is adjusted\\n return payout; \\n }\\n\\n /** \\n * @notice redeem bond for user\\n * @param _recipient address\\n * @param _stake bool\\n * @return uint\\n */ \\n function redeem( address _recipient, bool _stake ) external returns ( uint ) { \\n Bond memory info = bondInfo[ _recipient ];\\n uint percentVested = percentVestedFor( _recipient ); // (blocks since last interaction / vesting term remaining)\\n\\n if ( percentVested >= 10000 ) { // if fully vested\\n delete bondInfo[ _recipient ]; // delete user info\\n emit BondRedeemed( _recipient, info.payout, 0 ); // emit bond data\\n return stakeOrSend( _recipient, _stake, info.payout ); // pay user everything due\\n\\n } else { // if unfinished\\n // calculate payout vested\\n uint payout = info.payout.mul( percentVested ).div( 10000 );\\n\\n // store updated deposit info\\n bondInfo[ _recipient ] = Bond({\\n payout: info.payout.sub( payout ),\\n vesting: info.vesting.sub( block.timestamp.sub( info.lastTime ) ),\\n lastTime: block.timestamp,\\n pricePaid: info.pricePaid\\n });\\n\\n emit BondRedeemed( _recipient, payout, bondInfo[ _recipient ].payout );\\n return stakeOrSend( _recipient, _stake, payout );\\n }\\n }\\n\\n\\n\\n \\n /* ======== INTERNAL HELPER FUNCTIONS ======== */\\n\\n /**\\n * @notice allow user to stake payout automatically\\n * @param _stake bool\\n * @param _amount uint\\n * @return uint\\n */\\n function stakeOrSend( address _recipient, bool _stake, uint _amount ) internal returns ( uint ) {\\n if ( !_stake ) { // if user does not want to stake\\n IERC20( OHM ).transfer( _recipient, _amount ); // send payout\\n } else { // if user wants to stake\\n if ( useHelper ) { // use if staking warmup is 0\\n IERC20( OHM ).approve( stakingHelper, _amount );\\n IStakingHelper( stakingHelper ).stake( _amount, _recipient );\\n } else {\\n IERC20( OHM ).approve( staking, _amount );\\n IStaking( staking ).stake( _amount, _recipient );\\n }\\n }\\n return _amount;\\n }\\n\\n /**\\n * @notice makes incremental adjustment to control variable\\n */\\n function adjust() internal {\\n uint timeCanAdjust = adjustment.lastTime.add( adjustment.buffer );\\n if( adjustment.rate != 0 && block.timestamp >= timeCanAdjust ) {\\n uint initial = terms.controlVariable;\\n if ( adjustment.add ) {\\n terms.controlVariable = terms.controlVariable.add( adjustment.rate );\\n if ( terms.controlVariable >= adjustment.target ) {\\n adjustment.rate = 0;\\n }\\n } else {\\n terms.controlVariable = terms.controlVariable.sub( adjustment.rate );\\n if ( terms.controlVariable <= adjustment.target ) {\\n adjustment.rate = 0;\\n }\\n }\\n adjustment.lastTime = block.timestamp;\\n emit ControlVariableAdjustment( initial, terms.controlVariable, adjustment.rate, adjustment.add );\\n }\\n }\\n\\n /**\\n * @notice reduce total debt\\n */\\n function decayDebt() internal {\\n totalDebt = totalDebt.sub( debtDecay() );\\n lastDecay = block.timestamp;\\n }\\n\\n\\n\\n\\n /* ======== VIEW FUNCTIONS ======== */\\n\\n /**\\n * @notice determine maximum bond size\\n * @return uint\\n */\\n function maxPayout() public view returns ( uint ) {\\n return IERC20( OHM ).totalSupply().mul( terms.maxPayout ).div( 100000 );\\n }\\n\\n /**\\n * @notice calculate interest due for new bond\\n * @param _value uint\\n * @return uint\\n */\\n function payoutFor( uint _value ) public view returns ( uint ) {\\n return FixedPoint.fraction( _value, bondPrice() ).decode112with18().div( 1e16 );\\n }\\n\\n\\n /**\\n * @notice calculate current bond premium\\n * @return price_ uint\\n */\\n function bondPrice() public view returns ( uint price_ ) { \\n price_ = terms.controlVariable.mul( debtRatio() ).add( 1000000000 ).div( 1e7 );\\n if ( price_ < terms.minimumPrice ) {\\n price_ = terms.minimumPrice;\\n }\\n }\\n\\n /**\\n * @notice calculate current bond price and remove floor if above\\n * @return price_ uint\\n */\\n function _bondPrice() internal returns ( uint price_ ) {\\n price_ = terms.controlVariable.mul( debtRatio() ).add( 1000000000 ).div( 1e7 );\\n if ( price_ < terms.minimumPrice ) {\\n price_ = terms.minimumPrice; \\n } else if ( terms.minimumPrice != 0 ) {\\n terms.minimumPrice = 0;\\n }\\n }\\n\\n /**\\n * @notice converts bond price to DAI value\\n * @return price_ uint\\n */\\n function bondPriceInUSD() public view returns ( uint price_ ) {\\n if( isLiquidityBond ) {\\n price_ = bondPrice().mul( IBondCalculator( bondCalculator ).markdown( principle ) ).div( 100 );\\n } else {\\n price_ = bondPrice().mul( 10 ** IERC20( principle ).decimals() ).div( 100 );\\n }\\n }\\n\\n\\n /**\\n * @notice calculate current ratio of debt to OHM supply\\n * @return debtRatio_ uint\\n */\\n function debtRatio() public view returns ( uint debtRatio_ ) { \\n uint supply = IERC20( OHM ).totalSupply();\\n debtRatio_ = FixedPoint.fraction( \\n currentDebt().mul( 1e9 ), \\n supply\\n ).decode112with18().div( 1e18 );\\n }\\n\\n /**\\n * @notice debt ratio in same terms for reserve or liquidity bonds\\n * @return uint\\n */\\n function standardizedDebtRatio() external view returns ( uint ) {\\n if ( isLiquidityBond ) {\\n return debtRatio().mul( IBondCalculator( bondCalculator ).markdown( principle ) ).div( 1e9 );\\n } else {\\n return debtRatio();\\n }\\n }\\n\\n /**\\n * @notice calculate debt factoring in decay\\n * @return uint\\n */\\n function currentDebt() public view returns ( uint ) {\\n return totalDebt.sub( debtDecay() );\\n }\\n\\n /**\\n * @notice amount to decay total debt by\\n * @return decay_ uint\\n */\\n function debtDecay() public view returns ( uint decay_ ) {\\n uint timeSinceLast = block.timestamp.sub( lastDecay );\\n decay_ = totalDebt.mul( timeSinceLast ).div( terms.vestingTerm );\\n if ( decay_ > totalDebt ) {\\n decay_ = totalDebt;\\n }\\n }\\n\\n\\n /**\\n * @notice calculate how far into vesting a depositor is\\n * @param _depositor address\\n * @return percentVested_ uint\\n */\\n function percentVestedFor( address _depositor ) public view returns ( uint percentVested_ ) {\\n Bond memory bond = bondInfo[ _depositor ];\\n uint secondsSinceLast = block.timestamp.sub( bond.lastTime );\\n uint vesting = bond.vesting;\\n\\n if ( vesting > 0 ) {\\n percentVested_ = secondsSinceLast.mul( 10000 ).div( vesting );\\n } else {\\n percentVested_ = 0;\\n }\\n }\\n\\n /**\\n * @notice calculate amount of OHM available for claim by depositor\\n * @param _depositor address\\n * @return pendingPayout_ uint\\n */\\n function pendingPayoutFor( address _depositor ) external view returns ( uint pendingPayout_ ) {\\n uint percentVested = percentVestedFor( _depositor );\\n uint payout = bondInfo[ _depositor ].payout;\\n\\n if ( percentVested >= 10000 ) {\\n pendingPayout_ = payout;\\n } else {\\n pendingPayout_ = payout.mul( percentVested ).div( 10000 );\\n }\\n }\\n\\n\\n\\n\\n /* ======= AUXILLIARY ======= */\\n\\n /**\\n * @notice allow anyone to send lost tokens (excluding principle or OHM) to the DAO\\n * @return bool\\n */\\n function recoverLostToken( address _token ) external returns ( bool ) {\\n require( _token != OHM );\\n require( _token != principle );\\n IERC20( _token ).safeTransfer( DAO, IERC20( _token ).balanceOf( address(this) ) );\\n return true;\\n }\\n}\",\"keccak256\":\"0x145d41124d867bc2954e61be6336abc8bbc861b6fb9d5221e6bcb7276e1b4829\",\"license\":\"AGPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x6101406040523480156200001257600080fd5b506040516200466838038062004668833981810160405260a08110156200003857600080fd5b810190808051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a3600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614156200016757600080fd5b8473ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b81525050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415620001d957600080fd5b8373ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b81525050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156200024b57600080fd5b8273ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff1660601b81525050600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415620002bd57600080fd5b8173ffffffffffffffffffffffffffffffffffffffff1660e08173ffffffffffffffffffffffffffffffffffffffff1660601b815250508073ffffffffffffffffffffffffffffffffffffffff166101208173ffffffffffffffffffffffffffffffffffffffff1660601b81525050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561010081151560f81b81525050505050505060805160601c60a05160601c60c05160601c60e05160601c6101005160f81c6101205160601c6142236200044560003980611b5b52806125a652806128b2525080611b2d52806125755280612be852508061235e52806126c152806127c05250806118c25280611edd52806121ad528061225e5250806109a75280611b975280611c705280611f19528061212a5280612171528061229b52806125e2528061276452508061238052806126e5528061270b52806129095280612c855280612e865280612f6d528061310c52506142236000f3fe608060405234801561001057600080fd5b50600436106102115760003560e01c80637927ebf811610125578063cea55f57116100ad578063d7ccfb0b1161007c578063d7ccfb0b1461090f578063e0176de81461092d578063e392a2621461094b578063f5c2ab5b14610969578063fc7b9c181461098757610211565b8063cea55f5714610840578063d4d863ce1461085e578063d5025625146108ae578063d7969060146108ef57610211565b806398fabd3a116100f457806398fabd3a146106dd578063a6c41fec14610711578063b4abccba14610745578063c5332b7c1461079f578063cd1234b3146107d357610211565b80637927ebf8146105f3578063844b5c7c146106355780638dbdbe6d14610653578063904b3ece146106bf57610211565b8063451ee4a1116101a85780635a96ac0a116101775780635a96ac0a146104f957806361d027b3146105035780637153500814610537578063759076e5146105a157806377b81895146105bf57610211565b8063451ee4a1146103ed57806346f68ee9146104295780634cf088d91461046d578063507930ec146104a157610211565b80631a3d0068116101e45780631a3d0068146102e05780631e321a0f1461032e5780631feed31f146103695780632f3f470a146103cd57610211565b8063016a42841461021657806301b88ee81461024a5780630505c8c9146102a2578063089208d8146102d6575b600080fd5b61021e6109a5565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61028c6004803603602081101561026057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506109c9565b6040518082815260200191505060405180910390f35b6102aa610a60565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102de610a89565b005b61032c600480360360808110156102f657600080fd5b81019080803515159060200190929190803590602001909291908035906020019092919080359060200190929190505050610c08565b005b6103676004803603604081101561034457600080fd5b81019080803560ff16906020019092919080359060200190929190505050610de7565b005b6103b76004803603604081101561037f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035151590602001909291905050506110ad565b6040518082815260200191505060405180910390f35b6103d56113c5565b60405180821515815260200191505060405180910390f35b6103f56113d8565b6040518086151581526020018581526020018481526020018381526020018281526020019550505050505060405180910390f35b61046b6004803603602081101561043f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611409565b005b61047561160e565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6104e3600480360360208110156104b757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611634565b6040518082815260200191505060405180910390f35b61050161171a565b005b61050b6118c0565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61059f600480360360e081101561054d57600080fd5b81019080803590602001909291908035906020019092919080359060200190929190803590602001909291908035906020019092919080359060200190929190803590602001909291905050506118e4565b005b6105a9611aa5565b6040518082815260200191505060405180910390f35b6105c7611ac8565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61061f6004803603602081101561060957600080fd5b8101908080359060200190929190505050611aee565b6040518082815260200191505060405180910390f35b61063d611b29565b6040518082815260200191505060405180910390f35b6106a96004803603606081101561066957600080fd5b810190808035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611d3f565b6040518082815260200191505060405180910390f35b6106c7612571565b6040518082815260200191505060405180910390f35b6106e56126bf565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6107196126e3565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6107876004803603602081101561075b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612707565b60405180821515815260200191505060405180910390f35b6107a76128b0565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610815600480360360208110156107e957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506128d4565b6040518085815260200184815260200183815260200182815260200194505050505060405180910390f35b610848612904565b6040518082815260200191505060405180910390f35b6108ac6004803603604081101561087457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035151590602001909291905050506129f9565b005b6108b6612bbc565b60405180878152602001868152602001858152602001848152602001838152602001828152602001965050505050505060405180910390f35b6108f7612be6565b60405180821515815260200191505060405180910390f35b610917612c0a565b6040518082815260200191505060405180910390f35b610935612c71565b6040518082815260200191505060405180910390f35b610953612d45565b6040518082815260200191505060405180910390f35b610971612da1565b6040518082815260200191505060405180910390f35b61098f612da7565b6040518082815260200191505060405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806109d583611634565b90506000600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015490506127108210610a2f57809250610a59565b610a56612710610a488484612dad90919063ffffffff16565b612e3390919063ffffffff16565b92505b5050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b4a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610cc9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b610cf66103e8610ce86019600460000154612dad90919063ffffffff16565b612e3390919063ffffffff16565b831115610d6b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f496e6372656d656e7420746f6f206c617267650000000000000000000000000081525060200191505060405180910390fd5b6040518060a00160405280851515815260200184815260200183815260200182815260200142815250600a60008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020155606082015181600301556080820151816004015590505050505050565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610ea8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60006003811115610eb557fe5b826003811115610ec157fe5b1415610f32576201fa40811015610f23576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806141a06024913960400191505060405180910390fd5b806004600101819055506110a9565b60016003811115610f3f57fe5b826003811115610f4b57fe5b1415610fd8576103e8811115610fc9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f5061796f75742063616e6e6f742062652061626f766520312070657263656e7481525060200191505060405180910390fd5b806004600301819055506110a8565b60026003811115610fe557fe5b826003811115610ff157fe5b141561107d5761271081111561106f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f44414f206665652063616e6e6f7420657863656564207061796f75740000000081525060200191505060405180910390fd5b8060048001819055506110a7565b60038081111561108957fe5b82600381111561109557fe5b14156110a657806004600501819055505b5b5b5b5050565b60006110b7614094565b600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060800160405290816000820154815260200160018201548152602001600282015481526020016003820154815250509050600061113685611634565b9050612710811061121657600f60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008082016000905560018201600090556002820160009055600382016000905550508473ffffffffffffffffffffffffffffffffffffffff167f51c99f515c87b0d95ba97f616edd182e8f161c4932eac17c6fefe9dab58b77b183600001516000604051808381526020018281526020019250505060405180910390a261120d85858460000151612e7d565b925050506113bf565b6000611243612710611235848660000151612dad90919063ffffffff16565b612e3390919063ffffffff16565b905060405180608001604052806112678386600001516132d490919063ffffffff16565b81526020016112996112868660400151426132d490919063ffffffff16565b86602001516132d490919063ffffffff16565b81526020014281526020018460600151815250600f60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082015181600001556020820151816001015560408201518160020155606082015181600301559050508573ffffffffffffffffffffffffffffffffffffffff167f51c99f515c87b0d95ba97f616edd182e8f161c4932eac17c6fefe9dab58b77b182600f60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154604051808381526020018281526020019250505060405180910390a26113b9868683612e7d565b93505050505b92915050565b600360149054906101000a900460ff1681565b600a8060000160009054906101000a900460ff16908060010154908060020154908060030154908060040154905085565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146114ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611550576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806140ee6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a380600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600061163e614094565b600f60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020604051806080016040529081600082015481526020016001820154815260200160028201548152602001600382015481525050905060006116cb8260400151426132d490919063ffffffff16565b9050600082602001519050600081111561170d57611706816116f861271085612dad90919063ffffffff16565b612e3390919063ffffffff16565b9350611712565b600093505b505050919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146117c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806141146022913960400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167faa151555690c956fc3ea32f106bb9f119b5237a061eaa8557cff3e51e3792c8d60405160405180910390a3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146119a5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060046000015414611a20576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f426f6e6473206d75737420626520696e697469616c697a65642066726f6d203081525060200191505060405180910390fd5b6040518060c00160405280888152602001878152602001868152602001858152602001848152602001838152506004600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a08201518160050155905050806010819055504260118190555050505050505050565b6000611ac3611ab2612d45565b6010546132d490919063ffffffff16565b905090565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611b22662386f26fc10000611b14611b0f85611b0a612c0a565b61331e565b6135ff565b612e3390919063ffffffff16565b9050919050565b60007f000000000000000000000000000000000000000000000000000000000000000015611c6657611c5f6064611c517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166332da80a37f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611c0057600080fd5b505afa158015611c14573d6000803e3d6000fd5b505050506040513d6020811015611c2a57600080fd5b8101908080519060200190929190505050611c43612c0a565b612dad90919063ffffffff16565b612e3390919063ffffffff16565b9050611d3c565b611d396064611d2b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015611cd457600080fd5b505afa158015611ce8573d6000803e3d6000fd5b505050506040513d6020811015611cfe57600080fd5b810190808051906020019092919050505060ff16600a0a611d1d612c0a565b612dad90919063ffffffff16565b612e3390919063ffffffff16565b90505b90565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611de3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f496e76616c69642061646472657373000000000000000000000000000000000081525060200191505060405180910390fd5b611deb61363b565b6004600501546010541115611e68576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4d6178206361706163697479207265616368656400000000000000000000000081525060200191505060405180910390fd5b6000611e72611b29565b90506000611e7e613666565b905080851015611ed9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602381526020018061417d6023913960400191505060405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16631eec5a9a7f0000000000000000000000000000000000000000000000000000000000000000896040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060206040518083038186803b158015611f8a57600080fd5b505afa158015611f9e573d6000803e3d6000fd5b505050506040513d6020811015611fb457600080fd5b810190808051906020019092919050505090506000611fd282611aee565b90506298968081101561204d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f426f6e6420746f6f20736d616c6c00000000000000000000000000000000000081525060200191505060405180910390fd5b612055612c71565b8111156120ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f426f6e6420746f6f206c6172676500000000000000000000000000000000000081525060200191505060405180910390fd5b60006120f76127106120e9600480015485612dad90919063ffffffff16565b612e3390919063ffffffff16565b905060006121208261211285876132d490919063ffffffff16565b6132d490919063ffffffff16565b905061216f33308c7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166136eb909392919063ffffffff16565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b37f00000000000000000000000000000000000000000000000000000000000000008c6040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561222057600080fd5b505af1158015612234573d6000803e3d6000fd5b505050506040513d602081101561224a57600080fd5b8101908080519060200190929190505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663bc157ac18b7f0000000000000000000000000000000000000000000000000000000000000000846040518463ffffffff1660e01b8152600401808481526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b15801561231557600080fd5b505af1158015612329573d6000803e3d6000fd5b505050506040513d602081101561233f57600080fd5b810190808051906020019092919050505050600082146123c5576123c47f0000000000000000000000000000000000000000000000000000000000000000837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166137ac9092919063ffffffff16565b5b6123da8460105461384e90919063ffffffff16565b601081905550604051806080016040528061244085600f60008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015461384e90919063ffffffff16565b8152602001600460010154815260200142815260200187815250600f60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030155905050856124dd6004600101544261384e90919063ffffffff16565b847f1fec6dc81f140574bf43f6b1e420ae1dd47928b9d57db8cbd7b8611063b85ae58d6040518082815260200191505060405180910390a461251d612904565b612525613666565b61252d611b29565b7f375b221f40939bfd8f49723a17cf7bc6d576ebf72efe2cc3e991826f5b3f390a60405160405180910390a46125616138d6565b8296505050505050509392505050565b60007f0000000000000000000000000000000000000000000000000000000000000000156126b1576126aa633b9aca0061269c7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166332da80a37f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561264b57600080fd5b505afa15801561265f573d6000803e3d6000fd5b505050506040513d602081101561267557600080fd5b810190808051906020019092919050505061268e612904565b612dad90919063ffffffff16565b612e3390919063ffffffff16565b90506126bc565b6126b9612904565b90505b90565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561276257600080fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156127bb57600080fd5b6128a77f00000000000000000000000000000000000000000000000000000000000000008373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561284657600080fd5b505afa15801561285a573d6000803e3d6000fd5b505050506040513d602081101561287057600080fd5b81019080805190602001909291905050508473ffffffffffffffffffffffffffffffffffffffff166137ac9092919063ffffffff16565b60019050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600f6020528060005260406000206000915090508060000154908060010154908060020154908060030154905084565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561296d57600080fd5b505afa158015612981573d6000803e3d6000fd5b505050506040513d602081101561299757600080fd5b810190808051906020019092919050505090506129f3670de0b6b3a76400006129e56129e06129da633b9aca006129cc611aa5565b612dad90919063ffffffff16565b8561331e565b6135ff565b612e3390919063ffffffff16565b91505090565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612aba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612af457600080fd5b8015612b5b576001600360146101000a81548160ff02191690831515021790555081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550612bb8565b6000600360146101000a81548160ff02191690831515021790555081600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5050565b60048060000154908060010154908060020154908060030154908060040154908060050154905086565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000612c5662989680612c48633b9aca00612c3a612c26612904565b600460000154612dad90919063ffffffff16565b61384e90919063ffffffff16565b612e3390919063ffffffff16565b9050600460020154811015612c6e5760046002015490505b90565b6000612d40620186a0612d326004600301547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612ce957600080fd5b505afa158015612cfd573d6000803e3d6000fd5b505050506040513d6020811015612d1357600080fd5b8101908080519060200190929190505050612dad90919063ffffffff16565b612e3390919063ffffffff16565b905090565b600080612d5d601154426132d490919063ffffffff16565b9050612d8b600460010154612d7d83601054612dad90919063ffffffff16565b612e3390919063ffffffff16565b9150601054821115612d9d5760105491505b5090565b60115481565b60105481565b600080831415612dc05760009050612e2d565b6000828402905082848281612dd157fe5b0414612e28576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061415c6021913960400191505060405180910390fd5b809150505b92915050565b6000612e7583836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613a3c565b905092915050565b600082612f56577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612f1557600080fd5b505af1158015612f29573d6000803e3d6000fd5b505050506040513d6020811015612f3f57600080fd5b8101908080519060200190929190505050506132ca565b600360149054906101000a900460ff161561310a577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561301e57600080fd5b505af1158015613032573d6000803e3d6000fd5b505050506040513d602081101561304857600080fd5b810190808051906020019092919050505050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637acb775783866040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b1580156130ed57600080fd5b505af1158015613101573d6000803e3d6000fd5b505050506132c9565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156131bd57600080fd5b505af11580156131d1573d6000803e3d6000fd5b505050506040513d60208110156131e757600080fd5b810190808051906020019092919050505050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637acb775783866040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b15801561328c57600080fd5b505af11580156132a0573d6000803e3d6000fd5b505050506040513d60208110156132b657600080fd5b8101908080519060200190929190505050505b5b8190509392505050565b600061331683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613b02565b905092915050565b6133266140bc565b6000821161337f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806141366026913960400191505060405180910390fd5b60008314156133bd57604051806020016040528060007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525090506135f9565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff71ffffffffffffffffffffffffffffffffffff1683116134f657600082607060ff1685901b8161340a57fe5b0490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168111156134c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f77000081525060200191505060405180910390fd5b6040518060200160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509150506135f9565b6000613512846e01000000000000000000000000000085613bc2565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168111156135c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f77000081525060200191505060405180910390fd5b6040518060200160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509150505b92915050565b60006612725dd1d243ab82600001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168161363357fe5b049050919050565b613657613646612d45565b6010546132d490919063ffffffff16565b60108190555042601181905550565b60006136b2629896806136a4633b9aca00613696613682612904565b600460000154612dad90919063ffffffff16565b61384e90919063ffffffff16565b612e3390919063ffffffff16565b90506004600201548110156136ce5760046002015490506136e8565b6000600460020154146136e75760006004600201819055505b5b90565b6137a6846323b872dd60e01b858585604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613c84565b50505050565b6138498363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613c84565b505050565b6000808284019050838110156138cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b60006138f5600a60030154600a6004015461384e90919063ffffffff16565b90506000600a600101541415801561390d5750804210155b15613a395760006004600001549050600a60000160009054906101000a900460ff161561397c57613951600a6001015460046000015461384e90919063ffffffff16565b600460000181905550600a6002015460046000015410613977576000600a600101819055505b6139c0565b613999600a600101546004600001546132d490919063ffffffff16565b600460000181905550600a60020154600460000154116139bf576000600a600101819055505b5b42600a600401819055507fb923e581a0f83128e9e1d8297aa52b18d6744310476e0b54509c054cd7a93b2a81600460000154600a60010154600a60000160009054906101000a900460ff1660405180858152602001848152602001838152602001821515815260200194505050505060405180910390a1505b50565b60008083118290613ae8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613aad578082015181840152602081019050613a92565b50505050905090810190601f168015613ada5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581613af457fe5b049050809150509392505050565b6000838311158290613baf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613b74578082015181840152602081019050613b59565b50505050905090810190601f168015613ba15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b6000806000613bd18686613d73565b9150915060008480613bdf57fe5b868809905082811115613bf3576001820391505b8083039250848210613c6d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f46756c6c4d6174683a3a6d756c4469763a206f766572666c6f7700000000000081525060200191505060405180910390fd5b613c78838387613dc6565b93505050509392505050565b6060613ce6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613e639092919063ffffffff16565b9050600081511115613d6e57808060200190516020811015613d0757600080fd5b8101908080519060200190929190505050613d6d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a8152602001806141c4602a913960400191505060405180910390fd5b5b505050565b60008060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80613da057fe5b84860990508385029250828103915082811015613dbe576001820391505b509250929050565b6000808260000383169050808381613dda57fe5b049250808581613de657fe5b0494506001818260000381613df757fe5b04018402850194506000600190508084026002038102905080840260020381029050808402600203810290508084026002038102905080840260020381029050808402600203810290508084026002038102905080840260020381029050808602925050509392505050565b6060613e728484600085613e7b565b90509392505050565b6060613e8685614081565b613ef8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b60208310613f485780518252602082019150602081019050602083039250613f25565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613faa576040519150601f19603f3d011682016040523d82523d6000602084013e613faf565b606091505b50915091508115613fc4578092505050614079565b600081511115613fd75780518082602001fd5b836040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561403e578082015181840152602081019050614023565b50505050905090810190601f16801561406b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b949350505050565b600080823b905060008111915050919050565b6040518060800160405280600081526020016000815260200160008152602001600081525090565b604051806020016040528060007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a206d757374206265206e6577206f776e657220746f2070756c6c4669786564506f696e743a3a6672616374696f6e3a206469766973696f6e206279207a65726f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77536c697070616765206c696d69743a206d6f7265207468616e206d617820707269636556657374696e67206d757374206265206c6f6e676572207468616e20333620686f7572735361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a264697066735822122053be4518e6208ff68edac4e5334629c89de3521dd2fcec0ecc75153a7a8305f764736f6c63430007050033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102115760003560e01c80637927ebf811610125578063cea55f57116100ad578063d7ccfb0b1161007c578063d7ccfb0b1461090f578063e0176de81461092d578063e392a2621461094b578063f5c2ab5b14610969578063fc7b9c181461098757610211565b8063cea55f5714610840578063d4d863ce1461085e578063d5025625146108ae578063d7969060146108ef57610211565b806398fabd3a116100f457806398fabd3a146106dd578063a6c41fec14610711578063b4abccba14610745578063c5332b7c1461079f578063cd1234b3146107d357610211565b80637927ebf8146105f3578063844b5c7c146106355780638dbdbe6d14610653578063904b3ece146106bf57610211565b8063451ee4a1116101a85780635a96ac0a116101775780635a96ac0a146104f957806361d027b3146105035780637153500814610537578063759076e5146105a157806377b81895146105bf57610211565b8063451ee4a1146103ed57806346f68ee9146104295780634cf088d91461046d578063507930ec146104a157610211565b80631a3d0068116101e45780631a3d0068146102e05780631e321a0f1461032e5780631feed31f146103695780632f3f470a146103cd57610211565b8063016a42841461021657806301b88ee81461024a5780630505c8c9146102a2578063089208d8146102d6575b600080fd5b61021e6109a5565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61028c6004803603602081101561026057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506109c9565b6040518082815260200191505060405180910390f35b6102aa610a60565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102de610a89565b005b61032c600480360360808110156102f657600080fd5b81019080803515159060200190929190803590602001909291908035906020019092919080359060200190929190505050610c08565b005b6103676004803603604081101561034457600080fd5b81019080803560ff16906020019092919080359060200190929190505050610de7565b005b6103b76004803603604081101561037f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035151590602001909291905050506110ad565b6040518082815260200191505060405180910390f35b6103d56113c5565b60405180821515815260200191505060405180910390f35b6103f56113d8565b6040518086151581526020018581526020018481526020018381526020018281526020019550505050505060405180910390f35b61046b6004803603602081101561043f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611409565b005b61047561160e565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6104e3600480360360208110156104b757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611634565b6040518082815260200191505060405180910390f35b61050161171a565b005b61050b6118c0565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61059f600480360360e081101561054d57600080fd5b81019080803590602001909291908035906020019092919080359060200190929190803590602001909291908035906020019092919080359060200190929190803590602001909291905050506118e4565b005b6105a9611aa5565b6040518082815260200191505060405180910390f35b6105c7611ac8565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61061f6004803603602081101561060957600080fd5b8101908080359060200190929190505050611aee565b6040518082815260200191505060405180910390f35b61063d611b29565b6040518082815260200191505060405180910390f35b6106a96004803603606081101561066957600080fd5b810190808035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611d3f565b6040518082815260200191505060405180910390f35b6106c7612571565b6040518082815260200191505060405180910390f35b6106e56126bf565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6107196126e3565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6107876004803603602081101561075b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612707565b60405180821515815260200191505060405180910390f35b6107a76128b0565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610815600480360360208110156107e957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506128d4565b6040518085815260200184815260200183815260200182815260200194505050505060405180910390f35b610848612904565b6040518082815260200191505060405180910390f35b6108ac6004803603604081101561087457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035151590602001909291905050506129f9565b005b6108b6612bbc565b60405180878152602001868152602001858152602001848152602001838152602001828152602001965050505050505060405180910390f35b6108f7612be6565b60405180821515815260200191505060405180910390f35b610917612c0a565b6040518082815260200191505060405180910390f35b610935612c71565b6040518082815260200191505060405180910390f35b610953612d45565b6040518082815260200191505060405180910390f35b610971612da1565b6040518082815260200191505060405180910390f35b61098f612da7565b6040518082815260200191505060405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806109d583611634565b90506000600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015490506127108210610a2f57809250610a59565b610a56612710610a488484612dad90919063ffffffff16565b612e3390919063ffffffff16565b92505b5050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b4a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610cc9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b610cf66103e8610ce86019600460000154612dad90919063ffffffff16565b612e3390919063ffffffff16565b831115610d6b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f496e6372656d656e7420746f6f206c617267650000000000000000000000000081525060200191505060405180910390fd5b6040518060a00160405280851515815260200184815260200183815260200182815260200142815250600a60008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020155606082015181600301556080820151816004015590505050505050565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610ea8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60006003811115610eb557fe5b826003811115610ec157fe5b1415610f32576201fa40811015610f23576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806141a06024913960400191505060405180910390fd5b806004600101819055506110a9565b60016003811115610f3f57fe5b826003811115610f4b57fe5b1415610fd8576103e8811115610fc9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f5061796f75742063616e6e6f742062652061626f766520312070657263656e7481525060200191505060405180910390fd5b806004600301819055506110a8565b60026003811115610fe557fe5b826003811115610ff157fe5b141561107d5761271081111561106f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f44414f206665652063616e6e6f7420657863656564207061796f75740000000081525060200191505060405180910390fd5b8060048001819055506110a7565b60038081111561108957fe5b82600381111561109557fe5b14156110a657806004600501819055505b5b5b5b5050565b60006110b7614094565b600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060800160405290816000820154815260200160018201548152602001600282015481526020016003820154815250509050600061113685611634565b9050612710811061121657600f60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008082016000905560018201600090556002820160009055600382016000905550508473ffffffffffffffffffffffffffffffffffffffff167f51c99f515c87b0d95ba97f616edd182e8f161c4932eac17c6fefe9dab58b77b183600001516000604051808381526020018281526020019250505060405180910390a261120d85858460000151612e7d565b925050506113bf565b6000611243612710611235848660000151612dad90919063ffffffff16565b612e3390919063ffffffff16565b905060405180608001604052806112678386600001516132d490919063ffffffff16565b81526020016112996112868660400151426132d490919063ffffffff16565b86602001516132d490919063ffffffff16565b81526020014281526020018460600151815250600f60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082015181600001556020820151816001015560408201518160020155606082015181600301559050508573ffffffffffffffffffffffffffffffffffffffff167f51c99f515c87b0d95ba97f616edd182e8f161c4932eac17c6fefe9dab58b77b182600f60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154604051808381526020018281526020019250505060405180910390a26113b9868683612e7d565b93505050505b92915050565b600360149054906101000a900460ff1681565b600a8060000160009054906101000a900460ff16908060010154908060020154908060030154908060040154905085565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146114ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611550576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806140ee6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a380600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600061163e614094565b600f60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020604051806080016040529081600082015481526020016001820154815260200160028201548152602001600382015481525050905060006116cb8260400151426132d490919063ffffffff16565b9050600082602001519050600081111561170d57611706816116f861271085612dad90919063ffffffff16565b612e3390919063ffffffff16565b9350611712565b600093505b505050919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146117c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806141146022913960400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167faa151555690c956fc3ea32f106bb9f119b5237a061eaa8557cff3e51e3792c8d60405160405180910390a3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146119a5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060046000015414611a20576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f426f6e6473206d75737420626520696e697469616c697a65642066726f6d203081525060200191505060405180910390fd5b6040518060c00160405280888152602001878152602001868152602001858152602001848152602001838152506004600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a08201518160050155905050806010819055504260118190555050505050505050565b6000611ac3611ab2612d45565b6010546132d490919063ffffffff16565b905090565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611b22662386f26fc10000611b14611b0f85611b0a612c0a565b61331e565b6135ff565b612e3390919063ffffffff16565b9050919050565b60007f000000000000000000000000000000000000000000000000000000000000000015611c6657611c5f6064611c517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166332da80a37f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611c0057600080fd5b505afa158015611c14573d6000803e3d6000fd5b505050506040513d6020811015611c2a57600080fd5b8101908080519060200190929190505050611c43612c0a565b612dad90919063ffffffff16565b612e3390919063ffffffff16565b9050611d3c565b611d396064611d2b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015611cd457600080fd5b505afa158015611ce8573d6000803e3d6000fd5b505050506040513d6020811015611cfe57600080fd5b810190808051906020019092919050505060ff16600a0a611d1d612c0a565b612dad90919063ffffffff16565b612e3390919063ffffffff16565b90505b90565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611de3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f496e76616c69642061646472657373000000000000000000000000000000000081525060200191505060405180910390fd5b611deb61363b565b6004600501546010541115611e68576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4d6178206361706163697479207265616368656400000000000000000000000081525060200191505060405180910390fd5b6000611e72611b29565b90506000611e7e613666565b905080851015611ed9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602381526020018061417d6023913960400191505060405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16631eec5a9a7f0000000000000000000000000000000000000000000000000000000000000000896040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060206040518083038186803b158015611f8a57600080fd5b505afa158015611f9e573d6000803e3d6000fd5b505050506040513d6020811015611fb457600080fd5b810190808051906020019092919050505090506000611fd282611aee565b90506298968081101561204d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f426f6e6420746f6f20736d616c6c00000000000000000000000000000000000081525060200191505060405180910390fd5b612055612c71565b8111156120ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f426f6e6420746f6f206c6172676500000000000000000000000000000000000081525060200191505060405180910390fd5b60006120f76127106120e9600480015485612dad90919063ffffffff16565b612e3390919063ffffffff16565b905060006121208261211285876132d490919063ffffffff16565b6132d490919063ffffffff16565b905061216f33308c7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166136eb909392919063ffffffff16565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b37f00000000000000000000000000000000000000000000000000000000000000008c6040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561222057600080fd5b505af1158015612234573d6000803e3d6000fd5b505050506040513d602081101561224a57600080fd5b8101908080519060200190929190505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663bc157ac18b7f0000000000000000000000000000000000000000000000000000000000000000846040518463ffffffff1660e01b8152600401808481526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b15801561231557600080fd5b505af1158015612329573d6000803e3d6000fd5b505050506040513d602081101561233f57600080fd5b810190808051906020019092919050505050600082146123c5576123c47f0000000000000000000000000000000000000000000000000000000000000000837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166137ac9092919063ffffffff16565b5b6123da8460105461384e90919063ffffffff16565b601081905550604051806080016040528061244085600f60008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015461384e90919063ffffffff16565b8152602001600460010154815260200142815260200187815250600f60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030155905050856124dd6004600101544261384e90919063ffffffff16565b847f1fec6dc81f140574bf43f6b1e420ae1dd47928b9d57db8cbd7b8611063b85ae58d6040518082815260200191505060405180910390a461251d612904565b612525613666565b61252d611b29565b7f375b221f40939bfd8f49723a17cf7bc6d576ebf72efe2cc3e991826f5b3f390a60405160405180910390a46125616138d6565b8296505050505050509392505050565b60007f0000000000000000000000000000000000000000000000000000000000000000156126b1576126aa633b9aca0061269c7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166332da80a37f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561264b57600080fd5b505afa15801561265f573d6000803e3d6000fd5b505050506040513d602081101561267557600080fd5b810190808051906020019092919050505061268e612904565b612dad90919063ffffffff16565b612e3390919063ffffffff16565b90506126bc565b6126b9612904565b90505b90565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561276257600080fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156127bb57600080fd5b6128a77f00000000000000000000000000000000000000000000000000000000000000008373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561284657600080fd5b505afa15801561285a573d6000803e3d6000fd5b505050506040513d602081101561287057600080fd5b81019080805190602001909291905050508473ffffffffffffffffffffffffffffffffffffffff166137ac9092919063ffffffff16565b60019050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600f6020528060005260406000206000915090508060000154908060010154908060020154908060030154905084565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561296d57600080fd5b505afa158015612981573d6000803e3d6000fd5b505050506040513d602081101561299757600080fd5b810190808051906020019092919050505090506129f3670de0b6b3a76400006129e56129e06129da633b9aca006129cc611aa5565b612dad90919063ffffffff16565b8561331e565b6135ff565b612e3390919063ffffffff16565b91505090565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612aba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612af457600080fd5b8015612b5b576001600360146101000a81548160ff02191690831515021790555081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550612bb8565b6000600360146101000a81548160ff02191690831515021790555081600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5050565b60048060000154908060010154908060020154908060030154908060040154908060050154905086565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000612c5662989680612c48633b9aca00612c3a612c26612904565b600460000154612dad90919063ffffffff16565b61384e90919063ffffffff16565b612e3390919063ffffffff16565b9050600460020154811015612c6e5760046002015490505b90565b6000612d40620186a0612d326004600301547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612ce957600080fd5b505afa158015612cfd573d6000803e3d6000fd5b505050506040513d6020811015612d1357600080fd5b8101908080519060200190929190505050612dad90919063ffffffff16565b612e3390919063ffffffff16565b905090565b600080612d5d601154426132d490919063ffffffff16565b9050612d8b600460010154612d7d83601054612dad90919063ffffffff16565b612e3390919063ffffffff16565b9150601054821115612d9d5760105491505b5090565b60115481565b60105481565b600080831415612dc05760009050612e2d565b6000828402905082848281612dd157fe5b0414612e28576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061415c6021913960400191505060405180910390fd5b809150505b92915050565b6000612e7583836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613a3c565b905092915050565b600082612f56577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612f1557600080fd5b505af1158015612f29573d6000803e3d6000fd5b505050506040513d6020811015612f3f57600080fd5b8101908080519060200190929190505050506132ca565b600360149054906101000a900460ff161561310a577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561301e57600080fd5b505af1158015613032573d6000803e3d6000fd5b505050506040513d602081101561304857600080fd5b810190808051906020019092919050505050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637acb775783866040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b1580156130ed57600080fd5b505af1158015613101573d6000803e3d6000fd5b505050506132c9565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156131bd57600080fd5b505af11580156131d1573d6000803e3d6000fd5b505050506040513d60208110156131e757600080fd5b810190808051906020019092919050505050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637acb775783866040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b15801561328c57600080fd5b505af11580156132a0573d6000803e3d6000fd5b505050506040513d60208110156132b657600080fd5b8101908080519060200190929190505050505b5b8190509392505050565b600061331683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613b02565b905092915050565b6133266140bc565b6000821161337f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806141366026913960400191505060405180910390fd5b60008314156133bd57604051806020016040528060007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525090506135f9565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff71ffffffffffffffffffffffffffffffffffff1683116134f657600082607060ff1685901b8161340a57fe5b0490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168111156134c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f77000081525060200191505060405180910390fd5b6040518060200160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509150506135f9565b6000613512846e01000000000000000000000000000085613bc2565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168111156135c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f77000081525060200191505060405180910390fd5b6040518060200160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509150505b92915050565b60006612725dd1d243ab82600001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168161363357fe5b049050919050565b613657613646612d45565b6010546132d490919063ffffffff16565b60108190555042601181905550565b60006136b2629896806136a4633b9aca00613696613682612904565b600460000154612dad90919063ffffffff16565b61384e90919063ffffffff16565b612e3390919063ffffffff16565b90506004600201548110156136ce5760046002015490506136e8565b6000600460020154146136e75760006004600201819055505b5b90565b6137a6846323b872dd60e01b858585604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613c84565b50505050565b6138498363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613c84565b505050565b6000808284019050838110156138cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b60006138f5600a60030154600a6004015461384e90919063ffffffff16565b90506000600a600101541415801561390d5750804210155b15613a395760006004600001549050600a60000160009054906101000a900460ff161561397c57613951600a6001015460046000015461384e90919063ffffffff16565b600460000181905550600a6002015460046000015410613977576000600a600101819055505b6139c0565b613999600a600101546004600001546132d490919063ffffffff16565b600460000181905550600a60020154600460000154116139bf576000600a600101819055505b5b42600a600401819055507fb923e581a0f83128e9e1d8297aa52b18d6744310476e0b54509c054cd7a93b2a81600460000154600a60010154600a60000160009054906101000a900460ff1660405180858152602001848152602001838152602001821515815260200194505050505060405180910390a1505b50565b60008083118290613ae8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613aad578082015181840152602081019050613a92565b50505050905090810190601f168015613ada5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581613af457fe5b049050809150509392505050565b6000838311158290613baf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613b74578082015181840152602081019050613b59565b50505050905090810190601f168015613ba15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b6000806000613bd18686613d73565b9150915060008480613bdf57fe5b868809905082811115613bf3576001820391505b8083039250848210613c6d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f46756c6c4d6174683a3a6d756c4469763a206f766572666c6f7700000000000081525060200191505060405180910390fd5b613c78838387613dc6565b93505050509392505050565b6060613ce6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613e639092919063ffffffff16565b9050600081511115613d6e57808060200190516020811015613d0757600080fd5b8101908080519060200190929190505050613d6d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a8152602001806141c4602a913960400191505060405180910390fd5b5b505050565b60008060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80613da057fe5b84860990508385029250828103915082811015613dbe576001820391505b509250929050565b6000808260000383169050808381613dda57fe5b049250808581613de657fe5b0494506001818260000381613df757fe5b04018402850194506000600190508084026002038102905080840260020381029050808402600203810290508084026002038102905080840260020381029050808402600203810290508084026002038102905080840260020381029050808602925050509392505050565b6060613e728484600085613e7b565b90509392505050565b6060613e8685614081565b613ef8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b60208310613f485780518252602082019150602081019050602083039250613f25565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613faa576040519150601f19603f3d011682016040523d82523d6000602084013e613faf565b606091505b50915091508115613fc4578092505050614079565b600081511115613fd75780518082602001fd5b836040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561403e578082015181840152602081019050614023565b50505050905090810190601f16801561406b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b949350505050565b600080823b905060008111915050919050565b6040518060800160405280600081526020016000815260200160008152602001600081525090565b604051806020016040528060007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a206d757374206265206e6577206f776e657220746f2070756c6c4669786564506f696e743a3a6672616374696f6e3a206469766973696f6e206279207a65726f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77536c697070616765206c696d69743a206d6f7265207468616e206d617820707269636556657374696e67206d757374206265206c6f6e676572207468616e20333620686f7572735361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a264697066735822122053be4518e6208ff68edac4e5334629c89de3521dd2fcec0ecc75153a7a8305f764736f6c63430007050033", + "devdoc": { + "kind": "dev", + "methods": { + "bondPrice()": { + "returns": { + "price_": "uint" + } + }, + "bondPriceInUSD()": { + "returns": { + "price_": "uint" + } + }, + "currentDebt()": { + "returns": { + "_0": "uint" + } + }, + "debtDecay()": { + "returns": { + "decay_": "uint" + } + }, + "debtRatio()": { + "returns": { + "debtRatio_": "uint" + } + }, + "deposit(uint256,uint256,address)": { + "params": { + "_amount": "uint", + "_depositor": "address", + "_maxPrice": "uint" + }, + "returns": { + "_0": "uint" + } + }, + "initializeBondTerms(uint256,uint256,uint256,uint256,uint256,uint256,uint256)": { + "params": { + "_controlVariable": "uint", + "_fee": "uint", + "_initialDebt": "uint", + "_maxDebt": "uint", + "_maxPayout": "uint", + "_minimumPrice": "uint", + "_vestingTerm": "uint" + } + }, + "maxPayout()": { + "returns": { + "_0": "uint" + } + }, + "payoutFor(uint256)": { + "params": { + "_value": "uint" + }, + "returns": { + "_0": "uint" + } + }, + "pendingPayoutFor(address)": { + "params": { + "_depositor": "address" + }, + "returns": { + "pendingPayout_": "uint" + } + }, + "percentVestedFor(address)": { + "params": { + "_depositor": "address" + }, + "returns": { + "percentVested_": "uint" + } + }, + "recoverLostToken(address)": { + "returns": { + "_0": "bool" + } + }, + "redeem(address,bool)": { + "params": { + "_recipient": "address", + "_stake": "bool" + }, + "returns": { + "_0": "uint" + } + }, + "setAdjustment(bool,uint256,uint256,uint256)": { + "params": { + "_addition": "bool", + "_buffer": "uint", + "_increment": "uint", + "_target": "uint" + } + }, + "setBondTerms(uint8,uint256)": { + "params": { + "_input": "uint", + "_parameter": "PARAMETER" + } + }, + "setStaking(address,bool)": { + "params": { + "_helper": "bool", + "_staking": "address" + } + }, + "standardizedDebtRatio()": { + "returns": { + "_0": "uint" + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "bondPrice()": { + "notice": "calculate current bond premium" + }, + "bondPriceInUSD()": { + "notice": "converts bond price to DAI value" + }, + "currentDebt()": { + "notice": "calculate debt factoring in decay" + }, + "debtDecay()": { + "notice": "amount to decay total debt by" + }, + "debtRatio()": { + "notice": "calculate current ratio of debt to OHM supply" + }, + "deposit(uint256,uint256,address)": { + "notice": "deposit bond" + }, + "initializeBondTerms(uint256,uint256,uint256,uint256,uint256,uint256,uint256)": { + "notice": "initializes bond parameters" + }, + "maxPayout()": { + "notice": "determine maximum bond size" + }, + "payoutFor(uint256)": { + "notice": "calculate interest due for new bond" + }, + "pendingPayoutFor(address)": { + "notice": "calculate amount of OHM available for claim by depositor" + }, + "percentVestedFor(address)": { + "notice": "calculate how far into vesting a depositor is" + }, + "recoverLostToken(address)": { + "notice": "allow anyone to send lost tokens (excluding principle or OHM) to the DAO" + }, + "redeem(address,bool)": { + "notice": "redeem bond for user" + }, + "setAdjustment(bool,uint256,uint256,uint256)": { + "notice": "set control variable adjustment" + }, + "setBondTerms(uint8,uint256)": { + "notice": "set parameters for new bonds" + }, + "setStaking(address,bool)": { + "notice": "set contract for auto stake" + }, + "standardizedDebtRatio()": { + "notice": "debt ratio in same terms for reserve or liquidity bonds" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 22, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 24, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "_newOwner", + "offset": 0, + "slot": "1", + "type": "t_address" + }, + { + "astId": 2277, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "staking", + "offset": 0, + "slot": "2", + "type": "t_address" + }, + { + "astId": 2279, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "stakingHelper", + "offset": 0, + "slot": "3", + "type": "t_address" + }, + { + "astId": 2281, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "useHelper", + "offset": 20, + "slot": "3", + "type": "t_bool" + }, + { + "astId": 2283, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "terms", + "offset": 0, + "slot": "4", + "type": "t_struct(Terms)2306_storage" + }, + { + "astId": 2285, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "adjustment", + "offset": 0, + "slot": "10", + "type": "t_struct(Adjust)2326_storage" + }, + { + "astId": 2289, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "bondInfo", + "offset": 0, + "slot": "15", + "type": "t_mapping(t_address,t_struct(Bond)2315_storage)" + }, + { + "astId": 2291, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "totalDebt", + "offset": 0, + "slot": "16", + "type": "t_uint256" + }, + { + "astId": 2293, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "lastDecay", + "offset": 0, + "slot": "17", + "type": "t_uint256" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_mapping(t_address,t_struct(Bond)2315_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct OlympusBondDepository.Bond)", + "numberOfBytes": "32", + "value": "t_struct(Bond)2315_storage" + }, + "t_struct(Adjust)2326_storage": { + "encoding": "inplace", + "label": "struct OlympusBondDepository.Adjust", + "members": [ + { + "astId": 2317, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "add", + "offset": 0, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 2319, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "rate", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 2321, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "target", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 2323, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "buffer", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 2325, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "lastTime", + "offset": 0, + "slot": "4", + "type": "t_uint256" + } + ], + "numberOfBytes": "160" + }, + "t_struct(Bond)2315_storage": { + "encoding": "inplace", + "label": "struct OlympusBondDepository.Bond", + "members": [ + { + "astId": 2308, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "payout", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 2310, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "vesting", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 2312, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "lastTime", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 2314, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "pricePaid", + "offset": 0, + "slot": "3", + "type": "t_uint256" + } + ], + "numberOfBytes": "128" + }, + "t_struct(Terms)2306_storage": { + "encoding": "inplace", + "label": "struct OlympusBondDepository.Terms", + "members": [ + { + "astId": 2295, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "controlVariable", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 2297, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "vestingTerm", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 2299, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "minimumPrice", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 2301, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "maxPayout", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 2303, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "fee", + "offset": 0, + "slot": "4", + "type": "t_uint256" + }, + { + "astId": 2305, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "maxDebt", + "offset": 0, + "slot": "5", + "type": "t_uint256" + } + ], + "numberOfBytes": "192" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/src/abi/rinkeby/Distributor.json b/src/abi/rinkeby/Distributor.json new file mode 100644 index 0000000000..79b9debcab --- /dev/null +++ b/src/abi/rinkeby/Distributor.json @@ -0,0 +1,545 @@ +{ + "address": "0xAECEc67825F49AAD1962F0557266A6Ba501Ddcea", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_treasury", + "type": "address" + }, + { + "internalType": "address", + "name": "_ohm", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_epochLength", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_nextEpochTime", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "OHM", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_rewardRate", + "type": "uint256" + } + ], + "name": "addRecipient", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "adjustments", + "outputs": [ + { + "internalType": "bool", + "name": "add", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "rate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "target", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "distribute", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "epochLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "info", + "outputs": [ + { + "internalType": "uint256", + "name": "rate", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nextEpochTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_rate", + "type": "uint256" + } + ], + "name": "nextRewardAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_recipient", + "type": "address" + } + ], + "name": "nextRewardFor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "policy", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pullPolicy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newPolicy_", + "type": "address" + } + ], + "name": "pushPolicy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_recipient", + "type": "address" + } + ], + "name": "removeRecipient", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renouncePolicy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_add", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "_rate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_target", + "type": "uint256" + } + ], + "name": "setAdjustment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "treasury", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x2289014c8d8b4acb69e58a3448fa9e3f6c68d462ca16b60163afe897bf72ef69", + "receipt": { + "to": null, + "from": "0xA38F4E6718EdCF023a1d032a2193848CB932c8e3", + "contractAddress": "0xAECEc67825F49AAD1962F0557266A6Ba501Ddcea", + "transactionIndex": 1, + "gasUsed": "1397986", + "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000020000020000000000000800000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000020002000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x796d8aa0d2f6a208e8509b24cebe9f0583a194ee8b951c5a98c55692bee2782a", + "transactionHash": "0x2289014c8d8b4acb69e58a3448fa9e3f6c68d462ca16b60163afe897bf72ef69", + "logs": [ + { + "transactionIndex": 1, + "blockNumber": 9907136, + "transactionHash": "0x2289014c8d8b4acb69e58a3448fa9e3f6c68d462ca16b60163afe897bf72ef69", + "address": "0xAECEc67825F49AAD1962F0557266A6Ba501Ddcea", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000a38f4e6718edcf023a1d032a2193848cb932c8e3" + ], + "data": "0x", + "logIndex": 1, + "blockHash": "0x796d8aa0d2f6a208e8509b24cebe9f0583a194ee8b951c5a98c55692bee2782a" + } + ], + "blockNumber": 9907136, + "cumulativeGasUsed": "1531187", + "status": 1, + "byzantium": true + }, + "args": [ + "0x1e0AD0F8DDFF84FDc938373E9aa66b8d994ea066", + "0x9bb5E7183e6259183f8E79876eCC0228738C95F6", + 28800, + 1640930868 + ], + "solcInputHash": "80205d7caa85cf7d901b88f836b16309", + "metadata": "{\"compiler\":{\"version\":\"0.7.5+commit.eb77ed08\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_ohm\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_epochLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_nextEpochTime\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"OHM\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_rewardRate\",\"type\":\"uint256\"}],\"name\":\"addRecipient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"adjustments\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"add\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"rate\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"target\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"distribute\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"epochLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"info\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"rate\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nextEpochTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_rate\",\"type\":\"uint256\"}],\"name\":\"nextRewardAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"}],\"name\":\"nextRewardFor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"policy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pullPolicy\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newPolicy_\",\"type\":\"address\"}],\"name\":\"pushPolicy\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"}],\"name\":\"removeRecipient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renouncePolicy\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"_add\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"_rate\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_target\",\"type\":\"uint256\"}],\"name\":\"setAdjustment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"addRecipient(address,uint256)\":{\"params\":{\"_recipient\":\"address\",\"_rewardRate\":\"uint\"}},\"nextRewardAt(uint256)\":{\"params\":{\"_rate\":\"uint\"},\"returns\":{\"_0\":\"uint\"}},\"nextRewardFor(address)\":{\"params\":{\"_recipient\":\"address\"},\"returns\":{\"_0\":\"uint\"}},\"removeRecipient(uint256,address)\":{\"params\":{\"_index\":\"uint\",\"_recipient\":\"address\"}},\"setAdjustment(uint256,bool,uint256,uint256)\":{\"params\":{\"_add\":\"bool\",\"_index\":\"uint\",\"_rate\":\"uint\",\"_target\":\"uint\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"addRecipient(address,uint256)\":{\"notice\":\"adds recipient for distributions\"},\"distribute()\":{\"notice\":\"send epoch reward to staking contract\"},\"nextRewardAt(uint256)\":{\"notice\":\"view function for next reward at given rate\"},\"nextRewardFor(address)\":{\"notice\":\"view function for next reward for specified address\"},\"removeRecipient(uint256,address)\":{\"notice\":\"removes recipient for distributions\"},\"setAdjustment(uint256,bool,uint256,uint256)\":{\"notice\":\"set adjustment info for a collector's reward rate\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/StakingDistributor.sol\":\"Distributor\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/StakingDistributor.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-or-later\\n\\npragma solidity 0.7.5;\\n\\nlibrary SafeERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n\\n require((value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\\nlibrary SafeMath {\\n\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n\\n // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)\\n function sqrrt(uint256 a) internal pure returns (uint c) {\\n if (a > 3) {\\n c = a;\\n uint b = add( div( a, 2), 1 );\\n while (b < c) {\\n c = b;\\n b = div( add( div( a, b ), b), 2 );\\n }\\n } else if (a != 0) {\\n c = 1;\\n }\\n }\\n\\n function percentageAmount( uint256 total_, uint8 percentage_ ) internal pure returns ( uint256 percentAmount_ ) {\\n return div( mul( total_, percentage_ ), 1000 );\\n }\\n\\n function substractPercentage( uint256 total_, uint8 percentageToSub_ ) internal pure returns ( uint256 result_ ) {\\n return sub( total_, div( mul( total_, percentageToSub_ ), 1000 ) );\\n }\\n\\n function percentageOfTotal( uint256 part_, uint256 total_ ) internal pure returns ( uint256 percent_ ) {\\n return div( mul(part_, 100) , total_ );\\n }\\n\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow, so we distribute\\n return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);\\n }\\n\\n function quadraticPricing( uint256 payment_, uint256 multiplier_ ) internal pure returns (uint256) {\\n return sqrrt( mul( multiplier_, payment_ ) );\\n }\\n\\n function bondingCurve( uint256 supply_, uint256 multiplier_ ) internal pure returns (uint256) {\\n return mul( multiplier_, supply_ );\\n }\\n}\\n\\ninterface IERC20 {\\n\\n function totalSupply() external view returns (uint256);\\n\\n function balanceOf(address account) external view returns (uint256);\\n\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\\nlibrary Address {\\n\\n function isContract(address account) internal view returns (bool) {\\n // This method relies in extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return _functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n if (returndata.length > 0) {\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n\\n function addressToString(address _address) internal pure returns(string memory) {\\n bytes32 _bytes = bytes32(uint256(_address));\\n bytes memory HEX = \\\"0123456789abcdef\\\";\\n bytes memory _addr = new bytes(42);\\n\\n _addr[0] = '0';\\n _addr[1] = 'x';\\n\\n for(uint256 i = 0; i < 20; i++) {\\n _addr[2+i*2] = HEX[uint8(_bytes[i + 12] >> 4)];\\n _addr[3+i*2] = HEX[uint8(_bytes[i + 12] & 0x0f)];\\n }\\n\\n return string(_addr);\\n\\n }\\n}\\n\\n\\ninterface IPolicy {\\n\\n function policy() external view returns (address);\\n\\n function renouncePolicy() external;\\n\\n function pushPolicy( address newPolicy_ ) external;\\n\\n function pullPolicy() external;\\n}\\n\\ncontract Policy is IPolicy {\\n\\n address internal _policy;\\n address internal _newPolicy;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n constructor () {\\n _policy = msg.sender;\\n emit OwnershipTransferred( address(0), _policy );\\n }\\n\\n function policy() public view override returns (address) {\\n return _policy;\\n }\\n\\n modifier onlyPolicy() {\\n require( _policy == msg.sender, \\\"Ownable: caller is not the owner\\\" );\\n _;\\n }\\n\\n function renouncePolicy() public virtual override onlyPolicy() {\\n emit OwnershipTransferred( _policy, address(0) );\\n _policy = address(0);\\n }\\n\\n function pushPolicy( address newPolicy_ ) public virtual override onlyPolicy() {\\n require( newPolicy_ != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _newPolicy = newPolicy_;\\n }\\n\\n function pullPolicy() public virtual override {\\n require( msg.sender == _newPolicy );\\n emit OwnershipTransferred( _policy, _newPolicy );\\n _policy = _newPolicy;\\n }\\n}\\n\\ninterface ITreasury {\\n function mintRewards( address _recipient, uint _amount ) external;\\n}\\n\\ncontract Distributor is Policy {\\n using SafeMath for uint;\\n using SafeERC20 for IERC20;\\n\\n\\n\\n /* ====== VARIABLES ====== */\\n\\n address public immutable OHM;\\n address public immutable treasury;\\n\\n uint public immutable epochLength;\\n uint public nextEpochTime;\\n\\n mapping( uint => Adjust ) public adjustments;\\n\\n\\n /* ====== STRUCTS ====== */\\n\\n struct Info {\\n uint rate; // in ten-thousandths ( 5000 = 0.5% )\\n address recipient;\\n }\\n Info[] public info;\\n\\n struct Adjust {\\n bool add;\\n uint rate;\\n uint target;\\n }\\n\\n\\n\\n /* ====== CONSTRUCTOR ====== */\\n\\n constructor( address _treasury, address _ohm, uint _epochLength, uint _nextEpochTime ) {\\n require( _treasury != address(0) );\\n treasury = _treasury;\\n require( _ohm != address(0) );\\n OHM = _ohm;\\n epochLength = _epochLength;\\n nextEpochTime = _nextEpochTime;\\n }\\n\\n\\n\\n /* ====== PUBLIC FUNCTIONS ====== */\\n\\n /**\\n @notice send epoch reward to staking contract\\n */\\n function distribute() external returns ( bool ) {\\n if ( nextEpochTime <= block.timestamp ) {\\n nextEpochTime = nextEpochTime.add( epochLength ); // set next epoch time\\n\\n // distribute rewards to each recipient\\n for ( uint i = 0; i < info.length; i++ ) {\\n if ( info[ i ].rate > 0 ) {\\n ITreasury( treasury ).mintRewards( // mint and send from treasury\\n info[ i ].recipient,\\n nextRewardAt( info[ i ].rate )\\n );\\n adjust( i ); // check for adjustment\\n }\\n }\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n\\n\\n /* ====== INTERNAL FUNCTIONS ====== */\\n\\n /**\\n @notice increment reward rate for collector\\n */\\n function adjust( uint _index ) internal {\\n Adjust memory adjustment = adjustments[ _index ];\\n if ( adjustment.rate != 0 ) {\\n if ( adjustment.add ) { // if rate should increase\\n info[ _index ].rate = info[ _index ].rate.add( adjustment.rate ); // raise rate\\n if ( info[ _index ].rate >= adjustment.target ) { // if target met\\n adjustments[ _index ].rate = 0; // turn off adjustment\\n }\\n } else { // if rate should decrease\\n info[ _index ].rate = info[ _index ].rate.sub( adjustment.rate ); // lower rate\\n if ( info[ _index ].rate <= adjustment.target ) { // if target met\\n adjustments[ _index ].rate = 0; // turn off adjustment\\n }\\n }\\n }\\n }\\n\\n\\n\\n /* ====== VIEW FUNCTIONS ====== */\\n\\n /**\\n @notice view function for next reward at given rate\\n @param _rate uint\\n @return uint\\n */\\n function nextRewardAt( uint _rate ) public view returns ( uint ) {\\n return IERC20( OHM ).totalSupply().mul( _rate ).div( 1000000 );\\n }\\n\\n /**\\n @notice view function for next reward for specified address\\n @param _recipient address\\n @return uint\\n */\\n function nextRewardFor( address _recipient ) public view returns ( uint ) {\\n uint reward;\\n for ( uint i = 0; i < info.length; i++ ) {\\n if ( info[ i ].recipient == _recipient ) {\\n reward = nextRewardAt( info[ i ].rate );\\n }\\n }\\n return reward;\\n }\\n\\n\\n\\n /* ====== POLICY FUNCTIONS ====== */\\n\\n /**\\n @notice adds recipient for distributions\\n @param _recipient address\\n @param _rewardRate uint\\n */\\n function addRecipient( address _recipient, uint _rewardRate ) external onlyPolicy() {\\n require( _recipient != address(0) );\\n info.push( Info({\\n recipient: _recipient,\\n rate: _rewardRate\\n }));\\n }\\n\\n /**\\n @notice removes recipient for distributions\\n @param _index uint\\n @param _recipient address\\n */\\n function removeRecipient( uint _index, address _recipient ) external onlyPolicy() {\\n require( _recipient == info[ _index ].recipient );\\n info[ _index ].recipient = address(0);\\n info[ _index ].rate = 0;\\n }\\n\\n /**\\n @notice set adjustment info for a collector's reward rate\\n @param _index uint\\n @param _add bool\\n @param _rate uint\\n @param _target uint\\n */\\n function setAdjustment( uint _index, bool _add, uint _rate, uint _target ) external onlyPolicy() {\\n adjustments[ _index ] = Adjust({\\n add: _add,\\n rate: _rate,\\n target: _target\\n });\\n }\\n}\",\"keccak256\":\"0x1620daa7b83b019543e7785ecb468a0a801e520287e24510278c4c5840898f9d\",\"license\":\"AGPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x60e060405234801561001057600080fd5b506040516119be3803806119be8339818101604052608081101561003357600080fd5b8101908080519060200190929190805190602001909291908051906020019092919080519060200190929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141561015757600080fd5b8373ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b81525050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156101c857600080fd5b8273ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b815250508160c08181525050806002819055505050505060805160601c60a05160601c60c05161176b610253600039806105d55280610ce95250806108815280610d58525080610baf5280610c17525061176b6000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c8063a15ad07711610097578063c9fa8b2a11610066578063c9fa8b2a1461038c578063e4fc6b6d146103ce578063f7982243146103ee578063fe3fbbad1461043c57610100565b8063a15ad077146102b8578063a4b23980146102fc578063a6c41fec14610306578063bc3b2b121461033a57610100565b806357d775f8116100d357806357d775f81461020e5780635beede081461022c5780635db854b01461023657806361d027b31461028457610100565b80630505c8c9146101055780631da56eb3146101395780632e3405991461015757806336d33f44146101b6575b600080fd5b61010d61048a565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101416104b3565b6040518082815260200191505060405180910390f35b6101836004803603602081101561016d57600080fd5b81019080803590602001909291905050506104b9565b604051808381526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390f35b6101f8600480360360208110156101cc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061050d565b6040518082815260200191505060405180910390f35b6102166105d3565b6040518082815260200191505060405180910390f35b6102346105f7565b005b6102826004803603608081101561024c57600080fd5b81019080803590602001909291908035151590602001909291908035906020019092919080359060200190929190505050610751565b005b61028c61087f565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102fa600480360360208110156102ce57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506108a3565b005b610304610a2e565b005b61030e610bad565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103666004803603602081101561035057600080fd5b8101908080359060200190929190505050610bd1565b604051808415158152602001838152602001828152602001935050505060405180910390f35b6103b8600480360360208110156103a257600080fd5b8101908080359060200190929190505050610c08565b6040518082815260200191505060405180910390f35b6103d6610cd9565b60405180821515815260200191505060405180910390f35b61043a6004803603604081101561040457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610e8c565b005b6104886004803603604081101561045257600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611034565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60025481565b600481815481106104c957600080fd5b90600052602060002090600202016000915090508060000154908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082565b60008060005b6004805490508110156105c9578373ffffffffffffffffffffffffffffffffffffffff166004828154811061054457fe5b906000526020600020906002020160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156105bc576105b9600482815481106105a257fe5b906000526020600020906002020160000154610c08565b91505b8080600101915050610513565b5080915050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461065157600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610812576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60405180606001604052808415158152602001838152602001828152506003600086815260200190815260200160002060008201518160000160006101000a81548160ff021916908315150217905550602082015181600101556040820151816002015590505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610964576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156109ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806116ef6026913960400191505060405180910390fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610aef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b7f000000000000000000000000000000000000000000000000000000000000000081565b60036020528060005260406000206000915090508060000160009054906101000a900460ff16908060010154908060020154905083565b6000610cd2620f4240610cc4847f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610c7b57600080fd5b505afa158015610c8f573d6000803e3d6000fd5b505050506040513d6020811015610ca557600080fd5b81019080805190602001909291905050506111f190919063ffffffff16565b61127790919063ffffffff16565b9050919050565b60004260025411610e8457610d197f00000000000000000000000000000000000000000000000000000000000000006002546112c190919063ffffffff16565b60028190555060005b600480549050811015610e7a57600060048281548110610d3e57fe5b9060005260206000209060020201600001541115610e6d577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636a20de9260048381548110610d9f57fe5b906000526020600020906002020160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610df860048581548110610de157fe5b906000526020600020906002020160000154610c08565b6040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b158015610e4b57600080fd5b505af1158015610e5f573d6000803e3d6000fd5b50505050610e6c81611349565b5b8080600101915050610d22565b5060019050610e89565b600090505b90565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610f4d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610f8757600080fd5b600460405180604001604052808381526020018473ffffffffffffffffffffffffffffffffffffffff1681525090806001815401808255809150506001900390600052602060002090600202016000909190919091506000820151816000015560208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146110f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6004828154811061110257fe5b906000526020600020906002020160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461116b57600080fd5b60006004838154811061117a57fe5b906000526020600020906002020160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600483815481106111d857fe5b9060005260206000209060020201600001819055505050565b6000808314156112045760009050611271565b600082840290508284828161121557fe5b041461126c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117156021913960400191505060405180910390fd5b809150505b92915050565b60006112b983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506114fb565b905092915050565b60008082840190508381101561133f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b6113516116cb565b600360008381526020019081526020016000206040518060600160405290816000820160009054906101000a900460ff1615151515815260200160018201548152602001600282015481525050905060008160200151146114f757806000015115611458576113eb8160200151600484815481106113cb57fe5b9060005260206000209060020201600001546112c190919063ffffffff16565b600483815481106113f857fe5b90600052602060002090600202016000018190555080604001516004838154811061141f57fe5b9060005260206000209060020201600001541061145357600060036000848152602001908152602001600020600101819055505b6114f6565b61148d81602001516004848154811061146d57fe5b9060005260206000209060020201600001546115c190919063ffffffff16565b6004838154811061149a57fe5b9060005260206000209060020201600001819055508060400151600483815481106114c157fe5b906000526020600020906002020160000154116114f557600060036000848152602001908152602001600020600101819055505b5b5b5050565b600080831182906115a7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561156c578082015181840152602081019050611551565b50505050905090810190601f1680156115995780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816115b357fe5b049050809150509392505050565b600061160383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061160b565b905092915050565b60008383111582906116b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561167d578082015181840152602081019050611662565b50505050905090810190601f1680156116aa5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b60405180606001604052806000151581526020016000815260200160008152509056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a2646970667358221220da1e081b92d33f3b4f19bc0c14d9ea5513eb9924c2a3d9fda548113efbd01e6b64736f6c63430007050033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101005760003560e01c8063a15ad07711610097578063c9fa8b2a11610066578063c9fa8b2a1461038c578063e4fc6b6d146103ce578063f7982243146103ee578063fe3fbbad1461043c57610100565b8063a15ad077146102b8578063a4b23980146102fc578063a6c41fec14610306578063bc3b2b121461033a57610100565b806357d775f8116100d357806357d775f81461020e5780635beede081461022c5780635db854b01461023657806361d027b31461028457610100565b80630505c8c9146101055780631da56eb3146101395780632e3405991461015757806336d33f44146101b6575b600080fd5b61010d61048a565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101416104b3565b6040518082815260200191505060405180910390f35b6101836004803603602081101561016d57600080fd5b81019080803590602001909291905050506104b9565b604051808381526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390f35b6101f8600480360360208110156101cc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061050d565b6040518082815260200191505060405180910390f35b6102166105d3565b6040518082815260200191505060405180910390f35b6102346105f7565b005b6102826004803603608081101561024c57600080fd5b81019080803590602001909291908035151590602001909291908035906020019092919080359060200190929190505050610751565b005b61028c61087f565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102fa600480360360208110156102ce57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506108a3565b005b610304610a2e565b005b61030e610bad565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103666004803603602081101561035057600080fd5b8101908080359060200190929190505050610bd1565b604051808415158152602001838152602001828152602001935050505060405180910390f35b6103b8600480360360208110156103a257600080fd5b8101908080359060200190929190505050610c08565b6040518082815260200191505060405180910390f35b6103d6610cd9565b60405180821515815260200191505060405180910390f35b61043a6004803603604081101561040457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610e8c565b005b6104886004803603604081101561045257600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611034565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60025481565b600481815481106104c957600080fd5b90600052602060002090600202016000915090508060000154908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082565b60008060005b6004805490508110156105c9578373ffffffffffffffffffffffffffffffffffffffff166004828154811061054457fe5b906000526020600020906002020160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156105bc576105b9600482815481106105a257fe5b906000526020600020906002020160000154610c08565b91505b8080600101915050610513565b5080915050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461065157600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610812576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60405180606001604052808415158152602001838152602001828152506003600086815260200190815260200160002060008201518160000160006101000a81548160ff021916908315150217905550602082015181600101556040820151816002015590505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610964576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156109ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806116ef6026913960400191505060405180910390fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610aef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b7f000000000000000000000000000000000000000000000000000000000000000081565b60036020528060005260406000206000915090508060000160009054906101000a900460ff16908060010154908060020154905083565b6000610cd2620f4240610cc4847f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610c7b57600080fd5b505afa158015610c8f573d6000803e3d6000fd5b505050506040513d6020811015610ca557600080fd5b81019080805190602001909291905050506111f190919063ffffffff16565b61127790919063ffffffff16565b9050919050565b60004260025411610e8457610d197f00000000000000000000000000000000000000000000000000000000000000006002546112c190919063ffffffff16565b60028190555060005b600480549050811015610e7a57600060048281548110610d3e57fe5b9060005260206000209060020201600001541115610e6d577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636a20de9260048381548110610d9f57fe5b906000526020600020906002020160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610df860048581548110610de157fe5b906000526020600020906002020160000154610c08565b6040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b158015610e4b57600080fd5b505af1158015610e5f573d6000803e3d6000fd5b50505050610e6c81611349565b5b8080600101915050610d22565b5060019050610e89565b600090505b90565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610f4d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610f8757600080fd5b600460405180604001604052808381526020018473ffffffffffffffffffffffffffffffffffffffff1681525090806001815401808255809150506001900390600052602060002090600202016000909190919091506000820151816000015560208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146110f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6004828154811061110257fe5b906000526020600020906002020160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461116b57600080fd5b60006004838154811061117a57fe5b906000526020600020906002020160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600483815481106111d857fe5b9060005260206000209060020201600001819055505050565b6000808314156112045760009050611271565b600082840290508284828161121557fe5b041461126c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117156021913960400191505060405180910390fd5b809150505b92915050565b60006112b983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506114fb565b905092915050565b60008082840190508381101561133f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b6113516116cb565b600360008381526020019081526020016000206040518060600160405290816000820160009054906101000a900460ff1615151515815260200160018201548152602001600282015481525050905060008160200151146114f757806000015115611458576113eb8160200151600484815481106113cb57fe5b9060005260206000209060020201600001546112c190919063ffffffff16565b600483815481106113f857fe5b90600052602060002090600202016000018190555080604001516004838154811061141f57fe5b9060005260206000209060020201600001541061145357600060036000848152602001908152602001600020600101819055505b6114f6565b61148d81602001516004848154811061146d57fe5b9060005260206000209060020201600001546115c190919063ffffffff16565b6004838154811061149a57fe5b9060005260206000209060020201600001819055508060400151600483815481106114c157fe5b906000526020600020906002020160000154116114f557600060036000848152602001908152602001600020600101819055505b5b5b5050565b600080831182906115a7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561156c578082015181840152602081019050611551565b50505050905090810190601f1680156115995780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816115b357fe5b049050809150509392505050565b600061160383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061160b565b905092915050565b60008383111582906116b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561167d578082015181840152602081019050611662565b50505050905090810190601f1680156116aa5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b60405180606001604052806000151581526020016000815260200160008152509056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a2646970667358221220da1e081b92d33f3b4f19bc0c14d9ea5513eb9924c2a3d9fda548113efbd01e6b64736f6c63430007050033", + "devdoc": { + "kind": "dev", + "methods": { + "addRecipient(address,uint256)": { + "params": { + "_recipient": "address", + "_rewardRate": "uint" + } + }, + "nextRewardAt(uint256)": { + "params": { + "_rate": "uint" + }, + "returns": { + "_0": "uint" + } + }, + "nextRewardFor(address)": { + "params": { + "_recipient": "address" + }, + "returns": { + "_0": "uint" + } + }, + "removeRecipient(uint256,address)": { + "params": { + "_index": "uint", + "_recipient": "address" + } + }, + "setAdjustment(uint256,bool,uint256,uint256)": { + "params": { + "_add": "bool", + "_index": "uint", + "_rate": "uint", + "_target": "uint" + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "addRecipient(address,uint256)": { + "notice": "adds recipient for distributions" + }, + "distribute()": { + "notice": "send epoch reward to staking contract" + }, + "nextRewardAt(uint256)": { + "notice": "view function for next reward at given rate" + }, + "nextRewardFor(address)": { + "notice": "view function for next reward for specified address" + }, + "removeRecipient(uint256,address)": { + "notice": "removes recipient for distributions" + }, + "setAdjustment(uint256,bool,uint256,uint256)": { + "notice": "set adjustment info for a collector's reward rate" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 2765, + "contract": "contracts/StakingDistributor.sol:Distributor", + "label": "_policy", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 2767, + "contract": "contracts/StakingDistributor.sol:Distributor", + "label": "_newPolicy", + "offset": 0, + "slot": "1", + "type": "t_address" + }, + { + "astId": 2902, + "contract": "contracts/StakingDistributor.sol:Distributor", + "label": "nextEpochTime", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 2906, + "contract": "contracts/StakingDistributor.sol:Distributor", + "label": "adjustments", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_struct(Adjust)2921_storage)" + }, + { + "astId": 2914, + "contract": "contracts/StakingDistributor.sol:Distributor", + "label": "info", + "offset": 0, + "slot": "4", + "type": "t_array(t_struct(Info)2911_storage)dyn_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_struct(Info)2911_storage)dyn_storage": { + "base": "t_struct(Info)2911_storage", + "encoding": "dynamic_array", + "label": "struct Distributor.Info[]", + "numberOfBytes": "32" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_mapping(t_uint256,t_struct(Adjust)2921_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct Distributor.Adjust)", + "numberOfBytes": "32", + "value": "t_struct(Adjust)2921_storage" + }, + "t_struct(Adjust)2921_storage": { + "encoding": "inplace", + "label": "struct Distributor.Adjust", + "members": [ + { + "astId": 2916, + "contract": "contracts/StakingDistributor.sol:Distributor", + "label": "add", + "offset": 0, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 2918, + "contract": "contracts/StakingDistributor.sol:Distributor", + "label": "rate", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 2920, + "contract": "contracts/StakingDistributor.sol:Distributor", + "label": "target", + "offset": 0, + "slot": "2", + "type": "t_uint256" + } + ], + "numberOfBytes": "96" + }, + "t_struct(Info)2911_storage": { + "encoding": "inplace", + "label": "struct Distributor.Info", + "members": [ + { + "astId": 2908, + "contract": "contracts/StakingDistributor.sol:Distributor", + "label": "rate", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 2910, + "contract": "contracts/StakingDistributor.sol:Distributor", + "label": "recipient", + "offset": 0, + "slot": "1", + "type": "t_address" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/src/abi/rinkeby/FRAX.json b/src/abi/rinkeby/FRAX.json new file mode 100644 index 0000000000..c3ee923484 --- /dev/null +++ b/src/abi/rinkeby/FRAX.json @@ -0,0 +1,738 @@ +{ + "address": "0x0B81a995b28254D76e5148d29E8eb4c5c26D3aC0", + "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "chainId_", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "guy", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": true, + "inputs": [ + { + "indexed": true, + "internalType": "bytes4", + "name": "sig", + "type": "bytes4" + }, + { + "indexed": true, + "internalType": "address", + "name": "usr", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "arg1", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "arg2", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "LogNote", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "usr", + "type": "address" + } + ], + "name": "addAuth", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_limit", + "type": "uint256" + } + ], + "name": "adjustDailyFraxLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account_", + "type": "address" + }, + { + "internalType": "address", + "name": "sender_", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "usr_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad_", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "usr", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "dailyFraxLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "guy", + "type": "address" + } + ], + "name": "deny", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "fraxMintedToday", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lastMintRestart", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "usr", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "move", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "allowed", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "usr", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "pull", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "usr", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "push", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "guy", + "type": "address" + } + ], + "name": "rely", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "wards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x15bb81419feb74d5130372d72a8650a936ee7800c94c2df1131d0f13f0dd70a4", + "receipt": { + "to": null, + "from": "0xA38F4E6718EdCF023a1d032a2193848CB932c8e3", + "contractAddress": "0x0B81a995b28254D76e5148d29E8eb4c5c26D3aC0", + "transactionIndex": 11, + "gasUsed": "1988537", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x087253bdd1d16b0f353064f0006205dc745f1e7aba3a869e5626e2e80b7f1420", + "transactionHash": "0x15bb81419feb74d5130372d72a8650a936ee7800c94c2df1131d0f13f0dd70a4", + "logs": [], + "blockNumber": 9907129, + "cumulativeGasUsed": "11919772", + "status": 1, + "byzantium": true + }, + "args": [ + 4 + ], + "solcInputHash": "8d3774b312edc15e04c44a56a82de7d8", + "metadata": "{\"compiler\":{\"version\":\"0.7.5+commit.eb77ed08\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId_\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":true,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes4\",\"name\":\"sig\",\"type\":\"bytes4\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"usr\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"arg1\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"arg2\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"LogNote\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PERMIT_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"usr\",\"type\":\"address\"}],\"name\":\"addAuth\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_limit\",\"type\":\"uint256\"}],\"name\":\"adjustDailyFraxLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender_\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"usr_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad_\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"usr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dailyFraxLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"}],\"name\":\"deny\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"fraxMintedToday\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"lastMintRestart\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"usr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"move\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"holder\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiry\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"usr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"pull\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"usr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"push\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"}],\"name\":\"rely\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"wards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/mocks/Frax.sol\":\"FRAX\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/mocks/Frax.sol\":{\"content\":\"// SPDX-License-Identifier: Unlicensed\\npragma solidity 0.7.5;\\n\\n\\ncontract LibNote {\\n event LogNote(\\n bytes4 indexed sig,\\n address indexed usr,\\n bytes32 indexed arg1,\\n bytes32 indexed arg2,\\n bytes data\\n ) anonymous;\\n\\n modifier note {\\n _;\\n // assembly {\\n // // log an 'anonymous' event with a constant 6 words of calldata\\n // // and four indexed topics: selector, caller, arg1 and arg2\\n // let mark := msize() // end of memory ensures zero\\n // mstore(0x40, add(mark, 288)) // update free memory pointer\\n // mstore(mark, 0x20) // bytes type data offset\\n // mstore(add(mark, 0x20), 224) // bytes size (padded)\\n // calldatacopy(add(mark, 0x40), 0, 224) // bytes payload\\n // log4(mark, 288, // calldata\\n // shl(224, shr(224, calldataload(0))), // msg.sig\\n // caller(), // msg.sender\\n // calldataload(4), // arg1\\n // calldataload(36) // arg2\\n // )\\n // }\\n }\\n}\\n\\ninterface IFRAX {\\n\\n\\n // --- Auth ---\\n function wards() external returns ( uint256 );\\n\\n function rely(address guy) external;\\n\\n function deny(address guy) external;\\n\\n // --- Token ---\\n function transfer(address dst, uint wad) external returns (bool);\\n\\n function transferFrom(address src, address dst, uint wad) external returns (bool);\\n\\n function mint(address usr, uint wad) external;\\n\\n function burn(address usr, uint wad) external;\\n\\n function approve(address usr, uint wad) external returns (bool);\\n\\n // --- Alias ---\\n function push(address usr, uint wad) external;\\n\\n function pull(address usr, uint wad) external;\\n\\n function move(address src, address dst, uint wad) external;\\n\\n // --- Approve by signature ---\\n function permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s) external;\\n}\\n\\n\\ncontract FRAX is LibNote {\\n \\n event Approval(address indexed src, address indexed guy, uint wad);\\n event Transfer(address indexed src, address indexed dst, uint wad);\\n \\n // --- Auth ---\\n mapping (address => uint) public wards;\\n\\n function rely(address guy) external note auth { wards[guy] = 1; }\\n\\n function deny(address guy) external note auth { wards[guy] = 0; }\\n\\n modifier auth {\\n require(wards[msg.sender] == 1, \\\"Frax/not-authorized\\\");\\n _;\\n }\\n\\n // --- ERC20 Data ---\\n string public constant name = \\\"FRAX TOKEN\\\";\\n string public constant symbol = \\\"FRAX\\\";\\n string public constant version = \\\"1\\\";\\n uint8 public constant decimals = 18;\\n uint256 public totalSupply;\\n uint public dailyFraxLimit;\\n\\n mapping (address => uint) public balanceOf;\\n mapping (address => mapping (address => uint)) private allowances;\\n mapping (address => uint) public nonces;\\n mapping (address => uint) public lastMintRestart;\\n mapping (address => uint) public fraxMintedToday;\\n\\n // event Approval(address indexed src, address indexed guy, uint wad);\\n // event Transfer(address indexed src, address indexed dst, uint wad);\\n\\n // --- Math ---\\n function add(uint x, uint y) internal pure returns (uint z) {\\n require((z = x + y) >= x);\\n }\\n\\n function sub(uint x, uint y) internal pure returns (uint z) {\\n require((z = x - y) <= x);\\n }\\n\\n // --- EIP712 niceties ---\\n bytes32 public DOMAIN_SEPARATOR;\\n // bytes32 public constant PERMIT_TYPEHASH = keccak256(\\\"Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)\\\");\\n bytes32 public constant PERMIT_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb;\\n\\n constructor(uint256 chainId_) {\\n wards[msg.sender] = 1;\\n DOMAIN_SEPARATOR = keccak256(abi.encode(\\n keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"),\\n keccak256(bytes(name)),\\n keccak256(bytes(version)),\\n chainId_,\\n address(this)\\n ));\\n dailyFraxLimit = 10000000000000000000000;\\n }\\n\\n function allowance( address account_, address sender_ ) external view returns ( uint ) {\\n return _allowance( account_, sender_ );\\n }\\n\\n function _allowance( address account_, address sender_ ) internal view returns ( uint ) {\\n \\n return allowances[account_][sender_];\\n }\\n\\n // --- Token ---\\n function transfer(address dst, uint wad) external returns (bool) {\\n return transferFrom(msg.sender, dst, wad);\\n }\\n\\n function transferFrom(address src, address dst, uint wad) public returns (bool) {\\n \\n \\n require(balanceOf[src] >= wad, \\\"Frax/insufficient-balance\\\");\\n if (src != msg.sender && _allowance( src, msg.sender ) != uint(-1)) {\\n require(_allowance( src, msg.sender ) >= wad, \\\"Frax/insufficient-allowance\\\");\\n allowances[src][msg.sender] = sub(_allowance( src, msg.sender ), wad);\\n }\\n balanceOf[src] = sub(balanceOf[src], wad);\\n balanceOf[dst] = add(balanceOf[dst], wad);\\n emit Transfer(src, dst, wad);\\n return true;\\n }\\n\\n function addAuth(address usr) external auth {\\n wards[usr] = 1;\\n }\\n\\n function adjustDailyFraxLimit(uint _limit) external auth {\\n dailyFraxLimit = _limit;\\n }\\n\\n function mint(address usr, uint wad) external {\\n\\n if(wards[msg.sender] == 0) {\\n require(add(wad, fraxMintedToday[msg.sender]) <= dailyFraxLimit || sub(block.number, lastMintRestart[msg.sender]) >= 6500 && wad <= dailyFraxLimit, \\\"Over daily Frax Limit\\\");\\n if( sub(block.number, lastMintRestart[msg.sender]) >= 6500 ) {\\n fraxMintedToday[msg.sender] = wad;\\n lastMintRestart[msg.sender] = block.number;\\n } else {\\n fraxMintedToday[msg.sender] = add(fraxMintedToday[msg.sender], wad);\\n }\\n }\\n \\n balanceOf[usr] = add(balanceOf[usr], wad);\\n \\n totalSupply = add(totalSupply, wad);\\n \\n \\n emit Transfer(address(0), usr, wad);\\n }\\n\\n function burn(address usr, uint wad) external {\\n require(balanceOf[usr] >= wad, \\\"Frax/insufficient-balance\\\");\\n if (usr != msg.sender && _allowance( usr, msg.sender ) != uint(-1)) {\\n require(_allowance( usr, msg.sender ) >= wad, \\\"Frax/insufficient-allowance\\\");\\n allowances[usr][msg.sender] = sub(_allowance( usr, msg.sender ), wad);\\n }\\n balanceOf[usr] = sub(balanceOf[usr], wad);\\n totalSupply = sub(totalSupply, wad);\\n emit Transfer(usr, address(0), wad);\\n }\\n\\n function _approve(address usr, uint wad) internal returns (bool) {\\n \\n allowances[msg.sender][usr] = wad;\\n \\n emit Approval(msg.sender, usr, wad);\\n return true;\\n }\\n\\n function approve(address usr_, uint wad_ ) external returns (bool) {\\n \\n return _approve( usr_, wad_ ) ;\\n }\\n\\n // --- Alias ---\\n function push(address usr, uint wad) external {\\n transferFrom(msg.sender, usr, wad);\\n }\\n\\n function pull(address usr, uint wad) external {\\n transferFrom(usr, msg.sender, wad);\\n }\\n\\n function move(address src, address dst, uint wad) external {\\n transferFrom(src, dst, wad);\\n }\\n\\n // --- Approve by signature ---\\n function permit(address holder, address spender, uint256 nonce, uint256 expiry,\\n bool allowed, uint8 v, bytes32 r, bytes32 s) external\\n {\\n bytes32 digest =\\n keccak256(abi.encodePacked(\\n \\\"\\\\x19\\\\x01\\\",\\n DOMAIN_SEPARATOR,\\n keccak256(abi.encode(PERMIT_TYPEHASH,\\n holder,\\n spender,\\n nonce,\\n expiry,\\n allowed))\\n ));\\n\\n require(holder != address(0), \\\"Frax/invalid-address-0\\\");\\n require(holder == ecrecover(digest, v, r, s), \\\"Frax/invalid-permit\\\");\\n require(expiry == 0 || block.timestamp <= expiry, \\\"Frax/permit-expired\\\");\\n require(nonce == nonces[holder]++, \\\"Frax/invalid-nonce\\\");\\n uint wad = allowed ? uint(-1) : 0;\\n allowances[holder][spender] = wad;\\n emit Approval(holder, spender, wad);\\n }\\n}\",\"keccak256\":\"0xca41e81ecaeb3b5a694c9f750e6d24aca1c14299ead11f23168d9455bffedd00\",\"license\":\"Unlicensed\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506040516123753803806123758339818101604052602081101561003357600080fd5b810190808051906020019092919050505060016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6040518060400160405280600a81526020017f4652415820544f4b454e00000000000000000000000000000000000000000000815250805190602001206040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250805190602001208330604051602001808681526020018581526020018481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff168152602001955050505050506040516020818303038152906040528051906020012060088190555069021e19e0c9bab2400000600281905550506121d1806101a46000396000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c80637ecebe00116100f9578063b753a98c11610097578063d3fd35ec11610071578063d3fd35ec14610980578063d7f1bf12146109ae578063dd62ed3e146109cc578063f2d5d56b14610a44576101a9565b8063b753a98c1461086c578063bb35783b146108ba578063bf353dbb14610928576101a9565b80639c52a7f1116100d35780639c52a7f11461071e5780639dc29fac146107625780639e16de34146107b0578063a9059cbb14610808576101a9565b80637ecebe001461059d5780638fcbaf0c146105f557806395d89b411461069b576101a9565b80633644e5151161016657806354fd4d501161014057806354fd4d501461042657806365fae35e146104a957806370a08231146104ed578063798247ae14610545576101a9565b80633644e5151461037657806340c10f19146103945780635422224e146103e2576101a9565b806306fdde03146101ae578063095ea7b31461023157806318160ddd1461029557806323b872dd146102b357806330adf81f14610337578063313ce56714610355575b600080fd5b6101b6610a92565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101f65780820151818401526020810190506101db565b50505050905090810190601f1680156102235780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61027d6004803603604081101561024757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610acb565b60405180821515815260200191505060405180910390f35b61029d610adf565b6040518082815260200191505060405180910390f35b61031f600480360360608110156102c957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610ae5565b60405180821515815260200191505060405180910390f35b61033f610ea1565b6040518082815260200191505060405180910390f35b61035d610ec8565b604051808260ff16815260200191505060405180910390f35b61037e610ecd565b6040518082815260200191505060405180910390f35b6103e0600480360360408110156103aa57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610ed3565b005b610424600480360360208110156103f857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506112b1565b005b61042e6113ac565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561046e578082015181840152602081019050610453565b50505050905090810190601f16801561049b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6104eb600480360360208110156104bf57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506113e5565b005b61052f6004803603602081101561050357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506114e0565b6040518082815260200191505060405180910390f35b6105876004803603602081101561055b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506114f8565b6040518082815260200191505060405180910390f35b6105df600480360360208110156105b357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611510565b6040518082815260200191505060405180910390f35b610699600480360361010081101561060c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190803515159060200190929190803560ff1690602001909291908035906020019092919080359060200190929190505050611528565b005b6106a3611a32565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156106e35780820151818401526020810190506106c8565b50505050905090810190601f1680156107105780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6107606004803603602081101561073457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611a6b565b005b6107ae6004803603604081101561077857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611b66565b005b6107f2600480360360208110156107c657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611ea0565b6040518082815260200191505060405180910390f35b6108546004803603604081101561081e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611eb8565b60405180821515815260200191505060405180910390f35b6108b86004803603604081101561088257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611ecd565b005b610926600480360360608110156108d057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611edd565b005b61096a6004803603602081101561093e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611eee565b6040518082815260200191505060405180910390f35b6109ac6004803603602081101561099657600080fd5b8101908080359060200190929190505050611f06565b005b6109b6611fc4565b6040518082815260200191505060405180910390f35b610a2e600480360360408110156109e257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611fca565b6040518082815260200191505060405180910390f35b610a9060048036036040811015610a5a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611fde565b005b6040518060400160405280600a81526020017f4652415820544f4b454e0000000000000000000000000000000000000000000081525081565b6000610ad78383611fee565b905092915050565b60015481565b600081600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610b9c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f467261782f696e73756666696369656e742d62616c616e63650000000000000081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614158015610c0157507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610bfe85336120e0565b14155b15610d195781610c1185336120e0565b1015610c85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f467261782f696e73756666696369656e742d616c6c6f77616e6365000000000081525060200191505060405180910390fd5b610c98610c9285336120e0565b83612167565b600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b610d62600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483612167565b600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610dee600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483612181565b600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b7fea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb60001b81565b601281565b60085481565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414156111a957600254610f6682600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612181565b111580610fcb5750611964610fba43600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612167565b10158015610fca57506002548111155b5b61103d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f4f766572206461696c792046726178204c696d6974000000000000000000000081525060200191505060405180910390fd5b61196461108943600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612167565b1061111b5780600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555043600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506111a8565b611164600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482612181565b600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b5b6111f2600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482612181565b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061124160015482612181565b6001819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414611365576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f467261782f6e6f742d617574686f72697a65640000000000000000000000000081525060200191505060405180910390fd5b60016000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050565b6040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081565b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414611499576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f467261782f6e6f742d617574686f72697a65640000000000000000000000000081525060200191505060405180910390fd5b60016000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050565b60036020528060005260406000206000915090505481565b60066020528060005260406000206000915090505481565b60056020528060005260406000206000915090505481565b60006008547fea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb60001b8a8a8a8a8a604051602001808781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001848152602001838152602001821515815260200196505050505050506040516020818303038152906040528051906020012060405160200180807f190100000000000000000000000000000000000000000000000000000000000081525060020183815260200182815260200192505050604051602081830303815290604052805190602001209050600073ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1614156116c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f467261782f696e76616c69642d616464726573732d300000000000000000000081525060200191505060405180910390fd5b60018185858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015611721573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff16146117cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f467261782f696e76616c69642d7065726d69740000000000000000000000000081525060200191505060405180910390fd5b60008614806117da5750854211155b61184c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f467261782f7065726d69742d657870697265640000000000000000000000000081525060200191505060405180910390fd5b600560008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081548092919060010191905055871461190e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f467261782f696e76616c69642d6e6f6e6365000000000000000000000000000081525060200191505060405180910390fd5b60008561191c57600061193e565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b905080600460008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a350505050505050505050565b6040518060400160405280600481526020017f465241580000000000000000000000000000000000000000000000000000000081525081565b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414611b1f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f467261782f6e6f742d617574686f72697a65640000000000000000000000000081525060200191505060405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050565b80600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611c1b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f467261782f696e73756666696369656e742d62616c616e63650000000000000081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015611c8057507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611c7d83336120e0565b14155b15611d985780611c9083336120e0565b1015611d04576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f467261782f696e73756666696369656e742d616c6c6f77616e6365000000000081525060200191505060405180910390fd5b611d17611d1183336120e0565b82612167565b600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b611de1600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482612167565b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611e3060015482612167565b600181905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b60076020528060005260406000206000915090505481565b6000611ec5338484610ae5565b905092915050565b611ed8338383610ae5565b505050565b611ee8838383610ae5565b50505050565b60006020528060005260406000206000915090505481565b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414611fba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f467261782f6e6f742d617574686f72697a65640000000000000000000000000081525060200191505060405180910390fd5b8060028190555050565b60025481565b6000611fd683836120e0565b905092915050565b611fe9823383610ae5565b505050565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b6000600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600082828403915081111561217b57600080fd5b92915050565b600082828401915081101561219557600080fd5b9291505056fea2646970667358221220bb2c920a1d6fa039a547bead741137dcf2460205316c9f8db2e1abafa4387c3964736f6c63430007050033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101a95760003560e01c80637ecebe00116100f9578063b753a98c11610097578063d3fd35ec11610071578063d3fd35ec14610980578063d7f1bf12146109ae578063dd62ed3e146109cc578063f2d5d56b14610a44576101a9565b8063b753a98c1461086c578063bb35783b146108ba578063bf353dbb14610928576101a9565b80639c52a7f1116100d35780639c52a7f11461071e5780639dc29fac146107625780639e16de34146107b0578063a9059cbb14610808576101a9565b80637ecebe001461059d5780638fcbaf0c146105f557806395d89b411461069b576101a9565b80633644e5151161016657806354fd4d501161014057806354fd4d501461042657806365fae35e146104a957806370a08231146104ed578063798247ae14610545576101a9565b80633644e5151461037657806340c10f19146103945780635422224e146103e2576101a9565b806306fdde03146101ae578063095ea7b31461023157806318160ddd1461029557806323b872dd146102b357806330adf81f14610337578063313ce56714610355575b600080fd5b6101b6610a92565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101f65780820151818401526020810190506101db565b50505050905090810190601f1680156102235780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61027d6004803603604081101561024757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610acb565b60405180821515815260200191505060405180910390f35b61029d610adf565b6040518082815260200191505060405180910390f35b61031f600480360360608110156102c957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610ae5565b60405180821515815260200191505060405180910390f35b61033f610ea1565b6040518082815260200191505060405180910390f35b61035d610ec8565b604051808260ff16815260200191505060405180910390f35b61037e610ecd565b6040518082815260200191505060405180910390f35b6103e0600480360360408110156103aa57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610ed3565b005b610424600480360360208110156103f857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506112b1565b005b61042e6113ac565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561046e578082015181840152602081019050610453565b50505050905090810190601f16801561049b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6104eb600480360360208110156104bf57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506113e5565b005b61052f6004803603602081101561050357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506114e0565b6040518082815260200191505060405180910390f35b6105876004803603602081101561055b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506114f8565b6040518082815260200191505060405180910390f35b6105df600480360360208110156105b357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611510565b6040518082815260200191505060405180910390f35b610699600480360361010081101561060c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190803515159060200190929190803560ff1690602001909291908035906020019092919080359060200190929190505050611528565b005b6106a3611a32565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156106e35780820151818401526020810190506106c8565b50505050905090810190601f1680156107105780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6107606004803603602081101561073457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611a6b565b005b6107ae6004803603604081101561077857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611b66565b005b6107f2600480360360208110156107c657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611ea0565b6040518082815260200191505060405180910390f35b6108546004803603604081101561081e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611eb8565b60405180821515815260200191505060405180910390f35b6108b86004803603604081101561088257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611ecd565b005b610926600480360360608110156108d057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611edd565b005b61096a6004803603602081101561093e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611eee565b6040518082815260200191505060405180910390f35b6109ac6004803603602081101561099657600080fd5b8101908080359060200190929190505050611f06565b005b6109b6611fc4565b6040518082815260200191505060405180910390f35b610a2e600480360360408110156109e257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611fca565b6040518082815260200191505060405180910390f35b610a9060048036036040811015610a5a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611fde565b005b6040518060400160405280600a81526020017f4652415820544f4b454e0000000000000000000000000000000000000000000081525081565b6000610ad78383611fee565b905092915050565b60015481565b600081600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610b9c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f467261782f696e73756666696369656e742d62616c616e63650000000000000081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614158015610c0157507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610bfe85336120e0565b14155b15610d195781610c1185336120e0565b1015610c85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f467261782f696e73756666696369656e742d616c6c6f77616e6365000000000081525060200191505060405180910390fd5b610c98610c9285336120e0565b83612167565b600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b610d62600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483612167565b600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610dee600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483612181565b600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b7fea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb60001b81565b601281565b60085481565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414156111a957600254610f6682600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612181565b111580610fcb5750611964610fba43600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612167565b10158015610fca57506002548111155b5b61103d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f4f766572206461696c792046726178204c696d6974000000000000000000000081525060200191505060405180910390fd5b61196461108943600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612167565b1061111b5780600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555043600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506111a8565b611164600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482612181565b600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b5b6111f2600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482612181565b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061124160015482612181565b6001819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414611365576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f467261782f6e6f742d617574686f72697a65640000000000000000000000000081525060200191505060405180910390fd5b60016000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050565b6040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081565b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414611499576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f467261782f6e6f742d617574686f72697a65640000000000000000000000000081525060200191505060405180910390fd5b60016000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050565b60036020528060005260406000206000915090505481565b60066020528060005260406000206000915090505481565b60056020528060005260406000206000915090505481565b60006008547fea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb60001b8a8a8a8a8a604051602001808781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001848152602001838152602001821515815260200196505050505050506040516020818303038152906040528051906020012060405160200180807f190100000000000000000000000000000000000000000000000000000000000081525060020183815260200182815260200192505050604051602081830303815290604052805190602001209050600073ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1614156116c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f467261782f696e76616c69642d616464726573732d300000000000000000000081525060200191505060405180910390fd5b60018185858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015611721573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff16146117cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f467261782f696e76616c69642d7065726d69740000000000000000000000000081525060200191505060405180910390fd5b60008614806117da5750854211155b61184c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f467261782f7065726d69742d657870697265640000000000000000000000000081525060200191505060405180910390fd5b600560008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081548092919060010191905055871461190e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f467261782f696e76616c69642d6e6f6e6365000000000000000000000000000081525060200191505060405180910390fd5b60008561191c57600061193e565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b905080600460008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a350505050505050505050565b6040518060400160405280600481526020017f465241580000000000000000000000000000000000000000000000000000000081525081565b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414611b1f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f467261782f6e6f742d617574686f72697a65640000000000000000000000000081525060200191505060405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050565b80600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611c1b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f467261782f696e73756666696369656e742d62616c616e63650000000000000081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015611c8057507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611c7d83336120e0565b14155b15611d985780611c9083336120e0565b1015611d04576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f467261782f696e73756666696369656e742d616c6c6f77616e6365000000000081525060200191505060405180910390fd5b611d17611d1183336120e0565b82612167565b600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b611de1600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482612167565b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611e3060015482612167565b600181905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b60076020528060005260406000206000915090505481565b6000611ec5338484610ae5565b905092915050565b611ed8338383610ae5565b505050565b611ee8838383610ae5565b50505050565b60006020528060005260406000206000915090505481565b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414611fba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f467261782f6e6f742d617574686f72697a65640000000000000000000000000081525060200191505060405180910390fd5b8060028190555050565b60025481565b6000611fd683836120e0565b905092915050565b611fe9823383610ae5565b505050565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b6000600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600082828403915081111561217b57600080fd5b92915050565b600082828401915081101561219557600080fd5b9291505056fea2646970667358221220bb2c920a1d6fa039a547bead741137dcf2460205316c9f8db2e1abafa4387c3964736f6c63430007050033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 16840, + "contract": "contracts/mocks/Frax.sol:FRAX", + "label": "wards", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 16900, + "contract": "contracts/mocks/Frax.sol:FRAX", + "label": "totalSupply", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 16902, + "contract": "contracts/mocks/Frax.sol:FRAX", + "label": "dailyFraxLimit", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 16906, + "contract": "contracts/mocks/Frax.sol:FRAX", + "label": "balanceOf", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 16912, + "contract": "contracts/mocks/Frax.sol:FRAX", + "label": "allowances", + "offset": 0, + "slot": "4", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 16916, + "contract": "contracts/mocks/Frax.sol:FRAX", + "label": "nonces", + "offset": 0, + "slot": "5", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 16920, + "contract": "contracts/mocks/Frax.sol:FRAX", + "label": "lastMintRestart", + "offset": 0, + "slot": "6", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 16924, + "contract": "contracts/mocks/Frax.sol:FRAX", + "label": "fraxMintedToday", + "offset": 0, + "slot": "7", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 16968, + "contract": "contracts/mocks/Frax.sol:FRAX", + "label": "DOMAIN_SEPARATOR", + "offset": 0, + "slot": "8", + "type": "t_bytes32" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/src/abi/rinkeby/FraxBondDepository.json b/src/abi/rinkeby/FraxBondDepository.json new file mode 100644 index 0000000000..89b6527944 --- /dev/null +++ b/src/abi/rinkeby/FraxBondDepository.json @@ -0,0 +1,1269 @@ +{ + "address": "0xd3D1aD79DC0eeF622f71E786270CFf53719D261C", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_OHM", + "type": "address" + }, + { + "internalType": "address", + "name": "_principle", + "type": "address" + }, + { + "internalType": "address", + "name": "_treasury", + "type": "address" + }, + { + "internalType": "address", + "name": "_DAO", + "type": "address" + }, + { + "internalType": "address", + "name": "_bondCalculator", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "deposit", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "payout", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "expires", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "priceInUSD", + "type": "uint256" + } + ], + "name": "BondCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "priceInUSD", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "internalPrice", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "debtRatio", + "type": "uint256" + } + ], + "name": "BondPriceChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "payout", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "remaining", + "type": "uint256" + } + ], + "name": "BondRedeemed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "initialBCV", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newBCV", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "adjustment", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bool", + "name": "addition", + "type": "bool" + } + ], + "name": "ControlVariableAdjustment", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipPulled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipPushed", + "type": "event" + }, + { + "inputs": [], + "name": "DAO", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "OHM", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "adjustment", + "outputs": [ + { + "internalType": "bool", + "name": "add", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "rate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "target", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "buffer", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastTime", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bondCalculator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "bondInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "payout", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "vesting", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "pricePaid", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bondPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "price_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bondPriceInUSD", + "outputs": [ + { + "internalType": "uint256", + "name": "price_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "debtDecay", + "outputs": [ + { + "internalType": "uint256", + "name": "decay_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "debtRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "debtRatio_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxPrice", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_depositor", + "type": "address" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_controlVariable", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_vestingTerm", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_minimumPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxPayout", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_fee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_initialDebt", + "type": "uint256" + } + ], + "name": "initializeBondTerms", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isLiquidityBond", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastDecay", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxPayout", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + } + ], + "name": "payoutFor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_depositor", + "type": "address" + } + ], + "name": "pendingPayoutFor", + "outputs": [ + { + "internalType": "uint256", + "name": "pendingPayout_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_depositor", + "type": "address" + } + ], + "name": "percentVestedFor", + "outputs": [ + { + "internalType": "uint256", + "name": "percentVested_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "policy", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "principle", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pullManagement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner_", + "type": "address" + } + ], + "name": "pushManagement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "recoverLostToken", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "bool", + "name": "_stake", + "type": "bool" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceManagement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_addition", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "_increment", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_target", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_buffer", + "type": "uint256" + } + ], + "name": "setAdjustment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum OlympusBondDepository.PARAMETER", + "name": "_parameter", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "_input", + "type": "uint256" + } + ], + "name": "setBondTerms", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_staking", + "type": "address" + }, + { + "internalType": "bool", + "name": "_helper", + "type": "bool" + } + ], + "name": "setStaking", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "staking", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stakingHelper", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "standardizedDebtRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "terms", + "outputs": [ + { + "internalType": "uint256", + "name": "controlVariable", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "vestingTerm", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minimumPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPayout", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxDebt", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "treasury", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "useHelper", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x609d3d3927827082f7389142e4fc2b95c757046c473f487a19eea7a51d6580b8", + "receipt": { + "to": null, + "from": "0xA38F4E6718EdCF023a1d032a2193848CB932c8e3", + "contractAddress": "0xd3D1aD79DC0eeF622f71E786270CFf53719D261C", + "transactionIndex": 10, + "gasUsed": "3730909", + "logsBloom": "0x00000000000000000000000000040000000000000000000000000000000000000000400000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000100000000000000000010000000000400000000000000000000000000000000000000000000000020000000000020002000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x87ffa46e22d01aa04055487ccba86b60e338b4c518d169f71c05d3480b9d49fd", + "transactionHash": "0x609d3d3927827082f7389142e4fc2b95c757046c473f487a19eea7a51d6580b8", + "logs": [ + { + "transactionIndex": 10, + "blockNumber": 9907142, + "transactionHash": "0x609d3d3927827082f7389142e4fc2b95c757046c473f487a19eea7a51d6580b8", + "address": "0xd3D1aD79DC0eeF622f71E786270CFf53719D261C", + "topics": [ + "0xea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000a38f4e6718edcf023a1d032a2193848cb932c8e3" + ], + "data": "0x", + "logIndex": 8, + "blockHash": "0x87ffa46e22d01aa04055487ccba86b60e338b4c518d169f71c05d3480b9d49fd" + } + ], + "blockNumber": 9907142, + "cumulativeGasUsed": "4315980", + "status": 1, + "byzantium": true + }, + "args": [ + "0x9bb5E7183e6259183f8E79876eCC0228738C95F6", + "0x0B81a995b28254D76e5148d29E8eb4c5c26D3aC0", + "0x1e0AD0F8DDFF84FDc938373E9aa66b8d994ea066", + "0xA38F4E6718EdCF023a1d032a2193848CB932c8e3", + "0x0000000000000000000000000000000000000000" + ], + "solcInputHash": "bbf3f95bcfbd20e9e9f7857af806cde4", + "metadata": "{\"compiler\":{\"version\":\"0.7.5+commit.eb77ed08\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_OHM\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_principle\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_DAO\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_bondCalculator\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"deposit\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"payout\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"expires\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"priceInUSD\",\"type\":\"uint256\"}],\"name\":\"BondCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"priceInUSD\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"internalPrice\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"debtRatio\",\"type\":\"uint256\"}],\"name\":\"BondPriceChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payout\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remaining\",\"type\":\"uint256\"}],\"name\":\"BondRedeemed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"initialBCV\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBCV\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"adjustment\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"addition\",\"type\":\"bool\"}],\"name\":\"ControlVariableAdjustment\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipPulled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipPushed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DAO\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OHM\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"adjustment\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"add\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"rate\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"target\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"buffer\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lastTime\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bondCalculator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bondInfo\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"payout\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"vesting\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lastTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"pricePaid\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bondPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"price_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bondPriceInUSD\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"price_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentDebt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"debtDecay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"decay_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"debtRatio\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"debtRatio_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_depositor\",\"type\":\"address\"}],\"name\":\"deposit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_controlVariable\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_vestingTerm\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_minimumPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxPayout\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxDebt\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_initialDebt\",\"type\":\"uint256\"}],\"name\":\"initializeBondTerms\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isLiquidityBond\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastDecay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxPayout\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"payoutFor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_depositor\",\"type\":\"address\"}],\"name\":\"pendingPayoutFor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"pendingPayout_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_depositor\",\"type\":\"address\"}],\"name\":\"percentVestedFor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"percentVested_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"policy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"principle\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pullManagement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner_\",\"type\":\"address\"}],\"name\":\"pushManagement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"recoverLostToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_stake\",\"type\":\"bool\"}],\"name\":\"redeem\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceManagement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_addition\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"_increment\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_target\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_buffer\",\"type\":\"uint256\"}],\"name\":\"setAdjustment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enum OlympusBondDepository.PARAMETER\",\"name\":\"_parameter\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"_input\",\"type\":\"uint256\"}],\"name\":\"setBondTerms\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_staking\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_helper\",\"type\":\"bool\"}],\"name\":\"setStaking\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"staking\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stakingHelper\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"standardizedDebtRatio\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"terms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"controlVariable\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"vestingTerm\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minimumPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPayout\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxDebt\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalDebt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useHelper\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"bondPrice()\":{\"returns\":{\"price_\":\"uint\"}},\"bondPriceInUSD()\":{\"returns\":{\"price_\":\"uint\"}},\"currentDebt()\":{\"returns\":{\"_0\":\"uint\"}},\"debtDecay()\":{\"returns\":{\"decay_\":\"uint\"}},\"debtRatio()\":{\"returns\":{\"debtRatio_\":\"uint\"}},\"deposit(uint256,uint256,address)\":{\"params\":{\"_amount\":\"uint\",\"_depositor\":\"address\",\"_maxPrice\":\"uint\"},\"returns\":{\"_0\":\"uint\"}},\"initializeBondTerms(uint256,uint256,uint256,uint256,uint256,uint256,uint256)\":{\"params\":{\"_controlVariable\":\"uint\",\"_fee\":\"uint\",\"_initialDebt\":\"uint\",\"_maxDebt\":\"uint\",\"_maxPayout\":\"uint\",\"_minimumPrice\":\"uint\",\"_vestingTerm\":\"uint\"}},\"maxPayout()\":{\"returns\":{\"_0\":\"uint\"}},\"payoutFor(uint256)\":{\"params\":{\"_value\":\"uint\"},\"returns\":{\"_0\":\"uint\"}},\"pendingPayoutFor(address)\":{\"params\":{\"_depositor\":\"address\"},\"returns\":{\"pendingPayout_\":\"uint\"}},\"percentVestedFor(address)\":{\"params\":{\"_depositor\":\"address\"},\"returns\":{\"percentVested_\":\"uint\"}},\"recoverLostToken(address)\":{\"returns\":{\"_0\":\"bool\"}},\"redeem(address,bool)\":{\"params\":{\"_recipient\":\"address\",\"_stake\":\"bool\"},\"returns\":{\"_0\":\"uint\"}},\"setAdjustment(bool,uint256,uint256,uint256)\":{\"params\":{\"_addition\":\"bool\",\"_buffer\":\"uint\",\"_increment\":\"uint\",\"_target\":\"uint\"}},\"setBondTerms(uint8,uint256)\":{\"params\":{\"_input\":\"uint\",\"_parameter\":\"PARAMETER\"}},\"setStaking(address,bool)\":{\"params\":{\"_helper\":\"bool\",\"_staking\":\"address\"}},\"standardizedDebtRatio()\":{\"returns\":{\"_0\":\"uint\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"bondPrice()\":{\"notice\":\"calculate current bond premium\"},\"bondPriceInUSD()\":{\"notice\":\"converts bond price to DAI value\"},\"currentDebt()\":{\"notice\":\"calculate debt factoring in decay\"},\"debtDecay()\":{\"notice\":\"amount to decay total debt by\"},\"debtRatio()\":{\"notice\":\"calculate current ratio of debt to OHM supply\"},\"deposit(uint256,uint256,address)\":{\"notice\":\"deposit bond\"},\"initializeBondTerms(uint256,uint256,uint256,uint256,uint256,uint256,uint256)\":{\"notice\":\"initializes bond parameters\"},\"maxPayout()\":{\"notice\":\"determine maximum bond size\"},\"payoutFor(uint256)\":{\"notice\":\"calculate interest due for new bond\"},\"pendingPayoutFor(address)\":{\"notice\":\"calculate amount of OHM available for claim by depositor\"},\"percentVestedFor(address)\":{\"notice\":\"calculate how far into vesting a depositor is\"},\"recoverLostToken(address)\":{\"notice\":\"allow anyone to send lost tokens (excluding principle or OHM) to the DAO\"},\"redeem(address,bool)\":{\"notice\":\"redeem bond for user\"},\"setAdjustment(bool,uint256,uint256,uint256)\":{\"notice\":\"set control variable adjustment\"},\"setBondTerms(uint8,uint256)\":{\"notice\":\"set parameters for new bonds\"},\"setStaking(address,bool)\":{\"notice\":\"set contract for auto stake\"},\"standardizedDebtRatio()\":{\"notice\":\"debt ratio in same terms for reserve or liquidity bonds\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/BondDepository.sol\":\"OlympusBondDepository\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/BondDepository.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-or-later\\npragma solidity 0.7.5;\\n\\ninterface IOwnable {\\n function policy() external view returns (address);\\n\\n function renounceManagement() external;\\n \\n function pushManagement( address newOwner_ ) external;\\n \\n function pullManagement() external;\\n}\\n\\ncontract Ownable is IOwnable {\\n\\n address internal _owner;\\n address internal _newOwner;\\n\\n event OwnershipPushed(address indexed previousOwner, address indexed newOwner);\\n event OwnershipPulled(address indexed previousOwner, address indexed newOwner);\\n\\n constructor () {\\n _owner = msg.sender;\\n emit OwnershipPushed( address(0), _owner );\\n }\\n\\n function policy() public view override returns (address) {\\n return _owner;\\n }\\n\\n modifier onlyPolicy() {\\n require( _owner == msg.sender, \\\"Ownable: caller is not the owner\\\" );\\n _;\\n }\\n\\n function renounceManagement() public virtual override onlyPolicy() {\\n emit OwnershipPushed( _owner, address(0) );\\n _owner = address(0);\\n }\\n\\n function pushManagement( address newOwner_ ) public virtual override onlyPolicy() {\\n require( newOwner_ != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipPushed( _owner, newOwner_ );\\n _newOwner = newOwner_;\\n }\\n \\n function pullManagement() public virtual override {\\n require( msg.sender == _newOwner, \\\"Ownable: must be new owner to pull\\\");\\n emit OwnershipPulled( _owner, _newOwner );\\n _owner = _newOwner;\\n }\\n}\\n\\nlibrary SafeMath {\\n\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n return c;\\n }\\n\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n\\n function sqrrt(uint256 a) internal pure returns (uint c) {\\n if (a > 3) {\\n c = a;\\n uint b = add( div( a, 2), 1 );\\n while (b < c) {\\n c = b;\\n b = div( add( div( a, b ), b), 2 );\\n }\\n } else if (a != 0) {\\n c = 1;\\n }\\n }\\n}\\n\\nlibrary Address {\\n\\n function isContract(address account) internal view returns (bool) {\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return _functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n if (returndata.length > 0) {\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n\\n function addressToString(address _address) internal pure returns(string memory) {\\n bytes32 _bytes = bytes32(uint256(_address));\\n bytes memory HEX = \\\"0123456789abcdef\\\";\\n bytes memory _addr = new bytes(42);\\n\\n _addr[0] = '0';\\n _addr[1] = 'x';\\n\\n for(uint256 i = 0; i < 20; i++) {\\n _addr[2+i*2] = HEX[uint8(_bytes[i + 12] >> 4)];\\n _addr[3+i*2] = HEX[uint8(_bytes[i + 12] & 0x0f)];\\n }\\n\\n return string(_addr);\\n\\n }\\n}\\n\\ninterface IERC20 {\\n function decimals() external view returns (uint8);\\n\\n function totalSupply() external view returns (uint256);\\n\\n function balanceOf(address account) external view returns (uint256);\\n\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\\nabstract contract ERC20 is IERC20 {\\n\\n using SafeMath for uint256;\\n\\n // TODO comment actual hash value.\\n bytes32 constant private ERC20TOKEN_ERC1820_INTERFACE_ID = keccak256( \\\"ERC20Token\\\" );\\n \\n mapping (address => uint256) internal _balances;\\n\\n mapping (address => mapping (address => uint256)) internal _allowances;\\n\\n uint256 internal _totalSupply;\\n\\n string internal _name;\\n \\n string internal _symbol;\\n \\n uint8 internal _decimals;\\n\\n constructor (string memory name_, string memory symbol_, uint8 decimals_) {\\n _name = name_;\\n _symbol = symbol_;\\n _decimals = decimals_;\\n }\\n\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n function symbol() public view returns (string memory) {\\n return _symbol;\\n }\\n\\n function decimals() public view override returns (uint8) {\\n return _decimals;\\n }\\n\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(msg.sender, recipient, amount);\\n return true;\\n }\\n\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(msg.sender, spender, amount);\\n return true;\\n }\\n\\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\n return true;\\n }\\n\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\\n return true;\\n }\\n\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(sender, recipient, amount);\\n }\\n\\n function _mint(address account_, uint256 ammount_) internal virtual {\\n require(account_ != address(0), \\\"ERC20: mint to the zero address\\\");\\n _beforeTokenTransfer(address( this ), account_, ammount_);\\n _totalSupply = _totalSupply.add(ammount_);\\n _balances[account_] = _balances[account_].add(ammount_);\\n emit Transfer(address( this ), account_, ammount_);\\n }\\n\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(account, address(0), amount);\\n }\\n\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n function _beforeTokenTransfer( address from_, address to_, uint256 amount_ ) internal virtual { }\\n}\\n\\ninterface IERC2612Permit {\\n\\n function permit(\\n address owner,\\n address spender,\\n uint256 amount,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n function nonces(address owner) external view returns (uint256);\\n}\\n\\nlibrary Counters {\\n using SafeMath for uint256;\\n\\n struct Counter {\\n\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n counter._value += 1;\\n }\\n\\n function decrement(Counter storage counter) internal {\\n counter._value = counter._value.sub(1);\\n }\\n}\\n\\nabstract contract ERC20Permit is ERC20, IERC2612Permit {\\n using Counters for Counters.Counter;\\n\\n mapping(address => Counters.Counter) private _nonces;\\n\\n // keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\\n\\n bytes32 public DOMAIN_SEPARATOR;\\n\\n constructor() {\\n uint256 chainID;\\n assembly {\\n chainID := chainid()\\n }\\n\\n DOMAIN_SEPARATOR = keccak256(\\n abi.encode(\\n keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"),\\n keccak256(bytes(name())),\\n keccak256(bytes(\\\"1\\\")), // Version\\n chainID,\\n address(this)\\n )\\n );\\n }\\n\\n function permit(\\n address owner,\\n address spender,\\n uint256 amount,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"Permit: expired deadline\\\");\\n\\n bytes32 hashStruct =\\n keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, amount, _nonces[owner].current(), deadline));\\n\\n bytes32 _hash = keccak256(abi.encodePacked(uint16(0x1901), DOMAIN_SEPARATOR, hashStruct));\\n\\n address signer = ecrecover(_hash, v, r, s);\\n require(signer != address(0) && signer == owner, \\\"ZeroSwapPermit: Invalid signature\\\");\\n\\n _nonces[owner].increment();\\n _approve(owner, spender, amount);\\n }\\n\\n function nonces(address owner) public view override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n}\\n\\nlibrary SafeERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n\\n require((value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\\nlibrary FullMath {\\n function fullMul(uint256 x, uint256 y) private pure returns (uint256 l, uint256 h) {\\n uint256 mm = mulmod(x, y, uint256(-1));\\n l = x * y;\\n h = mm - l;\\n if (mm < l) h -= 1;\\n }\\n\\n function fullDiv(\\n uint256 l,\\n uint256 h,\\n uint256 d\\n ) private pure returns (uint256) {\\n uint256 pow2 = d & -d;\\n d /= pow2;\\n l /= pow2;\\n l += h * ((-pow2) / pow2 + 1);\\n uint256 r = 1;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n return l * r;\\n }\\n\\n function mulDiv(\\n uint256 x,\\n uint256 y,\\n uint256 d\\n ) internal pure returns (uint256) {\\n (uint256 l, uint256 h) = fullMul(x, y);\\n uint256 mm = mulmod(x, y, d);\\n if (mm > l) h -= 1;\\n l -= mm;\\n require(h < d, 'FullMath::mulDiv: overflow');\\n return fullDiv(l, h, d);\\n }\\n}\\n\\nlibrary FixedPoint {\\n\\n struct uq112x112 {\\n uint224 _x;\\n }\\n\\n struct uq144x112 {\\n uint256 _x;\\n }\\n\\n uint8 private constant RESOLUTION = 112;\\n uint256 private constant Q112 = 0x10000000000000000000000000000;\\n uint256 private constant Q224 = 0x100000000000000000000000000000000000000000000000000000000;\\n uint256 private constant LOWER_MASK = 0xffffffffffffffffffffffffffff; // decimal of UQ*x112 (lower 112 bits)\\n\\n function decode(uq112x112 memory self) internal pure returns (uint112) {\\n return uint112(self._x >> RESOLUTION);\\n }\\n\\n function decode112with18(uq112x112 memory self) internal pure returns (uint) {\\n\\n return uint(self._x) / 5192296858534827;\\n }\\n\\n function fraction(uint256 numerator, uint256 denominator) internal pure returns (uq112x112 memory) {\\n require(denominator > 0, 'FixedPoint::fraction: division by zero');\\n if (numerator == 0) return FixedPoint.uq112x112(0);\\n\\n if (numerator <= uint144(-1)) {\\n uint256 result = (numerator << RESOLUTION) / denominator;\\n require(result <= uint224(-1), 'FixedPoint::fraction: overflow');\\n return uq112x112(uint224(result));\\n } else {\\n uint256 result = FullMath.mulDiv(numerator, Q112, denominator);\\n require(result <= uint224(-1), 'FixedPoint::fraction: overflow');\\n return uq112x112(uint224(result));\\n }\\n }\\n}\\n\\ninterface ITreasury {\\n function deposit( uint _amount, address _token, uint _profit ) external returns ( bool );\\n function valueOf( address _token, uint _amount ) external view returns ( uint value_ );\\n}\\n\\ninterface IBondCalculator {\\n function valuation( address _LP, uint _amount ) external view returns ( uint );\\n function markdown( address _LP ) external view returns ( uint );\\n}\\n\\ninterface IStaking {\\n function stake( uint _amount, address _recipient ) external returns ( bool );\\n}\\n\\ninterface IStakingHelper {\\n function stake( uint _amount, address _recipient ) external;\\n}\\n\\ncontract OlympusBondDepository is Ownable {\\n\\n using FixedPoint for *;\\n using SafeERC20 for IERC20;\\n using SafeMath for uint;\\n\\n\\n\\n\\n /* ======== EVENTS ======== */\\n\\n event BondCreated( uint deposit, uint indexed payout, uint indexed expires, uint indexed priceInUSD );\\n event BondRedeemed( address indexed recipient, uint payout, uint remaining );\\n event BondPriceChanged( uint indexed priceInUSD, uint indexed internalPrice, uint indexed debtRatio );\\n event ControlVariableAdjustment( uint initialBCV, uint newBCV, uint adjustment, bool addition );\\n\\n\\n\\n\\n /* ======== STATE VARIABLES ======== */\\n\\n address public immutable OHM; // token given as payment for bond\\n address public immutable principle; // token used to create bond\\n address public immutable treasury; // mints OHM when receives principle\\n address public immutable DAO; // receives profit share from bond\\n\\n bool public immutable isLiquidityBond; // LP and Reserve bonds are treated slightly different\\n address public immutable bondCalculator; // calculates value of LP tokens\\n\\n address public staking; // to auto-stake payout\\n address public stakingHelper; // to stake and claim if no staking warmup\\n bool public useHelper;\\n\\n Terms public terms; // stores terms for new bonds\\n Adjust public adjustment; // stores adjustment to BCV data\\n\\n mapping( address => Bond ) public bondInfo; // stores bond information for depositors\\n\\n uint public totalDebt; // total value of outstanding bonds; used for pricing\\n uint public lastDecay; // reference block timestamp for debt decay\\n\\n\\n\\n\\n /* ======== STRUCTS ======== */\\n\\n // Info for creating new bonds\\n struct Terms {\\n uint controlVariable; // scaling variable for price\\n uint vestingTerm; // in seconds\\n uint minimumPrice; // vs principle value\\n uint maxPayout; // in thousandths of a %. i.e. 500 = 0.5%\\n uint fee; // as % of bond payout, in hundreths. ( 500 = 5% = 0.05 for every 1 paid)\\n uint maxDebt; // 9 decimal debt ratio, max % total supply created as debt\\n }\\n\\n // Info for bond holder\\n struct Bond {\\n uint payout; // OHM remaining to be paid\\n uint vesting; // Blocks left to vest\\n uint lastTime; // Last interaction\\n uint pricePaid; // In DAI, for front end viewing\\n }\\n\\n // Info for incremental adjustments to control variable\\n struct Adjust {\\n bool add; // addition or subtraction\\n uint rate; // increment\\n uint target; // BCV when adjustment finished\\n uint buffer; // minimum length (in seconds) between adjustments\\n uint lastTime; // time when last adjustment made\\n }\\n\\n\\n\\n\\n /* ======== INITIALIZATION ======== */\\n\\n constructor ( \\n address _OHM,\\n address _principle,\\n address _treasury, \\n address _DAO, \\n address _bondCalculator\\n ) {\\n require( _OHM != address(0) );\\n OHM = _OHM;\\n require( _principle != address(0) );\\n principle = _principle;\\n require( _treasury != address(0) );\\n treasury = _treasury;\\n require( _DAO != address(0) );\\n DAO = _DAO;\\n // bondCalculator should be address(0) if not LP bond\\n bondCalculator = _bondCalculator;\\n isLiquidityBond = ( _bondCalculator != address(0) );\\n }\\n\\n /**\\n * @notice initializes bond parameters\\n * @param _controlVariable uint\\n * @param _vestingTerm uint\\n * @param _minimumPrice uint\\n * @param _maxPayout uint\\n * @param _fee uint\\n * @param _maxDebt uint\\n * @param _initialDebt uint\\n */\\n function initializeBondTerms( \\n uint _controlVariable, \\n uint _vestingTerm,\\n uint _minimumPrice,\\n uint _maxPayout,\\n uint _fee,\\n uint _maxDebt,\\n uint _initialDebt\\n ) external onlyPolicy() {\\n require( terms.controlVariable == 0, \\\"Bonds must be initialized from 0\\\" );\\n terms = Terms ({\\n controlVariable: _controlVariable,\\n vestingTerm: _vestingTerm,\\n minimumPrice: _minimumPrice,\\n maxPayout: _maxPayout,\\n fee: _fee,\\n maxDebt: _maxDebt\\n });\\n totalDebt = _initialDebt;\\n lastDecay = block.timestamp;\\n }\\n\\n\\n\\n\\n /* ======== POLICY FUNCTIONS ======== */\\n\\n enum PARAMETER { VESTING, PAYOUT, FEE, DEBT }\\n /**\\n * @notice set parameters for new bonds\\n * @param _parameter PARAMETER\\n * @param _input uint\\n */\\n function setBondTerms ( PARAMETER _parameter, uint _input ) external onlyPolicy() {\\n if ( _parameter == PARAMETER.VESTING ) { // 0\\n require( _input >= 129600, \\\"Vesting must be longer than 36 hours\\\" );\\n terms.vestingTerm = _input;\\n } else if ( _parameter == PARAMETER.PAYOUT ) { // 1\\n require( _input <= 1000, \\\"Payout cannot be above 1 percent\\\" );\\n terms.maxPayout = _input;\\n } else if ( _parameter == PARAMETER.FEE ) { // 2\\n require( _input <= 10000, \\\"DAO fee cannot exceed payout\\\" );\\n terms.fee = _input;\\n } else if ( _parameter == PARAMETER.DEBT ) { // 3\\n terms.maxDebt = _input;\\n }\\n }\\n\\n /**\\n * @notice set control variable adjustment\\n * @param _addition bool\\n * @param _increment uint\\n * @param _target uint\\n * @param _buffer uint\\n */\\n function setAdjustment ( \\n bool _addition,\\n uint _increment, \\n uint _target,\\n uint _buffer \\n ) external onlyPolicy() {\\n require( _increment <= terms.controlVariable.mul( 25 ).div( 1000 ), \\\"Increment too large\\\" );\\n\\n adjustment = Adjust({\\n add: _addition,\\n rate: _increment,\\n target: _target,\\n buffer: _buffer,\\n lastTime: block.timestamp\\n });\\n }\\n\\n /**\\n * @notice set contract for auto stake\\n * @param _staking address\\n * @param _helper bool\\n */\\n function setStaking( address _staking, bool _helper ) external onlyPolicy() {\\n require( _staking != address(0) );\\n if ( _helper ) {\\n useHelper = true;\\n stakingHelper = _staking;\\n } else {\\n useHelper = false;\\n staking = _staking;\\n }\\n }\\n\\n\\n \\n\\n /* ======== USER FUNCTIONS ======== */\\n\\n /**\\n * @notice deposit bond\\n * @param _amount uint\\n * @param _maxPrice uint\\n * @param _depositor address\\n * @return uint\\n */\\n function deposit( \\n uint _amount, \\n uint _maxPrice,\\n address _depositor\\n ) external returns ( uint ) {\\n require( _depositor != address(0), \\\"Invalid address\\\" );\\n\\n decayDebt();\\n require( totalDebt <= terms.maxDebt, \\\"Max capacity reached\\\" );\\n \\n uint priceInUSD = bondPriceInUSD(); // Stored in bond info\\n uint nativePrice = _bondPrice();\\n\\n require( _maxPrice >= nativePrice, \\\"Slippage limit: more than max price\\\" ); // slippage protection\\n\\n uint value = ITreasury( treasury ).valueOf( principle, _amount );\\n uint payout = payoutFor( value ); // payout to bonder is computed\\n\\n require( payout >= 10000000, \\\"Bond too small\\\" ); // must be > 0.01 OHM ( underflow protection )\\n require( payout <= maxPayout(), \\\"Bond too large\\\"); // size protection because there is no slippage\\n\\n // profits are calculated\\n uint fee = payout.mul( terms.fee ).div( 10000 );\\n uint profit = value.sub( payout ).sub( fee );\\n\\n /**\\n principle is transferred in\\n approved and\\n deposited into the treasury, returning (_amount - profit) OHM\\n */\\n IERC20( principle ).safeTransferFrom( msg.sender, address(this), _amount );\\n IERC20( principle ).approve( address( treasury ), _amount );\\n ITreasury( treasury ).deposit( _amount, principle, profit );\\n \\n if ( fee != 0 ) { // fee is transferred to dao \\n IERC20( OHM ).safeTransfer( DAO, fee ); \\n }\\n \\n // total debt is increased\\n totalDebt = totalDebt.add( value ); \\n \\n // depositor info is stored\\n bondInfo[ _depositor ] = Bond({ \\n payout: bondInfo[ _depositor ].payout.add( payout ),\\n vesting: terms.vestingTerm,\\n lastTime: block.timestamp,\\n pricePaid: priceInUSD\\n });\\n\\n // indexed events are emitted\\n emit BondCreated( _amount, payout, block.timestamp.add( terms.vestingTerm ), priceInUSD );\\n emit BondPriceChanged( bondPriceInUSD(), _bondPrice(), debtRatio() );\\n\\n adjust(); // control variable is adjusted\\n return payout; \\n }\\n\\n /** \\n * @notice redeem bond for user\\n * @param _recipient address\\n * @param _stake bool\\n * @return uint\\n */ \\n function redeem( address _recipient, bool _stake ) external returns ( uint ) { \\n Bond memory info = bondInfo[ _recipient ];\\n uint percentVested = percentVestedFor( _recipient ); // (blocks since last interaction / vesting term remaining)\\n\\n if ( percentVested >= 10000 ) { // if fully vested\\n delete bondInfo[ _recipient ]; // delete user info\\n emit BondRedeemed( _recipient, info.payout, 0 ); // emit bond data\\n return stakeOrSend( _recipient, _stake, info.payout ); // pay user everything due\\n\\n } else { // if unfinished\\n // calculate payout vested\\n uint payout = info.payout.mul( percentVested ).div( 10000 );\\n\\n // store updated deposit info\\n bondInfo[ _recipient ] = Bond({\\n payout: info.payout.sub( payout ),\\n vesting: info.vesting.sub( block.timestamp.sub( info.lastTime ) ),\\n lastTime: block.timestamp,\\n pricePaid: info.pricePaid\\n });\\n\\n emit BondRedeemed( _recipient, payout, bondInfo[ _recipient ].payout );\\n return stakeOrSend( _recipient, _stake, payout );\\n }\\n }\\n\\n\\n\\n \\n /* ======== INTERNAL HELPER FUNCTIONS ======== */\\n\\n /**\\n * @notice allow user to stake payout automatically\\n * @param _stake bool\\n * @param _amount uint\\n * @return uint\\n */\\n function stakeOrSend( address _recipient, bool _stake, uint _amount ) internal returns ( uint ) {\\n if ( !_stake ) { // if user does not want to stake\\n IERC20( OHM ).transfer( _recipient, _amount ); // send payout\\n } else { // if user wants to stake\\n if ( useHelper ) { // use if staking warmup is 0\\n IERC20( OHM ).approve( stakingHelper, _amount );\\n IStakingHelper( stakingHelper ).stake( _amount, _recipient );\\n } else {\\n IERC20( OHM ).approve( staking, _amount );\\n IStaking( staking ).stake( _amount, _recipient );\\n }\\n }\\n return _amount;\\n }\\n\\n /**\\n * @notice makes incremental adjustment to control variable\\n */\\n function adjust() internal {\\n uint timeCanAdjust = adjustment.lastTime.add( adjustment.buffer );\\n if( adjustment.rate != 0 && block.timestamp >= timeCanAdjust ) {\\n uint initial = terms.controlVariable;\\n if ( adjustment.add ) {\\n terms.controlVariable = terms.controlVariable.add( adjustment.rate );\\n if ( terms.controlVariable >= adjustment.target ) {\\n adjustment.rate = 0;\\n }\\n } else {\\n terms.controlVariable = terms.controlVariable.sub( adjustment.rate );\\n if ( terms.controlVariable <= adjustment.target ) {\\n adjustment.rate = 0;\\n }\\n }\\n adjustment.lastTime = block.timestamp;\\n emit ControlVariableAdjustment( initial, terms.controlVariable, adjustment.rate, adjustment.add );\\n }\\n }\\n\\n /**\\n * @notice reduce total debt\\n */\\n function decayDebt() internal {\\n totalDebt = totalDebt.sub( debtDecay() );\\n lastDecay = block.timestamp;\\n }\\n\\n\\n\\n\\n /* ======== VIEW FUNCTIONS ======== */\\n\\n /**\\n * @notice determine maximum bond size\\n * @return uint\\n */\\n function maxPayout() public view returns ( uint ) {\\n return IERC20( OHM ).totalSupply().mul( terms.maxPayout ).div( 100000 );\\n }\\n\\n /**\\n * @notice calculate interest due for new bond\\n * @param _value uint\\n * @return uint\\n */\\n function payoutFor( uint _value ) public view returns ( uint ) {\\n return FixedPoint.fraction( _value, bondPrice() ).decode112with18().div( 1e16 );\\n }\\n\\n\\n /**\\n * @notice calculate current bond premium\\n * @return price_ uint\\n */\\n function bondPrice() public view returns ( uint price_ ) { \\n price_ = terms.controlVariable.mul( debtRatio() ).add( 1000000000 ).div( 1e7 );\\n if ( price_ < terms.minimumPrice ) {\\n price_ = terms.minimumPrice;\\n }\\n }\\n\\n /**\\n * @notice calculate current bond price and remove floor if above\\n * @return price_ uint\\n */\\n function _bondPrice() internal returns ( uint price_ ) {\\n price_ = terms.controlVariable.mul( debtRatio() ).add( 1000000000 ).div( 1e7 );\\n if ( price_ < terms.minimumPrice ) {\\n price_ = terms.minimumPrice; \\n } else if ( terms.minimumPrice != 0 ) {\\n terms.minimumPrice = 0;\\n }\\n }\\n\\n /**\\n * @notice converts bond price to DAI value\\n * @return price_ uint\\n */\\n function bondPriceInUSD() public view returns ( uint price_ ) {\\n if( isLiquidityBond ) {\\n price_ = bondPrice().mul( IBondCalculator( bondCalculator ).markdown( principle ) ).div( 100 );\\n } else {\\n price_ = bondPrice().mul( 10 ** IERC20( principle ).decimals() ).div( 100 );\\n }\\n }\\n\\n\\n /**\\n * @notice calculate current ratio of debt to OHM supply\\n * @return debtRatio_ uint\\n */\\n function debtRatio() public view returns ( uint debtRatio_ ) { \\n uint supply = IERC20( OHM ).totalSupply();\\n debtRatio_ = FixedPoint.fraction( \\n currentDebt().mul( 1e9 ), \\n supply\\n ).decode112with18().div( 1e18 );\\n }\\n\\n /**\\n * @notice debt ratio in same terms for reserve or liquidity bonds\\n * @return uint\\n */\\n function standardizedDebtRatio() external view returns ( uint ) {\\n if ( isLiquidityBond ) {\\n return debtRatio().mul( IBondCalculator( bondCalculator ).markdown( principle ) ).div( 1e9 );\\n } else {\\n return debtRatio();\\n }\\n }\\n\\n /**\\n * @notice calculate debt factoring in decay\\n * @return uint\\n */\\n function currentDebt() public view returns ( uint ) {\\n return totalDebt.sub( debtDecay() );\\n }\\n\\n /**\\n * @notice amount to decay total debt by\\n * @return decay_ uint\\n */\\n function debtDecay() public view returns ( uint decay_ ) {\\n uint timeSinceLast = block.timestamp.sub( lastDecay );\\n decay_ = totalDebt.mul( timeSinceLast ).div( terms.vestingTerm );\\n if ( decay_ > totalDebt ) {\\n decay_ = totalDebt;\\n }\\n }\\n\\n\\n /**\\n * @notice calculate how far into vesting a depositor is\\n * @param _depositor address\\n * @return percentVested_ uint\\n */\\n function percentVestedFor( address _depositor ) public view returns ( uint percentVested_ ) {\\n Bond memory bond = bondInfo[ _depositor ];\\n uint secondsSinceLast = block.timestamp.sub( bond.lastTime );\\n uint vesting = bond.vesting;\\n\\n if ( vesting > 0 ) {\\n percentVested_ = secondsSinceLast.mul( 10000 ).div( vesting );\\n } else {\\n percentVested_ = 0;\\n }\\n }\\n\\n /**\\n * @notice calculate amount of OHM available for claim by depositor\\n * @param _depositor address\\n * @return pendingPayout_ uint\\n */\\n function pendingPayoutFor( address _depositor ) external view returns ( uint pendingPayout_ ) {\\n uint percentVested = percentVestedFor( _depositor );\\n uint payout = bondInfo[ _depositor ].payout;\\n\\n if ( percentVested >= 10000 ) {\\n pendingPayout_ = payout;\\n } else {\\n pendingPayout_ = payout.mul( percentVested ).div( 10000 );\\n }\\n }\\n\\n\\n\\n\\n /* ======= AUXILLIARY ======= */\\n\\n /**\\n * @notice allow anyone to send lost tokens (excluding principle or OHM) to the DAO\\n * @return bool\\n */\\n function recoverLostToken( address _token ) external returns ( bool ) {\\n require( _token != OHM );\\n require( _token != principle );\\n IERC20( _token ).safeTransfer( DAO, IERC20( _token ).balanceOf( address(this) ) );\\n return true;\\n }\\n}\",\"keccak256\":\"0x145d41124d867bc2954e61be6336abc8bbc861b6fb9d5221e6bcb7276e1b4829\",\"license\":\"AGPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x6101406040523480156200001257600080fd5b506040516200466838038062004668833981810160405260a08110156200003857600080fd5b810190808051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a3600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614156200016757600080fd5b8473ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b81525050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415620001d957600080fd5b8373ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b81525050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156200024b57600080fd5b8273ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff1660601b81525050600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415620002bd57600080fd5b8173ffffffffffffffffffffffffffffffffffffffff1660e08173ffffffffffffffffffffffffffffffffffffffff1660601b815250508073ffffffffffffffffffffffffffffffffffffffff166101208173ffffffffffffffffffffffffffffffffffffffff1660601b81525050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561010081151560f81b81525050505050505060805160601c60a05160601c60c05160601c60e05160601c6101005160f81c6101205160601c6142236200044560003980611b5b52806125a652806128b2525080611b2d52806125755280612be852508061235e52806126c152806127c05250806118c25280611edd52806121ad528061225e5250806109a75280611b975280611c705280611f19528061212a5280612171528061229b52806125e2528061276452508061238052806126e5528061270b52806129095280612c855280612e865280612f6d528061310c52506142236000f3fe608060405234801561001057600080fd5b50600436106102115760003560e01c80637927ebf811610125578063cea55f57116100ad578063d7ccfb0b1161007c578063d7ccfb0b1461090f578063e0176de81461092d578063e392a2621461094b578063f5c2ab5b14610969578063fc7b9c181461098757610211565b8063cea55f5714610840578063d4d863ce1461085e578063d5025625146108ae578063d7969060146108ef57610211565b806398fabd3a116100f457806398fabd3a146106dd578063a6c41fec14610711578063b4abccba14610745578063c5332b7c1461079f578063cd1234b3146107d357610211565b80637927ebf8146105f3578063844b5c7c146106355780638dbdbe6d14610653578063904b3ece146106bf57610211565b8063451ee4a1116101a85780635a96ac0a116101775780635a96ac0a146104f957806361d027b3146105035780637153500814610537578063759076e5146105a157806377b81895146105bf57610211565b8063451ee4a1146103ed57806346f68ee9146104295780634cf088d91461046d578063507930ec146104a157610211565b80631a3d0068116101e45780631a3d0068146102e05780631e321a0f1461032e5780631feed31f146103695780632f3f470a146103cd57610211565b8063016a42841461021657806301b88ee81461024a5780630505c8c9146102a2578063089208d8146102d6575b600080fd5b61021e6109a5565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61028c6004803603602081101561026057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506109c9565b6040518082815260200191505060405180910390f35b6102aa610a60565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102de610a89565b005b61032c600480360360808110156102f657600080fd5b81019080803515159060200190929190803590602001909291908035906020019092919080359060200190929190505050610c08565b005b6103676004803603604081101561034457600080fd5b81019080803560ff16906020019092919080359060200190929190505050610de7565b005b6103b76004803603604081101561037f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035151590602001909291905050506110ad565b6040518082815260200191505060405180910390f35b6103d56113c5565b60405180821515815260200191505060405180910390f35b6103f56113d8565b6040518086151581526020018581526020018481526020018381526020018281526020019550505050505060405180910390f35b61046b6004803603602081101561043f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611409565b005b61047561160e565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6104e3600480360360208110156104b757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611634565b6040518082815260200191505060405180910390f35b61050161171a565b005b61050b6118c0565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61059f600480360360e081101561054d57600080fd5b81019080803590602001909291908035906020019092919080359060200190929190803590602001909291908035906020019092919080359060200190929190803590602001909291905050506118e4565b005b6105a9611aa5565b6040518082815260200191505060405180910390f35b6105c7611ac8565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61061f6004803603602081101561060957600080fd5b8101908080359060200190929190505050611aee565b6040518082815260200191505060405180910390f35b61063d611b29565b6040518082815260200191505060405180910390f35b6106a96004803603606081101561066957600080fd5b810190808035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611d3f565b6040518082815260200191505060405180910390f35b6106c7612571565b6040518082815260200191505060405180910390f35b6106e56126bf565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6107196126e3565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6107876004803603602081101561075b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612707565b60405180821515815260200191505060405180910390f35b6107a76128b0565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610815600480360360208110156107e957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506128d4565b6040518085815260200184815260200183815260200182815260200194505050505060405180910390f35b610848612904565b6040518082815260200191505060405180910390f35b6108ac6004803603604081101561087457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035151590602001909291905050506129f9565b005b6108b6612bbc565b60405180878152602001868152602001858152602001848152602001838152602001828152602001965050505050505060405180910390f35b6108f7612be6565b60405180821515815260200191505060405180910390f35b610917612c0a565b6040518082815260200191505060405180910390f35b610935612c71565b6040518082815260200191505060405180910390f35b610953612d45565b6040518082815260200191505060405180910390f35b610971612da1565b6040518082815260200191505060405180910390f35b61098f612da7565b6040518082815260200191505060405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806109d583611634565b90506000600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015490506127108210610a2f57809250610a59565b610a56612710610a488484612dad90919063ffffffff16565b612e3390919063ffffffff16565b92505b5050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b4a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610cc9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b610cf66103e8610ce86019600460000154612dad90919063ffffffff16565b612e3390919063ffffffff16565b831115610d6b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f496e6372656d656e7420746f6f206c617267650000000000000000000000000081525060200191505060405180910390fd5b6040518060a00160405280851515815260200184815260200183815260200182815260200142815250600a60008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020155606082015181600301556080820151816004015590505050505050565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610ea8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60006003811115610eb557fe5b826003811115610ec157fe5b1415610f32576201fa40811015610f23576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806141a06024913960400191505060405180910390fd5b806004600101819055506110a9565b60016003811115610f3f57fe5b826003811115610f4b57fe5b1415610fd8576103e8811115610fc9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f5061796f75742063616e6e6f742062652061626f766520312070657263656e7481525060200191505060405180910390fd5b806004600301819055506110a8565b60026003811115610fe557fe5b826003811115610ff157fe5b141561107d5761271081111561106f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f44414f206665652063616e6e6f7420657863656564207061796f75740000000081525060200191505060405180910390fd5b8060048001819055506110a7565b60038081111561108957fe5b82600381111561109557fe5b14156110a657806004600501819055505b5b5b5b5050565b60006110b7614094565b600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060800160405290816000820154815260200160018201548152602001600282015481526020016003820154815250509050600061113685611634565b9050612710811061121657600f60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008082016000905560018201600090556002820160009055600382016000905550508473ffffffffffffffffffffffffffffffffffffffff167f51c99f515c87b0d95ba97f616edd182e8f161c4932eac17c6fefe9dab58b77b183600001516000604051808381526020018281526020019250505060405180910390a261120d85858460000151612e7d565b925050506113bf565b6000611243612710611235848660000151612dad90919063ffffffff16565b612e3390919063ffffffff16565b905060405180608001604052806112678386600001516132d490919063ffffffff16565b81526020016112996112868660400151426132d490919063ffffffff16565b86602001516132d490919063ffffffff16565b81526020014281526020018460600151815250600f60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082015181600001556020820151816001015560408201518160020155606082015181600301559050508573ffffffffffffffffffffffffffffffffffffffff167f51c99f515c87b0d95ba97f616edd182e8f161c4932eac17c6fefe9dab58b77b182600f60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154604051808381526020018281526020019250505060405180910390a26113b9868683612e7d565b93505050505b92915050565b600360149054906101000a900460ff1681565b600a8060000160009054906101000a900460ff16908060010154908060020154908060030154908060040154905085565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146114ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611550576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806140ee6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a380600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600061163e614094565b600f60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020604051806080016040529081600082015481526020016001820154815260200160028201548152602001600382015481525050905060006116cb8260400151426132d490919063ffffffff16565b9050600082602001519050600081111561170d57611706816116f861271085612dad90919063ffffffff16565b612e3390919063ffffffff16565b9350611712565b600093505b505050919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146117c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806141146022913960400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167faa151555690c956fc3ea32f106bb9f119b5237a061eaa8557cff3e51e3792c8d60405160405180910390a3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146119a5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060046000015414611a20576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f426f6e6473206d75737420626520696e697469616c697a65642066726f6d203081525060200191505060405180910390fd5b6040518060c00160405280888152602001878152602001868152602001858152602001848152602001838152506004600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a08201518160050155905050806010819055504260118190555050505050505050565b6000611ac3611ab2612d45565b6010546132d490919063ffffffff16565b905090565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611b22662386f26fc10000611b14611b0f85611b0a612c0a565b61331e565b6135ff565b612e3390919063ffffffff16565b9050919050565b60007f000000000000000000000000000000000000000000000000000000000000000015611c6657611c5f6064611c517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166332da80a37f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611c0057600080fd5b505afa158015611c14573d6000803e3d6000fd5b505050506040513d6020811015611c2a57600080fd5b8101908080519060200190929190505050611c43612c0a565b612dad90919063ffffffff16565b612e3390919063ffffffff16565b9050611d3c565b611d396064611d2b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015611cd457600080fd5b505afa158015611ce8573d6000803e3d6000fd5b505050506040513d6020811015611cfe57600080fd5b810190808051906020019092919050505060ff16600a0a611d1d612c0a565b612dad90919063ffffffff16565b612e3390919063ffffffff16565b90505b90565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611de3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f496e76616c69642061646472657373000000000000000000000000000000000081525060200191505060405180910390fd5b611deb61363b565b6004600501546010541115611e68576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4d6178206361706163697479207265616368656400000000000000000000000081525060200191505060405180910390fd5b6000611e72611b29565b90506000611e7e613666565b905080851015611ed9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602381526020018061417d6023913960400191505060405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16631eec5a9a7f0000000000000000000000000000000000000000000000000000000000000000896040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060206040518083038186803b158015611f8a57600080fd5b505afa158015611f9e573d6000803e3d6000fd5b505050506040513d6020811015611fb457600080fd5b810190808051906020019092919050505090506000611fd282611aee565b90506298968081101561204d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f426f6e6420746f6f20736d616c6c00000000000000000000000000000000000081525060200191505060405180910390fd5b612055612c71565b8111156120ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f426f6e6420746f6f206c6172676500000000000000000000000000000000000081525060200191505060405180910390fd5b60006120f76127106120e9600480015485612dad90919063ffffffff16565b612e3390919063ffffffff16565b905060006121208261211285876132d490919063ffffffff16565b6132d490919063ffffffff16565b905061216f33308c7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166136eb909392919063ffffffff16565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b37f00000000000000000000000000000000000000000000000000000000000000008c6040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561222057600080fd5b505af1158015612234573d6000803e3d6000fd5b505050506040513d602081101561224a57600080fd5b8101908080519060200190929190505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663bc157ac18b7f0000000000000000000000000000000000000000000000000000000000000000846040518463ffffffff1660e01b8152600401808481526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b15801561231557600080fd5b505af1158015612329573d6000803e3d6000fd5b505050506040513d602081101561233f57600080fd5b810190808051906020019092919050505050600082146123c5576123c47f0000000000000000000000000000000000000000000000000000000000000000837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166137ac9092919063ffffffff16565b5b6123da8460105461384e90919063ffffffff16565b601081905550604051806080016040528061244085600f60008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015461384e90919063ffffffff16565b8152602001600460010154815260200142815260200187815250600f60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030155905050856124dd6004600101544261384e90919063ffffffff16565b847f1fec6dc81f140574bf43f6b1e420ae1dd47928b9d57db8cbd7b8611063b85ae58d6040518082815260200191505060405180910390a461251d612904565b612525613666565b61252d611b29565b7f375b221f40939bfd8f49723a17cf7bc6d576ebf72efe2cc3e991826f5b3f390a60405160405180910390a46125616138d6565b8296505050505050509392505050565b60007f0000000000000000000000000000000000000000000000000000000000000000156126b1576126aa633b9aca0061269c7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166332da80a37f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561264b57600080fd5b505afa15801561265f573d6000803e3d6000fd5b505050506040513d602081101561267557600080fd5b810190808051906020019092919050505061268e612904565b612dad90919063ffffffff16565b612e3390919063ffffffff16565b90506126bc565b6126b9612904565b90505b90565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561276257600080fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156127bb57600080fd5b6128a77f00000000000000000000000000000000000000000000000000000000000000008373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561284657600080fd5b505afa15801561285a573d6000803e3d6000fd5b505050506040513d602081101561287057600080fd5b81019080805190602001909291905050508473ffffffffffffffffffffffffffffffffffffffff166137ac9092919063ffffffff16565b60019050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600f6020528060005260406000206000915090508060000154908060010154908060020154908060030154905084565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561296d57600080fd5b505afa158015612981573d6000803e3d6000fd5b505050506040513d602081101561299757600080fd5b810190808051906020019092919050505090506129f3670de0b6b3a76400006129e56129e06129da633b9aca006129cc611aa5565b612dad90919063ffffffff16565b8561331e565b6135ff565b612e3390919063ffffffff16565b91505090565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612aba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612af457600080fd5b8015612b5b576001600360146101000a81548160ff02191690831515021790555081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550612bb8565b6000600360146101000a81548160ff02191690831515021790555081600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5050565b60048060000154908060010154908060020154908060030154908060040154908060050154905086565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000612c5662989680612c48633b9aca00612c3a612c26612904565b600460000154612dad90919063ffffffff16565b61384e90919063ffffffff16565b612e3390919063ffffffff16565b9050600460020154811015612c6e5760046002015490505b90565b6000612d40620186a0612d326004600301547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612ce957600080fd5b505afa158015612cfd573d6000803e3d6000fd5b505050506040513d6020811015612d1357600080fd5b8101908080519060200190929190505050612dad90919063ffffffff16565b612e3390919063ffffffff16565b905090565b600080612d5d601154426132d490919063ffffffff16565b9050612d8b600460010154612d7d83601054612dad90919063ffffffff16565b612e3390919063ffffffff16565b9150601054821115612d9d5760105491505b5090565b60115481565b60105481565b600080831415612dc05760009050612e2d565b6000828402905082848281612dd157fe5b0414612e28576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061415c6021913960400191505060405180910390fd5b809150505b92915050565b6000612e7583836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613a3c565b905092915050565b600082612f56577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612f1557600080fd5b505af1158015612f29573d6000803e3d6000fd5b505050506040513d6020811015612f3f57600080fd5b8101908080519060200190929190505050506132ca565b600360149054906101000a900460ff161561310a577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561301e57600080fd5b505af1158015613032573d6000803e3d6000fd5b505050506040513d602081101561304857600080fd5b810190808051906020019092919050505050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637acb775783866040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b1580156130ed57600080fd5b505af1158015613101573d6000803e3d6000fd5b505050506132c9565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156131bd57600080fd5b505af11580156131d1573d6000803e3d6000fd5b505050506040513d60208110156131e757600080fd5b810190808051906020019092919050505050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637acb775783866040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b15801561328c57600080fd5b505af11580156132a0573d6000803e3d6000fd5b505050506040513d60208110156132b657600080fd5b8101908080519060200190929190505050505b5b8190509392505050565b600061331683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613b02565b905092915050565b6133266140bc565b6000821161337f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806141366026913960400191505060405180910390fd5b60008314156133bd57604051806020016040528060007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525090506135f9565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff71ffffffffffffffffffffffffffffffffffff1683116134f657600082607060ff1685901b8161340a57fe5b0490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168111156134c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f77000081525060200191505060405180910390fd5b6040518060200160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509150506135f9565b6000613512846e01000000000000000000000000000085613bc2565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168111156135c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f77000081525060200191505060405180910390fd5b6040518060200160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509150505b92915050565b60006612725dd1d243ab82600001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168161363357fe5b049050919050565b613657613646612d45565b6010546132d490919063ffffffff16565b60108190555042601181905550565b60006136b2629896806136a4633b9aca00613696613682612904565b600460000154612dad90919063ffffffff16565b61384e90919063ffffffff16565b612e3390919063ffffffff16565b90506004600201548110156136ce5760046002015490506136e8565b6000600460020154146136e75760006004600201819055505b5b90565b6137a6846323b872dd60e01b858585604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613c84565b50505050565b6138498363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613c84565b505050565b6000808284019050838110156138cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b60006138f5600a60030154600a6004015461384e90919063ffffffff16565b90506000600a600101541415801561390d5750804210155b15613a395760006004600001549050600a60000160009054906101000a900460ff161561397c57613951600a6001015460046000015461384e90919063ffffffff16565b600460000181905550600a6002015460046000015410613977576000600a600101819055505b6139c0565b613999600a600101546004600001546132d490919063ffffffff16565b600460000181905550600a60020154600460000154116139bf576000600a600101819055505b5b42600a600401819055507fb923e581a0f83128e9e1d8297aa52b18d6744310476e0b54509c054cd7a93b2a81600460000154600a60010154600a60000160009054906101000a900460ff1660405180858152602001848152602001838152602001821515815260200194505050505060405180910390a1505b50565b60008083118290613ae8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613aad578082015181840152602081019050613a92565b50505050905090810190601f168015613ada5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581613af457fe5b049050809150509392505050565b6000838311158290613baf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613b74578082015181840152602081019050613b59565b50505050905090810190601f168015613ba15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b6000806000613bd18686613d73565b9150915060008480613bdf57fe5b868809905082811115613bf3576001820391505b8083039250848210613c6d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f46756c6c4d6174683a3a6d756c4469763a206f766572666c6f7700000000000081525060200191505060405180910390fd5b613c78838387613dc6565b93505050509392505050565b6060613ce6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613e639092919063ffffffff16565b9050600081511115613d6e57808060200190516020811015613d0757600080fd5b8101908080519060200190929190505050613d6d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a8152602001806141c4602a913960400191505060405180910390fd5b5b505050565b60008060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80613da057fe5b84860990508385029250828103915082811015613dbe576001820391505b509250929050565b6000808260000383169050808381613dda57fe5b049250808581613de657fe5b0494506001818260000381613df757fe5b04018402850194506000600190508084026002038102905080840260020381029050808402600203810290508084026002038102905080840260020381029050808402600203810290508084026002038102905080840260020381029050808602925050509392505050565b6060613e728484600085613e7b565b90509392505050565b6060613e8685614081565b613ef8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b60208310613f485780518252602082019150602081019050602083039250613f25565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613faa576040519150601f19603f3d011682016040523d82523d6000602084013e613faf565b606091505b50915091508115613fc4578092505050614079565b600081511115613fd75780518082602001fd5b836040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561403e578082015181840152602081019050614023565b50505050905090810190601f16801561406b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b949350505050565b600080823b905060008111915050919050565b6040518060800160405280600081526020016000815260200160008152602001600081525090565b604051806020016040528060007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a206d757374206265206e6577206f776e657220746f2070756c6c4669786564506f696e743a3a6672616374696f6e3a206469766973696f6e206279207a65726f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77536c697070616765206c696d69743a206d6f7265207468616e206d617820707269636556657374696e67206d757374206265206c6f6e676572207468616e20333620686f7572735361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a264697066735822122053be4518e6208ff68edac4e5334629c89de3521dd2fcec0ecc75153a7a8305f764736f6c63430007050033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102115760003560e01c80637927ebf811610125578063cea55f57116100ad578063d7ccfb0b1161007c578063d7ccfb0b1461090f578063e0176de81461092d578063e392a2621461094b578063f5c2ab5b14610969578063fc7b9c181461098757610211565b8063cea55f5714610840578063d4d863ce1461085e578063d5025625146108ae578063d7969060146108ef57610211565b806398fabd3a116100f457806398fabd3a146106dd578063a6c41fec14610711578063b4abccba14610745578063c5332b7c1461079f578063cd1234b3146107d357610211565b80637927ebf8146105f3578063844b5c7c146106355780638dbdbe6d14610653578063904b3ece146106bf57610211565b8063451ee4a1116101a85780635a96ac0a116101775780635a96ac0a146104f957806361d027b3146105035780637153500814610537578063759076e5146105a157806377b81895146105bf57610211565b8063451ee4a1146103ed57806346f68ee9146104295780634cf088d91461046d578063507930ec146104a157610211565b80631a3d0068116101e45780631a3d0068146102e05780631e321a0f1461032e5780631feed31f146103695780632f3f470a146103cd57610211565b8063016a42841461021657806301b88ee81461024a5780630505c8c9146102a2578063089208d8146102d6575b600080fd5b61021e6109a5565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61028c6004803603602081101561026057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506109c9565b6040518082815260200191505060405180910390f35b6102aa610a60565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102de610a89565b005b61032c600480360360808110156102f657600080fd5b81019080803515159060200190929190803590602001909291908035906020019092919080359060200190929190505050610c08565b005b6103676004803603604081101561034457600080fd5b81019080803560ff16906020019092919080359060200190929190505050610de7565b005b6103b76004803603604081101561037f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035151590602001909291905050506110ad565b6040518082815260200191505060405180910390f35b6103d56113c5565b60405180821515815260200191505060405180910390f35b6103f56113d8565b6040518086151581526020018581526020018481526020018381526020018281526020019550505050505060405180910390f35b61046b6004803603602081101561043f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611409565b005b61047561160e565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6104e3600480360360208110156104b757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611634565b6040518082815260200191505060405180910390f35b61050161171a565b005b61050b6118c0565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61059f600480360360e081101561054d57600080fd5b81019080803590602001909291908035906020019092919080359060200190929190803590602001909291908035906020019092919080359060200190929190803590602001909291905050506118e4565b005b6105a9611aa5565b6040518082815260200191505060405180910390f35b6105c7611ac8565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61061f6004803603602081101561060957600080fd5b8101908080359060200190929190505050611aee565b6040518082815260200191505060405180910390f35b61063d611b29565b6040518082815260200191505060405180910390f35b6106a96004803603606081101561066957600080fd5b810190808035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611d3f565b6040518082815260200191505060405180910390f35b6106c7612571565b6040518082815260200191505060405180910390f35b6106e56126bf565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6107196126e3565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6107876004803603602081101561075b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612707565b60405180821515815260200191505060405180910390f35b6107a76128b0565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610815600480360360208110156107e957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506128d4565b6040518085815260200184815260200183815260200182815260200194505050505060405180910390f35b610848612904565b6040518082815260200191505060405180910390f35b6108ac6004803603604081101561087457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035151590602001909291905050506129f9565b005b6108b6612bbc565b60405180878152602001868152602001858152602001848152602001838152602001828152602001965050505050505060405180910390f35b6108f7612be6565b60405180821515815260200191505060405180910390f35b610917612c0a565b6040518082815260200191505060405180910390f35b610935612c71565b6040518082815260200191505060405180910390f35b610953612d45565b6040518082815260200191505060405180910390f35b610971612da1565b6040518082815260200191505060405180910390f35b61098f612da7565b6040518082815260200191505060405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806109d583611634565b90506000600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015490506127108210610a2f57809250610a59565b610a56612710610a488484612dad90919063ffffffff16565b612e3390919063ffffffff16565b92505b5050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b4a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610cc9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b610cf66103e8610ce86019600460000154612dad90919063ffffffff16565b612e3390919063ffffffff16565b831115610d6b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f496e6372656d656e7420746f6f206c617267650000000000000000000000000081525060200191505060405180910390fd5b6040518060a00160405280851515815260200184815260200183815260200182815260200142815250600a60008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020155606082015181600301556080820151816004015590505050505050565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610ea8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60006003811115610eb557fe5b826003811115610ec157fe5b1415610f32576201fa40811015610f23576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806141a06024913960400191505060405180910390fd5b806004600101819055506110a9565b60016003811115610f3f57fe5b826003811115610f4b57fe5b1415610fd8576103e8811115610fc9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f5061796f75742063616e6e6f742062652061626f766520312070657263656e7481525060200191505060405180910390fd5b806004600301819055506110a8565b60026003811115610fe557fe5b826003811115610ff157fe5b141561107d5761271081111561106f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f44414f206665652063616e6e6f7420657863656564207061796f75740000000081525060200191505060405180910390fd5b8060048001819055506110a7565b60038081111561108957fe5b82600381111561109557fe5b14156110a657806004600501819055505b5b5b5b5050565b60006110b7614094565b600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060800160405290816000820154815260200160018201548152602001600282015481526020016003820154815250509050600061113685611634565b9050612710811061121657600f60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008082016000905560018201600090556002820160009055600382016000905550508473ffffffffffffffffffffffffffffffffffffffff167f51c99f515c87b0d95ba97f616edd182e8f161c4932eac17c6fefe9dab58b77b183600001516000604051808381526020018281526020019250505060405180910390a261120d85858460000151612e7d565b925050506113bf565b6000611243612710611235848660000151612dad90919063ffffffff16565b612e3390919063ffffffff16565b905060405180608001604052806112678386600001516132d490919063ffffffff16565b81526020016112996112868660400151426132d490919063ffffffff16565b86602001516132d490919063ffffffff16565b81526020014281526020018460600151815250600f60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082015181600001556020820151816001015560408201518160020155606082015181600301559050508573ffffffffffffffffffffffffffffffffffffffff167f51c99f515c87b0d95ba97f616edd182e8f161c4932eac17c6fefe9dab58b77b182600f60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154604051808381526020018281526020019250505060405180910390a26113b9868683612e7d565b93505050505b92915050565b600360149054906101000a900460ff1681565b600a8060000160009054906101000a900460ff16908060010154908060020154908060030154908060040154905085565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146114ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611550576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806140ee6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a380600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600061163e614094565b600f60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020604051806080016040529081600082015481526020016001820154815260200160028201548152602001600382015481525050905060006116cb8260400151426132d490919063ffffffff16565b9050600082602001519050600081111561170d57611706816116f861271085612dad90919063ffffffff16565b612e3390919063ffffffff16565b9350611712565b600093505b505050919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146117c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806141146022913960400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167faa151555690c956fc3ea32f106bb9f119b5237a061eaa8557cff3e51e3792c8d60405160405180910390a3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146119a5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060046000015414611a20576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f426f6e6473206d75737420626520696e697469616c697a65642066726f6d203081525060200191505060405180910390fd5b6040518060c00160405280888152602001878152602001868152602001858152602001848152602001838152506004600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a08201518160050155905050806010819055504260118190555050505050505050565b6000611ac3611ab2612d45565b6010546132d490919063ffffffff16565b905090565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611b22662386f26fc10000611b14611b0f85611b0a612c0a565b61331e565b6135ff565b612e3390919063ffffffff16565b9050919050565b60007f000000000000000000000000000000000000000000000000000000000000000015611c6657611c5f6064611c517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166332da80a37f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611c0057600080fd5b505afa158015611c14573d6000803e3d6000fd5b505050506040513d6020811015611c2a57600080fd5b8101908080519060200190929190505050611c43612c0a565b612dad90919063ffffffff16565b612e3390919063ffffffff16565b9050611d3c565b611d396064611d2b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015611cd457600080fd5b505afa158015611ce8573d6000803e3d6000fd5b505050506040513d6020811015611cfe57600080fd5b810190808051906020019092919050505060ff16600a0a611d1d612c0a565b612dad90919063ffffffff16565b612e3390919063ffffffff16565b90505b90565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611de3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f496e76616c69642061646472657373000000000000000000000000000000000081525060200191505060405180910390fd5b611deb61363b565b6004600501546010541115611e68576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4d6178206361706163697479207265616368656400000000000000000000000081525060200191505060405180910390fd5b6000611e72611b29565b90506000611e7e613666565b905080851015611ed9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602381526020018061417d6023913960400191505060405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16631eec5a9a7f0000000000000000000000000000000000000000000000000000000000000000896040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060206040518083038186803b158015611f8a57600080fd5b505afa158015611f9e573d6000803e3d6000fd5b505050506040513d6020811015611fb457600080fd5b810190808051906020019092919050505090506000611fd282611aee565b90506298968081101561204d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f426f6e6420746f6f20736d616c6c00000000000000000000000000000000000081525060200191505060405180910390fd5b612055612c71565b8111156120ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f426f6e6420746f6f206c6172676500000000000000000000000000000000000081525060200191505060405180910390fd5b60006120f76127106120e9600480015485612dad90919063ffffffff16565b612e3390919063ffffffff16565b905060006121208261211285876132d490919063ffffffff16565b6132d490919063ffffffff16565b905061216f33308c7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166136eb909392919063ffffffff16565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b37f00000000000000000000000000000000000000000000000000000000000000008c6040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561222057600080fd5b505af1158015612234573d6000803e3d6000fd5b505050506040513d602081101561224a57600080fd5b8101908080519060200190929190505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663bc157ac18b7f0000000000000000000000000000000000000000000000000000000000000000846040518463ffffffff1660e01b8152600401808481526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b15801561231557600080fd5b505af1158015612329573d6000803e3d6000fd5b505050506040513d602081101561233f57600080fd5b810190808051906020019092919050505050600082146123c5576123c47f0000000000000000000000000000000000000000000000000000000000000000837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166137ac9092919063ffffffff16565b5b6123da8460105461384e90919063ffffffff16565b601081905550604051806080016040528061244085600f60008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015461384e90919063ffffffff16565b8152602001600460010154815260200142815260200187815250600f60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030155905050856124dd6004600101544261384e90919063ffffffff16565b847f1fec6dc81f140574bf43f6b1e420ae1dd47928b9d57db8cbd7b8611063b85ae58d6040518082815260200191505060405180910390a461251d612904565b612525613666565b61252d611b29565b7f375b221f40939bfd8f49723a17cf7bc6d576ebf72efe2cc3e991826f5b3f390a60405160405180910390a46125616138d6565b8296505050505050509392505050565b60007f0000000000000000000000000000000000000000000000000000000000000000156126b1576126aa633b9aca0061269c7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166332da80a37f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561264b57600080fd5b505afa15801561265f573d6000803e3d6000fd5b505050506040513d602081101561267557600080fd5b810190808051906020019092919050505061268e612904565b612dad90919063ffffffff16565b612e3390919063ffffffff16565b90506126bc565b6126b9612904565b90505b90565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561276257600080fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156127bb57600080fd5b6128a77f00000000000000000000000000000000000000000000000000000000000000008373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561284657600080fd5b505afa15801561285a573d6000803e3d6000fd5b505050506040513d602081101561287057600080fd5b81019080805190602001909291905050508473ffffffffffffffffffffffffffffffffffffffff166137ac9092919063ffffffff16565b60019050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600f6020528060005260406000206000915090508060000154908060010154908060020154908060030154905084565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561296d57600080fd5b505afa158015612981573d6000803e3d6000fd5b505050506040513d602081101561299757600080fd5b810190808051906020019092919050505090506129f3670de0b6b3a76400006129e56129e06129da633b9aca006129cc611aa5565b612dad90919063ffffffff16565b8561331e565b6135ff565b612e3390919063ffffffff16565b91505090565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612aba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612af457600080fd5b8015612b5b576001600360146101000a81548160ff02191690831515021790555081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550612bb8565b6000600360146101000a81548160ff02191690831515021790555081600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5050565b60048060000154908060010154908060020154908060030154908060040154908060050154905086565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000612c5662989680612c48633b9aca00612c3a612c26612904565b600460000154612dad90919063ffffffff16565b61384e90919063ffffffff16565b612e3390919063ffffffff16565b9050600460020154811015612c6e5760046002015490505b90565b6000612d40620186a0612d326004600301547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612ce957600080fd5b505afa158015612cfd573d6000803e3d6000fd5b505050506040513d6020811015612d1357600080fd5b8101908080519060200190929190505050612dad90919063ffffffff16565b612e3390919063ffffffff16565b905090565b600080612d5d601154426132d490919063ffffffff16565b9050612d8b600460010154612d7d83601054612dad90919063ffffffff16565b612e3390919063ffffffff16565b9150601054821115612d9d5760105491505b5090565b60115481565b60105481565b600080831415612dc05760009050612e2d565b6000828402905082848281612dd157fe5b0414612e28576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061415c6021913960400191505060405180910390fd5b809150505b92915050565b6000612e7583836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613a3c565b905092915050565b600082612f56577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612f1557600080fd5b505af1158015612f29573d6000803e3d6000fd5b505050506040513d6020811015612f3f57600080fd5b8101908080519060200190929190505050506132ca565b600360149054906101000a900460ff161561310a577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561301e57600080fd5b505af1158015613032573d6000803e3d6000fd5b505050506040513d602081101561304857600080fd5b810190808051906020019092919050505050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637acb775783866040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b1580156130ed57600080fd5b505af1158015613101573d6000803e3d6000fd5b505050506132c9565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156131bd57600080fd5b505af11580156131d1573d6000803e3d6000fd5b505050506040513d60208110156131e757600080fd5b810190808051906020019092919050505050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637acb775783866040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b15801561328c57600080fd5b505af11580156132a0573d6000803e3d6000fd5b505050506040513d60208110156132b657600080fd5b8101908080519060200190929190505050505b5b8190509392505050565b600061331683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613b02565b905092915050565b6133266140bc565b6000821161337f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806141366026913960400191505060405180910390fd5b60008314156133bd57604051806020016040528060007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525090506135f9565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff71ffffffffffffffffffffffffffffffffffff1683116134f657600082607060ff1685901b8161340a57fe5b0490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168111156134c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f77000081525060200191505060405180910390fd5b6040518060200160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509150506135f9565b6000613512846e01000000000000000000000000000085613bc2565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168111156135c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f77000081525060200191505060405180910390fd5b6040518060200160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509150505b92915050565b60006612725dd1d243ab82600001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168161363357fe5b049050919050565b613657613646612d45565b6010546132d490919063ffffffff16565b60108190555042601181905550565b60006136b2629896806136a4633b9aca00613696613682612904565b600460000154612dad90919063ffffffff16565b61384e90919063ffffffff16565b612e3390919063ffffffff16565b90506004600201548110156136ce5760046002015490506136e8565b6000600460020154146136e75760006004600201819055505b5b90565b6137a6846323b872dd60e01b858585604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613c84565b50505050565b6138498363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613c84565b505050565b6000808284019050838110156138cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b60006138f5600a60030154600a6004015461384e90919063ffffffff16565b90506000600a600101541415801561390d5750804210155b15613a395760006004600001549050600a60000160009054906101000a900460ff161561397c57613951600a6001015460046000015461384e90919063ffffffff16565b600460000181905550600a6002015460046000015410613977576000600a600101819055505b6139c0565b613999600a600101546004600001546132d490919063ffffffff16565b600460000181905550600a60020154600460000154116139bf576000600a600101819055505b5b42600a600401819055507fb923e581a0f83128e9e1d8297aa52b18d6744310476e0b54509c054cd7a93b2a81600460000154600a60010154600a60000160009054906101000a900460ff1660405180858152602001848152602001838152602001821515815260200194505050505060405180910390a1505b50565b60008083118290613ae8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613aad578082015181840152602081019050613a92565b50505050905090810190601f168015613ada5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581613af457fe5b049050809150509392505050565b6000838311158290613baf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613b74578082015181840152602081019050613b59565b50505050905090810190601f168015613ba15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b6000806000613bd18686613d73565b9150915060008480613bdf57fe5b868809905082811115613bf3576001820391505b8083039250848210613c6d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f46756c6c4d6174683a3a6d756c4469763a206f766572666c6f7700000000000081525060200191505060405180910390fd5b613c78838387613dc6565b93505050509392505050565b6060613ce6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613e639092919063ffffffff16565b9050600081511115613d6e57808060200190516020811015613d0757600080fd5b8101908080519060200190929190505050613d6d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a8152602001806141c4602a913960400191505060405180910390fd5b5b505050565b60008060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80613da057fe5b84860990508385029250828103915082811015613dbe576001820391505b509250929050565b6000808260000383169050808381613dda57fe5b049250808581613de657fe5b0494506001818260000381613df757fe5b04018402850194506000600190508084026002038102905080840260020381029050808402600203810290508084026002038102905080840260020381029050808402600203810290508084026002038102905080840260020381029050808602925050509392505050565b6060613e728484600085613e7b565b90509392505050565b6060613e8685614081565b613ef8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b60208310613f485780518252602082019150602081019050602083039250613f25565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613faa576040519150601f19603f3d011682016040523d82523d6000602084013e613faf565b606091505b50915091508115613fc4578092505050614079565b600081511115613fd75780518082602001fd5b836040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561403e578082015181840152602081019050614023565b50505050905090810190601f16801561406b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b949350505050565b600080823b905060008111915050919050565b6040518060800160405280600081526020016000815260200160008152602001600081525090565b604051806020016040528060007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a206d757374206265206e6577206f776e657220746f2070756c6c4669786564506f696e743a3a6672616374696f6e3a206469766973696f6e206279207a65726f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77536c697070616765206c696d69743a206d6f7265207468616e206d617820707269636556657374696e67206d757374206265206c6f6e676572207468616e20333620686f7572735361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a264697066735822122053be4518e6208ff68edac4e5334629c89de3521dd2fcec0ecc75153a7a8305f764736f6c63430007050033", + "devdoc": { + "kind": "dev", + "methods": { + "bondPrice()": { + "returns": { + "price_": "uint" + } + }, + "bondPriceInUSD()": { + "returns": { + "price_": "uint" + } + }, + "currentDebt()": { + "returns": { + "_0": "uint" + } + }, + "debtDecay()": { + "returns": { + "decay_": "uint" + } + }, + "debtRatio()": { + "returns": { + "debtRatio_": "uint" + } + }, + "deposit(uint256,uint256,address)": { + "params": { + "_amount": "uint", + "_depositor": "address", + "_maxPrice": "uint" + }, + "returns": { + "_0": "uint" + } + }, + "initializeBondTerms(uint256,uint256,uint256,uint256,uint256,uint256,uint256)": { + "params": { + "_controlVariable": "uint", + "_fee": "uint", + "_initialDebt": "uint", + "_maxDebt": "uint", + "_maxPayout": "uint", + "_minimumPrice": "uint", + "_vestingTerm": "uint" + } + }, + "maxPayout()": { + "returns": { + "_0": "uint" + } + }, + "payoutFor(uint256)": { + "params": { + "_value": "uint" + }, + "returns": { + "_0": "uint" + } + }, + "pendingPayoutFor(address)": { + "params": { + "_depositor": "address" + }, + "returns": { + "pendingPayout_": "uint" + } + }, + "percentVestedFor(address)": { + "params": { + "_depositor": "address" + }, + "returns": { + "percentVested_": "uint" + } + }, + "recoverLostToken(address)": { + "returns": { + "_0": "bool" + } + }, + "redeem(address,bool)": { + "params": { + "_recipient": "address", + "_stake": "bool" + }, + "returns": { + "_0": "uint" + } + }, + "setAdjustment(bool,uint256,uint256,uint256)": { + "params": { + "_addition": "bool", + "_buffer": "uint", + "_increment": "uint", + "_target": "uint" + } + }, + "setBondTerms(uint8,uint256)": { + "params": { + "_input": "uint", + "_parameter": "PARAMETER" + } + }, + "setStaking(address,bool)": { + "params": { + "_helper": "bool", + "_staking": "address" + } + }, + "standardizedDebtRatio()": { + "returns": { + "_0": "uint" + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "bondPrice()": { + "notice": "calculate current bond premium" + }, + "bondPriceInUSD()": { + "notice": "converts bond price to DAI value" + }, + "currentDebt()": { + "notice": "calculate debt factoring in decay" + }, + "debtDecay()": { + "notice": "amount to decay total debt by" + }, + "debtRatio()": { + "notice": "calculate current ratio of debt to OHM supply" + }, + "deposit(uint256,uint256,address)": { + "notice": "deposit bond" + }, + "initializeBondTerms(uint256,uint256,uint256,uint256,uint256,uint256,uint256)": { + "notice": "initializes bond parameters" + }, + "maxPayout()": { + "notice": "determine maximum bond size" + }, + "payoutFor(uint256)": { + "notice": "calculate interest due for new bond" + }, + "pendingPayoutFor(address)": { + "notice": "calculate amount of OHM available for claim by depositor" + }, + "percentVestedFor(address)": { + "notice": "calculate how far into vesting a depositor is" + }, + "recoverLostToken(address)": { + "notice": "allow anyone to send lost tokens (excluding principle or OHM) to the DAO" + }, + "redeem(address,bool)": { + "notice": "redeem bond for user" + }, + "setAdjustment(bool,uint256,uint256,uint256)": { + "notice": "set control variable adjustment" + }, + "setBondTerms(uint8,uint256)": { + "notice": "set parameters for new bonds" + }, + "setStaking(address,bool)": { + "notice": "set contract for auto stake" + }, + "standardizedDebtRatio()": { + "notice": "debt ratio in same terms for reserve or liquidity bonds" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 22, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 24, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "_newOwner", + "offset": 0, + "slot": "1", + "type": "t_address" + }, + { + "astId": 2277, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "staking", + "offset": 0, + "slot": "2", + "type": "t_address" + }, + { + "astId": 2279, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "stakingHelper", + "offset": 0, + "slot": "3", + "type": "t_address" + }, + { + "astId": 2281, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "useHelper", + "offset": 20, + "slot": "3", + "type": "t_bool" + }, + { + "astId": 2283, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "terms", + "offset": 0, + "slot": "4", + "type": "t_struct(Terms)2306_storage" + }, + { + "astId": 2285, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "adjustment", + "offset": 0, + "slot": "10", + "type": "t_struct(Adjust)2326_storage" + }, + { + "astId": 2289, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "bondInfo", + "offset": 0, + "slot": "15", + "type": "t_mapping(t_address,t_struct(Bond)2315_storage)" + }, + { + "astId": 2291, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "totalDebt", + "offset": 0, + "slot": "16", + "type": "t_uint256" + }, + { + "astId": 2293, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "lastDecay", + "offset": 0, + "slot": "17", + "type": "t_uint256" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_mapping(t_address,t_struct(Bond)2315_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct OlympusBondDepository.Bond)", + "numberOfBytes": "32", + "value": "t_struct(Bond)2315_storage" + }, + "t_struct(Adjust)2326_storage": { + "encoding": "inplace", + "label": "struct OlympusBondDepository.Adjust", + "members": [ + { + "astId": 2317, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "add", + "offset": 0, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 2319, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "rate", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 2321, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "target", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 2323, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "buffer", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 2325, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "lastTime", + "offset": 0, + "slot": "4", + "type": "t_uint256" + } + ], + "numberOfBytes": "160" + }, + "t_struct(Bond)2315_storage": { + "encoding": "inplace", + "label": "struct OlympusBondDepository.Bond", + "members": [ + { + "astId": 2308, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "payout", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 2310, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "vesting", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 2312, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "lastTime", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 2314, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "pricePaid", + "offset": 0, + "slot": "3", + "type": "t_uint256" + } + ], + "numberOfBytes": "128" + }, + "t_struct(Terms)2306_storage": { + "encoding": "inplace", + "label": "struct OlympusBondDepository.Terms", + "members": [ + { + "astId": 2295, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "controlVariable", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 2297, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "vestingTerm", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 2299, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "minimumPrice", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 2301, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "maxPayout", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 2303, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "fee", + "offset": 0, + "slot": "4", + "type": "t_uint256" + }, + { + "astId": 2305, + "contract": "contracts/BondDepository.sol:OlympusBondDepository", + "label": "maxDebt", + "offset": 0, + "slot": "5", + "type": "t_uint256" + } + ], + "numberOfBytes": "192" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/src/abi/rinkeby/OlympusBondingCalculator.json b/src/abi/rinkeby/OlympusBondingCalculator.json new file mode 100644 index 0000000000..6b050f7ddb --- /dev/null +++ b/src/abi/rinkeby/OlympusBondingCalculator.json @@ -0,0 +1,147 @@ +{ + "address": "0x03E82c27761DaaA69852cF5238Bc2597a14592cd", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_OHM", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "OHM", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pair", + "type": "address" + } + ], + "name": "getKValue", + "outputs": [ + { + "internalType": "uint256", + "name": "k_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pair", + "type": "address" + } + ], + "name": "getTotalValue", + "outputs": [ + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pair", + "type": "address" + } + ], + "name": "markdown", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pair", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount_", + "type": "uint256" + } + ], + "name": "valuation", + "outputs": [ + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xa8249bd66275e90b92233e776dece1994e4b66586af5a93cdfa727a77af7f590", + "receipt": { + "to": null, + "from": "0xA38F4E6718EdCF023a1d032a2193848CB932c8e3", + "contractAddress": "0x03E82c27761DaaA69852cF5238Bc2597a14592cd", + "transactionIndex": 2, + "gasUsed": "1070654", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x9e5b7e02d5ce5b49c62647399da291a78f1401fd4e54a604f1960417dc07945f", + "transactionHash": "0xa8249bd66275e90b92233e776dece1994e4b66586af5a93cdfa727a77af7f590", + "logs": [], + "blockNumber": 9907134, + "cumulativeGasUsed": "1955945", + "status": 1, + "byzantium": true + }, + "args": [ + "0x9bb5E7183e6259183f8E79876eCC0228738C95F6" + ], + "solcInputHash": "8d3774b312edc15e04c44a56a82de7d8", + "metadata": "{\"compiler\":{\"version\":\"0.7.5+commit.eb77ed08\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_OHM\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"OHM\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pair\",\"type\":\"address\"}],\"name\":\"getKValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"k_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pair\",\"type\":\"address\"}],\"name\":\"getTotalValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pair\",\"type\":\"address\"}],\"name\":\"markdown\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pair\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount_\",\"type\":\"uint256\"}],\"name\":\"valuation\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/StandardBondingCalculator.sol\":\"OlympusBondingCalculator\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/StandardBondingCalculator.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-or-later\\npragma solidity 0.7.5;\\n\\nlibrary FullMath {\\n function fullMul(uint256 x, uint256 y) private pure returns (uint256 l, uint256 h) {\\n uint256 mm = mulmod(x, y, uint256(-1));\\n l = x * y;\\n h = mm - l;\\n if (mm < l) h -= 1;\\n }\\n\\n function fullDiv(\\n uint256 l,\\n uint256 h,\\n uint256 d\\n ) private pure returns (uint256) {\\n uint256 pow2 = d & -d;\\n d /= pow2;\\n l /= pow2;\\n l += h * ((-pow2) / pow2 + 1);\\n uint256 r = 1;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n return l * r;\\n }\\n\\n function mulDiv(\\n uint256 x,\\n uint256 y,\\n uint256 d\\n ) internal pure returns (uint256) {\\n (uint256 l, uint256 h) = fullMul(x, y);\\n uint256 mm = mulmod(x, y, d);\\n if (mm > l) h -= 1;\\n l -= mm;\\n require(h < d, 'FullMath::mulDiv: overflow');\\n return fullDiv(l, h, d);\\n }\\n}\\n\\nlibrary Babylonian {\\n\\n function sqrt(uint256 x) internal pure returns (uint256) {\\n if (x == 0) return 0;\\n\\n uint256 xx = x;\\n uint256 r = 1;\\n if (xx >= 0x100000000000000000000000000000000) {\\n xx >>= 128;\\n r <<= 64;\\n }\\n if (xx >= 0x10000000000000000) {\\n xx >>= 64;\\n r <<= 32;\\n }\\n if (xx >= 0x100000000) {\\n xx >>= 32;\\n r <<= 16;\\n }\\n if (xx >= 0x10000) {\\n xx >>= 16;\\n r <<= 8;\\n }\\n if (xx >= 0x100) {\\n xx >>= 8;\\n r <<= 4;\\n }\\n if (xx >= 0x10) {\\n xx >>= 4;\\n r <<= 2;\\n }\\n if (xx >= 0x8) {\\n r <<= 1;\\n }\\n r = (r + x / r) >> 1;\\n r = (r + x / r) >> 1;\\n r = (r + x / r) >> 1;\\n r = (r + x / r) >> 1;\\n r = (r + x / r) >> 1;\\n r = (r + x / r) >> 1;\\n r = (r + x / r) >> 1; // Seven iterations should be enough\\n uint256 r1 = x / r;\\n return (r < r1 ? r : r1);\\n }\\n}\\n\\nlibrary BitMath {\\n\\n function mostSignificantBit(uint256 x) internal pure returns (uint8 r) {\\n require(x > 0, 'BitMath::mostSignificantBit: zero');\\n\\n if (x >= 0x100000000000000000000000000000000) {\\n x >>= 128;\\n r += 128;\\n }\\n if (x >= 0x10000000000000000) {\\n x >>= 64;\\n r += 64;\\n }\\n if (x >= 0x100000000) {\\n x >>= 32;\\n r += 32;\\n }\\n if (x >= 0x10000) {\\n x >>= 16;\\n r += 16;\\n }\\n if (x >= 0x100) {\\n x >>= 8;\\n r += 8;\\n }\\n if (x >= 0x10) {\\n x >>= 4;\\n r += 4;\\n }\\n if (x >= 0x4) {\\n x >>= 2;\\n r += 2;\\n }\\n if (x >= 0x2) r += 1;\\n }\\n}\\n\\nlibrary FixedPoint {\\n // range: [0, 2**112 - 1]\\n // resolution: 1 / 2**112\\n struct uq112x112 {\\n uint224 _x;\\n }\\n\\n // range: [0, 2**144 - 1]\\n // resolution: 1 / 2**112\\n struct uq144x112 {\\n uint256 _x;\\n }\\n\\n uint8 private constant RESOLUTION = 112;\\n uint256 private constant Q112 = 0x10000000000000000000000000000;\\n uint256 private constant Q224 = 0x100000000000000000000000000000000000000000000000000000000;\\n uint256 private constant LOWER_MASK = 0xffffffffffffffffffffffffffff; // decimal of UQ*x112 (lower 112 bits)\\n\\n // decode a UQ112x112 into a uint112 by truncating after the radix point\\n function decode(uq112x112 memory self) internal pure returns (uint112) {\\n return uint112(self._x >> RESOLUTION);\\n }\\n\\n // decode a uq112x112 into a uint with 18 decimals of precision\\n function decode112with18(uq112x112 memory self) internal pure returns (uint) {\\n return uint(self._x) / 5192296858534827;\\n }\\n\\n function fraction(uint256 numerator, uint256 denominator) internal pure returns (uq112x112 memory) {\\n require(denominator > 0, 'FixedPoint::fraction: division by zero');\\n if (numerator == 0) return FixedPoint.uq112x112(0);\\n\\n if (numerator <= uint144(-1)) {\\n uint256 result = (numerator << RESOLUTION) / denominator;\\n require(result <= uint224(-1), 'FixedPoint::fraction: overflow');\\n return uq112x112(uint224(result));\\n } else {\\n uint256 result = FullMath.mulDiv(numerator, Q112, denominator);\\n require(result <= uint224(-1), 'FixedPoint::fraction: overflow');\\n return uq112x112(uint224(result));\\n }\\n }\\n\\n // square root of a UQ112x112\\n // lossy between 0/1 and 40 bits\\n function sqrt(uq112x112 memory self) internal pure returns (uq112x112 memory) {\\n if (self._x <= uint144(-1)) {\\n return uq112x112(uint224(Babylonian.sqrt(uint256(self._x) << 112)));\\n }\\n\\n uint8 safeShiftBits = 255 - BitMath.mostSignificantBit(self._x);\\n safeShiftBits -= safeShiftBits % 2;\\n return uq112x112(uint224(Babylonian.sqrt(uint256(self._x) << safeShiftBits) << ((112 - safeShiftBits) / 2)));\\n }\\n}\\n\\nlibrary SafeMath {\\n\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n function sqrrt(uint256 a) internal pure returns (uint c) {\\n if (a > 3) {\\n c = a;\\n uint b = add( div( a, 2), 1 );\\n while (b < c) {\\n c = b;\\n b = div( add( div( a, b ), b), 2 );\\n }\\n } else if (a != 0) {\\n c = 1;\\n }\\n }\\n}\\n\\ninterface IERC20 {\\n function decimals() external view returns (uint8);\\n}\\n\\ninterface IUniswapV2ERC20 {\\n function totalSupply() external view returns (uint);\\n}\\n\\ninterface IUniswapV2Pair is IUniswapV2ERC20 {\\n function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\\n function token0() external view returns ( address );\\n function token1() external view returns ( address );\\n}\\n\\ninterface IBondingCalculator {\\n function valuation( address pair_, uint amount_ ) external view returns ( uint _value );\\n}\\n\\ncontract OlympusBondingCalculator is IBondingCalculator {\\n\\n using FixedPoint for *;\\n using SafeMath for uint;\\n using SafeMath for uint112;\\n\\n address public immutable OHM;\\n\\n constructor( address _OHM ) {\\n require( _OHM != address(0) );\\n OHM = _OHM;\\n }\\n\\n function getKValue( address _pair ) public view returns( uint k_ ) {\\n uint token0 = IERC20( IUniswapV2Pair( _pair ).token0() ).decimals();\\n uint token1 = IERC20( IUniswapV2Pair( _pair ).token1() ).decimals();\\n uint decimals = token0.add( token1 ).sub( IERC20( _pair ).decimals() );\\n\\n (uint reserve0, uint reserve1, ) = IUniswapV2Pair( _pair ).getReserves();\\n k_ = reserve0.mul(reserve1).div( 10 ** decimals );\\n }\\n\\n function getTotalValue( address _pair ) public view returns ( uint _value ) {\\n _value = getKValue( _pair ).sqrrt().mul(2);\\n }\\n\\n function valuation( address _pair, uint amount_ ) external view override returns ( uint _value ) {\\n uint totalValue = getTotalValue( _pair );\\n uint totalSupply = IUniswapV2Pair( _pair ).totalSupply();\\n\\n _value = totalValue.mul( FixedPoint.fraction( amount_, totalSupply ).decode112with18() ).div( 1e18 );\\n }\\n\\n function markdown( address _pair ) external view returns ( uint ) {\\n ( uint reserve0, uint reserve1, ) = IUniswapV2Pair( _pair ).getReserves();\\n\\n uint reserve;\\n if ( IUniswapV2Pair( _pair ).token0() == OHM ) {\\n reserve = reserve1;\\n } else {\\n reserve = reserve0;\\n }\\n return reserve.mul( 2 * ( 10 ** IERC20( OHM ).decimals() ) ).div( getTotalValue( _pair ) );\\n }\\n}\\n\",\"keccak256\":\"0xee57d2d23076d56a8467c29cb433e7176d18b32d2147551948943a9183f546e3\",\"license\":\"AGPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b506040516113473803806113478339818101604052602081101561003357600080fd5b8101908080519060200190929190505050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561007e57600080fd5b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b815250505060805160601c61126a6100dd600039806102bd52806103ac5280610933525061126a6000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c806332da80a31461005c5780634249719f146100b4578063490084ef14610116578063686375491461016e578063a6c41fec146101c6575b600080fd5b61009e6004803603602081101561007257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506101fa565b6040518082815260200191505060405180910390f35b610100600480360360408110156100ca57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061047b565b6040518082815260200191505060405180910390f35b6101586004803603602081101561012c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610556565b6040518082815260200191505060405180910390f35b6101b06004803603602081101561018457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610904565b6040518082815260200191505060405180910390f35b6101ce610931565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60008060008373ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b15801561024557600080fd5b505afa158015610259573d6000803e3d6000fd5b505050506040513d606081101561026f57600080fd5b81019080805190602001909291908051906020019092919080519060200190929190505050506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561033857600080fd5b505afa15801561034c573d6000803e3d6000fd5b505050506040513d602081101561036257600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff1614156103975781905061039b565b8290505b6104716103a786610904565b6104637f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561041057600080fd5b505afa158015610424573d6000803e3d6000fd5b505050506040513d602081101561043a57600080fd5b810190808051906020019092919050505060ff16600a0a6002028461095590919063ffffffff16565b6109db90919063ffffffff16565b9350505050919050565b60008061048784610904565b905060008473ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156104d157600080fd5b505afa1580156104e5573d6000803e3d6000fd5b505050506040513d60208110156104fb57600080fd5b8101908080519060200190929190505050905061054c670de0b6b3a764000061053e61052f61052a8886610a25565b610d06565b8561095590919063ffffffff16565b6109db90919063ffffffff16565b9250505092915050565b6000808273ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561059f57600080fd5b505afa1580156105b3573d6000803e3d6000fd5b505050506040513d60208110156105c957600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561061f57600080fd5b505afa158015610633573d6000803e3d6000fd5b505050506040513d602081101561064957600080fd5b810190808051906020019092919050505060ff16905060008373ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b1580156106a757600080fd5b505afa1580156106bb573d6000803e3d6000fd5b505050506040513d60208110156106d157600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561072757600080fd5b505afa15801561073b573d6000803e3d6000fd5b505050506040513d602081101561075157600080fd5b810190808051906020019092919050505060ff16905060006108118573ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b1580156107b257600080fd5b505afa1580156107c6573d6000803e3d6000fd5b505050506040513d60208110156107dc57600080fd5b810190808051906020019092919050505060ff166108038486610d4290919063ffffffff16565b610dca90919063ffffffff16565b90506000808673ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b15801561085c57600080fd5b505afa158015610870573d6000803e3d6000fd5b505050506040513d606081101561088657600080fd5b81019080805190602001909291908051906020019092919080519060200190929190505050506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691506108f883600a0a6108ea838561095590919063ffffffff16565b6109db90919063ffffffff16565b95505050505050919050565b600061092a600261091c61091785610556565b610e14565b61095590919063ffffffff16565b9050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60008083141561096857600090506109d5565b600082840290508284828161097957fe5b04146109d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806112146021913960400191505060405180910390fd5b809150505b92915050565b6000610a1d83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250610e84565b905092915050565b610a2d6111bc565b60008211610a86576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806111ee6026913960400191505060405180910390fd5b6000831415610ac457604051806020016040528060007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509050610d00565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff71ffffffffffffffffffffffffffffffffffff168311610bfd57600082607060ff1685901b81610b1157fe5b0490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16811115610bc8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f77000081525060200191505060405180910390fd5b6040518060200160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815250915050610d00565b6000610c19846e01000000000000000000000000000085610f4a565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16811115610ccf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f77000081525060200191505060405180910390fd5b6040518060200160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509150505b92915050565b60006612725dd1d243ab82600001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681610d3a57fe5b049050919050565b600080828401905083811015610dc0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b6000610e0c83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061100c565b905092915050565b60006003821115610e71578190506000610e39610e328460026109db565b6001610d42565b90505b81811015610e6b57809150610e64610e5d610e5785846109db565b83610d42565b60026109db565b9050610e3c565b50610e7f565b60008214610e7e57600190505b5b919050565b60008083118290610f30576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ef5578082015181840152602081019050610eda565b50505050905090810190601f168015610f225780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581610f3c57fe5b049050809150509392505050565b6000806000610f5986866110cc565b9150915060008480610f6757fe5b868809905082811115610f7b576001820391505b8083039250848210610ff5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f46756c6c4d6174683a3a6d756c4469763a206f766572666c6f7700000000000081525060200191505060405180910390fd5b61100083838761111f565b93505050509392505050565b60008383111582906110b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561107e578082015181840152602081019050611063565b50505050905090810190601f1680156110ab5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b60008060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff806110f957fe5b84860990508385029250828103915082811015611117576001820391505b509250929050565b600080826000038316905080838161113357fe5b04925080858161113f57fe5b049450600181826000038161115057fe5b04018402850194506000600190508084026002038102905080840260020381029050808402600203810290508084026002038102905080840260020381029050808402600203810290508084026002038102905080840260020381029050808602925050509392505050565b604051806020016040528060007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509056fe4669786564506f696e743a3a6672616374696f6e3a206469766973696f6e206279207a65726f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a26469706673582212202228171061b7ef5f91e024ba90dd609d3a10226771cfd522a7da5af15e6f36b364736f6c63430007050033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100575760003560e01c806332da80a31461005c5780634249719f146100b4578063490084ef14610116578063686375491461016e578063a6c41fec146101c6575b600080fd5b61009e6004803603602081101561007257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506101fa565b6040518082815260200191505060405180910390f35b610100600480360360408110156100ca57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061047b565b6040518082815260200191505060405180910390f35b6101586004803603602081101561012c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610556565b6040518082815260200191505060405180910390f35b6101b06004803603602081101561018457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610904565b6040518082815260200191505060405180910390f35b6101ce610931565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60008060008373ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b15801561024557600080fd5b505afa158015610259573d6000803e3d6000fd5b505050506040513d606081101561026f57600080fd5b81019080805190602001909291908051906020019092919080519060200190929190505050506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561033857600080fd5b505afa15801561034c573d6000803e3d6000fd5b505050506040513d602081101561036257600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff1614156103975781905061039b565b8290505b6104716103a786610904565b6104637f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561041057600080fd5b505afa158015610424573d6000803e3d6000fd5b505050506040513d602081101561043a57600080fd5b810190808051906020019092919050505060ff16600a0a6002028461095590919063ffffffff16565b6109db90919063ffffffff16565b9350505050919050565b60008061048784610904565b905060008473ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156104d157600080fd5b505afa1580156104e5573d6000803e3d6000fd5b505050506040513d60208110156104fb57600080fd5b8101908080519060200190929190505050905061054c670de0b6b3a764000061053e61052f61052a8886610a25565b610d06565b8561095590919063ffffffff16565b6109db90919063ffffffff16565b9250505092915050565b6000808273ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561059f57600080fd5b505afa1580156105b3573d6000803e3d6000fd5b505050506040513d60208110156105c957600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561061f57600080fd5b505afa158015610633573d6000803e3d6000fd5b505050506040513d602081101561064957600080fd5b810190808051906020019092919050505060ff16905060008373ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b1580156106a757600080fd5b505afa1580156106bb573d6000803e3d6000fd5b505050506040513d60208110156106d157600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561072757600080fd5b505afa15801561073b573d6000803e3d6000fd5b505050506040513d602081101561075157600080fd5b810190808051906020019092919050505060ff16905060006108118573ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b1580156107b257600080fd5b505afa1580156107c6573d6000803e3d6000fd5b505050506040513d60208110156107dc57600080fd5b810190808051906020019092919050505060ff166108038486610d4290919063ffffffff16565b610dca90919063ffffffff16565b90506000808673ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b15801561085c57600080fd5b505afa158015610870573d6000803e3d6000fd5b505050506040513d606081101561088657600080fd5b81019080805190602001909291908051906020019092919080519060200190929190505050506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691506108f883600a0a6108ea838561095590919063ffffffff16565b6109db90919063ffffffff16565b95505050505050919050565b600061092a600261091c61091785610556565b610e14565b61095590919063ffffffff16565b9050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60008083141561096857600090506109d5565b600082840290508284828161097957fe5b04146109d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806112146021913960400191505060405180910390fd5b809150505b92915050565b6000610a1d83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250610e84565b905092915050565b610a2d6111bc565b60008211610a86576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806111ee6026913960400191505060405180910390fd5b6000831415610ac457604051806020016040528060007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509050610d00565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff71ffffffffffffffffffffffffffffffffffff168311610bfd57600082607060ff1685901b81610b1157fe5b0490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16811115610bc8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f77000081525060200191505060405180910390fd5b6040518060200160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815250915050610d00565b6000610c19846e01000000000000000000000000000085610f4a565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16811115610ccf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f77000081525060200191505060405180910390fd5b6040518060200160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509150505b92915050565b60006612725dd1d243ab82600001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681610d3a57fe5b049050919050565b600080828401905083811015610dc0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b6000610e0c83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061100c565b905092915050565b60006003821115610e71578190506000610e39610e328460026109db565b6001610d42565b90505b81811015610e6b57809150610e64610e5d610e5785846109db565b83610d42565b60026109db565b9050610e3c565b50610e7f565b60008214610e7e57600190505b5b919050565b60008083118290610f30576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ef5578082015181840152602081019050610eda565b50505050905090810190601f168015610f225780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581610f3c57fe5b049050809150509392505050565b6000806000610f5986866110cc565b9150915060008480610f6757fe5b868809905082811115610f7b576001820391505b8083039250848210610ff5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f46756c6c4d6174683a3a6d756c4469763a206f766572666c6f7700000000000081525060200191505060405180910390fd5b61100083838761111f565b93505050509392505050565b60008383111582906110b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561107e578082015181840152602081019050611063565b50505050905090810190601f1680156110ab5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b60008060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff806110f957fe5b84860990508385029250828103915082811015611117576001820391505b509250929050565b600080826000038316905080838161113357fe5b04925080858161113f57fe5b049450600181826000038161115057fe5b04018402850194506000600190508084026002038102905080840260020381029050808402600203810290508084026002038102905080840260020381029050808402600203810290508084026002038102905080840260020381029050808602925050509392505050565b604051806020016040528060007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509056fe4669786564506f696e743a3a6672616374696f6e3a206469766973696f6e206279207a65726f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a26469706673582212202228171061b7ef5f91e024ba90dd609d3a10226771cfd522a7da5af15e6f36b364736f6c63430007050033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/src/abi/rinkeby/OlympusERC20Token.json b/src/abi/rinkeby/OlympusERC20Token.json new file mode 100644 index 0000000000..d4b5218129 --- /dev/null +++ b/src/abi/rinkeby/OlympusERC20Token.json @@ -0,0 +1,745 @@ +{ + "address": "0x9bb5E7183e6259183f8E79876eCC0228738C95F6", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount_", + "type": "uint256" + } + ], + "name": "_burnFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount_", + "type": "uint256" + } + ], + "name": "burnFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount_", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vault_", + "type": "address" + } + ], + "name": "setVault", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner_", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "vault", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x83cdb178b286b62059eff21af7d8a23679680b24a6f0b2543c7f14a58f6eb400", + "receipt": { + "to": null, + "from": "0xA38F4E6718EdCF023a1d032a2193848CB932c8e3", + "contractAddress": "0x9bb5E7183e6259183f8E79876eCC0228738C95F6", + "transactionIndex": 3, + "gasUsed": "2126958", + "logsBloom": "0x00000000000010000000000000000000000000000000000000800000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000020002000000000000000000000000000000000000000000000000000020000000000", + "blockHash": "0xc863a0c635269a5d7ba5a1704d5d7952d42cc8ab0d3e0c784b3aa4dd4cd3fa09", + "transactionHash": "0x83cdb178b286b62059eff21af7d8a23679680b24a6f0b2543c7f14a58f6eb400", + "logs": [ + { + "transactionIndex": 3, + "blockNumber": 9907128, + "transactionHash": "0x83cdb178b286b62059eff21af7d8a23679680b24a6f0b2543c7f14a58f6eb400", + "address": "0x9bb5E7183e6259183f8E79876eCC0228738C95F6", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000a38f4e6718edcf023a1d032a2193848cb932c8e3" + ], + "data": "0x", + "logIndex": 2, + "blockHash": "0xc863a0c635269a5d7ba5a1704d5d7952d42cc8ab0d3e0c784b3aa4dd4cd3fa09" + } + ], + "blockNumber": 9907128, + "cumulativeGasUsed": "2226446", + "status": 1, + "byzantium": true + }, + "args": [ + "Brick", + "BRICK" + ], + "solcInputHash": "fb3b81c61761bcfb33ca99488ac60a1b", + "metadata": "{\"compiler\":{\"version\":\"0.7.5+commit.eb77ed08\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PERMIT_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount_\",\"type\":\"uint256\"}],\"name\":\"_burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount_\",\"type\":\"uint256\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount_\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vault_\",\"type\":\"address\"}],\"name\":\"setVault\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner_\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"vault\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"Returns the remaining number of tokens that `spender` will be allowed to spend on behalf of `owner` through {transferFrom}. This is zero by default. This value changes when {approve} or {transferFrom} are called.\"},\"approve(address,uint256)\":{\"details\":\"Sets `amount` as the allowance of `spender` over the caller's tokens. Returns a boolean value indicating whether the operation succeeded. IMPORTANT: Beware that changing an allowance with this method brings the risk that someone may use both the old and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 Emits an {Approval} event.\"},\"balanceOf(address)\":{\"details\":\"Returns the amount of tokens owned by `account`.\"},\"totalSupply()\":{\"details\":\"Returns the amount of tokens in existence.\"},\"transfer(address,uint256)\":{\"details\":\"Moves `amount` tokens from the caller's account to `recipient`. Returns a boolean value indicating whether the operation succeeded. Emits a {Transfer} event.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"Moves `amount` tokens from `sender` to `recipient` using the allowance mechanism. `amount` is then deducted from the caller's allowance. Returns a boolean value indicating whether the operation succeeded. Emits a {Transfer} event.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/OlympusERC20.sol\":\"OlympusERC20Token\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/OlympusERC20.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-or-later\\npragma solidity 0.7.5;\\n\\nlibrary EnumerableSet {\\n\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping (bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) { // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\n\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n require(set._values.length > index, \\\"EnumerableSet: index out of bounds\\\");\\n return set._values[index];\\n }\\n\\n function _getValues( Set storage set_ ) private view returns ( bytes32[] storage ) {\\n return set_._values;\\n }\\n\\n // TODO needs insert function that maintains order.\\n // TODO needs NatSpec documentation comment.\\n /**\\n * Inserts new value by moving existing value at provided index to end of array and setting provided value at provided index\\n */\\n function _insert(Set storage set_, uint256 index_, bytes32 valueToInsert_ ) private returns ( bool ) {\\n require( set_._values.length > index_ );\\n require( !_contains( set_, valueToInsert_ ), \\\"Remove value you wish to insert if you wish to reorder array.\\\" );\\n bytes32 existingValue_ = _at( set_, index_ );\\n set_._values[index_] = valueToInsert_;\\n return _add( set_, existingValue_);\\n }\\n\\n struct Bytes4Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes4Set storage set, bytes4 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes4Set storage set, bytes4 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes4Set storage set, bytes4 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(Bytes4Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes4Set storage set, uint256 index) internal view returns ( bytes4 ) {\\n return bytes4( _at( set._inner, index ) );\\n }\\n\\n function getValues( Bytes4Set storage set_ ) internal view returns ( bytes4[] memory ) {\\n bytes4[] memory bytes4Array_;\\n for( uint256 iteration_ = 0; _length( set_._inner ) > iteration_; iteration_++ ) {\\n bytes4Array_[iteration_] = bytes4( _at( set_._inner, iteration_ ) );\\n }\\n return bytes4Array_;\\n }\\n\\n function insert( Bytes4Set storage set_, uint256 index_, bytes4 valueToInsert_ ) internal returns ( bool ) {\\n return _insert( set_._inner, index_, valueToInsert_ );\\n }\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns ( bytes32 ) {\\n return _at(set._inner, index);\\n }\\n\\n function getValues( Bytes32Set storage set_ ) internal view returns ( bytes4[] memory ) {\\n bytes4[] memory bytes4Array_;\\n\\n for( uint256 iteration_ = 0; _length( set_._inner ) >= iteration_; iteration_++ ){\\n bytes4Array_[iteration_] = bytes4( at( set_, iteration_ ) );\\n }\\n\\n return bytes4Array_;\\n }\\n\\n function insert( Bytes32Set storage set_, uint256 index_, bytes32 valueToInsert_ ) internal returns ( bool ) {\\n return _insert( set_._inner, index_, valueToInsert_ );\\n }\\n\\n // AddressSet\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(value)));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(value)));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(value)));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint256(_at(set._inner, index)));\\n }\\n\\n /**\\n * TODO Might require explicit conversion of bytes32[] to address[].\\n * Might require iteration.\\n */\\n function getValues( AddressSet storage set_ ) internal view returns ( address[] memory ) {\\n\\n address[] memory addressArray;\\n\\n for( uint256 iteration_ = 0; _length(set_._inner) >= iteration_; iteration_++ ){\\n addressArray[iteration_] = at( set_, iteration_ );\\n }\\n\\n return addressArray;\\n }\\n\\n function insert(AddressSet storage set_, uint256 index_, address valueToInsert_ ) internal returns ( bool ) {\\n return _insert( set_._inner, index_, bytes32(uint256(valueToInsert_)) );\\n }\\n\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n struct UInt256Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UInt256Set storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UInt256Set storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UInt256Set storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UInt256Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UInt256Set storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n}\\n\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\\nlibrary SafeMath {\\n\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n\\n function sqrrt(uint256 a) internal pure returns (uint c) {\\n if (a > 3) {\\n c = a;\\n uint b = add( div( a, 2), 1 );\\n while (b < c) {\\n c = b;\\n b = div( add( div( a, b ), b), 2 );\\n }\\n } else if (a != 0) {\\n c = 1;\\n }\\n }\\n\\n function percentageAmount( uint256 total_, uint8 percentage_ ) internal pure returns ( uint256 percentAmount_ ) {\\n return div( mul( total_, percentage_ ), 1000 );\\n }\\n\\n function substractPercentage( uint256 total_, uint8 percentageToSub_ ) internal pure returns ( uint256 result_ ) {\\n return sub( total_, div( mul( total_, percentageToSub_ ), 1000 ) );\\n }\\n\\n function percentageOfTotal( uint256 part_, uint256 total_ ) internal pure returns ( uint256 percent_ ) {\\n return div( mul(part_, 100) , total_ );\\n }\\n\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow, so we distribute\\n return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);\\n }\\n\\n function quadraticPricing( uint256 payment_, uint256 multiplier_ ) internal pure returns (uint256) {\\n return sqrrt( mul( multiplier_, payment_ ) );\\n }\\n\\n function bondingCurve( uint256 supply_, uint256 multiplier_ ) internal pure returns (uint256) {\\n return mul( multiplier_, supply_ );\\n }\\n}\\n\\nabstract contract ERC20 is IERC20 {\\n\\n using SafeMath for uint256;\\n\\n // TODO comment actual hash value.\\n bytes32 constant private ERC20TOKEN_ERC1820_INTERFACE_ID = keccak256( \\\"ERC20Token\\\" );\\n\\n // Present in ERC777\\n mapping (address => uint256) internal _balances;\\n\\n // Present in ERC777\\n mapping (address => mapping (address => uint256)) internal _allowances;\\n\\n // Present in ERC777\\n uint256 internal _totalSupply;\\n\\n // Present in ERC777\\n string internal _name;\\n\\n // Present in ERC777\\n string internal _symbol;\\n\\n // Present in ERC777\\n uint8 internal _decimals;\\n\\n constructor (string memory name_, string memory symbol_, uint8 decimals_) {\\n _name = name_;\\n _symbol = symbol_;\\n _decimals = decimals_;\\n }\\n\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n function symbol() public view returns (string memory) {\\n return _symbol;\\n }\\n\\n function decimals() public view returns (uint8) {\\n return _decimals;\\n }\\n\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(msg.sender, recipient, amount);\\n return true;\\n }\\n\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(msg.sender, spender, amount);\\n return true;\\n }\\n\\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\n return true;\\n }\\n\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\\n return true;\\n }\\n\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(sender, recipient, amount);\\n }\\n\\n function _mint(address account_, uint256 amount_) internal virtual {\\n require(account_ != address(0), \\\"ERC20: mint to the zero address\\\");\\n _beforeTokenTransfer(address( this ), account_, amount_);\\n _totalSupply = _totalSupply.add(amount_);\\n _balances[account_] = _balances[account_].add(amount_);\\n emit Transfer(address( this ), account_, amount_);\\n }\\n\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(account, address(0), amount);\\n }\\n\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n function _beforeTokenTransfer( address from_, address to_, uint256 amount_ ) internal virtual { }\\n}\\n\\nlibrary Counters {\\n using SafeMath for uint256;\\n\\n struct Counter {\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n counter._value += 1;\\n }\\n\\n function decrement(Counter storage counter) internal {\\n counter._value = counter._value.sub(1);\\n }\\n}\\n\\ninterface IERC2612Permit {\\n\\n function permit(\\n address owner,\\n address spender,\\n uint256 amount,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n function nonces(address owner) external view returns (uint256);\\n}\\n\\nabstract contract ERC20Permit is ERC20, IERC2612Permit {\\n using Counters for Counters.Counter;\\n\\n mapping(address => Counters.Counter) private _nonces;\\n\\n // keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\\n\\n bytes32 public DOMAIN_SEPARATOR;\\n\\n constructor() {\\n uint256 chainID;\\n assembly {\\n chainID := chainid()\\n }\\n\\n DOMAIN_SEPARATOR = keccak256(\\n abi.encode(\\n keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"),\\n keccak256(bytes(name())),\\n keccak256(bytes(\\\"1\\\")), // Version\\n chainID,\\n address(this)\\n )\\n );\\n }\\n\\n function permit(\\n address owner,\\n address spender,\\n uint256 amount,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"Permit: expired deadline\\\");\\n\\n bytes32 hashStruct =\\n keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, amount, _nonces[owner].current(), deadline));\\n\\n bytes32 _hash = keccak256(abi.encodePacked(uint16(0x1901), DOMAIN_SEPARATOR, hashStruct));\\n\\n address signer = ecrecover(_hash, v, r, s);\\n require(signer != address(0) && signer == owner, \\\"ZeroSwapPermit: Invalid signature\\\");\\n\\n _nonces[owner].increment();\\n _approve(owner, spender, amount);\\n }\\n\\n function nonces(address owner) public view override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n}\\n\\ninterface IOwnable {\\n function owner() external view returns (address);\\n\\n function renounceOwnership() external;\\n\\n function transferOwnership( address newOwner_ ) external;\\n}\\n\\ncontract Ownable is IOwnable {\\n\\n address internal _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n constructor () {\\n _owner = msg.sender;\\n emit OwnershipTransferred( address(0), _owner );\\n }\\n\\n function owner() public view override returns (address) {\\n return _owner;\\n }\\n\\n modifier onlyOwner() {\\n require( _owner == msg.sender, \\\"Ownable: caller is not the owner\\\" );\\n _;\\n }\\n\\n function renounceOwnership() public virtual override onlyOwner() {\\n emit OwnershipTransferred( _owner, address(0) );\\n _owner = address(0);\\n }\\n\\n function transferOwnership( address newOwner_ ) public virtual override onlyOwner() {\\n require( newOwner_ != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipTransferred( _owner, newOwner_ );\\n _owner = newOwner_;\\n }\\n}\\n\\ncontract VaultOwned is Ownable {\\n\\n address internal _vault;\\n\\n function setVault( address vault_ ) external onlyOwner() returns ( bool ) {\\n _vault = vault_;\\n\\n return true;\\n }\\n\\n function vault() public view returns (address) {\\n return _vault;\\n }\\n\\n modifier onlyVault() {\\n require( _vault == msg.sender, \\\"VaultOwned: caller is not the Vault\\\" );\\n _;\\n }\\n\\n}\\n\\ncontract OlympusERC20Token is ERC20Permit, VaultOwned {\\n\\n using SafeMath for uint256;\\n\\n constructor(string memory _name, string memory _symbol) ERC20(_name, _symbol, 9) {\\n }\\n\\n function mint(address account_, uint256 amount_) external onlyVault() {\\n _mint(account_, amount_);\\n }\\n\\n function burn(uint256 amount) public virtual {\\n _burn(msg.sender, amount);\\n }\\n\\n function burnFrom(address account_, uint256 amount_) public virtual {\\n _burnFrom(account_, amount_);\\n }\\n\\n function _burnFrom(address account_, uint256 amount_) public virtual {\\n uint256 decreasedAllowance_ =\\n allowance(account_, msg.sender).sub(\\n amount_,\\n \\\"ERC20: burn amount exceeds allowance\\\"\\n );\\n\\n _approve(account_, msg.sender, decreasedAllowance_);\\n _burn(account_, amount_);\\n }\\n}\",\"keccak256\":\"0x0c5e01e7aa50a1ba8f00b8d7ed5e6ae2594dc05fa0d9cbfad80abfbdb7657a79\",\"license\":\"AGPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b506040516200283d3803806200283d833981810160405260408110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b838201915060208201858111156200006f57600080fd5b82518660018202830111640100000000821117156200008d57600080fd5b8083526020830192505050908051906020019080838360005b83811015620000c3578082015181840152602081019050620000a6565b50505050905090810190601f168015620000f15780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200011557600080fd5b838201915060208201858111156200012c57600080fd5b82518660018202830111640100000000821117156200014a57600080fd5b8083526020830192505050908051906020019080838360005b838110156200018057808201518184015260208101905062000163565b50505050905090810190601f168015620001ae5780820380516001836020036101000a031916815260200191505b50604052505050818160098260039080519060200190620001d192919062000450565b508160049080519060200190620001ea92919062000450565b5080600560006101000a81548160ff021916908360ff16021790555050505060004690507f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6200023f620003aa60201b60201c565b805190602001206040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250805190602001208330604051602001808681526020018581526020018481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200195505050505050604051602081830303815290604052805190602001206007819055505033600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3505062000506565b606060038054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620004465780601f106200041a5761010080835404028352916020019162000446565b820191906000526020600020905b8154815290600101906020018083116200042857829003601f168201915b5050505050905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620004885760008555620004d4565b82601f10620004a357805160ff1916838001178555620004d4565b82800160010185558215620004d4579182015b82811115620004d3578251825591602001919060010190620004b6565b5b509050620004e39190620004e7565b5090565b5b8082111562000502576000816000905550600101620004e8565b5090565b61232780620005166000396000f3fe608060405234801561001057600080fd5b50600436106101585760003560e01c8063715018a6116100c3578063a457c2d71161007c578063a457c2d71461068a578063a9059cbb146106ee578063d505accf14610752578063dd62ed3e146107eb578063f2fde38b14610863578063fbfa77cf146108a757610158565b8063715018a6146104d557806379cc6790146104df5780637ecebe001461052d5780638da5cb5b1461058557806395d89b41146105b9578063a22b35ce1461063c57610158565b80633644e515116101155780633644e51514610325578063395093511461034357806340c10f19146103a757806342966c68146103f55780636817031b1461042357806370a082311461047d57610158565b806306fdde031461015d578063095ea7b3146101e057806318160ddd1461024457806323b872dd1461026257806330adf81f146102e6578063313ce56714610304575b600080fd5b6101656108db565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101a557808201518184015260208101905061018a565b50505050905090810190601f1680156101d25780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61022c600480360360408110156101f657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061097d565b60405180821515815260200191505060405180910390f35b61024c610994565b6040518082815260200191505060405180910390f35b6102ce6004803603606081101561027857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061099e565b60405180821515815260200191505060405180910390f35b6102ee610a69565b6040518082815260200191505060405180910390f35b61030c610a90565b604051808260ff16815260200191505060405180910390f35b61032d610aa7565b6040518082815260200191505060405180910390f35b61038f6004803603604081101561035957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610aad565b60405180821515815260200191505060405180910390f35b6103f3600480360360408110156103bd57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610b52565b005b6104216004803603602081101561040b57600080fd5b8101908080359060200190929190505050610c06565b005b6104656004803603602081101561043957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c13565b60405180821515815260200191505060405180910390f35b6104bf6004803603602081101561049357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610d22565b6040518082815260200191505060405180910390f35b6104dd610d6a565b005b61052b600480360360408110156104f557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610eee565b005b61056f6004803603602081101561054357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610efc565b6040518082815260200191505060405180910390f35b61058d610f4c565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6105c1610f76565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156106015780820151818401526020810190506105e6565b50505050905090810190601f16801561062e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6106886004803603604081101561065257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611018565b005b6106d6600480360360408110156106a057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061106c565b60405180821515815260200191505060405180910390f35b61073a6004803603604081101561070457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061112b565b60405180821515815260200191505060405180910390f35b6107e9600480360360e081101561076857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190803560ff1690602001909291908035906020019092919080359060200190929190505050611142565b005b61084d6004803603604081101561080157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611469565b6040518082815260200191505060405180910390f35b6108a56004803603602081101561087957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506114f0565b005b6108af6116f9565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b606060038054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156109735780601f1061094857610100808354040283529160200191610973565b820191906000526020600020905b81548152906001019060200180831161095657829003601f168201915b5050505050905090565b600061098a338484611723565b6001905092915050565b6000600254905090565b60006109ab84848461191a565b610a5e8433610a59856040518060600160405280602881526020016121f460289139600160008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611bdb9092919063ffffffff16565b611723565b600190509392505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c960001b81565b6000600560009054906101000a900460ff16905090565b60075481565b6000610b483384610b4385600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611c9b90919063ffffffff16565b611723565b6001905092915050565b3373ffffffffffffffffffffffffffffffffffffffff16600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610bf8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602381526020018061221c6023913960400191505060405180910390fd5b610c028282611d23565b5050565b610c103382611ee8565b50565b60003373ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610cd8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b81600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060019050919050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b3373ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610e2d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b610ef88282611018565b5050565b6000610f45600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206120ac565b9050919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060048054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561100e5780601f10610fe35761010080835404028352916020019161100e565b820191906000526020600020905b815481529060010190602001808311610ff157829003601f168201915b5050505050905090565b60006110508260405180606001604052806024815260200161223f602491396110418633611469565b611bdb9092919063ffffffff16565b905061105d833383611723565b6110678383611ee8565b505050565b6000611121338461111c856040518060600160405280602581526020016122cd60259139600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611bdb9092919063ffffffff16565b611723565b6001905092915050565b600061113833848461191a565b6001905092915050565b834211156111b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f5065726d69743a206578706972656420646561646c696e65000000000000000081525060200191505060405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c960001b888888611228600660008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206120ac565b89604051602001808781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018381526020018281526020019650505050505050604051602081830303815290604052805190602001209050600061190160075483604051602001808461ffff1660f01b81526002018381526020018281526020019350505050604051602081830303815290604052805190602001209050600060018287878760405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015611342573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156113b657508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b61140b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806121d36021913960400191505060405180910390fd5b611452600660008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206120ba565b61145d8a8a8a611723565b50505050505050505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b3373ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146115b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611639576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806121656026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156117a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806122a96024913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561182f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061218b6022913960400191505060405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156119a0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806122846025913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611a26576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806121206023913960400191505060405180910390fd5b611a318383836120d0565b611a9c816040518060600160405280602681526020016121ad602691396000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611bdb9092919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611b2f816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611c9b90919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b6000838311158290611c88576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611c4d578082015181840152602081019050611c32565b50505050905090810190601f168015611c7a5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b600080828401905083811015611d19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611dc6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b611dd13083836120d0565b611de681600254611c9b90919063ffffffff16565b600281905550611e3d816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611c9b90919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611f6e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806122636021913960400191505060405180910390fd5b611f7a826000836120d0565b611fe581604051806060016040528060228152602001612143602291396000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611bdb9092919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061203c816002546120d590919063ffffffff16565b600281905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b600081600001549050919050565b6001816000016000828254019250508190555050565b505050565b600061211783836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611bdb565b90509291505056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e63654f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e63655a65726f537761705065726d69743a20496e76616c6964207369676e617475726545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63655661756c744f776e65643a2063616c6c6572206973206e6f7420746865205661756c7445524332303a206275726e20616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa264697066735822122033003866df3e33462190d328d71431dc18588996e0812e69e584d7fdc25dcebf64736f6c63430007050033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101585760003560e01c8063715018a6116100c3578063a457c2d71161007c578063a457c2d71461068a578063a9059cbb146106ee578063d505accf14610752578063dd62ed3e146107eb578063f2fde38b14610863578063fbfa77cf146108a757610158565b8063715018a6146104d557806379cc6790146104df5780637ecebe001461052d5780638da5cb5b1461058557806395d89b41146105b9578063a22b35ce1461063c57610158565b80633644e515116101155780633644e51514610325578063395093511461034357806340c10f19146103a757806342966c68146103f55780636817031b1461042357806370a082311461047d57610158565b806306fdde031461015d578063095ea7b3146101e057806318160ddd1461024457806323b872dd1461026257806330adf81f146102e6578063313ce56714610304575b600080fd5b6101656108db565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101a557808201518184015260208101905061018a565b50505050905090810190601f1680156101d25780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61022c600480360360408110156101f657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061097d565b60405180821515815260200191505060405180910390f35b61024c610994565b6040518082815260200191505060405180910390f35b6102ce6004803603606081101561027857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061099e565b60405180821515815260200191505060405180910390f35b6102ee610a69565b6040518082815260200191505060405180910390f35b61030c610a90565b604051808260ff16815260200191505060405180910390f35b61032d610aa7565b6040518082815260200191505060405180910390f35b61038f6004803603604081101561035957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610aad565b60405180821515815260200191505060405180910390f35b6103f3600480360360408110156103bd57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610b52565b005b6104216004803603602081101561040b57600080fd5b8101908080359060200190929190505050610c06565b005b6104656004803603602081101561043957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c13565b60405180821515815260200191505060405180910390f35b6104bf6004803603602081101561049357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610d22565b6040518082815260200191505060405180910390f35b6104dd610d6a565b005b61052b600480360360408110156104f557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610eee565b005b61056f6004803603602081101561054357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610efc565b6040518082815260200191505060405180910390f35b61058d610f4c565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6105c1610f76565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156106015780820151818401526020810190506105e6565b50505050905090810190601f16801561062e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6106886004803603604081101561065257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611018565b005b6106d6600480360360408110156106a057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061106c565b60405180821515815260200191505060405180910390f35b61073a6004803603604081101561070457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061112b565b60405180821515815260200191505060405180910390f35b6107e9600480360360e081101561076857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190803560ff1690602001909291908035906020019092919080359060200190929190505050611142565b005b61084d6004803603604081101561080157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611469565b6040518082815260200191505060405180910390f35b6108a56004803603602081101561087957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506114f0565b005b6108af6116f9565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b606060038054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156109735780601f1061094857610100808354040283529160200191610973565b820191906000526020600020905b81548152906001019060200180831161095657829003601f168201915b5050505050905090565b600061098a338484611723565b6001905092915050565b6000600254905090565b60006109ab84848461191a565b610a5e8433610a59856040518060600160405280602881526020016121f460289139600160008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611bdb9092919063ffffffff16565b611723565b600190509392505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c960001b81565b6000600560009054906101000a900460ff16905090565b60075481565b6000610b483384610b4385600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611c9b90919063ffffffff16565b611723565b6001905092915050565b3373ffffffffffffffffffffffffffffffffffffffff16600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610bf8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602381526020018061221c6023913960400191505060405180910390fd5b610c028282611d23565b5050565b610c103382611ee8565b50565b60003373ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610cd8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b81600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060019050919050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b3373ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610e2d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b610ef88282611018565b5050565b6000610f45600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206120ac565b9050919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060048054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561100e5780601f10610fe35761010080835404028352916020019161100e565b820191906000526020600020905b815481529060010190602001808311610ff157829003601f168201915b5050505050905090565b60006110508260405180606001604052806024815260200161223f602491396110418633611469565b611bdb9092919063ffffffff16565b905061105d833383611723565b6110678383611ee8565b505050565b6000611121338461111c856040518060600160405280602581526020016122cd60259139600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611bdb9092919063ffffffff16565b611723565b6001905092915050565b600061113833848461191a565b6001905092915050565b834211156111b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f5065726d69743a206578706972656420646561646c696e65000000000000000081525060200191505060405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c960001b888888611228600660008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206120ac565b89604051602001808781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018381526020018281526020019650505050505050604051602081830303815290604052805190602001209050600061190160075483604051602001808461ffff1660f01b81526002018381526020018281526020019350505050604051602081830303815290604052805190602001209050600060018287878760405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015611342573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156113b657508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b61140b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806121d36021913960400191505060405180910390fd5b611452600660008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206120ba565b61145d8a8a8a611723565b50505050505050505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b3373ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146115b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611639576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806121656026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156117a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806122a96024913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561182f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061218b6022913960400191505060405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156119a0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806122846025913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611a26576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806121206023913960400191505060405180910390fd5b611a318383836120d0565b611a9c816040518060600160405280602681526020016121ad602691396000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611bdb9092919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611b2f816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611c9b90919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b6000838311158290611c88576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611c4d578082015181840152602081019050611c32565b50505050905090810190601f168015611c7a5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b600080828401905083811015611d19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611dc6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b611dd13083836120d0565b611de681600254611c9b90919063ffffffff16565b600281905550611e3d816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611c9b90919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611f6e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806122636021913960400191505060405180910390fd5b611f7a826000836120d0565b611fe581604051806060016040528060228152602001612143602291396000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611bdb9092919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061203c816002546120d590919063ffffffff16565b600281905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b600081600001549050919050565b6001816000016000828254019250508190555050565b505050565b600061211783836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611bdb565b90509291505056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e63654f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e63655a65726f537761705065726d69743a20496e76616c6964207369676e617475726545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63655661756c744f776e65643a2063616c6c6572206973206e6f7420746865205661756c7445524332303a206275726e20616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa264697066735822122033003866df3e33462190d328d71431dc18588996e0812e69e584d7fdc25dcebf64736f6c63430007050033", + "devdoc": { + "kind": "dev", + "methods": { + "allowance(address,address)": { + "details": "Returns the remaining number of tokens that `spender` will be allowed to spend on behalf of `owner` through {transferFrom}. This is zero by default. This value changes when {approve} or {transferFrom} are called." + }, + "approve(address,uint256)": { + "details": "Sets `amount` as the allowance of `spender` over the caller's tokens. Returns a boolean value indicating whether the operation succeeded. IMPORTANT: Beware that changing an allowance with this method brings the risk that someone may use both the old and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 Emits an {Approval} event." + }, + "balanceOf(address)": { + "details": "Returns the amount of tokens owned by `account`." + }, + "totalSupply()": { + "details": "Returns the amount of tokens in existence." + }, + "transfer(address,uint256)": { + "details": "Moves `amount` tokens from the caller's account to `recipient`. Returns a boolean value indicating whether the operation succeeded. Emits a {Transfer} event." + }, + "transferFrom(address,address,uint256)": { + "details": "Moves `amount` tokens from `sender` to `recipient` using the allowance mechanism. `amount` is then deducted from the caller's allowance. Returns a boolean value indicating whether the operation succeeded. Emits a {Transfer} event." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 1372, + "contract": "contracts/OlympusERC20.sol:OlympusERC20Token", + "label": "_balances", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 1378, + "contract": "contracts/OlympusERC20.sol:OlympusERC20Token", + "label": "_allowances", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 1380, + "contract": "contracts/OlympusERC20.sol:OlympusERC20Token", + "label": "_totalSupply", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 1382, + "contract": "contracts/OlympusERC20.sol:OlympusERC20Token", + "label": "_name", + "offset": 0, + "slot": "3", + "type": "t_string_storage" + }, + { + "astId": 1384, + "contract": "contracts/OlympusERC20.sol:OlympusERC20Token", + "label": "_symbol", + "offset": 0, + "slot": "4", + "type": "t_string_storage" + }, + { + "astId": 1386, + "contract": "contracts/OlympusERC20.sol:OlympusERC20Token", + "label": "_decimals", + "offset": 0, + "slot": "5", + "type": "t_uint8" + }, + { + "astId": 1914, + "contract": "contracts/OlympusERC20.sol:OlympusERC20Token", + "label": "_nonces", + "offset": 0, + "slot": "6", + "type": "t_mapping(t_address,t_struct(Counter)1838_storage)" + }, + { + "astId": 1919, + "contract": "contracts/OlympusERC20.sol:OlympusERC20Token", + "label": "DOMAIN_SEPARATOR", + "offset": 0, + "slot": "7", + "type": "t_bytes32" + }, + { + "astId": 2084, + "contract": "contracts/OlympusERC20.sol:OlympusERC20Token", + "label": "_owner", + "offset": 0, + "slot": "8", + "type": "t_address" + }, + { + "astId": 2183, + "contract": "contracts/OlympusERC20.sol:OlympusERC20Token", + "label": "_vault", + "offset": 0, + "slot": "9", + "type": "t_address" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_struct(Counter)1838_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct Counters.Counter)", + "numberOfBytes": "32", + "value": "t_struct(Counter)1838_storage" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_struct(Counter)1838_storage": { + "encoding": "inplace", + "label": "struct Counters.Counter", + "members": [ + { + "astId": 1837, + "contract": "contracts/OlympusERC20.sol:OlympusERC20Token", + "label": "_value", + "offset": 0, + "slot": "0", + "type": "t_uint256" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/src/abi/rinkeby/OlympusStaking.json b/src/abi/rinkeby/OlympusStaking.json new file mode 100644 index 0000000000..207d59cae3 --- /dev/null +++ b/src/abi/rinkeby/OlympusStaking.json @@ -0,0 +1,743 @@ +{ + "address": "0xbB8b39A92D916D4c1c46c67CA22920A366127A4B", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_OHM", + "type": "address" + }, + { + "internalType": "address", + "name": "_sOHM", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_epochLength", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_firstEpochNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_firstEpochTime", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipPulled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipPushed", + "type": "event" + }, + { + "inputs": [], + "name": "OHM", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_recipient", + "type": "address" + } + ], + "name": "claim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "contractBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "distributor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "epoch", + "outputs": [ + { + "internalType": "uint256", + "name": "length", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "number", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "endTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "distribute", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "forfeit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "giveLockBonus", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "index", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "locker", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "manager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pullManagement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner_", + "type": "address" + } + ], + "name": "pushManagement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rebase", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceManagement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "returnLockBonus", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "sOHM", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum OlympusStaking.CONTRACTS", + "name": "_contract", + "type": "uint8" + }, + { + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "setContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_warmupPeriod", + "type": "uint256" + } + ], + "name": "setWarmup", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_recipient", + "type": "address" + } + ], + "name": "stake", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "toggleDepositLock", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalBonus", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_trigger", + "type": "bool" + } + ], + "name": "unstake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "warmupContract", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "warmupInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "deposit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gons", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "lock", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "warmupPeriod", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x5cface5c69bf754d0b6c0b4537edbedc7b08c6b69f5e09456d00553c935a4fe4", + "receipt": { + "to": null, + "from": "0xA38F4E6718EdCF023a1d032a2193848CB932c8e3", + "contractAddress": "0xbB8b39A92D916D4c1c46c67CA22920A366127A4B", + "transactionIndex": 3, + "gasUsed": "2346648", + "logsBloom": "0x00000000020000000000000000000000000000000000000000000000000000000000400000200000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000020000000000020002000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x97bb19011ae542b75a2072ea19fc4a2f8aa0782ce673ebdbb1740b8b01cec243", + "transactionHash": "0x5cface5c69bf754d0b6c0b4537edbedc7b08c6b69f5e09456d00553c935a4fe4", + "logs": [ + { + "transactionIndex": 3, + "blockNumber": 9907139, + "transactionHash": "0x5cface5c69bf754d0b6c0b4537edbedc7b08c6b69f5e09456d00553c935a4fe4", + "address": "0xbB8b39A92D916D4c1c46c67CA22920A366127A4B", + "topics": [ + "0xea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000a38f4e6718edcf023a1d032a2193848cb932c8e3" + ], + "data": "0x", + "logIndex": 1, + "blockHash": "0x97bb19011ae542b75a2072ea19fc4a2f8aa0782ce673ebdbb1740b8b01cec243" + } + ], + "blockNumber": 9907139, + "cumulativeGasUsed": "2432643", + "status": 1, + "byzantium": true + }, + "args": [ + "0x9bb5E7183e6259183f8E79876eCC0228738C95F6", + "0x230a8dC3c34336372b75549915DeBAEAACCF129D", + 28800, + 1, + "1640930868" + ], + "solcInputHash": "80205d7caa85cf7d901b88f836b16309", + "metadata": "{\"compiler\":{\"version\":\"0.7.5+commit.eb77ed08\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_OHM\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_sOHM\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_epochLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_firstEpochNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_firstEpochTime\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipPulled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipPushed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"OHM\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"}],\"name\":\"claim\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"contractBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"distributor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"epoch\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"number\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"endTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"distribute\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"forfeit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"giveLockBonus\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"index\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"locker\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"manager\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pullManagement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner_\",\"type\":\"address\"}],\"name\":\"pushManagement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rebase\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceManagement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"returnLockBonus\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sOHM\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enum OlympusStaking.CONTRACTS\",\"name\":\"_contract\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"setContract\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_warmupPeriod\",\"type\":\"uint256\"}],\"name\":\"setWarmup\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"}],\"name\":\"stake\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"toggleDepositLock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalBonus\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"_trigger\",\"type\":\"bool\"}],\"name\":\"unstake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"warmupContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"warmupInfo\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"deposit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gons\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiry\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"lock\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"warmupPeriod\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"claim(address)\":{\"params\":{\"_recipient\":\"address\"}},\"contractBalance()\":{\"returns\":{\"_0\":\"uint\"}},\"giveLockBonus(uint256)\":{\"params\":{\"_amount\":\"uint\"}},\"index()\":{\"returns\":{\"_0\":\"uint\"}},\"returnLockBonus(uint256)\":{\"params\":{\"_amount\":\"uint\"}},\"setContract(uint8,address)\":{\"params\":{\"_contract\":\"address\"}},\"setWarmup(uint256)\":{\"params\":{\"_warmupPeriod\":\"uint\"}},\"stake(uint256,address)\":{\"params\":{\"_amount\":\"uint\"},\"returns\":{\"_0\":\"bool\"}},\"unstake(uint256,bool)\":{\"params\":{\"_amount\":\"uint\",\"_trigger\":\"bool\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"claim(address)\":{\"notice\":\"retrieve sOHM from warmup\"},\"contractBalance()\":{\"notice\":\"returns contract OHM holdings, including bonuses provided\"},\"forfeit()\":{\"notice\":\"forfeit sOHM in warmup and retrieve OHM\"},\"giveLockBonus(uint256)\":{\"notice\":\"provide bonus to locked staking contract\"},\"index()\":{\"notice\":\"returns the sOHM index, which tracks rebase growth\"},\"rebase()\":{\"notice\":\"trigger rebase if epoch over\"},\"returnLockBonus(uint256)\":{\"notice\":\"reclaim bonus from locked staking contract\"},\"setContract(uint8,address)\":{\"notice\":\"sets the contract address for LP staking\"},\"setWarmup(uint256)\":{\"notice\":\"set warmup period for new stakers\"},\"stake(uint256,address)\":{\"notice\":\"stake OHM to enter warmup\"},\"toggleDepositLock()\":{\"notice\":\"prevent new deposits to address (protection from malicious activity)\"},\"unstake(uint256,bool)\":{\"notice\":\"redeem sOHM for OHM\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Staking.sol\":\"OlympusStaking\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/Staking.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-or-later\\npragma solidity 0.7.5;\\n\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n}\\n\\ninterface IERC20 {\\n function decimals() external view returns (uint8);\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies in extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return _functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.3._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.3._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n\\n function addressToString(address _address) internal pure returns(string memory) {\\n bytes32 _bytes = bytes32(uint256(_address));\\n bytes memory HEX = \\\"0123456789abcdef\\\";\\n bytes memory _addr = new bytes(42);\\n\\n _addr[0] = '0';\\n _addr[1] = 'x';\\n\\n for(uint256 i = 0; i < 20; i++) {\\n _addr[2+i*2] = HEX[uint8(_bytes[i + 12] >> 4)];\\n _addr[3+i*2] = HEX[uint8(_bytes[i + 12] & 0x0f)];\\n }\\n\\n return string(_addr);\\n\\n }\\n}\\n\\nlibrary SafeERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require((value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\\ninterface IOwnable {\\n function manager() external view returns (address);\\n\\n function renounceManagement() external;\\n \\n function pushManagement( address newOwner_ ) external;\\n \\n function pullManagement() external;\\n}\\n\\ncontract Ownable is IOwnable {\\n\\n address internal _owner;\\n address internal _newOwner;\\n\\n event OwnershipPushed(address indexed previousOwner, address indexed newOwner);\\n event OwnershipPulled(address indexed previousOwner, address indexed newOwner);\\n\\n constructor () {\\n _owner = msg.sender;\\n emit OwnershipPushed( address(0), _owner );\\n }\\n\\n function manager() public view override returns (address) {\\n return _owner;\\n }\\n\\n modifier onlyManager() {\\n require( _owner == msg.sender, \\\"Ownable: caller is not the owner\\\" );\\n _;\\n }\\n\\n function renounceManagement() public virtual override onlyManager() {\\n emit OwnershipPushed( _owner, address(0) );\\n _owner = address(0);\\n }\\n\\n function pushManagement( address newOwner_ ) public virtual override onlyManager() {\\n require( newOwner_ != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipPushed( _owner, newOwner_ );\\n _newOwner = newOwner_;\\n }\\n \\n function pullManagement() public virtual override {\\n require( msg.sender == _newOwner, \\\"Ownable: must be new owner to pull\\\");\\n emit OwnershipPulled( _owner, _newOwner );\\n _owner = _newOwner;\\n }\\n}\\n\\ninterface IsOHM {\\n function rebase( uint256 ohmProfit_, uint epoch_) external returns (uint256);\\n\\n function circulatingSupply() external view returns (uint256);\\n\\n function balanceOf(address who) external view returns (uint256);\\n\\n function gonsForBalance( uint amount ) external view returns ( uint );\\n\\n function balanceForGons( uint gons ) external view returns ( uint );\\n \\n function index() external view returns ( uint );\\n}\\n\\ninterface IWarmup {\\n function retrieve( address staker_, uint amount_ ) external;\\n}\\n\\ninterface IDistributor {\\n function distribute() external returns ( bool );\\n}\\n\\ncontract OlympusStaking is Ownable {\\n\\n using SafeMath for uint256;\\n using SafeERC20 for IERC20;\\n\\n address public immutable OHM;\\n address public immutable sOHM;\\n\\n struct Epoch {\\n uint length;\\n uint number;\\n uint endTime;\\n uint distribute;\\n }\\n Epoch public epoch;\\n\\n address public distributor;\\n\\n address public locker;\\n uint public totalBonus;\\n\\n address public warmupContract;\\n uint public warmupPeriod;\\n\\n constructor (\\n address _OHM,\\n address _sOHM,\\n uint _epochLength,\\n uint _firstEpochNumber,\\n uint _firstEpochTime\\n ) {\\n require( _OHM != address(0) );\\n OHM = _OHM;\\n require( _sOHM != address(0) );\\n sOHM = _sOHM;\\n\\n epoch = Epoch({\\n length: _epochLength,\\n number: _firstEpochNumber,\\n endTime: _firstEpochTime,\\n distribute: 0\\n });\\n }\\n\\n struct Claim {\\n uint deposit;\\n uint gons;\\n uint expiry;\\n bool lock; // prevents malicious delays\\n }\\n mapping( address => Claim ) public warmupInfo;\\n\\n /**\\n @notice stake OHM to enter warmup\\n @param _amount uint\\n @return bool\\n */\\n function stake( uint _amount, address _recipient ) external returns ( bool ) {\\n rebase();\\n \\n IERC20( OHM ).safeTransferFrom( msg.sender, address(this), _amount );\\n\\n Claim memory info = warmupInfo[ _recipient ];\\n require( !info.lock, \\\"Deposits for account are locked\\\" );\\n\\n warmupInfo[ _recipient ] = Claim ({\\n deposit: info.deposit.add( _amount ),\\n gons: info.gons.add( IsOHM( sOHM ).gonsForBalance( _amount ) ),\\n expiry: epoch.number.add( warmupPeriod ),\\n lock: false\\n });\\n \\n IERC20( sOHM ).safeTransfer( warmupContract, _amount );\\n return true;\\n }\\n\\n /**\\n @notice retrieve sOHM from warmup\\n @param _recipient address\\n */\\n function claim ( address _recipient ) public {\\n Claim memory info = warmupInfo[ _recipient ];\\n if ( epoch.number >= info.expiry && info.expiry != 0 ) {\\n delete warmupInfo[ _recipient ];\\n IWarmup( warmupContract ).retrieve( _recipient, IsOHM( sOHM ).balanceForGons( info.gons ) );\\n }\\n }\\n\\n /**\\n @notice forfeit sOHM in warmup and retrieve OHM\\n */\\n function forfeit() external {\\n Claim memory info = warmupInfo[ msg.sender ];\\n delete warmupInfo[ msg.sender ];\\n\\n IWarmup( warmupContract ).retrieve( address(this), IsOHM( sOHM ).balanceForGons( info.gons ) );\\n IERC20( OHM ).safeTransfer( msg.sender, info.deposit );\\n }\\n\\n /**\\n @notice prevent new deposits to address (protection from malicious activity)\\n */\\n function toggleDepositLock() external {\\n warmupInfo[ msg.sender ].lock = !warmupInfo[ msg.sender ].lock;\\n }\\n\\n /**\\n @notice redeem sOHM for OHM\\n @param _amount uint\\n @param _trigger bool\\n */\\n function unstake( uint _amount, bool _trigger ) external {\\n if ( _trigger ) {\\n rebase();\\n }\\n IERC20( sOHM ).safeTransferFrom( msg.sender, address(this), _amount );\\n IERC20( OHM ).safeTransfer( msg.sender, _amount );\\n }\\n\\n /**\\n @notice returns the sOHM index, which tracks rebase growth\\n @return uint\\n */\\n function index() public view returns ( uint ) {\\n return IsOHM( sOHM ).index();\\n }\\n\\n /**\\n @notice trigger rebase if epoch over\\n */\\n function rebase() public {\\n if( epoch.endTime <= block.timestamp ) {\\n\\n IsOHM( sOHM ).rebase( epoch.distribute, epoch.number );\\n\\n epoch.endTime = epoch.endTime.add( epoch.length );\\n epoch.number++;\\n\\n if ( distributor != address(0) ) {\\n IDistributor( distributor ).distribute();\\n }\\n\\n uint balance = contractBalance();\\n uint staked = IsOHM( sOHM ).circulatingSupply();\\n\\n if( balance <= staked ) {\\n epoch.distribute = 0;\\n } else {\\n epoch.distribute = balance.sub( staked );\\n }\\n }\\n }\\n\\n /**\\n @notice returns contract OHM holdings, including bonuses provided\\n @return uint\\n */\\n function contractBalance() public view returns ( uint ) {\\n return IERC20( OHM ).balanceOf( address(this) ).add( totalBonus );\\n }\\n\\n /**\\n @notice provide bonus to locked staking contract\\n @param _amount uint\\n */\\n function giveLockBonus( uint _amount ) external {\\n require( msg.sender == locker );\\n totalBonus = totalBonus.add( _amount );\\n IERC20( sOHM ).safeTransfer( locker, _amount );\\n }\\n\\n /**\\n @notice reclaim bonus from locked staking contract\\n @param _amount uint\\n */\\n function returnLockBonus( uint _amount ) external {\\n require( msg.sender == locker );\\n totalBonus = totalBonus.sub( _amount );\\n IERC20( sOHM ).safeTransferFrom( locker, address(this), _amount );\\n }\\n\\n enum CONTRACTS { DISTRIBUTOR, WARMUP, LOCKER }\\n\\n /**\\n @notice sets the contract address for LP staking\\n @param _contract address\\n */\\n function setContract( CONTRACTS _contract, address _address ) external onlyManager() {\\n if( _contract == CONTRACTS.DISTRIBUTOR ) { // 0\\n distributor = _address;\\n } else if ( _contract == CONTRACTS.WARMUP ) { // 1\\n require( warmupContract == address( 0 ), \\\"Warmup cannot be set more than once\\\" );\\n warmupContract = _address;\\n } else if ( _contract == CONTRACTS.LOCKER ) { // 2\\n require( locker == address(0), \\\"Locker cannot be set more than once\\\" );\\n locker = _address;\\n }\\n }\\n \\n /**\\n * @notice set warmup period for new stakers\\n * @param _warmupPeriod uint\\n */\\n function setWarmup( uint _warmupPeriod ) external onlyManager() {\\n warmupPeriod = _warmupPeriod;\\n }\\n}\",\"keccak256\":\"0x1a53883222964f140bc7d1da66bd6e79aa9fe64bdbf81930beadb47e308ae122\",\"license\":\"AGPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x60c060405234801561001057600080fd5b50604051612a94380380612a94833981810160405260a081101561003357600080fd5b810190808051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a3600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16141561016157600080fd5b8473ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b81525050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156101d257600080fd5b8373ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b8152505060405180608001604052808481526020018381526020018281526020016000815250600260008201518160000155602082015181600101556040820151816002015560608201518160030155905050505050505060805160601c60a05160601c6127c86102cc6000398061069b528061086352806109e45280610b06528061114352806112d4528061182052806118eb5280611af05280611e495280612053525080610fcd528061166c528061186c52806118b65280611f6d52506127c86000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80638f077b83116100de578063bfe1092811610097578063deac361a11610071578063deac361a14610573578063ed4acaa814610591578063f3d86e4a146105c5578063f62ae76a146105cf57610173565b8063bfe10928146104dd578063c9f464ff14610511578063d7b96d4e1461053f57610173565b80638f077b831461040a578063900cf0cf146104145780639ebea88c14610447578063a6c41fec14610481578063a8dd07dc146104b5578063af14052c146104d357610173565b8063481c6a7511610130578063481c6a751461028a5780635a96ac0a146102be5780636746f4c2146102c85780637acb775714610337578063865e6fd31461039b5780638b7afe2e146103ec57610173565b806303c2367014610178578063089208d8146101a657806315079925146101b05780631e83409a146101e45780632986c0e51461022857806346f68ee914610246575b600080fd5b6101a46004803603602081101561018e57600080fd5b81019080803590602001909291905050506105fd565b005b6101ae6106e2565b005b6101b8610861565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610226600480360360208110156101fa57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610885565b005b610230610b02565b6040518082815260200191505060405180910390f35b6102886004803603602081101561025c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610baa565b005b610292610daf565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102c6610dd8565b005b61030a600480360360208110156102de57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610f7e565b60405180858152602001848152602001838152602001821515815260200194505050505060405180910390f35b6103836004803603604081101561034d57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610fbb565b60405180821515815260200191505060405180910390f35b6103ea600480360360408110156103b157600080fd5b81019080803560ff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611323565b005b6103f4611662565b6040518082815260200191505060405180910390f35b61041261173f565b005b61041c6117eb565b6040518085815260200184815260200183815260200182815260200194505050505060405180910390f35b61047f6004803603604081101561045d57600080fd5b8101908080359060200190929190803515159060200190929190505050611809565b005b6104896118b4565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6104bd6118d8565b6040518082815260200191505060405180910390f35b6104db6118de565b005b6104e5611bca565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61053d6004803603602081101561052757600080fd5b8101908080359060200190929190505050611bf0565b005b610547611cbb565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61057b611ce1565b6040518082815260200191505060405180910390f35b610599611ce7565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6105cd611d0d565b005b6105fb600480360360208110156105e557600080fd5b8101908080359060200190929190505050611fb4565b005b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461065757600080fd5b61066c8160085461209b90919063ffffffff16565b6008819055506106df600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16827f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166121239092919063ffffffff16565b50565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146107a3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b7f000000000000000000000000000000000000000000000000000000000000000081565b61088d6126b0565b600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060800160405290816000820154815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff161515151581525050905080604001516002600101541015801561093057506000816040015114155b15610afe57600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600080820160009055600182016000905560028201600090556003820160006101000a81549060ff02191690555050600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c3a2a665837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637965d56d85602001516040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610a5757600080fd5b505afa158015610a6b573d6000803e3d6000fd5b505050506040513d6020811015610a8157600080fd5b81019080805190602001909291905050506040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b158015610ae557600080fd5b505af1158015610af9573d6000803e3d6000fd5b505050505b5050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632986c0e56040518163ffffffff1660e01b815260040160206040518083038186803b158015610b6a57600080fd5b505afa158015610b7e573d6000803e3d6000fd5b505050506040513d6020811015610b9457600080fd5b8101908080519060200190929190505050905090565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610c6b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610cf1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806126fe6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a380600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e7e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806127476022913960400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167faa151555690c956fc3ea32f106bb9f119b5237a061eaa8557cff3e51e3792c8d60405160405180910390a3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600b6020528060005260406000206000915090508060000154908060010154908060020154908060030160009054906101000a900460ff16905084565b6000610fc56118de565b6110123330857f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166121c5909392919063ffffffff16565b61101a6126b0565b600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060800160405290816000820154815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff1615151515815250509050806060015115611117576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4465706f7369747320666f72206163636f756e7420617265206c6f636b65640081525060200191505060405180910390fd5b604051806080016040528061113986846000015161209b90919063ffffffff16565b81526020016112007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16631bd39674886040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156111b257600080fd5b505afa1580156111c6573d6000803e3d6000fd5b505050506040513d60208110156111dc57600080fd5b8101908080519060200190929190505050846020015161209b90919063ffffffff16565b815260200161121f600a5460026001015461209b90919063ffffffff16565b815260200160001515815250600b60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030160006101000a81548160ff021916908315150217905550905050611318600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16857f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166121239092919063ffffffff16565b600191505092915050565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146113e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060028111156113f157fe5b8260028111156113fd57fe5b14156114495780600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061165e565b6001600281111561145657fe5b82600281111561146257fe5b141561155557600073ffffffffffffffffffffffffffffffffffffffff16600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461150f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806127246023913960400191505060405180910390fd5b80600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061165d565b60028081111561156157fe5b82600281111561156d57fe5b141561165c57600073ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461161a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806126db6023913960400191505060405180910390fd5b80600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b5b5050565b600061173a6008547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156116f157600080fd5b505afa158015611705573d6000803e3d6000fd5b505050506040513d602081101561171b57600080fd5b810190808051906020019092919050505061209b90919063ffffffff16565b905090565b600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160009054906101000a900460ff1615600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160006101000a81548160ff021916908315150217905550565b60028060000154908060010154908060020154908060030154905084565b8015611818576118176118de565b5b6118653330847f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166121c5909392919063ffffffff16565b6118b033837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166121239092919063ffffffff16565b5050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60085481565b42600280015411611bc8577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663058ecdb46002600301546002600101546040518363ffffffff1660e01b81526004018083815260200182815260200192505050602060405180830381600087803b15801561196e57600080fd5b505af1158015611982573d6000803e3d6000fd5b505050506040513d602081101561199857600080fd5b8101908080519060200190929190505050506119c6600260000154600280015461209b90919063ffffffff16565b6002800181905550600260010160008154809291906001019190505550600073ffffffffffffffffffffffffffffffffffffffff16600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611ae057600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e4fc6b6d6040518163ffffffff1660e01b8152600401602060405180830381600087803b158015611aa357600080fd5b505af1158015611ab7573d6000803e3d6000fd5b505050506040513d6020811015611acd57600080fd5b8101908080519060200190929190505050505b6000611aea611662565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639358928b6040518163ffffffff1660e01b815260040160206040518083038186803b158015611b5457600080fd5b505afa158015611b68573d6000803e3d6000fd5b505050506040513d6020811015611b7e57600080fd5b81019080805190602001909291905050509050808211611ba8576000600260030181905550611bc5565b611bbb818361228690919063ffffffff16565b6002600301819055505b50505b565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611cb1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b80600a8190555050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600a5481565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611d156126b0565b600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060800160405290816000820154815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff1615151515815250509050600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600080820160009055600182016000905560028201600090556003820160006101000a81549060ff02191690555050600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c3a2a665307f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637965d56d85602001516040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611ebc57600080fd5b505afa158015611ed0573d6000803e3d6000fd5b505050506040513d6020811015611ee657600080fd5b81019080805190602001909291905050506040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b158015611f4a57600080fd5b505af1158015611f5e573d6000803e3d6000fd5b50505050611fb13382600001517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166121239092919063ffffffff16565b50565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461200e57600080fd5b6120238160085461228690919063ffffffff16565b600881905550612098600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1630837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166121c5909392919063ffffffff16565b50565b600080828401905083811015612119576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b6121c08363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506122d0565b505050565b612280846323b872dd60e01b858585604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506122d0565b50505050565b60006122c883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506123bf565b905092915050565b6060612332826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661247f9092919063ffffffff16565b90506000815111156123ba5780806020019051602081101561235357600080fd5b81019080805190602001909291905050506123b9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180612769602a913960400191505060405180910390fd5b5b505050565b600083831115829061246c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612431578082015181840152602081019050612416565b50505050905090810190601f16801561245e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b606061248e8484600085612497565b90509392505050565b60606124a28561269d565b612514576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b602083106125645780518252602082019150602081019050602083039250612541565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146125c6576040519150601f19603f3d011682016040523d82523d6000602084013e6125cb565b606091505b509150915081156125e0578092505050612695565b6000815111156125f35780518082602001fd5b836040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561265a57808201518184015260208101905061263f565b50505050905090810190601f1680156126875780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b949350505050565b600080823b905060008111915050919050565b6040518060800160405280600081526020016000815260200160008152602001600015158152509056fe4c6f636b65722063616e6e6f7420626520736574206d6f7265207468616e206f6e63654f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573735761726d75702063616e6e6f7420626520736574206d6f7265207468616e206f6e63654f776e61626c653a206d757374206265206e6577206f776e657220746f2070756c6c5361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220a41f77f9eea5a118bf88bc8e0eee7aae8730e6ae78a4c28284076bed38df07b864736f6c63430007050033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101735760003560e01c80638f077b83116100de578063bfe1092811610097578063deac361a11610071578063deac361a14610573578063ed4acaa814610591578063f3d86e4a146105c5578063f62ae76a146105cf57610173565b8063bfe10928146104dd578063c9f464ff14610511578063d7b96d4e1461053f57610173565b80638f077b831461040a578063900cf0cf146104145780639ebea88c14610447578063a6c41fec14610481578063a8dd07dc146104b5578063af14052c146104d357610173565b8063481c6a7511610130578063481c6a751461028a5780635a96ac0a146102be5780636746f4c2146102c85780637acb775714610337578063865e6fd31461039b5780638b7afe2e146103ec57610173565b806303c2367014610178578063089208d8146101a657806315079925146101b05780631e83409a146101e45780632986c0e51461022857806346f68ee914610246575b600080fd5b6101a46004803603602081101561018e57600080fd5b81019080803590602001909291905050506105fd565b005b6101ae6106e2565b005b6101b8610861565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610226600480360360208110156101fa57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610885565b005b610230610b02565b6040518082815260200191505060405180910390f35b6102886004803603602081101561025c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610baa565b005b610292610daf565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102c6610dd8565b005b61030a600480360360208110156102de57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610f7e565b60405180858152602001848152602001838152602001821515815260200194505050505060405180910390f35b6103836004803603604081101561034d57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610fbb565b60405180821515815260200191505060405180910390f35b6103ea600480360360408110156103b157600080fd5b81019080803560ff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611323565b005b6103f4611662565b6040518082815260200191505060405180910390f35b61041261173f565b005b61041c6117eb565b6040518085815260200184815260200183815260200182815260200194505050505060405180910390f35b61047f6004803603604081101561045d57600080fd5b8101908080359060200190929190803515159060200190929190505050611809565b005b6104896118b4565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6104bd6118d8565b6040518082815260200191505060405180910390f35b6104db6118de565b005b6104e5611bca565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61053d6004803603602081101561052757600080fd5b8101908080359060200190929190505050611bf0565b005b610547611cbb565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61057b611ce1565b6040518082815260200191505060405180910390f35b610599611ce7565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6105cd611d0d565b005b6105fb600480360360208110156105e557600080fd5b8101908080359060200190929190505050611fb4565b005b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461065757600080fd5b61066c8160085461209b90919063ffffffff16565b6008819055506106df600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16827f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166121239092919063ffffffff16565b50565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146107a3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b7f000000000000000000000000000000000000000000000000000000000000000081565b61088d6126b0565b600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060800160405290816000820154815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff161515151581525050905080604001516002600101541015801561093057506000816040015114155b15610afe57600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600080820160009055600182016000905560028201600090556003820160006101000a81549060ff02191690555050600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c3a2a665837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637965d56d85602001516040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610a5757600080fd5b505afa158015610a6b573d6000803e3d6000fd5b505050506040513d6020811015610a8157600080fd5b81019080805190602001909291905050506040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b158015610ae557600080fd5b505af1158015610af9573d6000803e3d6000fd5b505050505b5050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632986c0e56040518163ffffffff1660e01b815260040160206040518083038186803b158015610b6a57600080fd5b505afa158015610b7e573d6000803e3d6000fd5b505050506040513d6020811015610b9457600080fd5b8101908080519060200190929190505050905090565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610c6b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610cf1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806126fe6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a380600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e7e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806127476022913960400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167faa151555690c956fc3ea32f106bb9f119b5237a061eaa8557cff3e51e3792c8d60405160405180910390a3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600b6020528060005260406000206000915090508060000154908060010154908060020154908060030160009054906101000a900460ff16905084565b6000610fc56118de565b6110123330857f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166121c5909392919063ffffffff16565b61101a6126b0565b600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060800160405290816000820154815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff1615151515815250509050806060015115611117576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4465706f7369747320666f72206163636f756e7420617265206c6f636b65640081525060200191505060405180910390fd5b604051806080016040528061113986846000015161209b90919063ffffffff16565b81526020016112007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16631bd39674886040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156111b257600080fd5b505afa1580156111c6573d6000803e3d6000fd5b505050506040513d60208110156111dc57600080fd5b8101908080519060200190929190505050846020015161209b90919063ffffffff16565b815260200161121f600a5460026001015461209b90919063ffffffff16565b815260200160001515815250600b60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030160006101000a81548160ff021916908315150217905550905050611318600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16857f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166121239092919063ffffffff16565b600191505092915050565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146113e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060028111156113f157fe5b8260028111156113fd57fe5b14156114495780600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061165e565b6001600281111561145657fe5b82600281111561146257fe5b141561155557600073ffffffffffffffffffffffffffffffffffffffff16600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461150f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806127246023913960400191505060405180910390fd5b80600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061165d565b60028081111561156157fe5b82600281111561156d57fe5b141561165c57600073ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461161a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806126db6023913960400191505060405180910390fd5b80600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b5b5050565b600061173a6008547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156116f157600080fd5b505afa158015611705573d6000803e3d6000fd5b505050506040513d602081101561171b57600080fd5b810190808051906020019092919050505061209b90919063ffffffff16565b905090565b600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160009054906101000a900460ff1615600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160006101000a81548160ff021916908315150217905550565b60028060000154908060010154908060020154908060030154905084565b8015611818576118176118de565b5b6118653330847f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166121c5909392919063ffffffff16565b6118b033837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166121239092919063ffffffff16565b5050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60085481565b42600280015411611bc8577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663058ecdb46002600301546002600101546040518363ffffffff1660e01b81526004018083815260200182815260200192505050602060405180830381600087803b15801561196e57600080fd5b505af1158015611982573d6000803e3d6000fd5b505050506040513d602081101561199857600080fd5b8101908080519060200190929190505050506119c6600260000154600280015461209b90919063ffffffff16565b6002800181905550600260010160008154809291906001019190505550600073ffffffffffffffffffffffffffffffffffffffff16600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611ae057600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e4fc6b6d6040518163ffffffff1660e01b8152600401602060405180830381600087803b158015611aa357600080fd5b505af1158015611ab7573d6000803e3d6000fd5b505050506040513d6020811015611acd57600080fd5b8101908080519060200190929190505050505b6000611aea611662565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639358928b6040518163ffffffff1660e01b815260040160206040518083038186803b158015611b5457600080fd5b505afa158015611b68573d6000803e3d6000fd5b505050506040513d6020811015611b7e57600080fd5b81019080805190602001909291905050509050808211611ba8576000600260030181905550611bc5565b611bbb818361228690919063ffffffff16565b6002600301819055505b50505b565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611cb1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b80600a8190555050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600a5481565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611d156126b0565b600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060800160405290816000820154815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff1615151515815250509050600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600080820160009055600182016000905560028201600090556003820160006101000a81549060ff02191690555050600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c3a2a665307f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637965d56d85602001516040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611ebc57600080fd5b505afa158015611ed0573d6000803e3d6000fd5b505050506040513d6020811015611ee657600080fd5b81019080805190602001909291905050506040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b158015611f4a57600080fd5b505af1158015611f5e573d6000803e3d6000fd5b50505050611fb13382600001517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166121239092919063ffffffff16565b50565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461200e57600080fd5b6120238160085461228690919063ffffffff16565b600881905550612098600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1630837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166121c5909392919063ffffffff16565b50565b600080828401905083811015612119576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b6121c08363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506122d0565b505050565b612280846323b872dd60e01b858585604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506122d0565b50505050565b60006122c883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506123bf565b905092915050565b6060612332826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661247f9092919063ffffffff16565b90506000815111156123ba5780806020019051602081101561235357600080fd5b81019080805190602001909291905050506123b9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180612769602a913960400191505060405180910390fd5b5b505050565b600083831115829061246c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612431578082015181840152602081019050612416565b50505050905090810190601f16801561245e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b606061248e8484600085612497565b90509392505050565b60606124a28561269d565b612514576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b602083106125645780518252602082019150602081019050602083039250612541565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146125c6576040519150601f19603f3d011682016040523d82523d6000602084013e6125cb565b606091505b509150915081156125e0578092505050612695565b6000815111156125f35780518082602001fd5b836040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561265a57808201518184015260208101905061263f565b50505050905090810190601f1680156126875780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b949350505050565b600080823b905060008111915050919050565b6040518060800160405280600081526020016000815260200160008152602001600015158152509056fe4c6f636b65722063616e6e6f7420626520736574206d6f7265207468616e206f6e63654f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573735761726d75702063616e6e6f7420626520736574206d6f7265207468616e206f6e63654f776e61626c653a206d757374206265206e6577206f776e657220746f2070756c6c5361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220a41f77f9eea5a118bf88bc8e0eee7aae8730e6ae78a4c28284076bed38df07b864736f6c63430007050033", + "devdoc": { + "kind": "dev", + "methods": { + "claim(address)": { + "params": { + "_recipient": "address" + } + }, + "contractBalance()": { + "returns": { + "_0": "uint" + } + }, + "giveLockBonus(uint256)": { + "params": { + "_amount": "uint" + } + }, + "index()": { + "returns": { + "_0": "uint" + } + }, + "returnLockBonus(uint256)": { + "params": { + "_amount": "uint" + } + }, + "setContract(uint8,address)": { + "params": { + "_contract": "address" + } + }, + "setWarmup(uint256)": { + "params": { + "_warmupPeriod": "uint" + } + }, + "stake(uint256,address)": { + "params": { + "_amount": "uint" + }, + "returns": { + "_0": "bool" + } + }, + "unstake(uint256,bool)": { + "params": { + "_amount": "uint", + "_trigger": "bool" + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "claim(address)": { + "notice": "retrieve sOHM from warmup" + }, + "contractBalance()": { + "notice": "returns contract OHM holdings, including bonuses provided" + }, + "forfeit()": { + "notice": "forfeit sOHM in warmup and retrieve OHM" + }, + "giveLockBonus(uint256)": { + "notice": "provide bonus to locked staking contract" + }, + "index()": { + "notice": "returns the sOHM index, which tracks rebase growth" + }, + "rebase()": { + "notice": "trigger rebase if epoch over" + }, + "returnLockBonus(uint256)": { + "notice": "reclaim bonus from locked staking contract" + }, + "setContract(uint8,address)": { + "notice": "sets the contract address for LP staking" + }, + "setWarmup(uint256)": { + "notice": "set warmup period for new stakers" + }, + "stake(uint256,address)": { + "notice": "stake OHM to enter warmup" + }, + "toggleDepositLock()": { + "notice": "prevent new deposits to address (protection from malicious activity)" + }, + "unstake(uint256,bool)": { + "notice": "redeem sOHM for OHM" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 916, + "contract": "contracts/Staking.sol:OlympusStaking", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 918, + "contract": "contracts/Staking.sol:OlympusStaking", + "label": "_newOwner", + "offset": 0, + "slot": "1", + "type": "t_address" + }, + { + "astId": 1119, + "contract": "contracts/Staking.sol:OlympusStaking", + "label": "epoch", + "offset": 0, + "slot": "2", + "type": "t_struct(Epoch)1117_storage" + }, + { + "astId": 1121, + "contract": "contracts/Staking.sol:OlympusStaking", + "label": "distributor", + "offset": 0, + "slot": "6", + "type": "t_address" + }, + { + "astId": 1123, + "contract": "contracts/Staking.sol:OlympusStaking", + "label": "locker", + "offset": 0, + "slot": "7", + "type": "t_address" + }, + { + "astId": 1125, + "contract": "contracts/Staking.sol:OlympusStaking", + "label": "totalBonus", + "offset": 0, + "slot": "8", + "type": "t_uint256" + }, + { + "astId": 1127, + "contract": "contracts/Staking.sol:OlympusStaking", + "label": "warmupContract", + "offset": 0, + "slot": "9", + "type": "t_address" + }, + { + "astId": 1129, + "contract": "contracts/Staking.sol:OlympusStaking", + "label": "warmupPeriod", + "offset": 0, + "slot": "10", + "type": "t_uint256" + }, + { + "astId": 1191, + "contract": "contracts/Staking.sol:OlympusStaking", + "label": "warmupInfo", + "offset": 0, + "slot": "11", + "type": "t_mapping(t_address,t_struct(Claim)1187_storage)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_mapping(t_address,t_struct(Claim)1187_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct OlympusStaking.Claim)", + "numberOfBytes": "32", + "value": "t_struct(Claim)1187_storage" + }, + "t_struct(Claim)1187_storage": { + "encoding": "inplace", + "label": "struct OlympusStaking.Claim", + "members": [ + { + "astId": 1180, + "contract": "contracts/Staking.sol:OlympusStaking", + "label": "deposit", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 1182, + "contract": "contracts/Staking.sol:OlympusStaking", + "label": "gons", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 1184, + "contract": "contracts/Staking.sol:OlympusStaking", + "label": "expiry", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 1186, + "contract": "contracts/Staking.sol:OlympusStaking", + "label": "lock", + "offset": 0, + "slot": "3", + "type": "t_bool" + } + ], + "numberOfBytes": "128" + }, + "t_struct(Epoch)1117_storage": { + "encoding": "inplace", + "label": "struct OlympusStaking.Epoch", + "members": [ + { + "astId": 1110, + "contract": "contracts/Staking.sol:OlympusStaking", + "label": "length", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 1112, + "contract": "contracts/Staking.sol:OlympusStaking", + "label": "number", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 1114, + "contract": "contracts/Staking.sol:OlympusStaking", + "label": "endTime", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 1116, + "contract": "contracts/Staking.sol:OlympusStaking", + "label": "distribute", + "offset": 0, + "slot": "3", + "type": "t_uint256" + } + ], + "numberOfBytes": "128" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/src/abi/rinkeby/OlympusTreasury.json b/src/abi/rinkeby/OlympusTreasury.json new file mode 100644 index 0000000000..e460335199 --- /dev/null +++ b/src/abi/rinkeby/OlympusTreasury.json @@ -0,0 +1,1682 @@ +{ + "address": "0x1e0AD0F8DDFF84FDc938373E9aa66b8d994ea066", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_OHM", + "type": "address" + }, + { + "internalType": "address", + "name": "_Frax", + "type": "address" + }, + { + "internalType": "address", + "name": "_WrappedToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_blocksNeededForQueue", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "enum OlympusTreasury.MANAGING", + "name": "managing", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "address", + "name": "activated", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "result", + "type": "bool" + } + ], + "name": "ChangeActivated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "enum OlympusTreasury.MANAGING", + "name": "managing", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "address", + "name": "queued", + "type": "address" + } + ], + "name": "ChangeQueued", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "debtor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "CreateDebt", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipPulled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipPushed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "debtor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "RepayDebt", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "totalReserves", + "type": "uint256" + } + ], + "name": "ReservesAudited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ReservesManaged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "totalReserves", + "type": "uint256" + } + ], + "name": "ReservesUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RewardsMinted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Withdrawal", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "LiquidityDepositorQueue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "LiquidityManagerQueue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "LiquidityTokenQueue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "OHM", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "ReserveManagerQueue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "auditReserves", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "blocksNeededForQueue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "bondCalculator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "debtorBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "debtorQueue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "debtors", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_profit", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "send_", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "excessReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "incurDebt", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isDebtor", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isLiquidityDepositor", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isLiquidityManager", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isLiquidityToken", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isReserveDepositor", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isReserveManager", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isReserveSpender", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isReserveToken", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isRewardManager", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "liquidityDepositors", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "liquidityManagers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "liquidityTokens", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "manage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "manager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "mintRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pullManagement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner_", + "type": "address" + } + ], + "name": "pushManagement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum OlympusTreasury.MANAGING", + "name": "_managing", + "type": "uint8" + }, + { + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "queue", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceManagement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "repayDebtWithOHM", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "repayDebtWithReserve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "reserveDepositorQueue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "reserveDepositors", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "reserveManagers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "reserveSpenderQueue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "reserveSpenders", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "reserveTokenQueue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "reserveTokens", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardManagerQueue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "rewardManagers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sOHM", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sOHMQueue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum OlympusTreasury.MANAGING", + "name": "_managing", + "type": "uint8" + }, + { + "internalType": "address", + "name": "_address", + "type": "address" + }, + { + "internalType": "address", + "name": "_calculator", + "type": "address" + } + ], + "name": "toggle", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "valueOf", + "outputs": [ + { + "internalType": "uint256", + "name": "value_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x6bd94cb2b21498d4c6be446e32cfa401fbe5643f2eaa4cfce8ebc8453cc45b70", + "receipt": { + "to": null, + "from": "0xA38F4E6718EdCF023a1d032a2193848CB932c8e3", + "contractAddress": "0x1e0AD0F8DDFF84FDc938373E9aa66b8d994ea066", + "transactionIndex": 0, + "gasUsed": "5481202", + "logsBloom": "0x00000000000000000000000000000000000000000100000000000000000000000000400000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000020000000000020002000000000000400000000000000000000000000000000000000000000000000", + "blockHash": "0x2c765419362462f188d26934858cd613d4cf3e4db6be6698e0f7b229b3285379", + "transactionHash": "0x6bd94cb2b21498d4c6be446e32cfa401fbe5643f2eaa4cfce8ebc8453cc45b70", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 9907135, + "transactionHash": "0x6bd94cb2b21498d4c6be446e32cfa401fbe5643f2eaa4cfce8ebc8453cc45b70", + "address": "0x1e0AD0F8DDFF84FDc938373E9aa66b8d994ea066", + "topics": [ + "0xea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000a38f4e6718edcf023a1d032a2193848cb932c8e3" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x2c765419362462f188d26934858cd613d4cf3e4db6be6698e0f7b229b3285379" + } + ], + "blockNumber": 9907135, + "cumulativeGasUsed": "5481202", + "status": 1, + "byzantium": true + }, + "args": [ + "0x9bb5E7183e6259183f8E79876eCC0228738C95F6", + "0x0B81a995b28254D76e5148d29E8eb4c5c26D3aC0", + "0xDd1875ddC7c832FA1CB82DfB8B34d3abD1F67a87", + 0 + ], + "solcInputHash": "d0f6f5ddb1e2301823073d2aeed57f8f", + "metadata": "{\"compiler\":{\"version\":\"0.7.5+commit.eb77ed08\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_OHM\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_Frax\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_WrappedToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_blocksNeededForQueue\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"enum OlympusTreasury.MANAGING\",\"name\":\"managing\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"activated\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"result\",\"type\":\"bool\"}],\"name\":\"ChangeActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"enum OlympusTreasury.MANAGING\",\"name\":\"managing\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"queued\",\"type\":\"address\"}],\"name\":\"ChangeQueued\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"debtor\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"CreateDebt\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipPulled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipPushed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"debtor\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"RepayDebt\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"totalReserves\",\"type\":\"uint256\"}],\"name\":\"ReservesAudited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"ReservesManaged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"totalReserves\",\"type\":\"uint256\"}],\"name\":\"ReservesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"RewardsMinted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"LiquidityDepositorQueue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"LiquidityManagerQueue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"LiquidityTokenQueue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OHM\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"ReserveManagerQueue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"auditReserves\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blocksNeededForQueue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bondCalculator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"debtorBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"debtorQueue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"debtors\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_profit\",\"type\":\"uint256\"}],\"name\":\"deposit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"send_\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"excessReserves\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"incurDebt\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isDebtor\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isLiquidityDepositor\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isLiquidityManager\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isLiquidityToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isReserveDepositor\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isReserveManager\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isReserveSpender\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isReserveToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isRewardManager\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"liquidityDepositors\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"liquidityManagers\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"liquidityTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"manage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"manager\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"mintRewards\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pullManagement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner_\",\"type\":\"address\"}],\"name\":\"pushManagement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enum OlympusTreasury.MANAGING\",\"name\":\"_managing\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"queue\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceManagement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"repayDebtWithOHM\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"repayDebtWithReserve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"reserveDepositorQueue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"reserveDepositors\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"reserveManagers\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"reserveSpenderQueue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"reserveSpenders\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"reserveTokenQueue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"reserveTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"rewardManagerQueue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"rewardManagers\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sOHM\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sOHMQueue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enum OlympusTreasury.MANAGING\",\"name\":\"_managing\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_calculator\",\"type\":\"address\"}],\"name\":\"toggle\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalDebt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalReserves\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"valueOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"value_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"deposit(uint256,address,uint256)\":{\"params\":{\"_amount\":\"uint\",\"_profit\":\"uint\",\"_token\":\"address\"},\"returns\":{\"send_\":\"uint\"}},\"excessReserves()\":{\"returns\":{\"_0\":\"uint\"}},\"incurDebt(uint256,address)\":{\"params\":{\"_amount\":\"uint\",\"_token\":\"address\"}},\"manage(address,uint256)\":{\"params\":{\"_amount\":\"uint\",\"_token\":\"address\"}},\"queue(uint8,address)\":{\"params\":{\"_address\":\"address\",\"_managing\":\"MANAGING\"},\"returns\":{\"_0\":\"bool\"}},\"repayDebtWithOHM(uint256)\":{\"params\":{\"_amount\":\"uint\"}},\"repayDebtWithReserve(uint256,address)\":{\"params\":{\"_amount\":\"uint\",\"_token\":\"address\"}},\"toggle(uint8,address,address)\":{\"params\":{\"_address\":\"address\",\"_calculator\":\"address\",\"_managing\":\"MANAGING\"},\"returns\":{\"_0\":\"bool\"}},\"valueOf(address,uint256)\":{\"params\":{\"_amount\":\"uint\",\"_token\":\"address\"},\"returns\":{\"value_\":\"uint\"}},\"withdraw(uint256,address)\":{\"params\":{\"_amount\":\"uint\",\"_token\":\"address\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"auditReserves()\":{\"notice\":\"takes inventory of all tracked assetsalways consolidate to recognized reserves before audit\"},\"deposit(uint256,address,uint256)\":{\"notice\":\"allow approved address to deposit an asset for OHM\"},\"excessReserves()\":{\"notice\":\"returns excess reserves not backing tokens\"},\"incurDebt(uint256,address)\":{\"notice\":\"allow approved address to borrow reserves\"},\"manage(address,uint256)\":{\"notice\":\"allow approved address to withdraw assets\"},\"mintRewards(address,uint256)\":{\"notice\":\"send epoch reward to staking contract\"},\"queue(uint8,address)\":{\"notice\":\"queue address to change boolean in mapping\"},\"repayDebtWithOHM(uint256)\":{\"notice\":\"allow approved address to repay borrowed reserves with OHM\"},\"repayDebtWithReserve(uint256,address)\":{\"notice\":\"allow approved address to repay borrowed reserves with reserves\"},\"toggle(uint8,address,address)\":{\"notice\":\"verify queue then set boolean in mapping\"},\"valueOf(address,uint256)\":{\"notice\":\"returns OHM valuation of asset\"},\"withdraw(uint256,address)\":{\"notice\":\"allow approved address to burn OHM for reserves\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Treasury.sol\":\"OlympusTreasury\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/Treasury.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-or-later\\npragma solidity 0.7.5;\\n\\nlibrary SafeMath {\\n\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n return c;\\n }\\n}\\n\\nlibrary Address {\\n\\n function isContract(address account) internal view returns (bool) {\\n // This method relies in extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return _functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\\n if (success) {\\n return returndata;\\n } else {\\n if (returndata.length > 0) {\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n if (returndata.length > 0) {\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\\ninterface IOwnable {\\n function manager() external view returns (address);\\n\\n function renounceManagement() external;\\n\\n function pushManagement( address newOwner_ ) external;\\n\\n function pullManagement() external;\\n}\\n\\ncontract Ownable is IOwnable {\\n\\n address internal _owner;\\n address internal _newOwner;\\n\\n event OwnershipPushed(address indexed previousOwner, address indexed newOwner);\\n event OwnershipPulled(address indexed previousOwner, address indexed newOwner);\\n\\n constructor () {\\n _owner = msg.sender;\\n emit OwnershipPushed( address(0), _owner );\\n }\\n\\n function manager() public view override returns (address) {\\n return _owner;\\n }\\n\\n modifier onlyManager() {\\n require( _owner == msg.sender, \\\"Ownable: caller is not the owner\\\" );\\n _;\\n }\\n\\n function renounceManagement() public virtual override onlyManager() {\\n emit OwnershipPushed( _owner, address(0) );\\n _owner = address(0);\\n }\\n\\n function pushManagement( address newOwner_ ) public virtual override onlyManager() {\\n require( newOwner_ != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipPushed( _owner, newOwner_ );\\n _newOwner = newOwner_;\\n }\\n\\n function pullManagement() public virtual override {\\n require( msg.sender == _newOwner, \\\"Ownable: must be new owner to pull\\\");\\n emit OwnershipPulled( _owner, _newOwner );\\n _owner = _newOwner;\\n }\\n}\\n\\ninterface IERC20 {\\n function decimals() external view returns (uint8);\\n\\n function balanceOf(address account) external view returns (uint256);\\n\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n function totalSupply() external view returns (uint256);\\n\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\\nlibrary SafeERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\\ninterface IERC20Mintable {\\n function mint( uint256 amount_ ) external;\\n\\n function mint( address account_, uint256 ammount_ ) external;\\n}\\n\\ninterface IOHMERC20 {\\n function burnFrom(address account_, uint256 amount_) external;\\n}\\n\\ninterface IBondCalculator {\\n function valuation( address pair_, uint amount_ ) external view returns ( uint _value );\\n}\\n\\ncontract OlympusTreasury is Ownable {\\n\\n using SafeMath for uint;\\n using SafeERC20 for IERC20;\\n\\n event Deposit( address indexed token, uint amount, uint value );\\n event Withdrawal( address indexed token, uint amount, uint value );\\n event CreateDebt( address indexed debtor, address indexed token, uint amount, uint value );\\n event RepayDebt( address indexed debtor, address indexed token, uint amount, uint value );\\n event ReservesManaged( address indexed token, uint amount );\\n event ReservesUpdated( uint indexed totalReserves );\\n event ReservesAudited( uint indexed totalReserves );\\n event RewardsMinted( address indexed caller, address indexed recipient, uint amount );\\n event ChangeQueued( MANAGING indexed managing, address queued );\\n event ChangeActivated( MANAGING indexed managing, address activated, bool result );\\n\\n enum MANAGING { RESERVEDEPOSITOR, RESERVESPENDER, RESERVETOKEN, RESERVEMANAGER, LIQUIDITYDEPOSITOR, LIQUIDITYTOKEN, LIQUIDITYMANAGER, DEBTOR, REWARDMANAGER, SOHM }\\n\\n address public immutable OHM;\\n uint public immutable blocksNeededForQueue;\\n\\n address[] public reserveTokens; // Push only, beware false-positives.\\n mapping( address => bool ) public isReserveToken;\\n mapping( address => uint ) public reserveTokenQueue; // Delays changes to mapping.\\n\\n address[] public reserveDepositors; // Push only, beware false-positives. Only for viewing.\\n mapping( address => bool ) public isReserveDepositor;\\n mapping( address => uint ) public reserveDepositorQueue; // Delays changes to mapping.\\n\\n address[] public reserveSpenders; // Push only, beware false-positives. Only for viewing.\\n mapping( address => bool ) public isReserveSpender;\\n mapping( address => uint ) public reserveSpenderQueue; // Delays changes to mapping.\\n\\n address[] public liquidityTokens; // Push only, beware false-positives.\\n mapping( address => bool ) public isLiquidityToken;\\n mapping( address => uint ) public LiquidityTokenQueue; // Delays changes to mapping.\\n\\n address[] public liquidityDepositors; // Push only, beware false-positives. Only for viewing.\\n mapping( address => bool ) public isLiquidityDepositor;\\n mapping( address => uint ) public LiquidityDepositorQueue; // Delays changes to mapping.\\n\\n mapping( address => address ) public bondCalculator; // bond calculator for liquidity token\\n\\n address[] public reserveManagers; // Push only, beware false-positives. Only for viewing.\\n mapping( address => bool ) public isReserveManager;\\n mapping( address => uint ) public ReserveManagerQueue; // Delays changes to mapping.\\n\\n address[] public liquidityManagers; // Push only, beware false-positives. Only for viewing.\\n mapping( address => bool ) public isLiquidityManager;\\n mapping( address => uint ) public LiquidityManagerQueue; // Delays changes to mapping.\\n\\n address[] public debtors; // Push only, beware false-positives. Only for viewing.\\n mapping( address => bool ) public isDebtor;\\n mapping( address => uint ) public debtorQueue; // Delays changes to mapping.\\n mapping( address => uint ) public debtorBalance;\\n\\n address[] public rewardManagers; // Push only, beware false-positives. Only for viewing.\\n mapping( address => bool ) public isRewardManager;\\n mapping( address => uint ) public rewardManagerQueue; // Delays changes to mapping.\\n\\n address public sOHM;\\n uint public sOHMQueue; // Delays change to sOHM address\\n\\n uint public totalReserves; // Risk-free value of all assets\\n uint public totalDebt;\\n\\n constructor (\\n address _OHM,\\n address _Frax,\\n address _WrappedToken,\\n uint _blocksNeededForQueue\\n ) {\\n require( _OHM != address(0) );\\n OHM = _OHM;\\n\\n isReserveToken[ _Frax] = true;\\n reserveTokens.push( _Frax );\\n\\n isReserveToken[ _WrappedToken] = true;\\n reserveTokens.push( _WrappedToken );\\n\\n blocksNeededForQueue = _blocksNeededForQueue;\\n }\\n\\n /**\\n @notice allow approved address to deposit an asset for OHM\\n @param _amount uint\\n @param _token address\\n @param _profit uint\\n @return send_ uint\\n */\\n function deposit( uint _amount, address _token, uint _profit ) external returns ( uint send_ ) {\\n require( isReserveToken[ _token ] || isLiquidityToken[ _token ], \\\"Not accepted\\\" );\\n IERC20( _token ).safeTransferFrom( msg.sender, address(this), _amount );\\n\\n if ( isReserveToken[ _token ] ) {\\n require( isReserveDepositor[ msg.sender ], \\\"Not approved\\\" );\\n } else {\\n require( isLiquidityDepositor[ msg.sender ], \\\"Not approved\\\" );\\n }\\n\\n uint value = valueOf(_token, _amount);\\n // mint OHM needed and store amount of rewards for distribution\\n send_ = value.sub( _profit );\\n IERC20Mintable( OHM ).mint( msg.sender, send_ );\\n\\n totalReserves = totalReserves.add( value );\\n emit ReservesUpdated( totalReserves );\\n\\n emit Deposit( _token, _amount, value );\\n }\\n\\n /**\\n @notice allow approved address to burn OHM for reserves\\n @param _amount uint\\n @param _token address\\n */\\n function withdraw( uint _amount, address _token ) external {\\n require( isReserveToken[ _token ], \\\"Not accepted\\\" ); // Only reserves can be used for redemptions\\n require( isReserveSpender[ msg.sender ] == true, \\\"Not approved\\\" );\\n\\n uint value = valueOf( _token, _amount );\\n IOHMERC20( OHM ).burnFrom( msg.sender, value );\\n\\n totalReserves = totalReserves.sub( value );\\n emit ReservesUpdated( totalReserves );\\n\\n IERC20( _token ).safeTransfer( msg.sender, _amount );\\n\\n emit Withdrawal( _token, _amount, value );\\n }\\n\\n /**\\n @notice allow approved address to borrow reserves\\n @param _amount uint\\n @param _token address\\n */\\n function incurDebt( uint _amount, address _token ) external {\\n require( isDebtor[ msg.sender ], \\\"Not approved\\\" );\\n require( isReserveToken[ _token ], \\\"Not accepted\\\" );\\n\\n uint value = valueOf( _token, _amount );\\n\\n uint maximumDebt = IERC20( sOHM ).balanceOf( msg.sender ); // Can only borrow against sOHM held\\n uint availableDebt = maximumDebt.sub( debtorBalance[ msg.sender ] );\\n require( value <= availableDebt, \\\"Exceeds debt limit\\\" );\\n\\n debtorBalance[ msg.sender ] = debtorBalance[ msg.sender ].add( value );\\n totalDebt = totalDebt.add( value );\\n\\n totalReserves = totalReserves.sub( value );\\n emit ReservesUpdated( totalReserves );\\n\\n IERC20( _token ).transfer( msg.sender, _amount );\\n\\n emit CreateDebt( msg.sender, _token, _amount, value );\\n }\\n\\n /**\\n @notice allow approved address to repay borrowed reserves with reserves\\n @param _amount uint\\n @param _token address\\n */\\n function repayDebtWithReserve( uint _amount, address _token ) external {\\n require( isDebtor[ msg.sender ], \\\"Not approved\\\" );\\n require( isReserveToken[ _token ], \\\"Not accepted\\\" );\\n\\n IERC20( _token ).safeTransferFrom( msg.sender, address(this), _amount );\\n\\n uint value = valueOf( _token, _amount );\\n debtorBalance[ msg.sender ] = debtorBalance[ msg.sender ].sub( value );\\n totalDebt = totalDebt.sub( value );\\n\\n totalReserves = totalReserves.add( value );\\n emit ReservesUpdated( totalReserves );\\n\\n emit RepayDebt( msg.sender, _token, _amount, value );\\n }\\n\\n /**\\n @notice allow approved address to repay borrowed reserves with OHM\\n @param _amount uint\\n */\\n function repayDebtWithOHM( uint _amount ) external {\\n require( isDebtor[ msg.sender ], \\\"Not approved\\\" );\\n\\n IOHMERC20( OHM ).burnFrom( msg.sender, _amount );\\n\\n debtorBalance[ msg.sender ] = debtorBalance[ msg.sender ].sub( _amount );\\n totalDebt = totalDebt.sub( _amount );\\n\\n emit RepayDebt( msg.sender, OHM, _amount, _amount );\\n }\\n\\n /**\\n @notice allow approved address to withdraw assets\\n @param _token address\\n @param _amount uint\\n */\\n function manage( address _token, uint _amount ) external {\\n if( isLiquidityToken[ _token ] ) {\\n require( isLiquidityManager[ msg.sender ], \\\"Not approved\\\" );\\n } else {\\n require( isReserveManager[ msg.sender ], \\\"Not approved\\\" );\\n }\\n\\n uint value = valueOf(_token, _amount);\\n require( value <= excessReserves(), \\\"Insufficient reserves\\\" );\\n\\n totalReserves = totalReserves.sub( value );\\n emit ReservesUpdated( totalReserves );\\n\\n IERC20( _token ).safeTransfer( msg.sender, _amount );\\n\\n emit ReservesManaged( _token, _amount );\\n }\\n\\n /**\\n @notice send epoch reward to staking contract\\n */\\n function mintRewards( address _recipient, uint _amount ) external {\\n require( isRewardManager[ msg.sender ], \\\"Not approved\\\" );\\n require( _amount <= excessReserves(), \\\"Insufficient reserves\\\" );\\n\\n IERC20Mintable( OHM ).mint( _recipient, _amount );\\n\\n emit RewardsMinted( msg.sender, _recipient, _amount );\\n }\\n\\n /**\\n @notice returns excess reserves not backing tokens\\n @return uint\\n */\\n function excessReserves() public view returns ( uint ) {\\n return totalReserves.sub( IERC20( OHM ).totalSupply().sub( totalDebt ) );\\n }\\n\\n /**\\n @notice takes inventory of all tracked assets\\n @notice always consolidate to recognized reserves before audit\\n */\\n function auditReserves() external onlyManager() {\\n uint reserves;\\n for( uint i = 0; i < reserveTokens.length; i++ ) {\\n reserves = reserves.add (\\n valueOf( reserveTokens[ i ], IERC20( reserveTokens[ i ] ).balanceOf( address(this) ) )\\n );\\n }\\n for( uint i = 0; i < liquidityTokens.length; i++ ) {\\n reserves = reserves.add (\\n valueOf( liquidityTokens[ i ], IERC20( liquidityTokens[ i ] ).balanceOf( address(this) ) )\\n );\\n }\\n totalReserves = reserves;\\n emit ReservesUpdated( reserves );\\n emit ReservesAudited( reserves );\\n }\\n\\n /**\\n @notice returns OHM valuation of asset\\n @param _token address\\n @param _amount uint\\n @return value_ uint\\n */\\n function valueOf( address _token, uint _amount ) public view returns ( uint value_ ) {\\n if ( isReserveToken[ _token ] ) {\\n // convert amount to match OHM decimals\\n value_ = _amount.mul( 10 ** IERC20( OHM ).decimals() ).div( 10 ** IERC20( _token ).decimals() );\\n } else if ( isLiquidityToken[ _token ] ) {\\n value_ = IBondCalculator( bondCalculator[ _token ] ).valuation( _token, _amount );\\n }\\n }\\n\\n /**\\n @notice queue address to change boolean in mapping\\n @param _managing MANAGING\\n @param _address address\\n @return bool\\n */\\n function queue( MANAGING _managing, address _address ) external onlyManager() returns ( bool ) {\\n require( _address != address(0) );\\n if ( _managing == MANAGING.RESERVEDEPOSITOR ) { // 0\\n reserveDepositorQueue[ _address ] = block.number.add( blocksNeededForQueue );\\n } else if ( _managing == MANAGING.RESERVESPENDER ) { // 1\\n reserveSpenderQueue[ _address ] = block.number.add( blocksNeededForQueue );\\n } else if ( _managing == MANAGING.RESERVETOKEN ) { // 2\\n reserveTokenQueue[ _address ] = block.number.add( blocksNeededForQueue );\\n } else if ( _managing == MANAGING.RESERVEMANAGER ) { // 3\\n ReserveManagerQueue[ _address ] = block.number.add( blocksNeededForQueue.mul( 2 ) );\\n } else if ( _managing == MANAGING.LIQUIDITYDEPOSITOR ) { // 4\\n LiquidityDepositorQueue[ _address ] = block.number.add( blocksNeededForQueue );\\n } else if ( _managing == MANAGING.LIQUIDITYTOKEN ) { // 5\\n LiquidityTokenQueue[ _address ] = block.number.add( blocksNeededForQueue );\\n } else if ( _managing == MANAGING.LIQUIDITYMANAGER ) { // 6\\n LiquidityManagerQueue[ _address ] = block.number.add( blocksNeededForQueue.mul( 2 ) );\\n } else if ( _managing == MANAGING.DEBTOR ) { // 7\\n debtorQueue[ _address ] = block.number.add( blocksNeededForQueue );\\n } else if ( _managing == MANAGING.REWARDMANAGER ) { // 8\\n rewardManagerQueue[ _address ] = block.number.add( blocksNeededForQueue );\\n } else if ( _managing == MANAGING.SOHM ) { // 9\\n sOHMQueue = block.number.add( blocksNeededForQueue );\\n } else return false;\\n\\n emit ChangeQueued( _managing, _address );\\n return true;\\n }\\n\\n /**\\n @notice verify queue then set boolean in mapping\\n @param _managing MANAGING\\n @param _address address\\n @param _calculator address\\n @return bool\\n */\\n function toggle( MANAGING _managing, address _address, address _calculator ) external onlyManager() returns ( bool ) {\\n require( _address != address(0) );\\n bool result;\\n if ( _managing == MANAGING.RESERVEDEPOSITOR ) { // 0\\n if ( requirements( reserveDepositorQueue, isReserveDepositor, _address ) ) {\\n reserveDepositorQueue[ _address ] = 0;\\n if( !listContains( reserveDepositors, _address ) ) {\\n reserveDepositors.push( _address );\\n }\\n }\\n result = !isReserveDepositor[ _address ];\\n isReserveDepositor[ _address ] = result;\\n\\n } else if ( _managing == MANAGING.RESERVESPENDER ) { // 1\\n if ( requirements( reserveSpenderQueue, isReserveSpender, _address ) ) {\\n reserveSpenderQueue[ _address ] = 0;\\n if( !listContains( reserveSpenders, _address ) ) {\\n reserveSpenders.push( _address );\\n }\\n }\\n result = !isReserveSpender[ _address ];\\n isReserveSpender[ _address ] = result;\\n\\n } else if ( _managing == MANAGING.RESERVETOKEN ) { // 2\\n if ( requirements( reserveTokenQueue, isReserveToken, _address ) ) {\\n reserveTokenQueue[ _address ] = 0;\\n if( !listContains( reserveTokens, _address ) ) {\\n reserveTokens.push( _address );\\n }\\n }\\n result = !isReserveToken[ _address ];\\n isReserveToken[ _address ] = result;\\n\\n } else if ( _managing == MANAGING.RESERVEMANAGER ) { // 3\\n if ( requirements( ReserveManagerQueue, isReserveManager, _address ) ) {\\n reserveManagers.push( _address );\\n ReserveManagerQueue[ _address ] = 0;\\n if( !listContains( reserveManagers, _address ) ) {\\n reserveManagers.push( _address );\\n }\\n }\\n result = !isReserveManager[ _address ];\\n isReserveManager[ _address ] = result;\\n\\n } else if ( _managing == MANAGING.LIQUIDITYDEPOSITOR ) { // 4\\n if ( requirements( LiquidityDepositorQueue, isLiquidityDepositor, _address ) ) {\\n liquidityDepositors.push( _address );\\n LiquidityDepositorQueue[ _address ] = 0;\\n if( !listContains( liquidityDepositors, _address ) ) {\\n liquidityDepositors.push( _address );\\n }\\n }\\n result = !isLiquidityDepositor[ _address ];\\n isLiquidityDepositor[ _address ] = result;\\n\\n } else if ( _managing == MANAGING.LIQUIDITYTOKEN ) { // 5\\n if ( requirements( LiquidityTokenQueue, isLiquidityToken, _address ) ) {\\n LiquidityTokenQueue[ _address ] = 0;\\n if( !listContains( liquidityTokens, _address ) ) {\\n liquidityTokens.push( _address );\\n }\\n }\\n result = !isLiquidityToken[ _address ];\\n isLiquidityToken[ _address ] = result;\\n bondCalculator[ _address ] = _calculator;\\n\\n } else if ( _managing == MANAGING.LIQUIDITYMANAGER ) { // 6\\n if ( requirements( LiquidityManagerQueue, isLiquidityManager, _address ) ) {\\n LiquidityManagerQueue[ _address ] = 0;\\n if( !listContains( liquidityManagers, _address ) ) {\\n liquidityManagers.push( _address );\\n }\\n }\\n result = !isLiquidityManager[ _address ];\\n isLiquidityManager[ _address ] = result;\\n\\n } else if ( _managing == MANAGING.DEBTOR ) { // 7\\n if ( requirements( debtorQueue, isDebtor, _address ) ) {\\n debtorQueue[ _address ] = 0;\\n if( !listContains( debtors, _address ) ) {\\n debtors.push( _address );\\n }\\n }\\n result = !isDebtor[ _address ];\\n isDebtor[ _address ] = result;\\n\\n } else if ( _managing == MANAGING.REWARDMANAGER ) { // 8\\n if ( requirements( rewardManagerQueue, isRewardManager, _address ) ) {\\n rewardManagerQueue[ _address ] = 0;\\n if( !listContains( rewardManagers, _address ) ) {\\n rewardManagers.push( _address );\\n }\\n }\\n result = !isRewardManager[ _address ];\\n isRewardManager[ _address ] = result;\\n\\n } else if ( _managing == MANAGING.SOHM ) { // 9\\n sOHMQueue = 0;\\n sOHM = _address;\\n result = true;\\n\\n } else return false;\\n\\n emit ChangeActivated( _managing, _address, result );\\n return true;\\n }\\n\\n /**\\n @notice checks requirements and returns altered structs\\n @param queue_ mapping( address => uint )\\n @param status_ mapping( address => bool )\\n @param _address address\\n @return bool\\n */\\n function requirements(\\n mapping( address => uint ) storage queue_,\\n mapping( address => bool ) storage status_,\\n address _address\\n ) internal view returns ( bool ) {\\n if ( !status_[ _address ] ) {\\n require( queue_[ _address ] != 0, \\\"Must queue\\\" );\\n require( queue_[ _address ] <= block.number, \\\"Queue not expired\\\" );\\n return true;\\n } return false;\\n }\\n\\n /**\\n @notice checks array to ensure against duplicate\\n @param _list address[]\\n @param _token address\\n @return bool\\n */\\n function listContains( address[] storage _list, address _token ) internal view returns ( bool ) {\\n for( uint i = 0; i < _list.length; i++ ) {\\n if( _list[ i ] == _token ) {\\n return true;\\n }\\n }\\n return false;\\n }\\n}\",\"keccak256\":\"0x8e786d8174133e2a83dd36d691b6ae7e0eb62aa96f0b143f093a121c09254c92\",\"license\":\"AGPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x60c06040523480156200001157600080fd5b506040516200636e3803806200636e833981810160405260808110156200003757600080fd5b8101908080519060200190929190805190602001909291908051906020019092919080519060200190929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a3600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156200015c57600080fd5b8373ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b815250506001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506002839080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506002829080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060a081815250505050505060805160601c60a051615fdd62000391600039806138025280613c8a5280613d245280613dbe5280613e5d5280613f055280613f9f528061403e52806140e6528061418052806142195250806113ae5280611a315280611bb55280611d0e52806124335280612fb8528061327452806136425250615fdd6000f3fe608060405234801561001057600080fd5b50600436106102f05760003560e01c806387d67dff1161019d578063cd85641a116100e9578063ebd83cd8116100a2578063fbfd393b1161007c578063fbfd393b146110c4578063fc7b9c181461114b578063fd1ec01014611169578063fff9ee87146111c1576102f0565b8063ebd83cd814610fb8578063ee4e19a114611012578063fb9395881461106c576102f0565b8063cd85641a14610ddb578063d031370b14610e33578063d07f390f14610e8b578063d796ffb814610ea9578063df89b34414610ef7578063e83afee314610f51576102f0565b8063a569e57111610156578063b1bd38b011610130578063b1bd38b014610c67578063b5b1d56014610cbf578063bc157ac114610d17578063c24ad43e14610d83576102f0565b8063a569e57114610b81578063a6c41fec14610bdb578063ab319c9a14610c0f576102f0565b806387d67dff146109a75780638f59c72714610a015780638f6a7b5714610a595780638f840ddd14610ab1578063932cc8c314610acf578063a1210a2d14610b27576102f0565b80632789de371161025c5780635a96ac0a116102155780636b5e40a7116101ef5780636b5e40a71461084757806370a0502a1461089f578063788c6c01146108f7578063869871bf1461094f576102f0565b80635a96ac0a1461079557806368c31dd51461079f5780636a20de92146107f9576102f0565b80632789de37146106435780632b7ce50014610661578063437f79121461066b57806346f68ee9146106c3578063481c6a75146107075780634e83423c1461073b576102f0565b80630f70431f116102ae5780630f70431f14610469578063124154ca1461049757806312422d23146104f1578063150799251461053f5780631af4da70146105735780631eec5a9a146105e1576102f0565b8062f714ce146102f55780630619aff114610343578063089208d81461039b578063094a8651146103a55780630b0eee30146103fd5780630c3513a81461044b575b600080fd5b6103416004803603604081101561030b57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611219565b005b61036f6004803603602081101561035957600080fd5b8101908080359060200190929190505050611525565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103a3611564565b005b6103e7600480360360208110156103bb57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506116e3565b6040518082815260200191505060405180910390f35b6104496004803603604081101561041357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506116fb565b005b610453611a24565b6040518082815260200191505060405180910390f35b6104956004803603602081101561047f57600080fd5b8101908080359060200190929190505050611af4565b005b6104d9600480360360208110156104ad57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611d9c565b60405180821515815260200191505060405180910390f35b61053d6004803603604081101561050757600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611dbc565b005b6105476122f7565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6105b56004803603602081101561058957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061231d565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61062d600480360360408110156105f757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612350565b6040518082815260200191505060405180910390f35b61064b612661565b6040518082815260200191505060405180910390f35b610669612667565b005b6106976004803603602081101561068157600080fd5b8101908080359060200190929190505050612a27565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610705600480360360208110156106d957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612a66565b005b61070f612c6b565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61077d6004803603602081101561075157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612c94565b60405180821515815260200191505060405180910390f35b61079d612cb4565b005b6107e1600480360360208110156107b557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612e5a565b60405180821515815260200191505060405180910390f35b6108456004803603604081101561080f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612e7a565b005b6108736004803603602081101561085d57600080fd5b81019080803590602001909291905050506130c8565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6108cb600480360360208110156108b557600080fd5b8101908080359060200190929190505050613107565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6109396004803603602081101561090d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613146565b6040518082815260200191505060405180910390f35b61097b6004803603602081101561096557600080fd5b810190808035906020019092919050505061315e565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6109e9600480360360208110156109bd57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061319d565b60405180821515815260200191505060405180910390f35b610a4360048036036020811015610a1757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506131bd565b6040518082815260200191505060405180910390f35b610a8560048036036020811015610a6f57600080fd5b81019080803590602001909291905050506131d5565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610ab9613214565b6040518082815260200191505060405180910390f35b610b1160048036036020811015610ae557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061321a565b6040518082815260200191505060405180910390f35b610b6960048036036020811015610b3d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613232565b60405180821515815260200191505060405180910390f35b610bc360048036036020811015610b9757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613252565b60405180821515815260200191505060405180910390f35b610be3613272565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610c5160048036036020811015610c2557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613296565b6040518082815260200191505060405180910390f35b610ca960048036036020811015610c7d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506132ae565b6040518082815260200191505060405180910390f35b610ceb60048036036020811015610cd557600080fd5b81019080803590602001909291905050506132c6565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610d6d60048036036060811015610d2d57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613305565b6040518082815260200191505060405180910390f35b610dc560048036036020811015610d9957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613791565b6040518082815260200191505060405180910390f35b610e1d60048036036020811015610df157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506137a9565b6040518082815260200191505060405180910390f35b610e5f60048036036020811015610e4957600080fd5b81019080803590602001909291905050506137c1565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610e93613800565b6040518082815260200191505060405180910390f35b610ef560048036036040811015610ebf57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613824565b005b610f3960048036036020811015610f0d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613b49565b60405180821515815260200191505060405180910390f35b610fa060048036036040811015610f6757600080fd5b81019080803560ff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613b69565b60405180821515815260200191505060405180910390f35b610ffa60048036036020811015610fce57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506142c8565b60405180821515815260200191505060405180910390f35b6110546004803603602081101561102857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506142e8565b60405180821515815260200191505060405180910390f35b6110ae6004803603602081101561108257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614308565b6040518082815260200191505060405180910390f35b611133600480360360608110156110da57600080fd5b81019080803560ff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614320565b60405180821515815260200191505060405180910390f35b61115361549b565b6040518082815260200191505060405180910390f35b6111956004803603602081101561117f57600080fd5b81019080803590602001909291905050506154a1565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b611203600480360360208110156111d757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506154e0565b6040518082815260200191505060405180910390f35b600360008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166112d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e6f74206163636570746564000000000000000000000000000000000000000081525060200191505060405180910390fd5b60011515600960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615151461139e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e6f7420617070726f766564000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006113aa8284612350565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166379cc679033836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b15801561143d57600080fd5b505af1158015611451573d6000803e3d6000fd5b5050505061146a816021546154f890919063ffffffff16565b6021819055506021547f93bb8edd35984706eee1b92541281f7f62d33c01c5b2ec0929a113603bd21d6660405160405180910390a26114ca33848473ffffffffffffffffffffffffffffffffffffffff166155429092919063ffffffff16565b8173ffffffffffffffffffffffffffffffffffffffff167fdf273cb619d95419a9cd0ec88123a0538c85064229baa6363788f743fff90deb8483604051808381526020018281526020019250505060405180910390a2505050565b6012818154811061153557600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611625576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b601b6020528060005260406000206000915090505481565b600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561181157601660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661180c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e6f7420617070726f766564000000000000000000000000000000000000000081525060200191505060405180910390fd5b6118d1565b601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166118d0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e6f7420617070726f766564000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b60006118dd8383612350565b90506118e7611a24565b81111561195c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f496e73756666696369656e74207265736572766573000000000000000000000081525060200191505060405180910390fd5b611971816021546154f890919063ffffffff16565b6021819055506021547f93bb8edd35984706eee1b92541281f7f62d33c01c5b2ec0929a113603bd21d6660405160405180910390a26119d133838573ffffffffffffffffffffffffffffffffffffffff166155429092919063ffffffff16565b8273ffffffffffffffffffffffffffffffffffffffff167f2bb2640731848fe9820ba48dbc978c1fc9bbd5f11b948bfab05b7dee3378fd80836040518082815260200191505060405180910390a2505050565b6000611aef611ade6022547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611a9557600080fd5b505afa158015611aa9573d6000803e3d6000fd5b505050506040513d6020811015611abf57600080fd5b81019080805190602001909291905050506154f890919063ffffffff16565b6021546154f890919063ffffffff16565b905090565b601960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611bb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e6f7420617070726f766564000000000000000000000000000000000000000081525060200191505060405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166379cc679033836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b158015611c4457600080fd5b505af1158015611c58573d6000803e3d6000fd5b50505050611cae81601b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546154f890919063ffffffff16565b601b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611d06816022546154f890919063ffffffff16565b6022819055507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc6d98eecfc9c78ab62c89a82950079b54874749f1f6f24090f7acc758bc2f3098384604051808381526020018281526020019250505060405180910390a350565b60066020528060005260406000206000915054906101000a900460ff1681565b601960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611e7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e6f7420617070726f766564000000000000000000000000000000000000000081525060200191505060405180910390fd5b600360008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611f3a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e6f74206163636570746564000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000611f468284612350565b90506000601f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611fd357600080fd5b505afa158015611fe7573d6000803e3d6000fd5b505050506040513d6020811015611ffd57600080fd5b810190808051906020019092919050505090506000612064601b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054836154f890919063ffffffff16565b9050808311156120dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f457863656564732064656274206c696d6974000000000000000000000000000081525060200191505060405180910390fd5b61212e83601b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546155e490919063ffffffff16565b601b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550612186836022546155e490919063ffffffff16565b6022819055506121a1836021546154f890919063ffffffff16565b6021819055506021547f93bb8edd35984706eee1b92541281f7f62d33c01c5b2ec0929a113603bd21d6660405160405180910390a28373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33876040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561224757600080fd5b505af115801561225b573d6000803e3d6000fd5b505050506040513d602081101561227157600080fd5b8101908080519060200190929190505050508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f7e1a939bed137a819b5d2979822c67f877689f7a863d5e4cb57cdca97b2977d68786604051808381526020018281526020019250505060405180910390a35050505050565b601f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60116020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156124fc576124f58373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b1580156123ed57600080fd5b505afa158015612401573d6000803e3d6000fd5b505050506040513d602081101561241757600080fd5b810190808051906020019092919050505060ff16600a0a6124e77f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561249757600080fd5b505afa1580156124ab573d6000803e3d6000fd5b505050506040513d60208110156124c157600080fd5b810190808051906020019092919050505060ff16600a0a8561566c90919063ffffffff16565b6156f290919063ffffffff16565b905061265b565b600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561265a57601160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634249719f84846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060206040518083038186803b15801561261c57600080fd5b505afa158015612630573d6000803e3d6000fd5b505050506040513d602081101561264657600080fd5b810190808051906020019092919050505090505b5b92915050565b60205481565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612728576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600080600090505b600280549050811015612877576128686128596002838154811061275057fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166002848154811061278857fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561281957600080fd5b505afa15801561282d573d6000803e3d6000fd5b505050506040513d602081101561284357600080fd5b8101908080519060200190929190505050612350565b836155e490919063ffffffff16565b91508080600101915050612730565b5060005b600b805490508110156129c2576129b36129a4600b838154811061289b57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600b84815481106128d357fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561296457600080fd5b505afa158015612978573d6000803e3d6000fd5b505050506040513d602081101561298e57600080fd5b8101908080519060200190929190505050612350565b836155e490919063ffffffff16565b9150808060010191505061287b565b5080602181905550807f93bb8edd35984706eee1b92541281f7f62d33c01c5b2ec0929a113603bd21d6660405160405180910390a2807fec691f09f6924b27932253f85caf99bacc30360cc0e50a1cc4d2acc24601446660405160405180910390a250565b60088181548110612a3757600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612b27576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612bad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180615f156026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a380600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b601d6020528060005260406000206000915054906101000a900460ff1681565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612d5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615f3b6022913960400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167faa151555690c956fc3ea32f106bb9f119b5237a061eaa8557cff3e51e3792c8d60405160405180910390a3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60036020528060005260406000206000915054906101000a900460ff1681565b601d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16612f39576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e6f7420617070726f766564000000000000000000000000000000000000000081525060200191505060405180910390fd5b612f41611a24565b811115612fb6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f496e73756666696369656e74207265736572766573000000000000000000000081525060200191505060405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166340c10f1983836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b15801561304757600080fd5b505af115801561305b573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167ffa8ccab40e7da8146c2304cd0950334fd30a6ba093abe86261aa13911fed849c836040518082815260200191505060405180910390a35050565b600581815481106130d857600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6015818154811061311757600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60046020528060005260406000206000915090505481565b6018818154811061316e57600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60096020528060005260406000206000915054906101000a900460ff1681565b600d6020528060005260406000206000915090505481565b600e81815481106131e557600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60215481565b60076020528060005260406000206000915090505481565b600f6020528060005260406000206000915054906101000a900460ff1681565b600c6020528060005260406000206000915054906101000a900460ff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b60176020528060005260406000206000915090505481565b60146020528060005260406000206000915090505481565b601c81815481106132d657600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16806133a85750600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b61341a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e6f74206163636570746564000000000000000000000000000000000000000081525060200191505060405180910390fd5b6134473330868673ffffffffffffffffffffffffffffffffffffffff1661573c909392919063ffffffff16565b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561355d57600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16613558576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e6f7420617070726f766564000000000000000000000000000000000000000081525060200191505060405180910390fd5b61361d565b600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661361c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e6f7420617070726f766564000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b60006136298486612350565b905061363e83826154f890919063ffffffff16565b91507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166340c10f1933846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b1580156136d157600080fd5b505af11580156136e5573d6000803e3d6000fd5b505050506136fe816021546155e490919063ffffffff16565b6021819055506021547f93bb8edd35984706eee1b92541281f7f62d33c01c5b2ec0929a113603bd21d6660405160405180910390a28373ffffffffffffffffffffffffffffffffffffffff167f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a158683604051808381526020018281526020019250505060405180910390a2509392505050565b600a6020528060005260406000206000915090505481565b601a6020528060005260406000206000915090505481565b600281815481106137d157600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b601960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166138e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e6f7420617070726f766564000000000000000000000000000000000000000081525060200191505060405180910390fd5b600360008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166139a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e6f74206163636570746564000000000000000000000000000000000000000081525060200191505060405180910390fd5b6139cf3330848473ffffffffffffffffffffffffffffffffffffffff1661573c909392919063ffffffff16565b60006139db8284612350565b9050613a2f81601b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546154f890919063ffffffff16565b601b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550613a87816022546154f890919063ffffffff16565b602281905550613aa2816021546155e490919063ffffffff16565b6021819055506021547f93bb8edd35984706eee1b92541281f7f62d33c01c5b2ec0929a113603bd21d6660405160405180910390a28173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc6d98eecfc9c78ab62c89a82950079b54874749f1f6f24090f7acc758bc2f3098584604051808381526020018281526020019250505060405180910390a3505050565b60166020528060005260406000206000915054906101000a900460ff1681565b60003373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613c2c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613c6657600080fd5b60006009811115613c7357fe5b836009811115613c7f57fe5b1415613d0057613cb87f0000000000000000000000000000000000000000000000000000000000000000436155e490919063ffffffff16565b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550614264565b60016009811115613d0d57fe5b836009811115613d1957fe5b1415613d9a57613d527f0000000000000000000000000000000000000000000000000000000000000000436155e490919063ffffffff16565b600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550614263565b60026009811115613da757fe5b836009811115613db357fe5b1415613e3457613dec7f0000000000000000000000000000000000000000000000000000000000000000436155e490919063ffffffff16565b600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550614262565b60036009811115613e4157fe5b836009811115613e4d57fe5b1415613ee157613e99613e8a60027f000000000000000000000000000000000000000000000000000000000000000061566c90919063ffffffff16565b436155e490919063ffffffff16565b601460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550614261565b60046009811115613eee57fe5b836009811115613efa57fe5b1415613f7b57613f337f0000000000000000000000000000000000000000000000000000000000000000436155e490919063ffffffff16565b601060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550614260565b60056009811115613f8857fe5b836009811115613f9457fe5b141561401557613fcd7f0000000000000000000000000000000000000000000000000000000000000000436155e490919063ffffffff16565b600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061425f565b6006600981111561402257fe5b83600981111561402e57fe5b14156140c25761407a61406b60027f000000000000000000000000000000000000000000000000000000000000000061566c90919063ffffffff16565b436155e490919063ffffffff16565b601760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061425e565b600760098111156140cf57fe5b8360098111156140db57fe5b141561415c576141147f0000000000000000000000000000000000000000000000000000000000000000436155e490919063ffffffff16565b601a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061425d565b6008600981111561416957fe5b83600981111561417557fe5b14156141f6576141ae7f0000000000000000000000000000000000000000000000000000000000000000436155e490919063ffffffff16565b601e60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061425c565b60098081111561420257fe5b83600981111561420e57fe5b1415614252576142477f0000000000000000000000000000000000000000000000000000000000000000436155e490919063ffffffff16565b60208190555061425b565b600090506142c2565b5b5b5b5b5b5b5b5b5b82600981111561427057fe5b7f0e4f2c4b5bc209d509bc3d49348c787fefadc66a79351b470599ac0f5be52eaf83604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a2600190505b92915050565b60136020528060005260406000206000915054906101000a900460ff1681565b60196020528060005260406000206000915054906101000a900460ff1681565b601e6020528060005260406000206000915090505481565b60003373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146143e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561441d57600080fd5b600080600981111561442b57fe5b85600981111561443757fe5b14156145b45761444a60076006866157fd565b15614508576000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061449f6005856159cd565b614507576005849080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615905080600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061542b565b600160098111156145c157fe5b8560098111156145cd57fe5b141561474a576145e0600a6009866157fd565b1561469e576000600a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506146356008856159cd565b61469d576008849080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b600960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615905080600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061542a565b6002600981111561475757fe5b85600981111561476357fe5b14156148e05761477660046003866157fd565b15614834576000600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506147cb6002856159cd565b614833576002849080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615905080600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550615429565b600360098111156148ed57fe5b8560098111156148f957fe5b1415614ad95761490c60146013866157fd565b15614a2d576012849080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000601460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506149c46012856159cd565b614a2c576012849080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b601360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615905080601360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550615428565b60046009811115614ae657fe5b856009811115614af257fe5b1415614cd257614b056010600f866157fd565b15614c2657600e849080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000601060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550614bbd600e856159cd565b614c2557600e849080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615905080600f60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550615427565b60056009811115614cdf57fe5b856009811115614ceb57fe5b1415614ee657614cfe600d600c866157fd565b15614dbc576000600d60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550614d53600b856159cd565b614dbb57600b849080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b600c60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615905080600c60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555082601160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550615426565b60066009811115614ef357fe5b856009811115614eff57fe5b141561507c57614f1260176016866157fd565b15614fd0576000601760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550614f676015856159cd565b614fcf576015849080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b601660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615905080601660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550615425565b6007600981111561508957fe5b85600981111561509557fe5b1415615212576150a8601a6019866157fd565b15615166576000601a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506150fd6018856159cd565b615165576018849080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b601960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615905080601960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550615424565b6008600981111561521f57fe5b85600981111561522b57fe5b14156153a85761523e601e601d866157fd565b156152fc576000601e60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550615293601c856159cd565b6152fb57601c849080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b601d60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615905080601d60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550615423565b6009808111156153b457fe5b8560098111156153c057fe5b141561541857600060208190555083601f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060019050615422565b6000915050615494565b5b5b5b5b5b5b5b5b5b84600981111561543757fe5b7f0dcacb7e392f3d6a216ed2660e3dcfd40b7793d33591db2ba185a6b8e44fc4778583604051808373ffffffffffffffffffffffffffffffffffffffff16815260200182151581526020019250505060405180910390a260019150505b9392505050565b60225481565b600b81815481106154b157600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60106020528060005260406000206000915090505481565b600061553a83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250615a6e565b905092915050565b6155df8363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050615b2e565b505050565b600080828401905083811015615662576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b60008083141561567f57600090506156ec565b600082840290508284828161569057fe5b04146156e7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180615f5d6021913960400191505060405180910390fd5b809150505b92915050565b600061573483836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250615c1d565b905092915050565b6157f7846323b872dd60e01b858585604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050615b2e565b50505050565b60008260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166159c15760008460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541415615904576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f4d7573742071756575650000000000000000000000000000000000000000000081525060200191505060405180910390fd5b438460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205411156159b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f5175657565206e6f74206578706972656400000000000000000000000000000081525060200191505060405180910390fd5b600190506159c6565b600090505b9392505050565b600080600090505b8380549050811015615a62578273ffffffffffffffffffffffffffffffffffffffff16848281548110615a0457fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415615a55576001915050615a68565b80806001019150506159d5565b50600090505b92915050565b6000838311158290615b1b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015615ae0578082015181840152602081019050615ac5565b50505050905090810190601f168015615b0d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b6060615b90826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16615ce39092919063ffffffff16565b9050600081511115615c1857808060200190516020811015615bb157600080fd5b8101908080519060200190929190505050615c17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180615f7e602a913960400191505060405180910390fd5b5b505050565b60008083118290615cc9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015615c8e578082015181840152602081019050615c73565b50505050905090810190601f168015615cbb5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581615cd557fe5b049050809150509392505050565b6060615cf28484600085615cfb565b90509392505050565b6060615d0685615f01565b615d78576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b60208310615dc85780518252602082019150602081019050602083039250615da5565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114615e2a576040519150601f19603f3d011682016040523d82523d6000602084013e615e2f565b606091505b50915091508115615e44578092505050615ef9565b600081511115615e575780518082602001fd5b836040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015615ebe578082015181840152602081019050615ea3565b50505050905090810190601f168015615eeb5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b949350505050565b600080823b90506000811191505091905056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a206d757374206265206e6577206f776e657220746f2070756c6c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a264697066735822122008d0f7e49153f0b48488475584a96ebc39560c77f97a005ed01ceee5d826e77b64736f6c63430007050033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102f05760003560e01c806387d67dff1161019d578063cd85641a116100e9578063ebd83cd8116100a2578063fbfd393b1161007c578063fbfd393b146110c4578063fc7b9c181461114b578063fd1ec01014611169578063fff9ee87146111c1576102f0565b8063ebd83cd814610fb8578063ee4e19a114611012578063fb9395881461106c576102f0565b8063cd85641a14610ddb578063d031370b14610e33578063d07f390f14610e8b578063d796ffb814610ea9578063df89b34414610ef7578063e83afee314610f51576102f0565b8063a569e57111610156578063b1bd38b011610130578063b1bd38b014610c67578063b5b1d56014610cbf578063bc157ac114610d17578063c24ad43e14610d83576102f0565b8063a569e57114610b81578063a6c41fec14610bdb578063ab319c9a14610c0f576102f0565b806387d67dff146109a75780638f59c72714610a015780638f6a7b5714610a595780638f840ddd14610ab1578063932cc8c314610acf578063a1210a2d14610b27576102f0565b80632789de371161025c5780635a96ac0a116102155780636b5e40a7116101ef5780636b5e40a71461084757806370a0502a1461089f578063788c6c01146108f7578063869871bf1461094f576102f0565b80635a96ac0a1461079557806368c31dd51461079f5780636a20de92146107f9576102f0565b80632789de37146106435780632b7ce50014610661578063437f79121461066b57806346f68ee9146106c3578063481c6a75146107075780634e83423c1461073b576102f0565b80630f70431f116102ae5780630f70431f14610469578063124154ca1461049757806312422d23146104f1578063150799251461053f5780631af4da70146105735780631eec5a9a146105e1576102f0565b8062f714ce146102f55780630619aff114610343578063089208d81461039b578063094a8651146103a55780630b0eee30146103fd5780630c3513a81461044b575b600080fd5b6103416004803603604081101561030b57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611219565b005b61036f6004803603602081101561035957600080fd5b8101908080359060200190929190505050611525565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103a3611564565b005b6103e7600480360360208110156103bb57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506116e3565b6040518082815260200191505060405180910390f35b6104496004803603604081101561041357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506116fb565b005b610453611a24565b6040518082815260200191505060405180910390f35b6104956004803603602081101561047f57600080fd5b8101908080359060200190929190505050611af4565b005b6104d9600480360360208110156104ad57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611d9c565b60405180821515815260200191505060405180910390f35b61053d6004803603604081101561050757600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611dbc565b005b6105476122f7565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6105b56004803603602081101561058957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061231d565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61062d600480360360408110156105f757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612350565b6040518082815260200191505060405180910390f35b61064b612661565b6040518082815260200191505060405180910390f35b610669612667565b005b6106976004803603602081101561068157600080fd5b8101908080359060200190929190505050612a27565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610705600480360360208110156106d957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612a66565b005b61070f612c6b565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61077d6004803603602081101561075157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612c94565b60405180821515815260200191505060405180910390f35b61079d612cb4565b005b6107e1600480360360208110156107b557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612e5a565b60405180821515815260200191505060405180910390f35b6108456004803603604081101561080f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612e7a565b005b6108736004803603602081101561085d57600080fd5b81019080803590602001909291905050506130c8565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6108cb600480360360208110156108b557600080fd5b8101908080359060200190929190505050613107565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6109396004803603602081101561090d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613146565b6040518082815260200191505060405180910390f35b61097b6004803603602081101561096557600080fd5b810190808035906020019092919050505061315e565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6109e9600480360360208110156109bd57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061319d565b60405180821515815260200191505060405180910390f35b610a4360048036036020811015610a1757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506131bd565b6040518082815260200191505060405180910390f35b610a8560048036036020811015610a6f57600080fd5b81019080803590602001909291905050506131d5565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610ab9613214565b6040518082815260200191505060405180910390f35b610b1160048036036020811015610ae557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061321a565b6040518082815260200191505060405180910390f35b610b6960048036036020811015610b3d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613232565b60405180821515815260200191505060405180910390f35b610bc360048036036020811015610b9757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613252565b60405180821515815260200191505060405180910390f35b610be3613272565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610c5160048036036020811015610c2557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613296565b6040518082815260200191505060405180910390f35b610ca960048036036020811015610c7d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506132ae565b6040518082815260200191505060405180910390f35b610ceb60048036036020811015610cd557600080fd5b81019080803590602001909291905050506132c6565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610d6d60048036036060811015610d2d57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613305565b6040518082815260200191505060405180910390f35b610dc560048036036020811015610d9957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613791565b6040518082815260200191505060405180910390f35b610e1d60048036036020811015610df157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506137a9565b6040518082815260200191505060405180910390f35b610e5f60048036036020811015610e4957600080fd5b81019080803590602001909291905050506137c1565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610e93613800565b6040518082815260200191505060405180910390f35b610ef560048036036040811015610ebf57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613824565b005b610f3960048036036020811015610f0d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613b49565b60405180821515815260200191505060405180910390f35b610fa060048036036040811015610f6757600080fd5b81019080803560ff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613b69565b60405180821515815260200191505060405180910390f35b610ffa60048036036020811015610fce57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506142c8565b60405180821515815260200191505060405180910390f35b6110546004803603602081101561102857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506142e8565b60405180821515815260200191505060405180910390f35b6110ae6004803603602081101561108257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614308565b6040518082815260200191505060405180910390f35b611133600480360360608110156110da57600080fd5b81019080803560ff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614320565b60405180821515815260200191505060405180910390f35b61115361549b565b6040518082815260200191505060405180910390f35b6111956004803603602081101561117f57600080fd5b81019080803590602001909291905050506154a1565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b611203600480360360208110156111d757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506154e0565b6040518082815260200191505060405180910390f35b600360008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166112d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e6f74206163636570746564000000000000000000000000000000000000000081525060200191505060405180910390fd5b60011515600960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615151461139e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e6f7420617070726f766564000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006113aa8284612350565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166379cc679033836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b15801561143d57600080fd5b505af1158015611451573d6000803e3d6000fd5b5050505061146a816021546154f890919063ffffffff16565b6021819055506021547f93bb8edd35984706eee1b92541281f7f62d33c01c5b2ec0929a113603bd21d6660405160405180910390a26114ca33848473ffffffffffffffffffffffffffffffffffffffff166155429092919063ffffffff16565b8173ffffffffffffffffffffffffffffffffffffffff167fdf273cb619d95419a9cd0ec88123a0538c85064229baa6363788f743fff90deb8483604051808381526020018281526020019250505060405180910390a2505050565b6012818154811061153557600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611625576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b601b6020528060005260406000206000915090505481565b600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561181157601660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661180c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e6f7420617070726f766564000000000000000000000000000000000000000081525060200191505060405180910390fd5b6118d1565b601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166118d0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e6f7420617070726f766564000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b60006118dd8383612350565b90506118e7611a24565b81111561195c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f496e73756666696369656e74207265736572766573000000000000000000000081525060200191505060405180910390fd5b611971816021546154f890919063ffffffff16565b6021819055506021547f93bb8edd35984706eee1b92541281f7f62d33c01c5b2ec0929a113603bd21d6660405160405180910390a26119d133838573ffffffffffffffffffffffffffffffffffffffff166155429092919063ffffffff16565b8273ffffffffffffffffffffffffffffffffffffffff167f2bb2640731848fe9820ba48dbc978c1fc9bbd5f11b948bfab05b7dee3378fd80836040518082815260200191505060405180910390a2505050565b6000611aef611ade6022547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611a9557600080fd5b505afa158015611aa9573d6000803e3d6000fd5b505050506040513d6020811015611abf57600080fd5b81019080805190602001909291905050506154f890919063ffffffff16565b6021546154f890919063ffffffff16565b905090565b601960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611bb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e6f7420617070726f766564000000000000000000000000000000000000000081525060200191505060405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166379cc679033836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b158015611c4457600080fd5b505af1158015611c58573d6000803e3d6000fd5b50505050611cae81601b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546154f890919063ffffffff16565b601b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611d06816022546154f890919063ffffffff16565b6022819055507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc6d98eecfc9c78ab62c89a82950079b54874749f1f6f24090f7acc758bc2f3098384604051808381526020018281526020019250505060405180910390a350565b60066020528060005260406000206000915054906101000a900460ff1681565b601960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611e7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e6f7420617070726f766564000000000000000000000000000000000000000081525060200191505060405180910390fd5b600360008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611f3a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e6f74206163636570746564000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000611f468284612350565b90506000601f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611fd357600080fd5b505afa158015611fe7573d6000803e3d6000fd5b505050506040513d6020811015611ffd57600080fd5b810190808051906020019092919050505090506000612064601b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054836154f890919063ffffffff16565b9050808311156120dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f457863656564732064656274206c696d6974000000000000000000000000000081525060200191505060405180910390fd5b61212e83601b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546155e490919063ffffffff16565b601b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550612186836022546155e490919063ffffffff16565b6022819055506121a1836021546154f890919063ffffffff16565b6021819055506021547f93bb8edd35984706eee1b92541281f7f62d33c01c5b2ec0929a113603bd21d6660405160405180910390a28373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33876040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561224757600080fd5b505af115801561225b573d6000803e3d6000fd5b505050506040513d602081101561227157600080fd5b8101908080519060200190929190505050508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f7e1a939bed137a819b5d2979822c67f877689f7a863d5e4cb57cdca97b2977d68786604051808381526020018281526020019250505060405180910390a35050505050565b601f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60116020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156124fc576124f58373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b1580156123ed57600080fd5b505afa158015612401573d6000803e3d6000fd5b505050506040513d602081101561241757600080fd5b810190808051906020019092919050505060ff16600a0a6124e77f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561249757600080fd5b505afa1580156124ab573d6000803e3d6000fd5b505050506040513d60208110156124c157600080fd5b810190808051906020019092919050505060ff16600a0a8561566c90919063ffffffff16565b6156f290919063ffffffff16565b905061265b565b600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561265a57601160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634249719f84846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060206040518083038186803b15801561261c57600080fd5b505afa158015612630573d6000803e3d6000fd5b505050506040513d602081101561264657600080fd5b810190808051906020019092919050505090505b5b92915050565b60205481565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612728576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600080600090505b600280549050811015612877576128686128596002838154811061275057fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166002848154811061278857fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561281957600080fd5b505afa15801561282d573d6000803e3d6000fd5b505050506040513d602081101561284357600080fd5b8101908080519060200190929190505050612350565b836155e490919063ffffffff16565b91508080600101915050612730565b5060005b600b805490508110156129c2576129b36129a4600b838154811061289b57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600b84815481106128d357fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561296457600080fd5b505afa158015612978573d6000803e3d6000fd5b505050506040513d602081101561298e57600080fd5b8101908080519060200190929190505050612350565b836155e490919063ffffffff16565b9150808060010191505061287b565b5080602181905550807f93bb8edd35984706eee1b92541281f7f62d33c01c5b2ec0929a113603bd21d6660405160405180910390a2807fec691f09f6924b27932253f85caf99bacc30360cc0e50a1cc4d2acc24601446660405160405180910390a250565b60088181548110612a3757600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612b27576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612bad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180615f156026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a380600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b601d6020528060005260406000206000915054906101000a900460ff1681565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612d5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615f3b6022913960400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167faa151555690c956fc3ea32f106bb9f119b5237a061eaa8557cff3e51e3792c8d60405160405180910390a3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60036020528060005260406000206000915054906101000a900460ff1681565b601d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16612f39576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e6f7420617070726f766564000000000000000000000000000000000000000081525060200191505060405180910390fd5b612f41611a24565b811115612fb6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f496e73756666696369656e74207265736572766573000000000000000000000081525060200191505060405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166340c10f1983836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b15801561304757600080fd5b505af115801561305b573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167ffa8ccab40e7da8146c2304cd0950334fd30a6ba093abe86261aa13911fed849c836040518082815260200191505060405180910390a35050565b600581815481106130d857600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6015818154811061311757600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60046020528060005260406000206000915090505481565b6018818154811061316e57600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60096020528060005260406000206000915054906101000a900460ff1681565b600d6020528060005260406000206000915090505481565b600e81815481106131e557600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60215481565b60076020528060005260406000206000915090505481565b600f6020528060005260406000206000915054906101000a900460ff1681565b600c6020528060005260406000206000915054906101000a900460ff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b60176020528060005260406000206000915090505481565b60146020528060005260406000206000915090505481565b601c81815481106132d657600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16806133a85750600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b61341a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e6f74206163636570746564000000000000000000000000000000000000000081525060200191505060405180910390fd5b6134473330868673ffffffffffffffffffffffffffffffffffffffff1661573c909392919063ffffffff16565b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561355d57600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16613558576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e6f7420617070726f766564000000000000000000000000000000000000000081525060200191505060405180910390fd5b61361d565b600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661361c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e6f7420617070726f766564000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b60006136298486612350565b905061363e83826154f890919063ffffffff16565b91507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166340c10f1933846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b1580156136d157600080fd5b505af11580156136e5573d6000803e3d6000fd5b505050506136fe816021546155e490919063ffffffff16565b6021819055506021547f93bb8edd35984706eee1b92541281f7f62d33c01c5b2ec0929a113603bd21d6660405160405180910390a28373ffffffffffffffffffffffffffffffffffffffff167f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a158683604051808381526020018281526020019250505060405180910390a2509392505050565b600a6020528060005260406000206000915090505481565b601a6020528060005260406000206000915090505481565b600281815481106137d157600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b601960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166138e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e6f7420617070726f766564000000000000000000000000000000000000000081525060200191505060405180910390fd5b600360008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166139a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e6f74206163636570746564000000000000000000000000000000000000000081525060200191505060405180910390fd5b6139cf3330848473ffffffffffffffffffffffffffffffffffffffff1661573c909392919063ffffffff16565b60006139db8284612350565b9050613a2f81601b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546154f890919063ffffffff16565b601b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550613a87816022546154f890919063ffffffff16565b602281905550613aa2816021546155e490919063ffffffff16565b6021819055506021547f93bb8edd35984706eee1b92541281f7f62d33c01c5b2ec0929a113603bd21d6660405160405180910390a28173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc6d98eecfc9c78ab62c89a82950079b54874749f1f6f24090f7acc758bc2f3098584604051808381526020018281526020019250505060405180910390a3505050565b60166020528060005260406000206000915054906101000a900460ff1681565b60003373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613c2c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613c6657600080fd5b60006009811115613c7357fe5b836009811115613c7f57fe5b1415613d0057613cb87f0000000000000000000000000000000000000000000000000000000000000000436155e490919063ffffffff16565b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550614264565b60016009811115613d0d57fe5b836009811115613d1957fe5b1415613d9a57613d527f0000000000000000000000000000000000000000000000000000000000000000436155e490919063ffffffff16565b600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550614263565b60026009811115613da757fe5b836009811115613db357fe5b1415613e3457613dec7f0000000000000000000000000000000000000000000000000000000000000000436155e490919063ffffffff16565b600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550614262565b60036009811115613e4157fe5b836009811115613e4d57fe5b1415613ee157613e99613e8a60027f000000000000000000000000000000000000000000000000000000000000000061566c90919063ffffffff16565b436155e490919063ffffffff16565b601460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550614261565b60046009811115613eee57fe5b836009811115613efa57fe5b1415613f7b57613f337f0000000000000000000000000000000000000000000000000000000000000000436155e490919063ffffffff16565b601060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550614260565b60056009811115613f8857fe5b836009811115613f9457fe5b141561401557613fcd7f0000000000000000000000000000000000000000000000000000000000000000436155e490919063ffffffff16565b600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061425f565b6006600981111561402257fe5b83600981111561402e57fe5b14156140c25761407a61406b60027f000000000000000000000000000000000000000000000000000000000000000061566c90919063ffffffff16565b436155e490919063ffffffff16565b601760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061425e565b600760098111156140cf57fe5b8360098111156140db57fe5b141561415c576141147f0000000000000000000000000000000000000000000000000000000000000000436155e490919063ffffffff16565b601a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061425d565b6008600981111561416957fe5b83600981111561417557fe5b14156141f6576141ae7f0000000000000000000000000000000000000000000000000000000000000000436155e490919063ffffffff16565b601e60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061425c565b60098081111561420257fe5b83600981111561420e57fe5b1415614252576142477f0000000000000000000000000000000000000000000000000000000000000000436155e490919063ffffffff16565b60208190555061425b565b600090506142c2565b5b5b5b5b5b5b5b5b5b82600981111561427057fe5b7f0e4f2c4b5bc209d509bc3d49348c787fefadc66a79351b470599ac0f5be52eaf83604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a2600190505b92915050565b60136020528060005260406000206000915054906101000a900460ff1681565b60196020528060005260406000206000915054906101000a900460ff1681565b601e6020528060005260406000206000915090505481565b60003373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146143e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561441d57600080fd5b600080600981111561442b57fe5b85600981111561443757fe5b14156145b45761444a60076006866157fd565b15614508576000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061449f6005856159cd565b614507576005849080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615905080600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061542b565b600160098111156145c157fe5b8560098111156145cd57fe5b141561474a576145e0600a6009866157fd565b1561469e576000600a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506146356008856159cd565b61469d576008849080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b600960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615905080600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061542a565b6002600981111561475757fe5b85600981111561476357fe5b14156148e05761477660046003866157fd565b15614834576000600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506147cb6002856159cd565b614833576002849080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615905080600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550615429565b600360098111156148ed57fe5b8560098111156148f957fe5b1415614ad95761490c60146013866157fd565b15614a2d576012849080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000601460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506149c46012856159cd565b614a2c576012849080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b601360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615905080601360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550615428565b60046009811115614ae657fe5b856009811115614af257fe5b1415614cd257614b056010600f866157fd565b15614c2657600e849080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000601060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550614bbd600e856159cd565b614c2557600e849080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615905080600f60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550615427565b60056009811115614cdf57fe5b856009811115614ceb57fe5b1415614ee657614cfe600d600c866157fd565b15614dbc576000600d60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550614d53600b856159cd565b614dbb57600b849080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b600c60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615905080600c60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555082601160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550615426565b60066009811115614ef357fe5b856009811115614eff57fe5b141561507c57614f1260176016866157fd565b15614fd0576000601760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550614f676015856159cd565b614fcf576015849080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b601660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615905080601660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550615425565b6007600981111561508957fe5b85600981111561509557fe5b1415615212576150a8601a6019866157fd565b15615166576000601a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506150fd6018856159cd565b615165576018849080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b601960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615905080601960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550615424565b6008600981111561521f57fe5b85600981111561522b57fe5b14156153a85761523e601e601d866157fd565b156152fc576000601e60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550615293601c856159cd565b6152fb57601c849080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b601d60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615905080601d60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550615423565b6009808111156153b457fe5b8560098111156153c057fe5b141561541857600060208190555083601f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060019050615422565b6000915050615494565b5b5b5b5b5b5b5b5b5b84600981111561543757fe5b7f0dcacb7e392f3d6a216ed2660e3dcfd40b7793d33591db2ba185a6b8e44fc4778583604051808373ffffffffffffffffffffffffffffffffffffffff16815260200182151581526020019250505060405180910390a260019150505b9392505050565b60225481565b600b81815481106154b157600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60106020528060005260406000206000915090505481565b600061553a83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250615a6e565b905092915050565b6155df8363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050615b2e565b505050565b600080828401905083811015615662576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b60008083141561567f57600090506156ec565b600082840290508284828161569057fe5b04146156e7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180615f5d6021913960400191505060405180910390fd5b809150505b92915050565b600061573483836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250615c1d565b905092915050565b6157f7846323b872dd60e01b858585604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050615b2e565b50505050565b60008260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166159c15760008460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541415615904576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f4d7573742071756575650000000000000000000000000000000000000000000081525060200191505060405180910390fd5b438460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205411156159b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f5175657565206e6f74206578706972656400000000000000000000000000000081525060200191505060405180910390fd5b600190506159c6565b600090505b9392505050565b600080600090505b8380549050811015615a62578273ffffffffffffffffffffffffffffffffffffffff16848281548110615a0457fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415615a55576001915050615a68565b80806001019150506159d5565b50600090505b92915050565b6000838311158290615b1b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015615ae0578082015181840152602081019050615ac5565b50505050905090810190601f168015615b0d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b6060615b90826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16615ce39092919063ffffffff16565b9050600081511115615c1857808060200190516020811015615bb157600080fd5b8101908080519060200190929190505050615c17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180615f7e602a913960400191505060405180910390fd5b5b505050565b60008083118290615cc9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015615c8e578082015181840152602081019050615c73565b50505050905090810190601f168015615cbb5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581615cd557fe5b049050809150509392505050565b6060615cf28484600085615cfb565b90509392505050565b6060615d0685615f01565b615d78576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b60208310615dc85780518252602082019150602081019050602083039250615da5565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114615e2a576040519150601f19603f3d011682016040523d82523d6000602084013e615e2f565b606091505b50915091508115615e44578092505050615ef9565b600081511115615e575780518082602001fd5b836040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015615ebe578082015181840152602081019050615ea3565b50505050905090810190601f168015615eeb5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b949350505050565b600080823b90506000811191505091905056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a206d757374206265206e6577206f776e657220746f2070756c6c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a264697066735822122008d0f7e49153f0b48488475584a96ebc39560c77f97a005ed01ceee5d826e77b64736f6c63430007050033", + "devdoc": { + "kind": "dev", + "methods": { + "deposit(uint256,address,uint256)": { + "params": { + "_amount": "uint", + "_profit": "uint", + "_token": "address" + }, + "returns": { + "send_": "uint" + } + }, + "excessReserves()": { + "returns": { + "_0": "uint" + } + }, + "incurDebt(uint256,address)": { + "params": { + "_amount": "uint", + "_token": "address" + } + }, + "manage(address,uint256)": { + "params": { + "_amount": "uint", + "_token": "address" + } + }, + "queue(uint8,address)": { + "params": { + "_address": "address", + "_managing": "MANAGING" + }, + "returns": { + "_0": "bool" + } + }, + "repayDebtWithOHM(uint256)": { + "params": { + "_amount": "uint" + } + }, + "repayDebtWithReserve(uint256,address)": { + "params": { + "_amount": "uint", + "_token": "address" + } + }, + "toggle(uint8,address,address)": { + "params": { + "_address": "address", + "_calculator": "address", + "_managing": "MANAGING" + }, + "returns": { + "_0": "bool" + } + }, + "valueOf(address,uint256)": { + "params": { + "_amount": "uint", + "_token": "address" + }, + "returns": { + "value_": "uint" + } + }, + "withdraw(uint256,address)": { + "params": { + "_amount": "uint", + "_token": "address" + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "auditReserves()": { + "notice": "takes inventory of all tracked assetsalways consolidate to recognized reserves before audit" + }, + "deposit(uint256,address,uint256)": { + "notice": "allow approved address to deposit an asset for OHM" + }, + "excessReserves()": { + "notice": "returns excess reserves not backing tokens" + }, + "incurDebt(uint256,address)": { + "notice": "allow approved address to borrow reserves" + }, + "manage(address,uint256)": { + "notice": "allow approved address to withdraw assets" + }, + "mintRewards(address,uint256)": { + "notice": "send epoch reward to staking contract" + }, + "queue(uint8,address)": { + "notice": "queue address to change boolean in mapping" + }, + "repayDebtWithOHM(uint256)": { + "notice": "allow approved address to repay borrowed reserves with OHM" + }, + "repayDebtWithReserve(uint256,address)": { + "notice": "allow approved address to repay borrowed reserves with reserves" + }, + "toggle(uint8,address,address)": { + "notice": "verify queue then set boolean in mapping" + }, + "valueOf(address,uint256)": { + "notice": "returns OHM valuation of asset" + }, + "withdraw(uint256,address)": { + "notice": "allow approved address to burn OHM for reserves" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 284, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 286, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "_newOwner", + "offset": 0, + "slot": "1", + "type": "t_address" + }, + { + "astId": 691, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "reserveTokens", + "offset": 0, + "slot": "2", + "type": "t_array(t_address)dyn_storage" + }, + { + "astId": 695, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "isReserveToken", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 699, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "reserveTokenQueue", + "offset": 0, + "slot": "4", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 702, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "reserveDepositors", + "offset": 0, + "slot": "5", + "type": "t_array(t_address)dyn_storage" + }, + { + "astId": 706, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "isReserveDepositor", + "offset": 0, + "slot": "6", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 710, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "reserveDepositorQueue", + "offset": 0, + "slot": "7", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 713, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "reserveSpenders", + "offset": 0, + "slot": "8", + "type": "t_array(t_address)dyn_storage" + }, + { + "astId": 717, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "isReserveSpender", + "offset": 0, + "slot": "9", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 721, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "reserveSpenderQueue", + "offset": 0, + "slot": "10", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 724, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "liquidityTokens", + "offset": 0, + "slot": "11", + "type": "t_array(t_address)dyn_storage" + }, + { + "astId": 728, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "isLiquidityToken", + "offset": 0, + "slot": "12", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 732, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "LiquidityTokenQueue", + "offset": 0, + "slot": "13", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 735, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "liquidityDepositors", + "offset": 0, + "slot": "14", + "type": "t_array(t_address)dyn_storage" + }, + { + "astId": 739, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "isLiquidityDepositor", + "offset": 0, + "slot": "15", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 743, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "LiquidityDepositorQueue", + "offset": 0, + "slot": "16", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 747, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "bondCalculator", + "offset": 0, + "slot": "17", + "type": "t_mapping(t_address,t_address)" + }, + { + "astId": 750, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "reserveManagers", + "offset": 0, + "slot": "18", + "type": "t_array(t_address)dyn_storage" + }, + { + "astId": 754, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "isReserveManager", + "offset": 0, + "slot": "19", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 758, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "ReserveManagerQueue", + "offset": 0, + "slot": "20", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 761, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "liquidityManagers", + "offset": 0, + "slot": "21", + "type": "t_array(t_address)dyn_storage" + }, + { + "astId": 765, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "isLiquidityManager", + "offset": 0, + "slot": "22", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 769, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "LiquidityManagerQueue", + "offset": 0, + "slot": "23", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 772, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "debtors", + "offset": 0, + "slot": "24", + "type": "t_array(t_address)dyn_storage" + }, + { + "astId": 776, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "isDebtor", + "offset": 0, + "slot": "25", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 780, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "debtorQueue", + "offset": 0, + "slot": "26", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 784, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "debtorBalance", + "offset": 0, + "slot": "27", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 787, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "rewardManagers", + "offset": 0, + "slot": "28", + "type": "t_array(t_address)dyn_storage" + }, + { + "astId": 791, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "isRewardManager", + "offset": 0, + "slot": "29", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 795, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "rewardManagerQueue", + "offset": 0, + "slot": "30", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 797, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "sOHM", + "offset": 0, + "slot": "31", + "type": "t_address" + }, + { + "astId": 799, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "sOHMQueue", + "offset": 0, + "slot": "32", + "type": "t_uint256" + }, + { + "astId": 801, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "totalReserves", + "offset": 0, + "slot": "33", + "type": "t_uint256" + }, + { + "astId": 803, + "contract": "contracts/Treasury.sol:OlympusTreasury", + "label": "totalDebt", + "offset": 0, + "slot": "34", + "type": "t_uint256" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_address)dyn_storage": { + "base": "t_address", + "encoding": "dynamic_array", + "label": "address[]", + "numberOfBytes": "32" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_mapping(t_address,t_address)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => address)", + "numberOfBytes": "32", + "value": "t_address" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/src/abi/rinkeby/RedeemHelper.json b/src/abi/rinkeby/RedeemHelper.json new file mode 100644 index 0000000000..c688a8b65c --- /dev/null +++ b/src/abi/rinkeby/RedeemHelper.json @@ -0,0 +1,233 @@ +{ + "address": "0x1084A389cff0a8c378ddFbC673fb0E24C2442045", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipPulled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipPushed", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_bond", + "type": "address" + } + ], + "name": "addBondContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "bonds", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "policy", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pullManagement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner_", + "type": "address" + } + ], + "name": "pushManagement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "bool", + "name": "_stake", + "type": "bool" + } + ], + "name": "redeemAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + } + ], + "name": "removeBondContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceManagement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xac041f6a513817eb5b68dccd2eb8c0310051986943162ae456c836aacc6924e5", + "receipt": { + "to": null, + "from": "0xA38F4E6718EdCF023a1d032a2193848CB932c8e3", + "contractAddress": "0x1084A389cff0a8c378ddFbC673fb0E24C2442045", + "transactionIndex": 20, + "gasUsed": "801122", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000400000208000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000001020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000020000000000020002000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x2267aa1d65276b8551e953234ddcabd2e4d1d2814888e90b6ad94c9d43e2a472", + "transactionHash": "0xac041f6a513817eb5b68dccd2eb8c0310051986943162ae456c836aacc6924e5", + "logs": [ + { + "transactionIndex": 20, + "blockNumber": 9991628, + "transactionHash": "0xac041f6a513817eb5b68dccd2eb8c0310051986943162ae456c836aacc6924e5", + "address": "0x1084A389cff0a8c378ddFbC673fb0E24C2442045", + "topics": [ + "0xea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000a38f4e6718edcf023a1d032a2193848cb932c8e3" + ], + "data": "0x", + "logIndex": 50, + "blockHash": "0x2267aa1d65276b8551e953234ddcabd2e4d1d2814888e90b6ad94c9d43e2a472" + } + ], + "blockNumber": 9991628, + "cumulativeGasUsed": "2676368", + "status": 1, + "byzantium": true + }, + "args": [], + "solcInputHash": "8d3774b312edc15e04c44a56a82de7d8", + "metadata": "{\"compiler\":{\"version\":\"0.7.5+commit.eb77ed08\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipPulled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipPushed\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bond\",\"type\":\"address\"}],\"name\":\"addBondContract\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bonds\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"policy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pullManagement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner_\",\"type\":\"address\"}],\"name\":\"pushManagement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_stake\",\"type\":\"bool\"}],\"name\":\"redeemAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"removeBondContract\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceManagement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/RedeemHelper.sol\":\"RedeemHelper\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/RedeemHelper.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-or-later\\npragma solidity 0.7.5;\\n\\ninterface IOwnable {\\n function policy() external view returns (address);\\n\\n function renounceManagement() external;\\n \\n function pushManagement( address newOwner_ ) external;\\n \\n function pullManagement() external;\\n}\\n\\ncontract Ownable is IOwnable {\\n\\n address internal _owner;\\n address internal _newOwner;\\n\\n event OwnershipPushed(address indexed previousOwner, address indexed newOwner);\\n event OwnershipPulled(address indexed previousOwner, address indexed newOwner);\\n\\n constructor () {\\n _owner = msg.sender;\\n emit OwnershipPushed( address(0), _owner );\\n }\\n\\n function policy() public view override returns (address) {\\n return _owner;\\n }\\n\\n modifier onlyPolicy() {\\n require( _owner == msg.sender, \\\"Ownable: caller is not the owner\\\" );\\n _;\\n }\\n\\n function renounceManagement() public virtual override onlyPolicy() {\\n emit OwnershipPushed( _owner, address(0) );\\n _owner = address(0);\\n }\\n\\n function pushManagement( address newOwner_ ) public virtual override onlyPolicy() {\\n require( newOwner_ != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipPushed( _owner, newOwner_ );\\n _newOwner = newOwner_;\\n }\\n \\n function pullManagement() public virtual override {\\n require( msg.sender == _newOwner, \\\"Ownable: must be new owner to pull\\\");\\n emit OwnershipPulled( _owner, _newOwner );\\n _owner = _newOwner;\\n }\\n}\\n\\ninterface IBond {\\n function redeem( address _recipient, bool _stake ) external returns ( uint );\\n function pendingPayoutFor( address _depositor ) external view returns ( uint pendingPayout_ );\\n}\\n\\ncontract RedeemHelper is Ownable {\\n\\n address[] public bonds;\\n\\n function redeemAll( address _recipient, bool _stake ) external {\\n for( uint i = 0; i < bonds.length; i++ ) {\\n if ( bonds[i] != address(0) ) {\\n if ( IBond( bonds[i] ).pendingPayoutFor( _recipient ) > 0 ) {\\n IBond( bonds[i] ).redeem( _recipient, _stake );\\n }\\n }\\n }\\n }\\n\\n function addBondContract( address _bond ) external onlyPolicy() {\\n require( _bond != address(0) );\\n bonds.push( _bond );\\n }\\n\\n function removeBondContract( uint _index ) external onlyPolicy() {\\n bonds[ _index ] = address(0);\\n }\\n}\",\"keccak256\":\"0x63054884c30b69052cc99139e062a9e801f4eef74142cbb776295e6aad579a1a\",\"license\":\"AGPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a3610d15806100db6000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c806346f68ee91161005b57806346f68ee91461015f5780635a96ac0a146101a35780635f1c17c0146101ad578063b1e59ab71461020557610088565b80630505c8c91461008d578063089208d8146100c15780630a6d1860146100cb57806346aed74e1461010f575b600080fd5b610095610233565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100c961025c565b005b61010d600480360360208110156100e157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506103db565b005b61015d6004803603604081101561012557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080351515906020019092919050505061053c565b005b6101a16004803603602081101561017557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610792565b005b6101ab610997565b005b6101d9600480360360208110156101c357600080fd5b8101908080359060200190929190505050610b3d565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102316004803603602081101561021b57600080fd5b8101908080359060200190929190505050610b7c565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461031d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461049c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156104d657600080fd5b6002819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60005b60028054905081101561078d57600073ffffffffffffffffffffffffffffffffffffffff166002828154811061057157fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610780576000600282815481106105c657fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166301b88ee8856040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561065757600080fd5b505afa15801561066b573d6000803e3d6000fd5b505050506040513d602081101561068157600080fd5b8101908080519060200190929190505050111561077f57600281815481106106a557fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631feed31f84846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff168152602001821515815260200192505050602060405180830381600087803b15801561074257600080fd5b505af1158015610756573d6000803e3d6000fd5b505050506040513d602081101561076c57600080fd5b8101908080519060200190929190505050505b5b808060010191505061053f565b505050565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610853576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156108d9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180610c986026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a380600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180610cbe6022913960400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167faa151555690c956fc3ea32f106bb9f119b5237a061eaa8557cff3e51e3792c8d60405160405180910390a3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60028181548110610b4d57600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610c3d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060028281548110610c4c57fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a206d757374206265206e6577206f776e657220746f2070756c6ca26469706673582212208fcc9c74d1b99bbd630564fd21bafb64a29f4cee164be7ccaaf4503253ae80fc64736f6c63430007050033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100885760003560e01c806346f68ee91161005b57806346f68ee91461015f5780635a96ac0a146101a35780635f1c17c0146101ad578063b1e59ab71461020557610088565b80630505c8c91461008d578063089208d8146100c15780630a6d1860146100cb57806346aed74e1461010f575b600080fd5b610095610233565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100c961025c565b005b61010d600480360360208110156100e157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506103db565b005b61015d6004803603604081101561012557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080351515906020019092919050505061053c565b005b6101a16004803603602081101561017557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610792565b005b6101ab610997565b005b6101d9600480360360208110156101c357600080fd5b8101908080359060200190929190505050610b3d565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102316004803603602081101561021b57600080fd5b8101908080359060200190929190505050610b7c565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461031d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461049c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156104d657600080fd5b6002819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60005b60028054905081101561078d57600073ffffffffffffffffffffffffffffffffffffffff166002828154811061057157fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610780576000600282815481106105c657fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166301b88ee8856040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561065757600080fd5b505afa15801561066b573d6000803e3d6000fd5b505050506040513d602081101561068157600080fd5b8101908080519060200190929190505050111561077f57600281815481106106a557fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631feed31f84846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff168152602001821515815260200192505050602060405180830381600087803b15801561074257600080fd5b505af1158015610756573d6000803e3d6000fd5b505050506040513d602081101561076c57600080fd5b8101908080519060200190929190505050505b5b808060010191505061053f565b505050565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610853576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156108d9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180610c986026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a380600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180610cbe6022913960400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167faa151555690c956fc3ea32f106bb9f119b5237a061eaa8557cff3e51e3792c8d60405160405180910390a3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60028181548110610b4d57600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610c3d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060028281548110610c4c57fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a206d757374206265206e6577206f776e657220746f2070756c6ca26469706673582212208fcc9c74d1b99bbd630564fd21bafb64a29f4cee164be7ccaaf4503253ae80fc64736f6c63430007050033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 8447, + "contract": "contracts/RedeemHelper.sol:RedeemHelper", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 8449, + "contract": "contracts/RedeemHelper.sol:RedeemHelper", + "label": "_newOwner", + "offset": 0, + "slot": "1", + "type": "t_address" + }, + { + "astId": 8594, + "contract": "contracts/RedeemHelper.sol:RedeemHelper", + "label": "bonds", + "offset": 0, + "slot": "2", + "type": "t_array(t_address)dyn_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_address)dyn_storage": { + "base": "t_address", + "encoding": "dynamic_array", + "label": "address[]", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/src/abi/rinkeby/StakingHelper.json b/src/abi/rinkeby/StakingHelper.json new file mode 100644 index 0000000000..93ea6ce049 --- /dev/null +++ b/src/abi/rinkeby/StakingHelper.json @@ -0,0 +1,98 @@ +{ + "address": "0x179C45D4c6F8370c68A53aF068b5Fa20e3fE2Af4", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_staking", + "type": "address" + }, + { + "internalType": "address", + "name": "_OHM", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "OHM", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "stake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "staking", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x4c163f5a941022f1980fc2c0a5d6572c83c533e322c9643c5e96d5f2b2671a36", + "receipt": { + "to": null, + "from": "0xA38F4E6718EdCF023a1d032a2193848CB932c8e3", + "contractAddress": "0x179C45D4c6F8370c68A53aF068b5Fa20e3fE2Af4", + "transactionIndex": 0, + "gasUsed": "313447", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x1c775cb90fee6aa6aad8796b127d6a5af2b5d3254103a39e20da2ed64745c8e5", + "transactionHash": "0x4c163f5a941022f1980fc2c0a5d6572c83c533e322c9643c5e96d5f2b2671a36", + "logs": [], + "blockNumber": 9907141, + "cumulativeGasUsed": "313447", + "status": 1, + "byzantium": true + }, + "args": [ + "0xbB8b39A92D916D4c1c46c67CA22920A366127A4B", + "0x9bb5E7183e6259183f8E79876eCC0228738C95F6" + ], + "solcInputHash": "8d3774b312edc15e04c44a56a82de7d8", + "metadata": "{\"compiler\":{\"version\":\"0.7.5+commit.eb77ed08\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_staking\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_OHM\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"OHM\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"stake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"staking\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/StakingHelper.sol\":\"StakingHelper\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/StakingHelper.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-or-later\\npragma solidity 0.7.5;\\n\\n\\ninterface IERC20 {\\n function decimals() external view returns (uint8);\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\\ninterface IStaking {\\n function stake( uint _amount, address _recipient ) external returns ( bool );\\n function claim( address _recipient ) external;\\n}\\n\\ncontract StakingHelper {\\n\\n address public immutable staking;\\n address public immutable OHM;\\n\\n constructor ( address _staking, address _OHM ) {\\n require( _staking != address(0) );\\n staking = _staking;\\n require( _OHM != address(0) );\\n OHM = _OHM;\\n }\\n\\n function stake( uint _amount ) external {\\n IERC20( OHM ).transferFrom( msg.sender, address(this), _amount );\\n IERC20( OHM ).approve( staking, _amount );\\n IStaking( staking ).stake( _amount, msg.sender );\\n IStaking( staking ).claim( msg.sender );\\n }\\n}\",\"keccak256\":\"0x7b35deed9eb8b3e0f63d19d28f02123772c26a766f652d957140d349118b1f5d\",\"license\":\"AGPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x60c060405234801561001057600080fd5b506040516106163803806106168339818101604052604081101561003357600080fd5b810190808051906020019092919080519060200190929190505050600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561008857600080fd5b8173ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b81525050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156100f957600080fd5b8073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b81525050505060805160601c60a05160601c6104a36101736000398061010252806101ed528061044b52508060de528061022952806102da52806103a752506104a36000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80634cf088d914610046578063a694fc3a1461007a578063a6c41fec146100a8575b600080fd5b61004e6100dc565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100a66004803603602081101561009057600080fd5b8101908080359060200190929190505050610100565b005b6100b0610449565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166323b872dd3330846040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b1580156101af57600080fd5b505af11580156101c3573d6000803e3d6000fd5b505050506040513d60208110156101d957600080fd5b8101908080519060200190929190505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b37f0000000000000000000000000000000000000000000000000000000000000000836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561029c57600080fd5b505af11580156102b0573d6000803e3d6000fd5b505050506040513d60208110156102c657600080fd5b8101908080519060200190929190505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637acb775782336040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b15801561036957600080fd5b505af115801561037d573d6000803e3d6000fd5b505050506040513d602081101561039357600080fd5b8101908080519060200190929190505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16631e83409a336040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b15801561042e57600080fd5b505af1158015610442573d6000803e3d6000fd5b5050505050565b7f00000000000000000000000000000000000000000000000000000000000000008156fea2646970667358221220e00da5a107b22af35ca659ee921161d0f71790b915b995931cf7d2282cfae6e664736f6c63430007050033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80634cf088d914610046578063a694fc3a1461007a578063a6c41fec146100a8575b600080fd5b61004e6100dc565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100a66004803603602081101561009057600080fd5b8101908080359060200190929190505050610100565b005b6100b0610449565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166323b872dd3330846040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b1580156101af57600080fd5b505af11580156101c3573d6000803e3d6000fd5b505050506040513d60208110156101d957600080fd5b8101908080519060200190929190505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b37f0000000000000000000000000000000000000000000000000000000000000000836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561029c57600080fd5b505af11580156102b0573d6000803e3d6000fd5b505050506040513d60208110156102c657600080fd5b8101908080519060200190929190505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637acb775782336040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b15801561036957600080fd5b505af115801561037d573d6000803e3d6000fd5b505050506040513d602081101561039357600080fd5b8101908080519060200190929190505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16631e83409a336040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b15801561042e57600080fd5b505af1158015610442573d6000803e3d6000fd5b5050505050565b7f00000000000000000000000000000000000000000000000000000000000000008156fea2646970667358221220e00da5a107b22af35ca659ee921161d0f71790b915b995931cf7d2282cfae6e664736f6c63430007050033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/src/abi/rinkeby/StakingWarmup.json b/src/abi/rinkeby/StakingWarmup.json new file mode 100644 index 0000000000..e34a0a6129 --- /dev/null +++ b/src/abi/rinkeby/StakingWarmup.json @@ -0,0 +1,103 @@ +{ + "address": "0x949CADd109a54184a90DC875405BF9f022d35b49", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_staking", + "type": "address" + }, + { + "internalType": "address", + "name": "_sOHM", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_staker", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "retrieve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "sOHM", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "staking", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xbda6ede931e8e7195346592598c60a6ee2d9a4719dc7e1481d86ff0ec38ec601", + "receipt": { + "to": null, + "from": "0xA38F4E6718EdCF023a1d032a2193848CB932c8e3", + "contractAddress": "0x949CADd109a54184a90DC875405BF9f022d35b49", + "transactionIndex": 3, + "gasUsed": "203822", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x1fdea1d347a540ae606f64c89824d10de8fe9a5d242b584405b9158a2799ccc1", + "transactionHash": "0xbda6ede931e8e7195346592598c60a6ee2d9a4719dc7e1481d86ff0ec38ec601", + "logs": [], + "blockNumber": 9907140, + "cumulativeGasUsed": "5228684", + "status": 1, + "byzantium": true + }, + "args": [ + "0xbB8b39A92D916D4c1c46c67CA22920A366127A4B", + "0x230a8dC3c34336372b75549915DeBAEAACCF129D" + ], + "solcInputHash": "8d3774b312edc15e04c44a56a82de7d8", + "metadata": "{\"compiler\":{\"version\":\"0.7.5+commit.eb77ed08\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_staking\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_sOHM\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_staker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"retrieve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sOHM\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"staking\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/StakingWarmup.sol\":\"StakingWarmup\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/StakingWarmup.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-or-later\\npragma solidity 0.7.5;\\n\\n\\ninterface IERC20 {\\n function decimals() external view returns (uint8);\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\\ncontract StakingWarmup {\\n\\n address public immutable staking;\\n address public immutable sOHM;\\n\\n constructor ( address _staking, address _sOHM ) {\\n require( _staking != address(0) );\\n staking = _staking;\\n require( _sOHM != address(0) );\\n sOHM = _sOHM;\\n }\\n\\n function retrieve( address _staker, uint _amount ) external {\\n require( msg.sender == staking );\\n IERC20( sOHM ).transfer( _staker, _amount );\\n }\\n}\",\"keccak256\":\"0x306ca518b8625257ee4427b9507a15380cf371f372885bf037656008aa3d66a8\",\"license\":\"AGPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x60c060405234801561001057600080fd5b506040516104073803806104078339818101604052604081101561003357600080fd5b810190808051906020019092919080519060200190929190505050600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561008857600080fd5b8173ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b81525050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156100f957600080fd5b8073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b81525050505060805160601c60a05160601c6102a36101646000398060fe528061019e525080610122528061014652506102a36000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806315079925146100465780634cf088d91461007a578063c3a2a665146100ae575b600080fd5b61004e6100fc565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610082610120565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100fa600480360360408110156100c457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610144565b005b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461019c57600080fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb83836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561022d57600080fd5b505af1158015610241573d6000803e3d6000fd5b505050506040513d602081101561025757600080fd5b810190808051906020019092919050505050505056fea264697066735822122043c5f043bb7cd415c2ce0f02b8a9d3ddcd862e880f8440b143141b4ba2e1347964736f6c63430007050033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806315079925146100465780634cf088d91461007a578063c3a2a665146100ae575b600080fd5b61004e6100fc565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610082610120565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100fa600480360360408110156100c457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610144565b005b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461019c57600080fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb83836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561022d57600080fd5b505af1158015610241573d6000803e3d6000fd5b505050506040513d602081101561025757600080fd5b810190808051906020019092919050505050505056fea264697066735822122043c5f043bb7cd415c2ce0f02b8a9d3ddcd862e880f8440b143141b4ba2e1347964736f6c63430007050033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/src/abi/rinkeby/WrappedToken.json b/src/abi/rinkeby/WrappedToken.json new file mode 100644 index 0000000000..392849f8b4 --- /dev/null +++ b/src/abi/rinkeby/WrappedToken.json @@ -0,0 +1,560 @@ +{ + "address": "0xDd1875ddC7c832FA1CB82DfB8B34d3abD1F67a87", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "name_", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol_", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "ERR_INVALID_ZERO_VALUE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ERR_NO_ERROR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x4d976c06bda91e5f440531fe8753ce5c4288a20779f478430ec97f6995e61c72", + "receipt": { + "to": null, + "from": "0xA38F4E6718EdCF023a1d032a2193848CB932c8e3", + "contractAddress": "0xDd1875ddC7c832FA1CB82DfB8B34d3abD1F67a87", + "transactionIndex": 11, + "gasUsed": "1480609", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x2b13df44a45882682cf42bdad6c666a13f9d511cdc6e8b2118d8f9c2ef0ca91f", + "transactionHash": "0x4d976c06bda91e5f440531fe8753ce5c4288a20779f478430ec97f6995e61c72", + "logs": [], + "blockNumber": 9907132, + "cumulativeGasUsed": "13453249", + "status": 1, + "byzantium": true + }, + "args": [ + "Wrapped Ether", + "WETH" + ], + "solcInputHash": "77788eae31d169a831f4a6df224e3de9", + "metadata": "{\"compiler\":{\"version\":\"0.7.5+commit.eb77ed08\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"ERR_INVALID_ZERO_VALUE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ERR_NO_ERROR\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"deposit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5,05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is called. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"name()\":{\"details\":\"Returns the name of the token.\"},\"paused()\":{\"details\":\"Returns true if the contract is paused, and false otherwise.\"},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for ``sender``'s tokens of at least `amount`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/mocks/WrappedToken.sol\":\"WrappedToken\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b > a) return (false, 0);\\n return (true, a - b);\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) return (true, 0);\\n uint256 c = a * b;\\n if (c / a != b) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a / b);\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a % b);\\n }\\n\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a, \\\"SafeMath: subtraction overflow\\\");\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a == 0) return 0;\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: division by zero\\\");\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: modulo by zero\\\");\\n return a % b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {trySub}.\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryDiv}.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting with custom message when dividing by zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryMod}.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0xcc78a17dd88fa5a2edc60c8489e2f405c0913b377216a5b26b35656b2d0dab52\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin guidelines: functions revert instead\\n * of returning `false` on failure. This behavior is nonetheless conventional\\n * and does not conflict with the expectations of ERC20 applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20 {\\n using SafeMath for uint256;\\n\\n mapping (address => uint256) private _balances;\\n\\n mapping (address => mapping (address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n uint8 private _decimals;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\\n * a default value of 18.\\n *\\n * To select a different value for {decimals}, use {_setupDecimals}.\\n *\\n * All three of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor (string memory name_, string memory symbol_) public {\\n _name = name_;\\n _symbol = symbol_;\\n _decimals = 18;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\\n * called.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual returns (uint8) {\\n return _decimals;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Moves tokens `amount` from `sender` to `recipient`.\\n *\\n * This is internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply = _totalSupply.add(amount);\\n _balances[account] = _balances[account].add(amount);\\n emit Transfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Sets {decimals} to a value other than the default one of 18.\\n *\\n * WARNING: This function should only be called from the constructor. Most\\n * applications that interact with token contracts will not expect\\n * {decimals} to ever change, and may work incorrectly if it does.\\n */\\n function _setupDecimals(uint8 decimals_) internal virtual {\\n _decimals = decimals_;\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be to transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\\n}\\n\",\"keccak256\":\"0xca0c2396dbeb3503b51abf4248ebf77a1461edad513c01529df51850a012bee3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20Pausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"./ERC20.sol\\\";\\nimport \\\"../../utils/Pausable.sol\\\";\\n\\n/**\\n * @dev ERC20 token with pausable token transfers, minting and burning.\\n *\\n * Useful for scenarios such as preventing trades until the end of an evaluation\\n * period, or having an emergency switch for freezing all token transfers in the\\n * event of a large bug.\\n */\\nabstract contract ERC20Pausable is ERC20, Pausable {\\n /**\\n * @dev See {ERC20-_beforeTokenTransfer}.\\n *\\n * Requirements:\\n *\\n * - the contract must not be paused.\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {\\n super._beforeTokenTransfer(from, to, amount);\\n\\n require(!paused(), \\\"ERC20Pausable: token transfer while paused\\\");\\n }\\n}\\n\",\"keccak256\":\"0xa22af140ae7ec1f8f2f3bed5869cd0d548dfaac66343f0efc7324ff34aaf1254\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x5f02220344881ce43204ae4a6281145a67bc52c2bb1290a791857df3d19d78f5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x8d3cb350f04ff49cfb10aef08d87f19dcbaecc8027b0bed12f3275cd12f38cf0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Pausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"./Context.sol\\\";\\n\\n/**\\n * @dev Contract module which allows children to implement an emergency stop\\n * mechanism that can be triggered by an authorized account.\\n *\\n * This module is used through inheritance. It will make available the\\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\\n * the functions of your contract. Note that they will not be pausable by\\n * simply including this module, only once the modifiers are put in place.\\n */\\nabstract contract Pausable is Context {\\n /**\\n * @dev Emitted when the pause is triggered by `account`.\\n */\\n event Paused(address account);\\n\\n /**\\n * @dev Emitted when the pause is lifted by `account`.\\n */\\n event Unpaused(address account);\\n\\n bool private _paused;\\n\\n /**\\n * @dev Initializes the contract in unpaused state.\\n */\\n constructor () internal {\\n _paused = false;\\n }\\n\\n /**\\n * @dev Returns true if the contract is paused, and false otherwise.\\n */\\n function paused() public view virtual returns (bool) {\\n return _paused;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is not paused.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n modifier whenNotPaused() {\\n require(!paused(), \\\"Pausable: paused\\\");\\n _;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is paused.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n modifier whenPaused() {\\n require(paused(), \\\"Pausable: not paused\\\");\\n _;\\n }\\n\\n /**\\n * @dev Triggers stopped state.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n function _pause() internal virtual whenNotPaused {\\n _paused = true;\\n emit Paused(_msgSender());\\n }\\n\\n /**\\n * @dev Returns to normal state.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n function _unpause() internal virtual whenPaused {\\n _paused = false;\\n emit Unpaused(_msgSender());\\n }\\n}\\n\",\"keccak256\":\"0x212fb1b1d4beaf74354dad9bc329f44ee3c5375ef1c32acff76b4ecefc10f1d8\",\"license\":\"MIT\"},\"contracts/mocks/WrappedToken.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-or-later\\npragma solidity 0.7.5;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20Pausable.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Context.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\n\\ncontract WrappedToken is ERC20, ERC20Pausable {\\n // Error Code: No error.\\n uint256 public constant ERR_NO_ERROR = 0x0;\\n\\n // Error Code: Non-zero value expected to perform the function.\\n uint256 public constant ERR_INVALID_ZERO_VALUE = 0x01;\\n\\n constructor (string memory name_, string memory symbol_) ERC20(name_, symbol_) {}\\n\\n function name() public view override returns (string memory) {\\n return \\\"Wrapped Token\\\";\\n }\\n\\n function symbol() public view override returns (string memory) {\\n return \\\"WTOKEN\\\";\\n }\\n\\n function decimals() public view override returns (uint8) {\\n return 18;\\n }\\n\\n // deposit wraps received FTM tokens as wFTM in 1:1 ratio by minting\\n // the received amount of FTMs in wFTM on the sender's address.\\n function deposit() public whenNotPaused payable returns (uint256) {\\n // there has to be some value to be converted\\n if (msg.value == 0) {\\n return ERR_INVALID_ZERO_VALUE;\\n }\\n\\n // we already received FTMs, mint the appropriate amount of wFTM\\n _mint(msg.sender, msg.value);\\n\\n // all went well here\\n return ERR_NO_ERROR;\\n }\\n\\n // withdraw unwraps FTM tokens by burning specified amount\\n // of wFTM from the caller address and sending the same amount\\n // of FTMs back in exchange.\\n function withdraw(uint256 amount) public whenNotPaused returns (uint256) {\\n // there has to be some value to be converted\\n if (amount == 0) {\\n return ERR_INVALID_ZERO_VALUE;\\n }\\n\\n // burn wFTM from the sender first to prevent re-entrance issue\\n _burn(msg.sender, amount);\\n\\n // if wFTM were burned, transfer native tokens back to the sender\\n msg.sender.transfer(amount);\\n\\n // all went well here\\n return ERR_NO_ERROR;\\n }\\n\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal override(ERC20, ERC20Pausable) {\\n super._beforeTokenTransfer(from, to, amount);\\n }\\n}\",\"keccak256\":\"0x30ca6d5fb6fc22e2d80709bfa4aae820ef4d95231d61985583e6d99d0655a7af\",\"license\":\"AGPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b5060405162001b6438038062001b64833981810160405260408110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b838201915060208201858111156200006f57600080fd5b82518660018202830111640100000000821117156200008d57600080fd5b8083526020830192505050908051906020019080838360005b83811015620000c3578082015181840152602081019050620000a6565b50505050905090810190601f168015620000f15780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200011557600080fd5b838201915060208201858111156200012c57600080fd5b82518660018202830111640100000000821117156200014a57600080fd5b8083526020830192505050908051906020019080838360005b838110156200018057808201518184015260208101905062000163565b50505050905090810190601f168015620001ae5780820380516001836020036101000a031916815260200191505b5060405250505081818160039080519060200190620001cf9291906200022a565b508060049080519060200190620001e89291906200022a565b506012600560006101000a81548160ff021916908360ff16021790555050506000600560016101000a81548160ff0219169083151502179055505050620002e0565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620002625760008555620002ae565b82601f106200027d57805160ff1916838001178555620002ae565b82800160010185558215620002ae579182015b82811115620002ad57825182559160200191906001019062000290565b5b509050620002bd9190620002c1565b5090565b5b80821115620002dc576000816000905550600101620002c2565b5090565b61187480620002f06000396000f3fe6080604052600436106100f35760003560e01c80635c975abb1161008a578063a457c2d711610059578063a457c2d71461051b578063a9059cbb1461058c578063d0e30db0146105fd578063dd62ed3e1461061b576100f3565b80635c975abb146103ce5780636d7497b3146103fb57806370a082311461042657806395d89b411461048b576100f3565b80632e1a7d4d116100c65780632e1a7d4d146102b5578063313ce5671461030457806335052d6e14610332578063395093511461035d576100f3565b806306fdde03146100f8578063095ea7b31461018857806318160ddd146101f957806323b872dd14610224575b600080fd5b34801561010457600080fd5b5061010d6106a0565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561014d578082015181840152602081019050610132565b50505050905090810190601f16801561017a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561019457600080fd5b506101e1600480360360408110156101ab57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506106dd565b60405180821515815260200191505060405180910390f35b34801561020557600080fd5b5061020e6106fb565b6040518082815260200191505060405180910390f35b34801561023057600080fd5b5061029d6004803603606081101561024757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610705565b60405180821515815260200191505060405180910390f35b3480156102c157600080fd5b506102ee600480360360208110156102d857600080fd5b81019080803590602001909291905050506107de565b6040518082815260200191505060405180910390f35b34801561031057600080fd5b506103196108c8565b604051808260ff16815260200191505060405180910390f35b34801561033e57600080fd5b506103476108d1565b6040518082815260200191505060405180910390f35b34801561036957600080fd5b506103b66004803603604081101561038057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506108d6565b60405180821515815260200191505060405180910390f35b3480156103da57600080fd5b506103e3610989565b60405180821515815260200191505060405180910390f35b34801561040757600080fd5b506104106109a0565b6040518082815260200191505060405180910390f35b34801561043257600080fd5b506104756004803603602081101561044957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506109a5565b6040518082815260200191505060405180910390f35b34801561049757600080fd5b506104a06109ed565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156104e05780820151818401526020810190506104c5565b50505050905090810190601f16801561050d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561052757600080fd5b506105746004803603604081101561053e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610a2a565b60405180821515815260200191505060405180910390f35b34801561059857600080fd5b506105e5600480360360408110156105af57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610af7565b60405180821515815260200191505060405180910390f35b610605610b15565b6040518082815260200191505060405180910390f35b34801561062757600080fd5b5061068a6004803603604081101561063e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bb6565b6040518082815260200191505060405180910390f35b60606040518060400160405280600d81526020017f5772617070656420546f6b656e00000000000000000000000000000000000000815250905090565b60006106f16106ea610c3d565b8484610c45565b6001905092915050565b6000600254905090565b6000610712848484610e3c565b6107d38461071e610c3d565b6107ce8560405180606001604052806028815260200161175e60289139600160008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000610784610c3d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546110fd9092919063ffffffff16565b610c45565b600190509392505050565b60006107e8610989565b1561085b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f5061757361626c653a207061757365640000000000000000000000000000000081525060200191505060405180910390fd5b600082141561086d57600190506108c3565b61087733836111b7565b3373ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050501580156108bd573d6000803e3d6000fd5b50600090505b919050565b60006012905090565b600081565b600061097f6108e3610c3d565b8461097a85600160006108f4610c3d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461137b90919063ffffffff16565b610c45565b6001905092915050565b6000600560019054906101000a900460ff16905090565b600181565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60606040518060400160405280600681526020017f57544f4b454e0000000000000000000000000000000000000000000000000000815250905090565b6000610aed610a37610c3d565b84610ae8856040518060600160405280602581526020016117f06025913960016000610a61610c3d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546110fd9092919063ffffffff16565b610c45565b6001905092915050565b6000610b0b610b04610c3d565b8484610e3c565b6001905092915050565b6000610b1f610989565b15610b92576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f5061757361626c653a207061757365640000000000000000000000000000000081525060200191505060405180910390fd5b6000341415610ba45760019050610bb3565b610bae3334611403565b600090505b90565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610ccb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806117cc6024913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610d51576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806117166022913960400191505060405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610ec2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806117a76025913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610f48576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806116d16023913960400191505060405180910390fd5b610f538383836115ca565b610fbe81604051806060016040528060268152602001611738602691396000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546110fd9092919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611051816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461137b90919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b60008383111582906111aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561116f578082015181840152602081019050611154565b50505050905090810190601f16801561119c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5082840390509392505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561123d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117866021913960400191505060405180910390fd5b611249826000836115ca565b6112b4816040518060600160405280602281526020016116f4602291396000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546110fd9092919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061130b816002546115da90919063ffffffff16565b600281905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b6000808284019050838110156113f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156114a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b6114b2600083836115ca565b6114c78160025461137b90919063ffffffff16565b60028190555061151e816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461137b90919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b6115d583838361165d565b505050565b600082821115611652576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b818303905092915050565b6116688383836116cb565b611670610989565b156116c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180611815602a913960400191505060405180910390fd5b505050565b50505056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726f45524332305061757361626c653a20746f6b656e207472616e73666572207768696c6520706175736564a26469706673582212207f803552e28d002e99a21aa5e7ba778e975c7c2f8d474575fd7ccdca6ff2c03164736f6c63430007050033", + "deployedBytecode": "0x6080604052600436106100f35760003560e01c80635c975abb1161008a578063a457c2d711610059578063a457c2d71461051b578063a9059cbb1461058c578063d0e30db0146105fd578063dd62ed3e1461061b576100f3565b80635c975abb146103ce5780636d7497b3146103fb57806370a082311461042657806395d89b411461048b576100f3565b80632e1a7d4d116100c65780632e1a7d4d146102b5578063313ce5671461030457806335052d6e14610332578063395093511461035d576100f3565b806306fdde03146100f8578063095ea7b31461018857806318160ddd146101f957806323b872dd14610224575b600080fd5b34801561010457600080fd5b5061010d6106a0565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561014d578082015181840152602081019050610132565b50505050905090810190601f16801561017a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561019457600080fd5b506101e1600480360360408110156101ab57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506106dd565b60405180821515815260200191505060405180910390f35b34801561020557600080fd5b5061020e6106fb565b6040518082815260200191505060405180910390f35b34801561023057600080fd5b5061029d6004803603606081101561024757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610705565b60405180821515815260200191505060405180910390f35b3480156102c157600080fd5b506102ee600480360360208110156102d857600080fd5b81019080803590602001909291905050506107de565b6040518082815260200191505060405180910390f35b34801561031057600080fd5b506103196108c8565b604051808260ff16815260200191505060405180910390f35b34801561033e57600080fd5b506103476108d1565b6040518082815260200191505060405180910390f35b34801561036957600080fd5b506103b66004803603604081101561038057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506108d6565b60405180821515815260200191505060405180910390f35b3480156103da57600080fd5b506103e3610989565b60405180821515815260200191505060405180910390f35b34801561040757600080fd5b506104106109a0565b6040518082815260200191505060405180910390f35b34801561043257600080fd5b506104756004803603602081101561044957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506109a5565b6040518082815260200191505060405180910390f35b34801561049757600080fd5b506104a06109ed565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156104e05780820151818401526020810190506104c5565b50505050905090810190601f16801561050d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561052757600080fd5b506105746004803603604081101561053e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610a2a565b60405180821515815260200191505060405180910390f35b34801561059857600080fd5b506105e5600480360360408110156105af57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610af7565b60405180821515815260200191505060405180910390f35b610605610b15565b6040518082815260200191505060405180910390f35b34801561062757600080fd5b5061068a6004803603604081101561063e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bb6565b6040518082815260200191505060405180910390f35b60606040518060400160405280600d81526020017f5772617070656420546f6b656e00000000000000000000000000000000000000815250905090565b60006106f16106ea610c3d565b8484610c45565b6001905092915050565b6000600254905090565b6000610712848484610e3c565b6107d38461071e610c3d565b6107ce8560405180606001604052806028815260200161175e60289139600160008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000610784610c3d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546110fd9092919063ffffffff16565b610c45565b600190509392505050565b60006107e8610989565b1561085b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f5061757361626c653a207061757365640000000000000000000000000000000081525060200191505060405180910390fd5b600082141561086d57600190506108c3565b61087733836111b7565b3373ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050501580156108bd573d6000803e3d6000fd5b50600090505b919050565b60006012905090565b600081565b600061097f6108e3610c3d565b8461097a85600160006108f4610c3d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461137b90919063ffffffff16565b610c45565b6001905092915050565b6000600560019054906101000a900460ff16905090565b600181565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60606040518060400160405280600681526020017f57544f4b454e0000000000000000000000000000000000000000000000000000815250905090565b6000610aed610a37610c3d565b84610ae8856040518060600160405280602581526020016117f06025913960016000610a61610c3d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546110fd9092919063ffffffff16565b610c45565b6001905092915050565b6000610b0b610b04610c3d565b8484610e3c565b6001905092915050565b6000610b1f610989565b15610b92576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f5061757361626c653a207061757365640000000000000000000000000000000081525060200191505060405180910390fd5b6000341415610ba45760019050610bb3565b610bae3334611403565b600090505b90565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610ccb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806117cc6024913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610d51576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806117166022913960400191505060405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610ec2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806117a76025913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610f48576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806116d16023913960400191505060405180910390fd5b610f538383836115ca565b610fbe81604051806060016040528060268152602001611738602691396000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546110fd9092919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611051816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461137b90919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b60008383111582906111aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561116f578082015181840152602081019050611154565b50505050905090810190601f16801561119c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5082840390509392505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561123d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117866021913960400191505060405180910390fd5b611249826000836115ca565b6112b4816040518060600160405280602281526020016116f4602291396000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546110fd9092919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061130b816002546115da90919063ffffffff16565b600281905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b6000808284019050838110156113f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156114a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b6114b2600083836115ca565b6114c78160025461137b90919063ffffffff16565b60028190555061151e816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461137b90919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b6115d583838361165d565b505050565b600082821115611652576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b818303905092915050565b6116688383836116cb565b611670610989565b156116c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180611815602a913960400191505060405180910390fd5b505050565b50505056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726f45524332305061757361626c653a20746f6b656e207472616e73666572207768696c6520706175736564a26469706673582212207f803552e28d002e99a21aa5e7ba778e975c7c2f8d474575fd7ccdca6ff2c03164736f6c63430007050033", + "devdoc": { + "kind": "dev", + "methods": { + "allowance(address,address)": { + "details": "See {IERC20-allowance}." + }, + "approve(address,uint256)": { + "details": "See {IERC20-approve}. Requirements: - `spender` cannot be the zero address." + }, + "balanceOf(address)": { + "details": "See {IERC20-balanceOf}." + }, + "decimals()": { + "details": "Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5,05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is called. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}." + }, + "decreaseAllowance(address,uint256)": { + "details": "Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`." + }, + "increaseAllowance(address,uint256)": { + "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address." + }, + "name()": { + "details": "Returns the name of the token." + }, + "paused()": { + "details": "Returns true if the contract is paused, and false otherwise." + }, + "symbol()": { + "details": "Returns the symbol of the token, usually a shorter version of the name." + }, + "totalSupply()": { + "details": "See {IERC20-totalSupply}." + }, + "transfer(address,uint256)": { + "details": "See {IERC20-transfer}. Requirements: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`." + }, + "transferFrom(address,address,uint256)": { + "details": "See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for ``sender``'s tokens of at least `amount`." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 371, + "contract": "contracts/mocks/WrappedToken.sol:WrappedToken", + "label": "_balances", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 377, + "contract": "contracts/mocks/WrappedToken.sol:WrappedToken", + "label": "_allowances", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 379, + "contract": "contracts/mocks/WrappedToken.sol:WrappedToken", + "label": "_totalSupply", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 381, + "contract": "contracts/mocks/WrappedToken.sol:WrappedToken", + "label": "_name", + "offset": 0, + "slot": "3", + "type": "t_string_storage" + }, + { + "astId": 383, + "contract": "contracts/mocks/WrappedToken.sol:WrappedToken", + "label": "_symbol", + "offset": 0, + "slot": "4", + "type": "t_string_storage" + }, + { + "astId": 385, + "contract": "contracts/mocks/WrappedToken.sol:WrappedToken", + "label": "_decimals", + "offset": 0, + "slot": "5", + "type": "t_uint8" + }, + { + "astId": 1013, + "contract": "contracts/mocks/WrappedToken.sol:WrappedToken", + "label": "_paused", + "offset": 1, + "slot": "5", + "type": "t_bool" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/src/abi/rinkeby/WrappedTokenBondDepository.json b/src/abi/rinkeby/WrappedTokenBondDepository.json new file mode 100644 index 0000000000..591d9836a6 --- /dev/null +++ b/src/abi/rinkeby/WrappedTokenBondDepository.json @@ -0,0 +1,1253 @@ +{ + "address": "0x6fE3e4644a1CBB087D411A52C931B630cD5F899f", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_OHM", + "type": "address" + }, + { + "internalType": "address", + "name": "_principle", + "type": "address" + }, + { + "internalType": "address", + "name": "_treasury", + "type": "address" + }, + { + "internalType": "address", + "name": "_DAO", + "type": "address" + }, + { + "internalType": "address", + "name": "_feed", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "deposit", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "payout", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "expires", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "priceInUSD", + "type": "uint256" + } + ], + "name": "BondCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "priceInUSD", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "internalPrice", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "debtRatio", + "type": "uint256" + } + ], + "name": "BondPriceChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "payout", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "remaining", + "type": "uint256" + } + ], + "name": "BondRedeemed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "initialBCV", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newBCV", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "adjustment", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bool", + "name": "addition", + "type": "bool" + } + ], + "name": "ControlVariableAdjustment", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipPulled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipPushed", + "type": "event" + }, + { + "inputs": [], + "name": "DAO", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "OHM", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "adjustment", + "outputs": [ + { + "internalType": "bool", + "name": "add", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "rate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "target", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "buffer", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastTime", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "assetPrice", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "bondInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "payout", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "vesting", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "pricePaid", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bondPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "price_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bondPriceInUSD", + "outputs": [ + { + "internalType": "uint256", + "name": "price_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "debtDecay", + "outputs": [ + { + "internalType": "uint256", + "name": "decay_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "debtRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "debtRatio_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxPrice", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_depositor", + "type": "address" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_controlVariable", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_vestingTerm", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_minimumPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxPayout", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_initialDebt", + "type": "uint256" + } + ], + "name": "initializeBondTerms", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastDecay", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxPayout", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + } + ], + "name": "payoutFor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_depositor", + "type": "address" + } + ], + "name": "pendingPayoutFor", + "outputs": [ + { + "internalType": "uint256", + "name": "pendingPayout_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_depositor", + "type": "address" + } + ], + "name": "percentVestedFor", + "outputs": [ + { + "internalType": "uint256", + "name": "percentVested_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "policy", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "principle", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pullManagement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner_", + "type": "address" + } + ], + "name": "pushManagement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "recoverLostToken", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "bool", + "name": "_stake", + "type": "bool" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceManagement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_addition", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "_increment", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_target", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_buffer", + "type": "uint256" + } + ], + "name": "setAdjustment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum OlympusBondDepository.PARAMETER", + "name": "_parameter", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "_input", + "type": "uint256" + } + ], + "name": "setBondTerms", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_staking", + "type": "address" + }, + { + "internalType": "bool", + "name": "_helper", + "type": "bool" + } + ], + "name": "setStaking", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "staking", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stakingHelper", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "standardizedDebtRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "terms", + "outputs": [ + { + "internalType": "uint256", + "name": "controlVariable", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "vestingTerm", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minimumPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPayout", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxDebt", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "treasury", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "useHelper", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xee68ee4137e166323c32186bceef18778396d21943b042ee741faa72aa84751b", + "receipt": { + "to": null, + "from": "0xA38F4E6718EdCF023a1d032a2193848CB932c8e3", + "contractAddress": "0x6fE3e4644a1CBB087D411A52C931B630cD5F899f", + "transactionIndex": 7, + "gasUsed": "3455719", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000001000000400000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000020000000000020002000000000000000000001000000000000000000000000000000000000000002", + "blockHash": "0xa9ff22c2ed37d1cc660f42f63f8b7cefb153b20a97a8f046ee091df65b601eb3", + "transactionHash": "0xee68ee4137e166323c32186bceef18778396d21943b042ee741faa72aa84751b", + "logs": [ + { + "transactionIndex": 7, + "blockNumber": 9907143, + "transactionHash": "0xee68ee4137e166323c32186bceef18778396d21943b042ee741faa72aa84751b", + "address": "0x6fE3e4644a1CBB087D411A52C931B630cD5F899f", + "topics": [ + "0xea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000a38f4e6718edcf023a1d032a2193848cb932c8e3" + ], + "data": "0x", + "logIndex": 7, + "blockHash": "0xa9ff22c2ed37d1cc660f42f63f8b7cefb153b20a97a8f046ee091df65b601eb3" + } + ], + "blockNumber": 9907143, + "cumulativeGasUsed": "3888901", + "status": 1, + "byzantium": true + }, + "args": [ + "0x9bb5E7183e6259183f8E79876eCC0228738C95F6", + "0xDd1875ddC7c832FA1CB82DfB8B34d3abD1F67a87", + "0x1e0AD0F8DDFF84FDc938373E9aa66b8d994ea066", + "0xA38F4E6718EdCF023a1d032a2193848CB932c8e3", + "0x8A753747A1Fa494EC906cE90E9f37563A8AF630e" + ], + "solcInputHash": "778fd7df05b9b5e245a90ea93cf9b329", + "metadata": "{\"compiler\":{\"version\":\"0.7.5+commit.eb77ed08\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_OHM\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_principle\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_DAO\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_feed\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"deposit\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"payout\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"expires\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"priceInUSD\",\"type\":\"uint256\"}],\"name\":\"BondCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"priceInUSD\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"internalPrice\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"debtRatio\",\"type\":\"uint256\"}],\"name\":\"BondPriceChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payout\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remaining\",\"type\":\"uint256\"}],\"name\":\"BondRedeemed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"initialBCV\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBCV\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"adjustment\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"addition\",\"type\":\"bool\"}],\"name\":\"ControlVariableAdjustment\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipPulled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipPushed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DAO\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OHM\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"adjustment\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"add\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"rate\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"target\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"buffer\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lastTime\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"assetPrice\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bondInfo\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"payout\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"vesting\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lastTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"pricePaid\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bondPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"price_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bondPriceInUSD\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"price_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentDebt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"debtDecay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"decay_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"debtRatio\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"debtRatio_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_depositor\",\"type\":\"address\"}],\"name\":\"deposit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_controlVariable\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_vestingTerm\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_minimumPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxPayout\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxDebt\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_initialDebt\",\"type\":\"uint256\"}],\"name\":\"initializeBondTerms\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastDecay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxPayout\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"payoutFor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_depositor\",\"type\":\"address\"}],\"name\":\"pendingPayoutFor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"pendingPayout_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_depositor\",\"type\":\"address\"}],\"name\":\"percentVestedFor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"percentVested_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"policy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"principle\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pullManagement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner_\",\"type\":\"address\"}],\"name\":\"pushManagement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"recoverLostToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_stake\",\"type\":\"bool\"}],\"name\":\"redeem\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceManagement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_addition\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"_increment\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_target\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_buffer\",\"type\":\"uint256\"}],\"name\":\"setAdjustment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enum OlympusBondDepository.PARAMETER\",\"name\":\"_parameter\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"_input\",\"type\":\"uint256\"}],\"name\":\"setBondTerms\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_staking\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_helper\",\"type\":\"bool\"}],\"name\":\"setStaking\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"staking\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stakingHelper\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"standardizedDebtRatio\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"terms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"controlVariable\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"vestingTerm\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minimumPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPayout\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxDebt\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalDebt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useHelper\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"bondPrice()\":{\"returns\":{\"price_\":\"uint\"}},\"bondPriceInUSD()\":{\"returns\":{\"price_\":\"uint\"}},\"currentDebt()\":{\"returns\":{\"_0\":\"uint\"}},\"debtDecay()\":{\"returns\":{\"decay_\":\"uint\"}},\"debtRatio()\":{\"returns\":{\"debtRatio_\":\"uint\"}},\"deposit(uint256,uint256,address)\":{\"params\":{\"_amount\":\"uint\",\"_depositor\":\"address\",\"_maxPrice\":\"uint\"},\"returns\":{\"_0\":\"uint\"}},\"initializeBondTerms(uint256,uint256,uint256,uint256,uint256,uint256)\":{\"params\":{\"_controlVariable\":\"uint\",\"_initialDebt\":\"uint\",\"_maxDebt\":\"uint\",\"_maxPayout\":\"uint\",\"_minimumPrice\":\"uint\",\"_vestingTerm\":\"uint\"}},\"maxPayout()\":{\"returns\":{\"_0\":\"uint\"}},\"payoutFor(uint256)\":{\"params\":{\"_value\":\"uint\"},\"returns\":{\"_0\":\"uint\"}},\"pendingPayoutFor(address)\":{\"params\":{\"_depositor\":\"address\"},\"returns\":{\"pendingPayout_\":\"uint\"}},\"percentVestedFor(address)\":{\"params\":{\"_depositor\":\"address\"},\"returns\":{\"percentVested_\":\"uint\"}},\"recoverLostToken(address)\":{\"returns\":{\"_0\":\"bool\"}},\"redeem(address,bool)\":{\"params\":{\"_recipient\":\"address\",\"_stake\":\"bool\"},\"returns\":{\"_0\":\"uint\"}},\"setAdjustment(bool,uint256,uint256,uint256)\":{\"params\":{\"_addition\":\"bool\",\"_buffer\":\"uint\",\"_increment\":\"uint\",\"_target\":\"uint\"}},\"setBondTerms(uint8,uint256)\":{\"params\":{\"_input\":\"uint\",\"_parameter\":\"PARAMETER\"}},\"setStaking(address,bool)\":{\"params\":{\"_helper\":\"bool\",\"_staking\":\"address\"}},\"standardizedDebtRatio()\":{\"returns\":{\"_0\":\"uint\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"assetPrice()\":{\"notice\":\"get asset price from chainlink\"},\"bondPrice()\":{\"notice\":\"calculate current bond premium\"},\"bondPriceInUSD()\":{\"notice\":\"converts bond price to DAI value\"},\"currentDebt()\":{\"notice\":\"calculate debt factoring in decay\"},\"debtDecay()\":{\"notice\":\"amount to decay total debt by\"},\"debtRatio()\":{\"notice\":\"calculate current ratio of debt to OHM supply\"},\"deposit(uint256,uint256,address)\":{\"notice\":\"deposit bond\"},\"initializeBondTerms(uint256,uint256,uint256,uint256,uint256,uint256)\":{\"notice\":\"initializes bond parameters\"},\"maxPayout()\":{\"notice\":\"determine maximum bond size\"},\"payoutFor(uint256)\":{\"notice\":\"calculate interest due for new bond\"},\"pendingPayoutFor(address)\":{\"notice\":\"calculate amount of OHM available for claim by depositor\"},\"percentVestedFor(address)\":{\"notice\":\"calculate how far into vesting a depositor is\"},\"recoverLostToken(address)\":{\"notice\":\"allow anyone to send lost tokens (excluding principle or OHM) to the DAO\"},\"redeem(address,bool)\":{\"notice\":\"redeem bond for user\"},\"setAdjustment(bool,uint256,uint256,uint256)\":{\"notice\":\"set control variable adjustment\"},\"setBondTerms(uint8,uint256)\":{\"notice\":\"set parameters for new bonds\"},\"setStaking(address,bool)\":{\"notice\":\"set contract for auto stake\"},\"standardizedDebtRatio()\":{\"notice\":\"debt ratio in same terms as reserve bonds\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/wETHBondDepository.sol\":\"OlympusBondDepository\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/wETHBondDepository.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-or-later\\npragma solidity 0.7.5;\\n\\ninterface IOwnable {\\n function policy() external view returns (address);\\n\\n function renounceManagement() external;\\n \\n function pushManagement( address newOwner_ ) external;\\n \\n function pullManagement() external;\\n}\\n\\ncontract Ownable is IOwnable {\\n\\n address internal _owner;\\n address internal _newOwner;\\n\\n event OwnershipPushed(address indexed previousOwner, address indexed newOwner);\\n event OwnershipPulled(address indexed previousOwner, address indexed newOwner);\\n\\n constructor () {\\n _owner = msg.sender;\\n emit OwnershipPushed( address(0), _owner );\\n }\\n\\n function policy() public view override returns (address) {\\n return _owner;\\n }\\n\\n modifier onlyPolicy() {\\n require( _owner == msg.sender, \\\"Ownable: caller is not the owner\\\" );\\n _;\\n }\\n\\n function renounceManagement() public virtual override onlyPolicy() {\\n emit OwnershipPushed( _owner, address(0) );\\n _owner = address(0);\\n }\\n\\n function pushManagement( address newOwner_ ) public virtual override onlyPolicy() {\\n require( newOwner_ != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipPushed( _owner, newOwner_ );\\n _newOwner = newOwner_;\\n }\\n \\n function pullManagement() public virtual override {\\n require( msg.sender == _newOwner, \\\"Ownable: must be new owner to pull\\\");\\n emit OwnershipPulled( _owner, _newOwner );\\n _owner = _newOwner;\\n }\\n}\\n\\nlibrary SafeMath {\\n\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n return c;\\n }\\n\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n\\n function sqrrt(uint256 a) internal pure returns (uint c) {\\n if (a > 3) {\\n c = a;\\n uint b = add( div( a, 2), 1 );\\n while (b < c) {\\n c = b;\\n b = div( add( div( a, b ), b), 2 );\\n }\\n } else if (a != 0) {\\n c = 1;\\n }\\n }\\n}\\n\\nlibrary Address {\\n\\n function isContract(address account) internal view returns (bool) {\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return _functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n if (returndata.length > 0) {\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n\\n function addressToString(address _address) internal pure returns(string memory) {\\n bytes32 _bytes = bytes32(uint256(_address));\\n bytes memory HEX = \\\"0123456789abcdef\\\";\\n bytes memory _addr = new bytes(42);\\n\\n _addr[0] = '0';\\n _addr[1] = 'x';\\n\\n for(uint256 i = 0; i < 20; i++) {\\n _addr[2+i*2] = HEX[uint8(_bytes[i + 12] >> 4)];\\n _addr[3+i*2] = HEX[uint8(_bytes[i + 12] & 0x0f)];\\n }\\n\\n return string(_addr);\\n\\n }\\n}\\n\\ninterface IERC20 {\\n function decimals() external view returns (uint8);\\n\\n function totalSupply() external view returns (uint256);\\n\\n function balanceOf(address account) external view returns (uint256);\\n\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\\nabstract contract ERC20 is IERC20 {\\n\\n using SafeMath for uint256;\\n\\n // TODO comment actual hash value.\\n bytes32 constant private ERC20TOKEN_ERC1820_INTERFACE_ID = keccak256( \\\"ERC20Token\\\" );\\n \\n mapping (address => uint256) internal _balances;\\n\\n mapping (address => mapping (address => uint256)) internal _allowances;\\n\\n uint256 internal _totalSupply;\\n\\n string internal _name;\\n \\n string internal _symbol;\\n \\n uint8 internal _decimals;\\n\\n constructor (string memory name_, string memory symbol_, uint8 decimals_) {\\n _name = name_;\\n _symbol = symbol_;\\n _decimals = decimals_;\\n }\\n\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n function symbol() public view returns (string memory) {\\n return _symbol;\\n }\\n\\n function decimals() public view override returns (uint8) {\\n return _decimals;\\n }\\n\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(msg.sender, recipient, amount);\\n return true;\\n }\\n\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(msg.sender, spender, amount);\\n return true;\\n }\\n\\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\n return true;\\n }\\n\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\\n return true;\\n }\\n\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(sender, recipient, amount);\\n }\\n\\n function _mint(address account_, uint256 ammount_) internal virtual {\\n require(account_ != address(0), \\\"ERC20: mint to the zero address\\\");\\n _beforeTokenTransfer(address( this ), account_, ammount_);\\n _totalSupply = _totalSupply.add(ammount_);\\n _balances[account_] = _balances[account_].add(ammount_);\\n emit Transfer(address( this ), account_, ammount_);\\n }\\n\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(account, address(0), amount);\\n }\\n\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n function _beforeTokenTransfer( address from_, address to_, uint256 amount_ ) internal virtual { }\\n}\\n\\ninterface IERC2612Permit {\\n\\n function permit(\\n address owner,\\n address spender,\\n uint256 amount,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n function nonces(address owner) external view returns (uint256);\\n}\\n\\nlibrary Counters {\\n using SafeMath for uint256;\\n\\n struct Counter {\\n\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n counter._value += 1;\\n }\\n\\n function decrement(Counter storage counter) internal {\\n counter._value = counter._value.sub(1);\\n }\\n}\\n\\nabstract contract ERC20Permit is ERC20, IERC2612Permit {\\n using Counters for Counters.Counter;\\n\\n mapping(address => Counters.Counter) private _nonces;\\n\\n // keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\\n\\n bytes32 public DOMAIN_SEPARATOR;\\n\\n constructor() {\\n uint256 chainID;\\n assembly {\\n chainID := chainid()\\n }\\n\\n DOMAIN_SEPARATOR = keccak256(\\n abi.encode(\\n keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"),\\n keccak256(bytes(name())),\\n keccak256(bytes(\\\"1\\\")), // Version\\n chainID,\\n address(this)\\n )\\n );\\n }\\n\\n function permit(\\n address owner,\\n address spender,\\n uint256 amount,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"Permit: expired deadline\\\");\\n\\n bytes32 hashStruct =\\n keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, amount, _nonces[owner].current(), deadline));\\n\\n bytes32 _hash = keccak256(abi.encodePacked(uint16(0x1901), DOMAIN_SEPARATOR, hashStruct));\\n\\n address signer = ecrecover(_hash, v, r, s);\\n require(signer != address(0) && signer == owner, \\\"ZeroSwapPermit: Invalid signature\\\");\\n\\n _nonces[owner].increment();\\n _approve(owner, spender, amount);\\n }\\n\\n function nonces(address owner) public view override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n}\\n\\nlibrary SafeERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n\\n require((value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\\nlibrary FullMath {\\n function fullMul(uint256 x, uint256 y) private pure returns (uint256 l, uint256 h) {\\n uint256 mm = mulmod(x, y, uint256(-1));\\n l = x * y;\\n h = mm - l;\\n if (mm < l) h -= 1;\\n }\\n\\n function fullDiv(\\n uint256 l,\\n uint256 h,\\n uint256 d\\n ) private pure returns (uint256) {\\n uint256 pow2 = d & -d;\\n d /= pow2;\\n l /= pow2;\\n l += h * ((-pow2) / pow2 + 1);\\n uint256 r = 1;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n r *= 2 - d * r;\\n return l * r;\\n }\\n\\n function mulDiv(\\n uint256 x,\\n uint256 y,\\n uint256 d\\n ) internal pure returns (uint256) {\\n (uint256 l, uint256 h) = fullMul(x, y);\\n uint256 mm = mulmod(x, y, d);\\n if (mm > l) h -= 1;\\n l -= mm;\\n require(h < d, 'FullMath::mulDiv: overflow');\\n return fullDiv(l, h, d);\\n }\\n}\\n\\nlibrary FixedPoint {\\n\\n struct uq112x112 {\\n uint224 _x;\\n }\\n\\n struct uq144x112 {\\n uint256 _x;\\n }\\n\\n uint8 private constant RESOLUTION = 112;\\n uint256 private constant Q112 = 0x10000000000000000000000000000;\\n uint256 private constant Q224 = 0x100000000000000000000000000000000000000000000000000000000;\\n uint256 private constant LOWER_MASK = 0xffffffffffffffffffffffffffff; // decimal of UQ*x112 (lower 112 bits)\\n\\n function decode(uq112x112 memory self) internal pure returns (uint112) {\\n return uint112(self._x >> RESOLUTION);\\n }\\n\\n function decode112with18(uq112x112 memory self) internal pure returns (uint) {\\n\\n return uint(self._x) / 5192296858534827;\\n }\\n\\n function fraction(uint256 numerator, uint256 denominator) internal pure returns (uq112x112 memory) {\\n require(denominator > 0, 'FixedPoint::fraction: division by zero');\\n if (numerator == 0) return FixedPoint.uq112x112(0);\\n\\n if (numerator <= uint144(-1)) {\\n uint256 result = (numerator << RESOLUTION) / denominator;\\n require(result <= uint224(-1), 'FixedPoint::fraction: overflow');\\n return uq112x112(uint224(result));\\n } else {\\n uint256 result = FullMath.mulDiv(numerator, Q112, denominator);\\n require(result <= uint224(-1), 'FixedPoint::fraction: overflow');\\n return uq112x112(uint224(result));\\n }\\n }\\n}\\n\\ninterface AggregatorV3Interface {\\n\\n function decimals() external view returns (uint8);\\n function description() external view returns (string memory);\\n function version() external view returns (uint256);\\n\\n // getRoundData and latestRoundData should both raise \\\"No data present\\\"\\n // if they do not have data to report, instead of returning unset values\\n // which could be misinterpreted as actual reported values.\\n function getRoundData(uint80 _roundId)\\n external\\n view\\n returns (\\n uint80 roundId,\\n int256 answer,\\n uint256 startedAt,\\n uint256 updatedAt,\\n uint80 answeredInRound\\n );\\n function latestRoundData()\\n external\\n view\\n returns (\\n uint80 roundId,\\n int256 answer,\\n uint256 startedAt,\\n uint256 updatedAt,\\n uint80 answeredInRound\\n );\\n}\\n\\ninterface ITreasury {\\n function deposit( uint _amount, address _token, uint _profit ) external returns ( bool );\\n function valueOf( address _token, uint _amount ) external view returns ( uint value_ );\\n function mintRewards( address _recipient, uint _amount ) external;\\n}\\n\\ninterface IStaking {\\n function stake( uint _amount, address _recipient ) external returns ( bool );\\n}\\n\\ninterface IStakingHelper {\\n function stake( uint _amount, address _recipient ) external;\\n}\\n\\ncontract OlympusBondDepository is Ownable {\\n\\n using FixedPoint for *;\\n using SafeERC20 for IERC20;\\n using SafeMath for uint;\\n\\n\\n\\n\\n /* ======== EVENTS ======== */\\n\\n event BondCreated( uint deposit, uint indexed payout, uint indexed expires, uint indexed priceInUSD );\\n event BondRedeemed( address indexed recipient, uint payout, uint remaining );\\n event BondPriceChanged( uint indexed priceInUSD, uint indexed internalPrice, uint indexed debtRatio );\\n event ControlVariableAdjustment( uint initialBCV, uint newBCV, uint adjustment, bool addition );\\n\\n\\n\\n\\n /* ======== STATE VARIABLES ======== */\\n\\n address public immutable OHM; // token given as payment for bond\\n address public immutable principle; // token used to create bond\\n address public immutable treasury; // mints OHM when receives principle\\n address public immutable DAO; // receives profit share from bond\\n\\n AggregatorV3Interface internal priceFeed;\\n\\n address public staking; // to auto-stake payout\\n address public stakingHelper; // to stake and claim if no staking warmup\\n bool public useHelper;\\n\\n Terms public terms; // stores terms for new bonds\\n Adjust public adjustment; // stores adjustment to BCV data\\n\\n mapping( address => Bond ) public bondInfo; // stores bond information for depositors\\n\\n uint public totalDebt; // total value of outstanding bonds; used for pricing\\n uint public lastDecay; // reference time for debt decay\\n\\n\\n\\n\\n /* ======== STRUCTS ======== */\\n\\n // Info for creating new bonds\\n struct Terms {\\n uint controlVariable; // scaling variable for price\\n uint vestingTerm; // in seconds\\n uint minimumPrice; // vs principle value. 4 decimals (1500 = 0.15)\\n uint maxPayout; // in thousandths of a %. i.e. 500 = 0.5%\\n uint maxDebt; // 9 decimal debt ratio, max % total supply created as debt\\n }\\n\\n // Info for bond holder\\n struct Bond {\\n uint payout; // OHM remaining to be paid\\n uint vesting; // seconds left to vest\\n uint lastTime; // Last interaction\\n uint pricePaid; // In DAI, for front end viewing\\n }\\n\\n // Info for incremental adjustments to control variable\\n struct Adjust {\\n bool add; // addition or subtraction\\n uint rate; // increment\\n uint target; // BCV when adjustment finished\\n uint buffer; // minimum length (in seconds) between adjustments\\n uint lastTime; // time when last adjustment made\\n }\\n\\n\\n\\n\\n /* ======== INITIALIZATION ======== */\\n\\n constructor ( \\n address _OHM,\\n address _principle,\\n address _treasury, \\n address _DAO,\\n address _feed\\n ) {\\n require( _OHM != address(0) );\\n OHM = _OHM;\\n require( _principle != address(0) );\\n principle = _principle;\\n require( _treasury != address(0) );\\n treasury = _treasury;\\n require( _DAO != address(0) );\\n DAO = _DAO;\\n require( _feed != address(0) );\\n priceFeed = AggregatorV3Interface( _feed );\\n }\\n\\n /**\\n * @notice initializes bond parameters\\n * @param _controlVariable uint\\n * @param _vestingTerm uint\\n * @param _minimumPrice uint\\n * @param _maxPayout uint\\n * @param _maxDebt uint\\n * @param _initialDebt uint\\n */\\n function initializeBondTerms( \\n uint _controlVariable, \\n uint _vestingTerm,\\n uint _minimumPrice,\\n uint _maxPayout,\\n uint _maxDebt,\\n uint _initialDebt\\n ) external onlyPolicy() {\\n require( currentDebt() == 0, \\\"Debt must be 0 for initialization\\\" );\\n terms = Terms ({\\n controlVariable: _controlVariable,\\n vestingTerm: _vestingTerm,\\n minimumPrice: _minimumPrice,\\n maxPayout: _maxPayout,\\n maxDebt: _maxDebt\\n });\\n totalDebt = _initialDebt;\\n lastDecay = block.timestamp;\\n }\\n\\n\\n\\n \\n /* ======== POLICY FUNCTIONS ======== */\\n\\n enum PARAMETER { VESTING, PAYOUT, DEBT }\\n /**\\n * @notice set parameters for new bonds\\n * @param _parameter PARAMETER\\n * @param _input uint\\n */\\n function setBondTerms ( PARAMETER _parameter, uint _input ) external onlyPolicy() {\\n if ( _parameter == PARAMETER.VESTING ) { // 0\\n require( _input >= 129600, \\\"Vesting must be longer than 36 hours\\\" );\\n terms.vestingTerm = _input;\\n } else if ( _parameter == PARAMETER.PAYOUT ) { // 1\\n require( _input <= 1000, \\\"Payout cannot be above 1 percent\\\" );\\n terms.maxPayout = _input;\\n } else if ( _parameter == PARAMETER.DEBT ) { // 3\\n terms.maxDebt = _input;\\n }\\n }\\n\\n /**\\n * @notice set control variable adjustment\\n * @param _addition bool\\n * @param _increment uint\\n * @param _target uint\\n * @param _buffer uint\\n */\\n function setAdjustment ( \\n bool _addition,\\n uint _increment, \\n uint _target,\\n uint _buffer \\n ) external onlyPolicy() {\\n require( _increment <= terms.controlVariable.mul( 25 ).div( 1000 ), \\\"Increment too large\\\" );\\n\\n adjustment = Adjust({\\n add: _addition,\\n rate: _increment,\\n target: _target,\\n buffer: _buffer,\\n lastTime: block.timestamp\\n });\\n }\\n\\n /**\\n * @notice set contract for auto stake\\n * @param _staking address\\n * @param _helper bool\\n */\\n function setStaking( address _staking, bool _helper ) external onlyPolicy() {\\n require( _staking != address(0) );\\n if ( _helper ) {\\n useHelper = true;\\n stakingHelper = _staking;\\n } else {\\n useHelper = false;\\n staking = _staking;\\n }\\n }\\n\\n\\n \\n\\n /* ======== USER FUNCTIONS ======== */\\n\\n /**\\n * @notice deposit bond\\n * @param _amount uint\\n * @param _maxPrice uint\\n * @param _depositor address\\n * @return uint\\n */\\n function deposit( \\n uint _amount, \\n uint _maxPrice,\\n address _depositor\\n ) external returns ( uint ) {\\n require( _depositor != address(0), \\\"Invalid address\\\" );\\n\\n decayDebt();\\n require( totalDebt <= terms.maxDebt, \\\"Max capacity reached\\\" );\\n \\n uint priceInUSD = bondPriceInUSD(); // Stored in bond info\\n uint nativePrice = _bondPrice();\\n\\n require( _maxPrice >= nativePrice, \\\"Slippage limit: more than max price\\\" ); // slippage protection\\n\\n uint value = ITreasury( treasury ).valueOf( principle, _amount );\\n uint payout = payoutFor( value ); // payout to bonder is computed\\n\\n require( payout >= 10000000, \\\"Bond too small\\\" ); // must be > 0.01 OHM ( underflow protection )\\n require( payout <= maxPayout(), \\\"Bond too large\\\"); // size protection because there is no slippage\\n\\n /**\\n asset carries risk and is not minted against\\n asset transfered to treasury and rewards minted as payout\\n */\\n IERC20( principle ).safeTransferFrom( msg.sender, treasury, _amount );\\n ITreasury( treasury ).mintRewards( address(this), payout );\\n \\n // total debt is increased\\n totalDebt = totalDebt.add( value ); \\n \\n // depositor info is stored\\n bondInfo[ _depositor ] = Bond({ \\n payout: bondInfo[ _depositor ].payout.add( payout ),\\n vesting: terms.vestingTerm,\\n lastTime: block.timestamp,\\n pricePaid: priceInUSD\\n });\\n\\n // indexed events are emitted\\n emit BondCreated( _amount, payout, block.timestamp.add( terms.vestingTerm ), priceInUSD );\\n emit BondPriceChanged( bondPriceInUSD(), _bondPrice(), debtRatio() );\\n\\n adjust(); // control variable is adjusted\\n return payout; \\n }\\n\\n /** \\n * @notice redeem bond for user\\n * @param _recipient address\\n * @param _stake bool\\n * @return uint\\n */ \\n function redeem( address _recipient, bool _stake ) external returns ( uint ) { \\n Bond memory info = bondInfo[ _recipient ];\\n uint percentVested = percentVestedFor( _recipient ); // (time since last interaction / vesting term remaining)\\n\\n if ( percentVested >= 10000 ) { // if fully vested\\n delete bondInfo[ _recipient ]; // delete user info\\n emit BondRedeemed( _recipient, info.payout, 0 ); // emit bond data\\n return stakeOrSend( _recipient, _stake, info.payout ); // pay user everything due\\n\\n } else { // if unfinished\\n // calculate payout vested\\n uint payout = info.payout.mul( percentVested ).div( 10000 );\\n\\n // store updated deposit info\\n bondInfo[ _recipient ] = Bond({\\n payout: info.payout.sub( payout ),\\n vesting: info.vesting.sub( block.timestamp.sub( info.lastTime ) ),\\n lastTime: block.timestamp,\\n pricePaid: info.pricePaid\\n });\\n\\n emit BondRedeemed( _recipient, payout, bondInfo[ _recipient ].payout );\\n return stakeOrSend( _recipient, _stake, payout );\\n }\\n }\\n\\n\\n\\n \\n /* ======== INTERNAL HELPER FUNCTIONS ======== */\\n\\n /**\\n * @notice allow user to stake payout automatically\\n * @param _stake bool\\n * @param _amount uint\\n * @return uint\\n */\\n function stakeOrSend( address _recipient, bool _stake, uint _amount ) internal returns ( uint ) {\\n if ( !_stake ) { // if user does not want to stake\\n IERC20( OHM ).transfer( _recipient, _amount ); // send payout\\n } else { // if user wants to stake\\n if ( useHelper ) { // use if staking warmup is 0\\n IERC20( OHM ).approve( stakingHelper, _amount );\\n IStakingHelper( stakingHelper ).stake( _amount, _recipient );\\n } else {\\n IERC20( OHM ).approve( staking, _amount );\\n IStaking( staking ).stake( _amount, _recipient );\\n }\\n }\\n return _amount;\\n }\\n\\n /**\\n * @notice makes incremental adjustment to control variable\\n */\\n function adjust() internal {\\n uint timeCanAdjust = adjustment.lastTime.add( adjustment.buffer );\\n if( adjustment.rate != 0 && block.timestamp >= timeCanAdjust ) {\\n uint initial = terms.controlVariable;\\n if ( adjustment.add ) {\\n terms.controlVariable = terms.controlVariable.add( adjustment.rate );\\n if ( terms.controlVariable >= adjustment.target ) {\\n adjustment.rate = 0;\\n }\\n } else {\\n terms.controlVariable = terms.controlVariable.sub( adjustment.rate );\\n if ( terms.controlVariable <= adjustment.target ) {\\n adjustment.rate = 0;\\n }\\n }\\n adjustment.lastTime = block.timestamp;\\n emit ControlVariableAdjustment( initial, terms.controlVariable, adjustment.rate, adjustment.add );\\n }\\n }\\n\\n /**\\n * @notice reduce total debt\\n */\\n function decayDebt() internal {\\n totalDebt = totalDebt.sub( debtDecay() );\\n lastDecay = block.timestamp;\\n }\\n\\n\\n\\n\\n /* ======== VIEW FUNCTIONS ======== */\\n\\n /**\\n * @notice determine maximum bond size\\n * @return uint\\n */\\n function maxPayout() public view returns ( uint ) {\\n return IERC20( OHM ).totalSupply().mul( terms.maxPayout ).div( 100000 );\\n }\\n\\n /**\\n * @notice calculate interest due for new bond\\n * @param _value uint\\n * @return uint\\n */\\n function payoutFor( uint _value ) public view returns ( uint ) {\\n return FixedPoint.fraction( _value, bondPrice() ).decode112with18().div( 1e14 );\\n }\\n\\n\\n /**\\n * @notice calculate current bond premium\\n * @return price_ uint\\n */\\n function bondPrice() public view returns ( uint price_ ) { \\n price_ = terms.controlVariable.mul( debtRatio() ).div( 1e5 );\\n if ( price_ < terms.minimumPrice ) {\\n price_ = terms.minimumPrice;\\n }\\n }\\n\\n /**\\n * @notice calculate current bond price and remove floor if above\\n * @return price_ uint\\n */\\n function _bondPrice() internal returns ( uint price_ ) {\\n price_ = terms.controlVariable.mul( debtRatio() ).div( 1e5 );\\n if ( price_ < terms.minimumPrice ) {\\n price_ = terms.minimumPrice; \\n } else if ( terms.minimumPrice != 0 ) {\\n terms.minimumPrice = 0;\\n }\\n }\\n\\n /**\\n * @notice get asset price from chainlink\\n */\\n function assetPrice() public view returns (int) {\\n ( , int price, , , ) = priceFeed.latestRoundData();\\n return price;\\n }\\n\\n /**\\n * @notice converts bond price to DAI value\\n * @return price_ uint\\n */\\n function bondPriceInUSD() public view returns ( uint price_ ) {\\n price_ = bondPrice().mul( uint( assetPrice() ) ).mul( 1e6 );\\n }\\n\\n\\n /**\\n * @notice calculate current ratio of debt to OHM supply\\n * @return debtRatio_ uint\\n */\\n function debtRatio() public view returns ( uint debtRatio_ ) { \\n uint supply = IERC20( OHM ).totalSupply();\\n debtRatio_ = FixedPoint.fraction( \\n currentDebt().mul( 1e9 ), \\n supply\\n ).decode112with18().div( 1e18 );\\n }\\n\\n /**\\n * @notice debt ratio in same terms as reserve bonds\\n * @return uint\\n */\\n function standardizedDebtRatio() external view returns ( uint ) {\\n return debtRatio().mul( uint( assetPrice() ) ).div( 1e8 ); // ETH feed is 8 decimals\\n }\\n\\n /**\\n * @notice calculate debt factoring in decay\\n * @return uint\\n */\\n function currentDebt() public view returns ( uint ) {\\n return totalDebt.sub( debtDecay() );\\n }\\n\\n /**\\n * @notice amount to decay total debt by\\n * @return decay_ uint\\n */\\n function debtDecay() public view returns ( uint decay_ ) {\\n uint timeSinceLast = block.timestamp.sub( lastDecay );\\n decay_ = totalDebt.mul( timeSinceLast ).div( terms.vestingTerm );\\n if ( decay_ > totalDebt ) {\\n decay_ = totalDebt;\\n }\\n }\\n\\n\\n /**\\n * @notice calculate how far into vesting a depositor is\\n * @param _depositor address\\n * @return percentVested_ uint\\n */\\n function percentVestedFor( address _depositor ) public view returns ( uint percentVested_ ) {\\n Bond memory bond = bondInfo[ _depositor ];\\n uint timeSinceLast = block.timestamp.sub( bond.lastTime );\\n uint vesting = bond.vesting;\\n\\n if ( vesting > 0 ) {\\n percentVested_ = timeSinceLast.mul( 10000 ).div( vesting );\\n } else {\\n percentVested_ = 0;\\n }\\n }\\n\\n /**\\n * @notice calculate amount of OHM available for claim by depositor\\n * @param _depositor address\\n * @return pendingPayout_ uint\\n */\\n function pendingPayoutFor( address _depositor ) external view returns ( uint pendingPayout_ ) {\\n uint percentVested = percentVestedFor( _depositor );\\n uint payout = bondInfo[ _depositor ].payout;\\n\\n if ( percentVested >= 10000 ) {\\n pendingPayout_ = payout;\\n } else {\\n pendingPayout_ = payout.mul( percentVested ).div( 10000 );\\n }\\n }\\n\\n\\n\\n\\n /* ======= AUXILLIARY ======= */\\n\\n /**\\n * @notice allow anyone to send lost tokens (excluding principle or OHM) to the DAO\\n * @return bool\\n */\\n function recoverLostToken( address _token ) external returns ( bool ) {\\n require( _token != OHM );\\n require( _token != principle );\\n IERC20( _token ).safeTransfer( DAO, IERC20( _token ).balanceOf( address(this) ) );\\n return true;\\n }\\n}\",\"keccak256\":\"0xd453a8b71a50fff181f5b167a466d989e3a0eb825c7c86bb4be612c166815aeb\",\"license\":\"AGPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x6101006040523480156200001257600080fd5b50604051620040a8380380620040a8833981810160405260a08110156200003857600080fd5b810190808051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a3600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614156200016757600080fd5b8473ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b81525050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415620001d957600080fd5b8373ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b81525050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156200024b57600080fd5b8273ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff1660601b81525050600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415620002bd57600080fd5b8173ffffffffffffffffffffffffffffffffffffffff1660e08173ffffffffffffffffffffffffffffffffffffffff1660601b81525050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156200032f57600080fd5b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050505060805160601c60a05160601c60c05160601c60e05160601c613cb0620003f8600039806120cc52806121cb5250806117ca5280611bdf5280611dd25280611e3b5250806109555280611c1b5280611df4528061216f5250806120f0528061211652806122f05280612707528061290852806129ef5280612b8e5250613cb06000f3fe608060405234801561001057600080fd5b50600436106102065760003560e01c80637b2617271161011a578063cea55f57116100ad578063d7ccfb0b1161007c578063d7ccfb0b146108bd578063e0176de8146108db578063e392a262146108f9578063f5c2ab5b14610917578063fc7b9c181461093557610206565b8063cea55f57146107f7578063d24378eb14610815578063d4d863ce14610833578063d50256251461088357610206565b806398fabd3a116100e957806398fabd3a146106c8578063a6c41fec146106fc578063b4abccba14610730578063cd1234b31461078a57610206565b80637b261727146105c0578063844b5c7c146106205780638dbdbe6d1461063e578063904b3ece146106aa57610206565b8063451ee4a11161019d5780635a96ac0a1161016c5780635a96ac0a146104ee57806361d027b3146104f8578063759076e51461052c57806377b818951461054a5780637927ebf81461057e57610206565b8063451ee4a1146103e257806346f68ee91461041e5780634cf088d914610462578063507930ec1461049657610206565b80631a3d0068116101d95780631a3d0068146102d55780631e321a0f146103235780631feed31f1461035e5780632f3f470a146103c257610206565b8063016a42841461020b57806301b88ee81461023f5780630505c8c914610297578063089208d8146102cb575b600080fd5b610213610953565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102816004803603602081101561025557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610977565b6040518082815260200191505060405180910390f35b61029f610a0e565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102d3610a37565b005b610321600480360360808110156102eb57600080fd5b81019080803515159060200190929190803590602001909291908035906020019092919080359060200190929190505050610bb6565b005b61035c6004803603604081101561033957600080fd5b81019080803560ff16906020019092919080359060200190929190505050610d95565b005b6103ac6004803603604081101561037457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050610fb5565b6040518082815260200191505060405180910390f35b6103ca6112cd565b60405180821515815260200191505060405180910390f35b6103ea6112e0565b6040518086151581526020018581526020018481526020018381526020018281526020019550505050505060405180910390f35b6104606004803603602081101561043457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611311565b005b61046a611516565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6104d8600480360360208110156104ac57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061153c565b6040518082815260200191505060405180910390f35b6104f6611622565b005b6105006117c8565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6105346117ec565b6040518082815260200191505060405180910390f35b61055261180f565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6105aa6004803603602081101561059457600080fd5b8101908080359060200190929190505050611835565b6040518082815260200191505060405180910390f35b61061e600480360360c08110156105d657600080fd5b8101908080359060200190929190803590602001909291908035906020019092919080359060200190929190803590602001909291908035906020019092919050505061186f565b005b610628611a04565b6040518082815260200191505060405180910390f35b6106946004803603606081101561065457600080fd5b810190808035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611a41565b6040518082815260200191505060405180910390f35b6106b261208c565b6040518082815260200191505060405180910390f35b6106d06120ca565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6107046120ee565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6107726004803603602081101561074657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612112565b60405180821515815260200191505060405180910390f35b6107cc600480360360208110156107a057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506122bb565b6040518085815260200184815260200183815260200182815260200194505050505060405180910390f35b6107ff6122eb565b6040518082815260200191505060405180910390f35b61081d6123e0565b6040518082815260200191505060405180910390f35b6108816004803603604081101561084957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035151590602001909291905050506124bb565b005b61088b61267e565b604051808681526020018581526020018481526020018381526020018281526020019550505050505060405180910390f35b6108c56126a2565b6040518082815260200191505060405180910390f35b6108e36126f3565b6040518082815260200191505060405180910390f35b6109016127c7565b6040518082815260200191505060405180910390f35b61091f612823565b6040518082815260200191505060405180910390f35b61093d612829565b6040518082815260200191505060405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806109838361153c565b90506000600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154905061271082106109dd57809250610a07565b610a046127106109f6848461282f90919063ffffffff16565b6128b590919063ffffffff16565b92505b5050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610af8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610c77576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b610ca46103e8610c96601960056000015461282f90919063ffffffff16565b6128b590919063ffffffff16565b831115610d19576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f496e6372656d656e7420746f6f206c617267650000000000000000000000000081525060200191505060405180910390fd5b6040518060a00160405280851515815260200184815260200183815260200182815260200142815250600a60008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020155606082015181600301556080820151816004015590505050505050565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610e56576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60006002811115610e6357fe5b826002811115610e6f57fe5b1415610ee0576201fa40811015610ed1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180613c2d6024913960400191505060405180910390fd5b80600560010181905550610fb1565b60016002811115610eed57fe5b826002811115610ef957fe5b1415610f86576103e8811115610f77576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f5061796f75742063616e6e6f742062652061626f766520312070657263656e7481525060200191505060405180910390fd5b80600560030181905550610fb0565b600280811115610f9257fe5b826002811115610f9e57fe5b1415610faf57806005600401819055505b5b5b5050565b6000610fbf613b00565b600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060800160405290816000820154815260200160018201548152602001600282015481526020016003820154815250509050600061103e8561153c565b9050612710811061111e57600f60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008082016000905560018201600090556002820160009055600382016000905550508473ffffffffffffffffffffffffffffffffffffffff167f51c99f515c87b0d95ba97f616edd182e8f161c4932eac17c6fefe9dab58b77b183600001516000604051808381526020018281526020019250505060405180910390a2611115858584600001516128ff565b925050506112c7565b600061114b61271061113d84866000015161282f90919063ffffffff16565b6128b590919063ffffffff16565b9050604051806080016040528061116f838660000151612d5690919063ffffffff16565b81526020016111a161118e866040015142612d5690919063ffffffff16565b8660200151612d5690919063ffffffff16565b81526020014281526020018460600151815250600f60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082015181600001556020820151816001015560408201518160020155606082015181600301559050508573ffffffffffffffffffffffffffffffffffffffff167f51c99f515c87b0d95ba97f616edd182e8f161c4932eac17c6fefe9dab58b77b182600f60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154604051808381526020018281526020019250505060405180910390a26112c18686836128ff565b93505050505b92915050565b600460149054906101000a900460ff1681565b600a8060000160009054906101000a900460ff16908060010154908060020154908060030154908060040154905085565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146113d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611458576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180613b5a6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a380600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611546613b00565b600f60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020604051806080016040529081600082015481526020016001820154815260200160028201548152602001600382015481525050905060006115d3826040015142612d5690919063ffffffff16565b905060008260200151905060008111156116155761160e816116006127108561282f90919063ffffffff16565b6128b590919063ffffffff16565b935061161a565b600093505b505050919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146116c8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180613b806022913960400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167faa151555690c956fc3ea32f106bb9f119b5237a061eaa8557cff3e51e3792c8d60405160405180910390a3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b7f000000000000000000000000000000000000000000000000000000000000000081565b600061180a6117f96127c7565b601054612d5690919063ffffffff16565b905090565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611868655af3107a400061185a611855856118506126a2565b612da0565b613081565b6128b590919063ffffffff16565b9050919050565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611930576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600061193a6117ec565b14611990576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180613bc86021913960400191505060405180910390fd5b6040518060a0016040528087815260200186815260200185815260200184815260200183815250600560008201518160000155602082015181600101556040820151816002015560608201518160030155608082015181600401559050508060108190555042601181905550505050505050565b6000611a3c620f4240611a2e611a186123e0565b611a206126a2565b61282f90919063ffffffff16565b61282f90919063ffffffff16565b905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ae5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f496e76616c69642061646472657373000000000000000000000000000000000081525060200191505060405180910390fd5b611aed6130bd565b6005600401546010541115611b6a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4d6178206361706163697479207265616368656400000000000000000000000081525060200191505060405180910390fd5b6000611b74611a04565b90506000611b806130e8565b905080851015611bdb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180613c0a6023913960400191505060405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16631eec5a9a7f0000000000000000000000000000000000000000000000000000000000000000896040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060206040518083038186803b158015611c8c57600080fd5b505afa158015611ca0573d6000803e3d6000fd5b505050506040513d6020811015611cb657600080fd5b810190808051906020019092919050505090506000611cd482611835565b905062989680811015611d4f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f426f6e6420746f6f20736d616c6c00000000000000000000000000000000000081525060200191505060405180910390fd5b611d576126f3565b811115611dcc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f426f6e6420746f6f206c6172676500000000000000000000000000000000000081525060200191505060405180910390fd5b611e39337f00000000000000000000000000000000000000000000000000000000000000008a7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16613157909392919063ffffffff16565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636a20de9230836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b158015611eca57600080fd5b505af1158015611ede573d6000803e3d6000fd5b50505050611ef78260105461321890919063ffffffff16565b6010819055506040518060800160405280611f5d83600f60008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015461321890919063ffffffff16565b8152602001600560010154815260200142815260200185815250600f60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000820151816000015560208201518160010155604082015181600201556060820151816003015590505083611ffa6005600101544261321890919063ffffffff16565b827f1fec6dc81f140574bf43f6b1e420ae1dd47928b9d57db8cbd7b8611063b85ae58b6040518082815260200191505060405180910390a461203a6122eb565b6120426130e8565b61204a611a04565b7f375b221f40939bfd8f49723a17cf7bc6d576ebf72efe2cc3e991826f5b3f390a60405160405180910390a461207e6132a0565b809450505050509392505050565b60006120c56305f5e1006120b76120a16123e0565b6120a96122eb565b61282f90919063ffffffff16565b6128b590919063ffffffff16565b905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561216d57600080fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156121c657600080fd5b6122b27f00000000000000000000000000000000000000000000000000000000000000008373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561225157600080fd5b505afa158015612265573d6000803e3d6000fd5b505050506040513d602081101561227b57600080fd5b81019080805190602001909291905050508473ffffffffffffffffffffffffffffffffffffffff166134069092919063ffffffff16565b60019050919050565b600f6020528060005260406000206000915090508060000154908060010154908060020154908060030154905084565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561235457600080fd5b505afa158015612368573d6000803e3d6000fd5b505050506040513d602081101561237e57600080fd5b810190808051906020019092919050505090506123da670de0b6b3a76400006123cc6123c76123c1633b9aca006123b36117ec565b61282f90919063ffffffff16565b85612da0565b613081565b6128b590919063ffffffff16565b91505090565b600080600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b15801561244b57600080fd5b505afa15801561245f573d6000803e3d6000fd5b505050506040513d60a081101561247557600080fd5b8101908080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291905050505050509150508091505090565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461257c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156125b657600080fd5b801561261d576001600460146101000a81548160ff02191690831515021790555081600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061267a565b6000600460146101000a81548160ff02191690831515021790555081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5050565b60058060000154908060010154908060020154908060030154908060040154905085565b60006126d8620186a06126ca6126b66122eb565b60056000015461282f90919063ffffffff16565b6128b590919063ffffffff16565b90506005600201548110156126f05760056002015490505b90565b60006127c2620186a06127b46005600301547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561276b57600080fd5b505afa15801561277f573d6000803e3d6000fd5b505050506040513d602081101561279557600080fd5b810190808051906020019092919050505061282f90919063ffffffff16565b6128b590919063ffffffff16565b905090565b6000806127df60115442612d5690919063ffffffff16565b905061280d6005600101546127ff8360105461282f90919063ffffffff16565b6128b590919063ffffffff16565b915060105482111561281f5760105491505b5090565b60115481565b60105481565b60008083141561284257600090506128af565b600082840290508284828161285357fe5b04146128aa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180613be96021913960400191505060405180910390fd5b809150505b92915050565b60006128f783836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506134a8565b905092915050565b6000826129d8577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561299757600080fd5b505af11580156129ab573d6000803e3d6000fd5b505050506040513d60208110156129c157600080fd5b810190808051906020019092919050505050612d4c565b600460149054906101000a900460ff1615612b8c577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612aa057600080fd5b505af1158015612ab4573d6000803e3d6000fd5b505050506040513d6020811015612aca57600080fd5b810190808051906020019092919050505050600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637acb775783866040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b158015612b6f57600080fd5b505af1158015612b83573d6000803e3d6000fd5b50505050612d4b565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612c3f57600080fd5b505af1158015612c53573d6000803e3d6000fd5b505050506040513d6020811015612c6957600080fd5b810190808051906020019092919050505050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637acb775783866040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b158015612d0e57600080fd5b505af1158015612d22573d6000803e3d6000fd5b505050506040513d6020811015612d3857600080fd5b8101908080519060200190929190505050505b5b8190509392505050565b6000612d9883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061356e565b905092915050565b612da8613b28565b60008211612e01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180613ba26026913960400191505060405180910390fd5b6000831415612e3f57604051806020016040528060007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815250905061307b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff71ffffffffffffffffffffffffffffffffffff168311612f7857600082607060ff1685901b81612e8c57fe5b0490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16811115612f43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f77000081525060200191505060405180910390fd5b6040518060200160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525091505061307b565b6000612f94846e0100000000000000000000000000008561362e565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681111561304a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f77000081525060200191505060405180910390fd5b6040518060200160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509150505b92915050565b60006612725dd1d243ab82600001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16816130b557fe5b049050919050565b6130d96130c86127c7565b601054612d5690919063ffffffff16565b60108190555042601181905550565b600061311e620186a06131106130fc6122eb565b60056000015461282f90919063ffffffff16565b6128b590919063ffffffff16565b905060056002015481101561313a576005600201549050613154565b6000600560020154146131535760006005600201819055505b5b90565b613212846323b872dd60e01b858585604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506136f0565b50505050565b600080828401905083811015613296576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b60006132bf600a60030154600a6004015461321890919063ffffffff16565b90506000600a60010154141580156132d75750804210155b156134035760006005600001549050600a60000160009054906101000a900460ff16156133465761331b600a6001015460056000015461321890919063ffffffff16565b600560000181905550600a6002015460056000015410613341576000600a600101819055505b61338a565b613363600a60010154600560000154612d5690919063ffffffff16565b600560000181905550600a6002015460056000015411613389576000600a600101819055505b5b42600a600401819055507fb923e581a0f83128e9e1d8297aa52b18d6744310476e0b54509c054cd7a93b2a81600560000154600a60010154600a60000160009054906101000a900460ff1660405180858152602001848152602001838152602001821515815260200194505050505060405180910390a1505b50565b6134a38363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506136f0565b505050565b60008083118290613554576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156135195780820151818401526020810190506134fe565b50505050905090810190601f1680156135465780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161356057fe5b049050809150509392505050565b600083831115829061361b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156135e05780820151818401526020810190506135c5565b50505050905090810190601f16801561360d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b600080600061363d86866137df565b915091506000848061364b57fe5b86880990508281111561365f576001820391505b80830392508482106136d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f46756c6c4d6174683a3a6d756c4469763a206f766572666c6f7700000000000081525060200191505060405180910390fd5b6136e4838387613832565b93505050509392505050565b6060613752826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166138cf9092919063ffffffff16565b90506000815111156137da5780806020019051602081101561377357600080fd5b81019080805190602001909291905050506137d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180613c51602a913960400191505060405180910390fd5b5b505050565b60008060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8061380c57fe5b8486099050838502925082810391508281101561382a576001820391505b509250929050565b600080826000038316905080838161384657fe5b04925080858161385257fe5b049450600181826000038161386357fe5b04018402850194506000600190508084026002038102905080840260020381029050808402600203810290508084026002038102905080840260020381029050808402600203810290508084026002038102905080840260020381029050808602925050509392505050565b60606138de84846000856138e7565b90509392505050565b60606138f285613aed565b613964576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b602083106139b45780518252602082019150602081019050602083039250613991565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613a16576040519150601f19603f3d011682016040523d82523d6000602084013e613a1b565b606091505b50915091508115613a30578092505050613ae5565b600081511115613a435780518082602001fd5b836040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613aaa578082015181840152602081019050613a8f565b50505050905090810190601f168015613ad75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b949350505050565b600080823b905060008111915050919050565b6040518060800160405280600081526020016000815260200160008152602001600081525090565b604051806020016040528060007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a206d757374206265206e6577206f776e657220746f2070756c6c4669786564506f696e743a3a6672616374696f6e3a206469766973696f6e206279207a65726f44656274206d757374206265203020666f7220696e697469616c697a6174696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77536c697070616765206c696d69743a206d6f7265207468616e206d617820707269636556657374696e67206d757374206265206c6f6e676572207468616e20333620686f7572735361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220209db489c1b06d84f6d95cec036d144d41d0ccd9b278411b8f7ab0da078bbb8a64736f6c63430007050033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102065760003560e01c80637b2617271161011a578063cea55f57116100ad578063d7ccfb0b1161007c578063d7ccfb0b146108bd578063e0176de8146108db578063e392a262146108f9578063f5c2ab5b14610917578063fc7b9c181461093557610206565b8063cea55f57146107f7578063d24378eb14610815578063d4d863ce14610833578063d50256251461088357610206565b806398fabd3a116100e957806398fabd3a146106c8578063a6c41fec146106fc578063b4abccba14610730578063cd1234b31461078a57610206565b80637b261727146105c0578063844b5c7c146106205780638dbdbe6d1461063e578063904b3ece146106aa57610206565b8063451ee4a11161019d5780635a96ac0a1161016c5780635a96ac0a146104ee57806361d027b3146104f8578063759076e51461052c57806377b818951461054a5780637927ebf81461057e57610206565b8063451ee4a1146103e257806346f68ee91461041e5780634cf088d914610462578063507930ec1461049657610206565b80631a3d0068116101d95780631a3d0068146102d55780631e321a0f146103235780631feed31f1461035e5780632f3f470a146103c257610206565b8063016a42841461020b57806301b88ee81461023f5780630505c8c914610297578063089208d8146102cb575b600080fd5b610213610953565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102816004803603602081101561025557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610977565b6040518082815260200191505060405180910390f35b61029f610a0e565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102d3610a37565b005b610321600480360360808110156102eb57600080fd5b81019080803515159060200190929190803590602001909291908035906020019092919080359060200190929190505050610bb6565b005b61035c6004803603604081101561033957600080fd5b81019080803560ff16906020019092919080359060200190929190505050610d95565b005b6103ac6004803603604081101561037457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050610fb5565b6040518082815260200191505060405180910390f35b6103ca6112cd565b60405180821515815260200191505060405180910390f35b6103ea6112e0565b6040518086151581526020018581526020018481526020018381526020018281526020019550505050505060405180910390f35b6104606004803603602081101561043457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611311565b005b61046a611516565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6104d8600480360360208110156104ac57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061153c565b6040518082815260200191505060405180910390f35b6104f6611622565b005b6105006117c8565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6105346117ec565b6040518082815260200191505060405180910390f35b61055261180f565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6105aa6004803603602081101561059457600080fd5b8101908080359060200190929190505050611835565b6040518082815260200191505060405180910390f35b61061e600480360360c08110156105d657600080fd5b8101908080359060200190929190803590602001909291908035906020019092919080359060200190929190803590602001909291908035906020019092919050505061186f565b005b610628611a04565b6040518082815260200191505060405180910390f35b6106946004803603606081101561065457600080fd5b810190808035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611a41565b6040518082815260200191505060405180910390f35b6106b261208c565b6040518082815260200191505060405180910390f35b6106d06120ca565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6107046120ee565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6107726004803603602081101561074657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612112565b60405180821515815260200191505060405180910390f35b6107cc600480360360208110156107a057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506122bb565b6040518085815260200184815260200183815260200182815260200194505050505060405180910390f35b6107ff6122eb565b6040518082815260200191505060405180910390f35b61081d6123e0565b6040518082815260200191505060405180910390f35b6108816004803603604081101561084957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035151590602001909291905050506124bb565b005b61088b61267e565b604051808681526020018581526020018481526020018381526020018281526020019550505050505060405180910390f35b6108c56126a2565b6040518082815260200191505060405180910390f35b6108e36126f3565b6040518082815260200191505060405180910390f35b6109016127c7565b6040518082815260200191505060405180910390f35b61091f612823565b6040518082815260200191505060405180910390f35b61093d612829565b6040518082815260200191505060405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806109838361153c565b90506000600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154905061271082106109dd57809250610a07565b610a046127106109f6848461282f90919063ffffffff16565b6128b590919063ffffffff16565b92505b5050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610af8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610c77576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b610ca46103e8610c96601960056000015461282f90919063ffffffff16565b6128b590919063ffffffff16565b831115610d19576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f496e6372656d656e7420746f6f206c617267650000000000000000000000000081525060200191505060405180910390fd5b6040518060a00160405280851515815260200184815260200183815260200182815260200142815250600a60008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020155606082015181600301556080820151816004015590505050505050565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610e56576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60006002811115610e6357fe5b826002811115610e6f57fe5b1415610ee0576201fa40811015610ed1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180613c2d6024913960400191505060405180910390fd5b80600560010181905550610fb1565b60016002811115610eed57fe5b826002811115610ef957fe5b1415610f86576103e8811115610f77576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f5061796f75742063616e6e6f742062652061626f766520312070657263656e7481525060200191505060405180910390fd5b80600560030181905550610fb0565b600280811115610f9257fe5b826002811115610f9e57fe5b1415610faf57806005600401819055505b5b5b5050565b6000610fbf613b00565b600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060800160405290816000820154815260200160018201548152602001600282015481526020016003820154815250509050600061103e8561153c565b9050612710811061111e57600f60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008082016000905560018201600090556002820160009055600382016000905550508473ffffffffffffffffffffffffffffffffffffffff167f51c99f515c87b0d95ba97f616edd182e8f161c4932eac17c6fefe9dab58b77b183600001516000604051808381526020018281526020019250505060405180910390a2611115858584600001516128ff565b925050506112c7565b600061114b61271061113d84866000015161282f90919063ffffffff16565b6128b590919063ffffffff16565b9050604051806080016040528061116f838660000151612d5690919063ffffffff16565b81526020016111a161118e866040015142612d5690919063ffffffff16565b8660200151612d5690919063ffffffff16565b81526020014281526020018460600151815250600f60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082015181600001556020820151816001015560408201518160020155606082015181600301559050508573ffffffffffffffffffffffffffffffffffffffff167f51c99f515c87b0d95ba97f616edd182e8f161c4932eac17c6fefe9dab58b77b182600f60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154604051808381526020018281526020019250505060405180910390a26112c18686836128ff565b93505050505b92915050565b600460149054906101000a900460ff1681565b600a8060000160009054906101000a900460ff16908060010154908060020154908060030154908060040154905085565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146113d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611458576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180613b5a6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a380600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611546613b00565b600f60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020604051806080016040529081600082015481526020016001820154815260200160028201548152602001600382015481525050905060006115d3826040015142612d5690919063ffffffff16565b905060008260200151905060008111156116155761160e816116006127108561282f90919063ffffffff16565b6128b590919063ffffffff16565b935061161a565b600093505b505050919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146116c8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180613b806022913960400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167faa151555690c956fc3ea32f106bb9f119b5237a061eaa8557cff3e51e3792c8d60405160405180910390a3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b7f000000000000000000000000000000000000000000000000000000000000000081565b600061180a6117f96127c7565b601054612d5690919063ffffffff16565b905090565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611868655af3107a400061185a611855856118506126a2565b612da0565b613081565b6128b590919063ffffffff16565b9050919050565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611930576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600061193a6117ec565b14611990576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180613bc86021913960400191505060405180910390fd5b6040518060a0016040528087815260200186815260200185815260200184815260200183815250600560008201518160000155602082015181600101556040820151816002015560608201518160030155608082015181600401559050508060108190555042601181905550505050505050565b6000611a3c620f4240611a2e611a186123e0565b611a206126a2565b61282f90919063ffffffff16565b61282f90919063ffffffff16565b905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ae5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f496e76616c69642061646472657373000000000000000000000000000000000081525060200191505060405180910390fd5b611aed6130bd565b6005600401546010541115611b6a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4d6178206361706163697479207265616368656400000000000000000000000081525060200191505060405180910390fd5b6000611b74611a04565b90506000611b806130e8565b905080851015611bdb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180613c0a6023913960400191505060405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16631eec5a9a7f0000000000000000000000000000000000000000000000000000000000000000896040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060206040518083038186803b158015611c8c57600080fd5b505afa158015611ca0573d6000803e3d6000fd5b505050506040513d6020811015611cb657600080fd5b810190808051906020019092919050505090506000611cd482611835565b905062989680811015611d4f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f426f6e6420746f6f20736d616c6c00000000000000000000000000000000000081525060200191505060405180910390fd5b611d576126f3565b811115611dcc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f426f6e6420746f6f206c6172676500000000000000000000000000000000000081525060200191505060405180910390fd5b611e39337f00000000000000000000000000000000000000000000000000000000000000008a7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16613157909392919063ffffffff16565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636a20de9230836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b158015611eca57600080fd5b505af1158015611ede573d6000803e3d6000fd5b50505050611ef78260105461321890919063ffffffff16565b6010819055506040518060800160405280611f5d83600f60008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015461321890919063ffffffff16565b8152602001600560010154815260200142815260200185815250600f60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000820151816000015560208201518160010155604082015181600201556060820151816003015590505083611ffa6005600101544261321890919063ffffffff16565b827f1fec6dc81f140574bf43f6b1e420ae1dd47928b9d57db8cbd7b8611063b85ae58b6040518082815260200191505060405180910390a461203a6122eb565b6120426130e8565b61204a611a04565b7f375b221f40939bfd8f49723a17cf7bc6d576ebf72efe2cc3e991826f5b3f390a60405160405180910390a461207e6132a0565b809450505050509392505050565b60006120c56305f5e1006120b76120a16123e0565b6120a96122eb565b61282f90919063ffffffff16565b6128b590919063ffffffff16565b905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561216d57600080fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156121c657600080fd5b6122b27f00000000000000000000000000000000000000000000000000000000000000008373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561225157600080fd5b505afa158015612265573d6000803e3d6000fd5b505050506040513d602081101561227b57600080fd5b81019080805190602001909291905050508473ffffffffffffffffffffffffffffffffffffffff166134069092919063ffffffff16565b60019050919050565b600f6020528060005260406000206000915090508060000154908060010154908060020154908060030154905084565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561235457600080fd5b505afa158015612368573d6000803e3d6000fd5b505050506040513d602081101561237e57600080fd5b810190808051906020019092919050505090506123da670de0b6b3a76400006123cc6123c76123c1633b9aca006123b36117ec565b61282f90919063ffffffff16565b85612da0565b613081565b6128b590919063ffffffff16565b91505090565b600080600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b15801561244b57600080fd5b505afa15801561245f573d6000803e3d6000fd5b505050506040513d60a081101561247557600080fd5b8101908080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291905050505050509150508091505090565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461257c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156125b657600080fd5b801561261d576001600460146101000a81548160ff02191690831515021790555081600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061267a565b6000600460146101000a81548160ff02191690831515021790555081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5050565b60058060000154908060010154908060020154908060030154908060040154905085565b60006126d8620186a06126ca6126b66122eb565b60056000015461282f90919063ffffffff16565b6128b590919063ffffffff16565b90506005600201548110156126f05760056002015490505b90565b60006127c2620186a06127b46005600301547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561276b57600080fd5b505afa15801561277f573d6000803e3d6000fd5b505050506040513d602081101561279557600080fd5b810190808051906020019092919050505061282f90919063ffffffff16565b6128b590919063ffffffff16565b905090565b6000806127df60115442612d5690919063ffffffff16565b905061280d6005600101546127ff8360105461282f90919063ffffffff16565b6128b590919063ffffffff16565b915060105482111561281f5760105491505b5090565b60115481565b60105481565b60008083141561284257600090506128af565b600082840290508284828161285357fe5b04146128aa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180613be96021913960400191505060405180910390fd5b809150505b92915050565b60006128f783836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506134a8565b905092915050565b6000826129d8577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561299757600080fd5b505af11580156129ab573d6000803e3d6000fd5b505050506040513d60208110156129c157600080fd5b810190808051906020019092919050505050612d4c565b600460149054906101000a900460ff1615612b8c577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612aa057600080fd5b505af1158015612ab4573d6000803e3d6000fd5b505050506040513d6020811015612aca57600080fd5b810190808051906020019092919050505050600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637acb775783866040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b158015612b6f57600080fd5b505af1158015612b83573d6000803e3d6000fd5b50505050612d4b565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612c3f57600080fd5b505af1158015612c53573d6000803e3d6000fd5b505050506040513d6020811015612c6957600080fd5b810190808051906020019092919050505050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637acb775783866040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b158015612d0e57600080fd5b505af1158015612d22573d6000803e3d6000fd5b505050506040513d6020811015612d3857600080fd5b8101908080519060200190929190505050505b5b8190509392505050565b6000612d9883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061356e565b905092915050565b612da8613b28565b60008211612e01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180613ba26026913960400191505060405180910390fd5b6000831415612e3f57604051806020016040528060007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815250905061307b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff71ffffffffffffffffffffffffffffffffffff168311612f7857600082607060ff1685901b81612e8c57fe5b0490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16811115612f43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f77000081525060200191505060405180910390fd5b6040518060200160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525091505061307b565b6000612f94846e0100000000000000000000000000008561362e565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681111561304a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f77000081525060200191505060405180910390fd5b6040518060200160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509150505b92915050565b60006612725dd1d243ab82600001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16816130b557fe5b049050919050565b6130d96130c86127c7565b601054612d5690919063ffffffff16565b60108190555042601181905550565b600061311e620186a06131106130fc6122eb565b60056000015461282f90919063ffffffff16565b6128b590919063ffffffff16565b905060056002015481101561313a576005600201549050613154565b6000600560020154146131535760006005600201819055505b5b90565b613212846323b872dd60e01b858585604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506136f0565b50505050565b600080828401905083811015613296576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b60006132bf600a60030154600a6004015461321890919063ffffffff16565b90506000600a60010154141580156132d75750804210155b156134035760006005600001549050600a60000160009054906101000a900460ff16156133465761331b600a6001015460056000015461321890919063ffffffff16565b600560000181905550600a6002015460056000015410613341576000600a600101819055505b61338a565b613363600a60010154600560000154612d5690919063ffffffff16565b600560000181905550600a6002015460056000015411613389576000600a600101819055505b5b42600a600401819055507fb923e581a0f83128e9e1d8297aa52b18d6744310476e0b54509c054cd7a93b2a81600560000154600a60010154600a60000160009054906101000a900460ff1660405180858152602001848152602001838152602001821515815260200194505050505060405180910390a1505b50565b6134a38363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506136f0565b505050565b60008083118290613554576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156135195780820151818401526020810190506134fe565b50505050905090810190601f1680156135465780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161356057fe5b049050809150509392505050565b600083831115829061361b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156135e05780820151818401526020810190506135c5565b50505050905090810190601f16801561360d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b600080600061363d86866137df565b915091506000848061364b57fe5b86880990508281111561365f576001820391505b80830392508482106136d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f46756c6c4d6174683a3a6d756c4469763a206f766572666c6f7700000000000081525060200191505060405180910390fd5b6136e4838387613832565b93505050509392505050565b6060613752826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166138cf9092919063ffffffff16565b90506000815111156137da5780806020019051602081101561377357600080fd5b81019080805190602001909291905050506137d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180613c51602a913960400191505060405180910390fd5b5b505050565b60008060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8061380c57fe5b8486099050838502925082810391508281101561382a576001820391505b509250929050565b600080826000038316905080838161384657fe5b04925080858161385257fe5b049450600181826000038161386357fe5b04018402850194506000600190508084026002038102905080840260020381029050808402600203810290508084026002038102905080840260020381029050808402600203810290508084026002038102905080840260020381029050808602925050509392505050565b60606138de84846000856138e7565b90509392505050565b60606138f285613aed565b613964576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b602083106139b45780518252602082019150602081019050602083039250613991565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613a16576040519150601f19603f3d011682016040523d82523d6000602084013e613a1b565b606091505b50915091508115613a30578092505050613ae5565b600081511115613a435780518082602001fd5b836040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613aaa578082015181840152602081019050613a8f565b50505050905090810190601f168015613ad75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b949350505050565b600080823b905060008111915050919050565b6040518060800160405280600081526020016000815260200160008152602001600081525090565b604051806020016040528060007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a206d757374206265206e6577206f776e657220746f2070756c6c4669786564506f696e743a3a6672616374696f6e3a206469766973696f6e206279207a65726f44656274206d757374206265203020666f7220696e697469616c697a6174696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77536c697070616765206c696d69743a206d6f7265207468616e206d617820707269636556657374696e67206d757374206265206c6f6e676572207468616e20333620686f7572735361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220209db489c1b06d84f6d95cec036d144d41d0ccd9b278411b8f7ab0da078bbb8a64736f6c63430007050033", + "devdoc": { + "kind": "dev", + "methods": { + "bondPrice()": { + "returns": { + "price_": "uint" + } + }, + "bondPriceInUSD()": { + "returns": { + "price_": "uint" + } + }, + "currentDebt()": { + "returns": { + "_0": "uint" + } + }, + "debtDecay()": { + "returns": { + "decay_": "uint" + } + }, + "debtRatio()": { + "returns": { + "debtRatio_": "uint" + } + }, + "deposit(uint256,uint256,address)": { + "params": { + "_amount": "uint", + "_depositor": "address", + "_maxPrice": "uint" + }, + "returns": { + "_0": "uint" + } + }, + "initializeBondTerms(uint256,uint256,uint256,uint256,uint256,uint256)": { + "params": { + "_controlVariable": "uint", + "_initialDebt": "uint", + "_maxDebt": "uint", + "_maxPayout": "uint", + "_minimumPrice": "uint", + "_vestingTerm": "uint" + } + }, + "maxPayout()": { + "returns": { + "_0": "uint" + } + }, + "payoutFor(uint256)": { + "params": { + "_value": "uint" + }, + "returns": { + "_0": "uint" + } + }, + "pendingPayoutFor(address)": { + "params": { + "_depositor": "address" + }, + "returns": { + "pendingPayout_": "uint" + } + }, + "percentVestedFor(address)": { + "params": { + "_depositor": "address" + }, + "returns": { + "percentVested_": "uint" + } + }, + "recoverLostToken(address)": { + "returns": { + "_0": "bool" + } + }, + "redeem(address,bool)": { + "params": { + "_recipient": "address", + "_stake": "bool" + }, + "returns": { + "_0": "uint" + } + }, + "setAdjustment(bool,uint256,uint256,uint256)": { + "params": { + "_addition": "bool", + "_buffer": "uint", + "_increment": "uint", + "_target": "uint" + } + }, + "setBondTerms(uint8,uint256)": { + "params": { + "_input": "uint", + "_parameter": "PARAMETER" + } + }, + "setStaking(address,bool)": { + "params": { + "_helper": "bool", + "_staking": "address" + } + }, + "standardizedDebtRatio()": { + "returns": { + "_0": "uint" + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "assetPrice()": { + "notice": "get asset price from chainlink" + }, + "bondPrice()": { + "notice": "calculate current bond premium" + }, + "bondPriceInUSD()": { + "notice": "converts bond price to DAI value" + }, + "currentDebt()": { + "notice": "calculate debt factoring in decay" + }, + "debtDecay()": { + "notice": "amount to decay total debt by" + }, + "debtRatio()": { + "notice": "calculate current ratio of debt to OHM supply" + }, + "deposit(uint256,uint256,address)": { + "notice": "deposit bond" + }, + "initializeBondTerms(uint256,uint256,uint256,uint256,uint256,uint256)": { + "notice": "initializes bond parameters" + }, + "maxPayout()": { + "notice": "determine maximum bond size" + }, + "payoutFor(uint256)": { + "notice": "calculate interest due for new bond" + }, + "pendingPayoutFor(address)": { + "notice": "calculate amount of OHM available for claim by depositor" + }, + "percentVestedFor(address)": { + "notice": "calculate how far into vesting a depositor is" + }, + "recoverLostToken(address)": { + "notice": "allow anyone to send lost tokens (excluding principle or OHM) to the DAO" + }, + "redeem(address,bool)": { + "notice": "redeem bond for user" + }, + "setAdjustment(bool,uint256,uint256,uint256)": { + "notice": "set control variable adjustment" + }, + "setBondTerms(uint8,uint256)": { + "notice": "set parameters for new bonds" + }, + "setStaking(address,bool)": { + "notice": "set contract for auto stake" + }, + "standardizedDebtRatio()": { + "notice": "debt ratio in same terms as reserve bonds" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 4748, + "contract": "contracts/wETHBondDepository.sol:OlympusBondDepository", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 4750, + "contract": "contracts/wETHBondDepository.sol:OlympusBondDepository", + "label": "_newOwner", + "offset": 0, + "slot": "1", + "type": "t_address" + }, + { + "astId": 7033, + "contract": "contracts/wETHBondDepository.sol:OlympusBondDepository", + "label": "priceFeed", + "offset": 0, + "slot": "2", + "type": "t_contract(AggregatorV3Interface)6931" + }, + { + "astId": 7035, + "contract": "contracts/wETHBondDepository.sol:OlympusBondDepository", + "label": "staking", + "offset": 0, + "slot": "3", + "type": "t_address" + }, + { + "astId": 7037, + "contract": "contracts/wETHBondDepository.sol:OlympusBondDepository", + "label": "stakingHelper", + "offset": 0, + "slot": "4", + "type": "t_address" + }, + { + "astId": 7039, + "contract": "contracts/wETHBondDepository.sol:OlympusBondDepository", + "label": "useHelper", + "offset": 20, + "slot": "4", + "type": "t_bool" + }, + { + "astId": 7041, + "contract": "contracts/wETHBondDepository.sol:OlympusBondDepository", + "label": "terms", + "offset": 0, + "slot": "5", + "type": "t_struct(Terms)7062_storage" + }, + { + "astId": 7043, + "contract": "contracts/wETHBondDepository.sol:OlympusBondDepository", + "label": "adjustment", + "offset": 0, + "slot": "10", + "type": "t_struct(Adjust)7082_storage" + }, + { + "astId": 7047, + "contract": "contracts/wETHBondDepository.sol:OlympusBondDepository", + "label": "bondInfo", + "offset": 0, + "slot": "15", + "type": "t_mapping(t_address,t_struct(Bond)7071_storage)" + }, + { + "astId": 7049, + "contract": "contracts/wETHBondDepository.sol:OlympusBondDepository", + "label": "totalDebt", + "offset": 0, + "slot": "16", + "type": "t_uint256" + }, + { + "astId": 7051, + "contract": "contracts/wETHBondDepository.sol:OlympusBondDepository", + "label": "lastDecay", + "offset": 0, + "slot": "17", + "type": "t_uint256" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_contract(AggregatorV3Interface)6931": { + "encoding": "inplace", + "label": "contract AggregatorV3Interface", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_struct(Bond)7071_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct OlympusBondDepository.Bond)", + "numberOfBytes": "32", + "value": "t_struct(Bond)7071_storage" + }, + "t_struct(Adjust)7082_storage": { + "encoding": "inplace", + "label": "struct OlympusBondDepository.Adjust", + "members": [ + { + "astId": 7073, + "contract": "contracts/wETHBondDepository.sol:OlympusBondDepository", + "label": "add", + "offset": 0, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 7075, + "contract": "contracts/wETHBondDepository.sol:OlympusBondDepository", + "label": "rate", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 7077, + "contract": "contracts/wETHBondDepository.sol:OlympusBondDepository", + "label": "target", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 7079, + "contract": "contracts/wETHBondDepository.sol:OlympusBondDepository", + "label": "buffer", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 7081, + "contract": "contracts/wETHBondDepository.sol:OlympusBondDepository", + "label": "lastTime", + "offset": 0, + "slot": "4", + "type": "t_uint256" + } + ], + "numberOfBytes": "160" + }, + "t_struct(Bond)7071_storage": { + "encoding": "inplace", + "label": "struct OlympusBondDepository.Bond", + "members": [ + { + "astId": 7064, + "contract": "contracts/wETHBondDepository.sol:OlympusBondDepository", + "label": "payout", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 7066, + "contract": "contracts/wETHBondDepository.sol:OlympusBondDepository", + "label": "vesting", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 7068, + "contract": "contracts/wETHBondDepository.sol:OlympusBondDepository", + "label": "lastTime", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 7070, + "contract": "contracts/wETHBondDepository.sol:OlympusBondDepository", + "label": "pricePaid", + "offset": 0, + "slot": "3", + "type": "t_uint256" + } + ], + "numberOfBytes": "128" + }, + "t_struct(Terms)7062_storage": { + "encoding": "inplace", + "label": "struct OlympusBondDepository.Terms", + "members": [ + { + "astId": 7053, + "contract": "contracts/wETHBondDepository.sol:OlympusBondDepository", + "label": "controlVariable", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 7055, + "contract": "contracts/wETHBondDepository.sol:OlympusBondDepository", + "label": "vestingTerm", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 7057, + "contract": "contracts/wETHBondDepository.sol:OlympusBondDepository", + "label": "minimumPrice", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 7059, + "contract": "contracts/wETHBondDepository.sol:OlympusBondDepository", + "label": "maxPayout", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 7061, + "contract": "contracts/wETHBondDepository.sol:OlympusBondDepository", + "label": "maxDebt", + "offset": 0, + "slot": "4", + "type": "t_uint256" + } + ], + "numberOfBytes": "160" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/src/abi/rinkeby/sOlympus.json b/src/abi/rinkeby/sOlympus.json new file mode 100644 index 0000000000..33851d7e84 --- /dev/null +++ b/src/abi/rinkeby/sOlympus.json @@ -0,0 +1,1092 @@ +{ + "address": "0x230a8dC3c34336372b75549915DeBAEAACCF129D", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "epoch", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rebase", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "LogRebase", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "stakingContract", + "type": "address" + } + ], + "name": "LogStakingContractUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "epoch", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + } + ], + "name": "LogSupply", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipPulled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipPushed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INDEX", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner_", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "gons", + "type": "uint256" + } + ], + "name": "balanceForGons", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "who", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "circulatingSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "gonsForBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "index", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "stakingContract_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "initializer", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "manager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pullManagement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner_", + "type": "address" + } + ], + "name": "pushManagement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "profit_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "epoch_", + "type": "uint256" + } + ], + "name": "rebase", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "rebases", + "outputs": [ + { + "internalType": "uint256", + "name": "epoch", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rebase", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalStakedBefore", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalStakedAfter", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountRebased", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "blockNumberOccured", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceManagement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_INDEX", + "type": "uint256" + } + ], + "name": "setIndex", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stakingContract", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xaf543a6f5d4288356b0d598eea62c3fb82ae786fb231bf6d05373133c11c8027", + "receipt": { + "to": null, + "from": "0xA38F4E6718EdCF023a1d032a2193848CB932c8e3", + "contractAddress": "0x230a8dC3c34336372b75549915DeBAEAACCF129D", + "transactionIndex": 12, + "gasUsed": "2766768", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000020000000400000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000020000000000020002000000000000000000000000000000000000000000000000000000000000002", + "blockHash": "0x67f078a9389be98fcdc8e9c9096c38c790365cd9aa9dad77f6735e7535c990a3", + "transactionHash": "0xaf543a6f5d4288356b0d598eea62c3fb82ae786fb231bf6d05373133c11c8027", + "logs": [ + { + "transactionIndex": 12, + "blockNumber": 9907137, + "transactionHash": "0xaf543a6f5d4288356b0d598eea62c3fb82ae786fb231bf6d05373133c11c8027", + "address": "0x230a8dC3c34336372b75549915DeBAEAACCF129D", + "topics": [ + "0xea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000a38f4e6718edcf023a1d032a2193848cb932c8e3" + ], + "data": "0x", + "logIndex": 39, + "blockHash": "0x67f078a9389be98fcdc8e9c9096c38c790365cd9aa9dad77f6735e7535c990a3" + } + ], + "blockNumber": 9907137, + "cumulativeGasUsed": "10110916", + "status": 1, + "byzantium": true + }, + "args": [ + "Staked Brick", + "sBRICK" + ], + "solcInputHash": "fb3b81c61761bcfb33ca99488ac60a1b", + "metadata": "{\"compiler\":{\"version\":\"0.7.5+commit.eb77ed08\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"epoch\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"rebase\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"LogRebase\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"stakingContract\",\"type\":\"address\"}],\"name\":\"LogStakingContractUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"epoch\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalSupply\",\"type\":\"uint256\"}],\"name\":\"LogSupply\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipPulled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipPushed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INDEX\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PERMIT_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"gons\",\"type\":\"uint256\"}],\"name\":\"balanceForGons\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"who\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"circulatingSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"gonsForBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"index\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"stakingContract_\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initializer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"manager\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pullManagement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner_\",\"type\":\"address\"}],\"name\":\"pushManagement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"profit_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"epoch_\",\"type\":\"uint256\"}],\"name\":\"rebase\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"rebases\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"epoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rebase\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalStakedBefore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalStakedAfter\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountRebased\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockNumberOccured\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceManagement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_INDEX\",\"type\":\"uint256\"}],\"name\":\"setIndex\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stakingContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5,05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is called. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"name()\":{\"details\":\"Returns the name of the token.\"},\"nonces(address)\":{\"details\":\"See {IERC2612Permit-nonces}.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"See {IERC2612Permit-permit}.\"},\"rebase(uint256,uint256)\":{\"params\":{\"profit_\":\"uint256\"},\"returns\":{\"_0\":\"uint256\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"rebase(uint256,uint256)\":{\"notice\":\"increases sOHM supply to increase staking balances relative to profit_\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/sOlympusERC20.sol\":\"sOlympus\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/sOlympusERC20.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-or-later\\npragma solidity 0.7.5;\\n\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n\\n // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)\\n function sqrrt(uint256 a) internal pure returns (uint c) {\\n if (a > 3) {\\n c = a;\\n uint b = add( div( a, 2), 1 );\\n while (b < c) {\\n c = b;\\n b = div( add( div( a, b ), b), 2 );\\n }\\n } else if (a != 0) {\\n c = 1;\\n }\\n }\\n\\n /*\\n * Expects percentage to be trailed by 00,\\n */\\n function percentageAmount( uint256 total_, uint8 percentage_ ) internal pure returns ( uint256 percentAmount_ ) {\\n return div( mul( total_, percentage_ ), 1000 );\\n }\\n\\n /*\\n * Expects percentage to be trailed by 00,\\n */\\n function substractPercentage( uint256 total_, uint8 percentageToSub_ ) internal pure returns ( uint256 result_ ) {\\n return sub( total_, div( mul( total_, percentageToSub_ ), 1000 ) );\\n }\\n\\n function percentageOfTotal( uint256 part_, uint256 total_ ) internal pure returns ( uint256 percent_ ) {\\n return div( mul(part_, 100) , total_ );\\n }\\n\\n /**\\n * Taken from Hypersonic https://github.com/M2629/HyperSonic/blob/main/Math.sol\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow, so we distribute\\n return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);\\n }\\n\\n function quadraticPricing( uint256 payment_, uint256 multiplier_ ) internal pure returns (uint256) {\\n return sqrrt( mul( multiplier_, payment_ ) );\\n }\\n\\n function bondingCurve( uint256 supply_, uint256 multiplier_ ) internal pure returns (uint256) {\\n return mul( multiplier_, supply_ );\\n }\\n}\\n\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies in extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return _functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n // function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n // require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n // return _functionCallWithValue(target, data, value, errorMessage);\\n // }\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.3._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.3._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n\\n function addressToString(address _address) internal pure returns(string memory) {\\n bytes32 _bytes = bytes32(uint256(_address));\\n bytes memory HEX = \\\"0123456789abcdef\\\";\\n bytes memory _addr = new bytes(42);\\n\\n _addr[0] = '0';\\n _addr[1] = 'x';\\n\\n for(uint256 i = 0; i < 20; i++) {\\n _addr[2+i*2] = HEX[uint8(_bytes[i + 12] >> 4)];\\n _addr[3+i*2] = HEX[uint8(_bytes[i + 12] & 0x0f)];\\n }\\n\\n return string(_addr);\\n\\n }\\n}\\n\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\\nabstract contract ERC20\\n is\\n IERC20\\n {\\n\\n using SafeMath for uint256;\\n\\n // TODO comment actual hash value.\\n bytes32 constant private ERC20TOKEN_ERC1820_INTERFACE_ID = keccak256( \\\"ERC20Token\\\" );\\n\\n // Present in ERC777\\n mapping (address => uint256) internal _balances;\\n\\n // Present in ERC777\\n mapping (address => mapping (address => uint256)) internal _allowances;\\n\\n // Present in ERC777\\n uint256 internal _totalSupply;\\n\\n // Present in ERC777\\n string internal _name;\\n\\n // Present in ERC777\\n string internal _symbol;\\n\\n // Present in ERC777\\n uint8 internal _decimals;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\\n * a default value of 18.\\n *\\n * To select a different value for {decimals}, use {_setupDecimals}.\\n *\\n * All three of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor (string memory name_, string memory symbol_, uint8 decimals_) {\\n _name = name_;\\n _symbol = symbol_;\\n _decimals = decimals_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n // Present in ERC777\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n // Present in ERC777\\n function symbol() public view returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\\n * called.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n // Present in ERC777\\n function decimals() public view returns (uint8) {\\n return _decimals;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n // Present in ERC777\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n // Present in ERC777\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n // Overrideen in ERC777\\n // Confirm that this behavior changes\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(msg.sender, recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n // Present in ERC777\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n // Present in ERC777\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(msg.sender, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n // Present in ERC777\\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Moves tokens `amount` from `sender` to `recipient`.\\n *\\n * This is internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n */\\n // Present in ERC777\\n function _mint(address account_, uint256 ammount_) internal virtual {\\n require(account_ != address(0), \\\"ERC20: mint to the zero address\\\");\\n _beforeTokenTransfer(address( this ), account_, ammount_);\\n _totalSupply = _totalSupply.add(ammount_);\\n _balances[account_] = _balances[account_].add(ammount_);\\n emit Transfer(address( this ), account_, ammount_);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n // Present in ERC777\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n // Present in ERC777\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Sets {decimals} to a value other than the default one of 18.\\n *\\n * WARNING: This function should only be called from the constructor. Most\\n * applications that interact with token contracts will not expect\\n * {decimals} to ever change, and may work incorrectly if it does.\\n */\\n // Considering deprication to reduce size of bytecode as changing _decimals to internal acheived the same functionality.\\n // function _setupDecimals(uint8 decimals_) internal {\\n // _decimals = decimals_;\\n // }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be to transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n // Present in ERC777\\n function _beforeTokenTransfer( address from_, address to_, uint256 amount_ ) internal virtual { }\\n}\\n\\nlibrary Counters {\\n using SafeMath for uint256;\\n\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n // The {SafeMath} overflow check can be skipped here, see the comment at the top\\n counter._value += 1;\\n }\\n\\n function decrement(Counter storage counter) internal {\\n counter._value = counter._value.sub(1);\\n }\\n}\\n\\ninterface IERC2612Permit {\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over `owner`'s tokens,\\n * given `owner`'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 amount,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current ERC2612 nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n}\\n\\nabstract contract ERC20Permit is ERC20, IERC2612Permit {\\n using Counters for Counters.Counter;\\n\\n mapping(address => Counters.Counter) private _nonces;\\n\\n // keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\\n\\n bytes32 public DOMAIN_SEPARATOR;\\n\\n constructor() {\\n\\n uint256 chainID;\\n assembly {\\n chainID := chainid()\\n }\\n\\n DOMAIN_SEPARATOR = keccak256(abi.encode(\\n keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"),\\n keccak256(bytes(name())),\\n keccak256(bytes(\\\"1\\\")), // Version\\n chainID,\\n address(this)\\n ));\\n }\\n\\n /**\\n * @dev See {IERC2612Permit-permit}.\\n *\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 amount,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"Permit: expired deadline\\\");\\n\\n bytes32 hashStruct =\\n keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, amount, _nonces[owner].current(), deadline));\\n\\n bytes32 _hash = keccak256(abi.encodePacked(uint16(0x1901), DOMAIN_SEPARATOR, hashStruct));\\n\\n address signer = ecrecover(_hash, v, r, s);\\n require(signer != address(0) && signer == owner, \\\"ZeroSwapPermit: Invalid signature\\\");\\n\\n _nonces[owner].increment();\\n _approve(owner, spender, amount);\\n }\\n\\n /**\\n * @dev See {IERC2612Permit-nonces}.\\n */\\n function nonces(address owner) public view override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n}\\n\\ninterface IOwnable {\\n function manager() external view returns (address);\\n\\n function renounceManagement() external;\\n\\n function pushManagement( address newOwner_ ) external;\\n\\n function pullManagement() external;\\n}\\n\\ncontract Ownable is IOwnable {\\n\\n address internal _owner;\\n address internal _newOwner;\\n\\n event OwnershipPushed(address indexed previousOwner, address indexed newOwner);\\n event OwnershipPulled(address indexed previousOwner, address indexed newOwner);\\n\\n constructor () {\\n _owner = msg.sender;\\n emit OwnershipPushed( address(0), _owner );\\n }\\n\\n function manager() public view override returns (address) {\\n return _owner;\\n }\\n\\n modifier onlyManager() {\\n require( _owner == msg.sender, \\\"Ownable: caller is not the owner\\\" );\\n _;\\n }\\n\\n function renounceManagement() public virtual override onlyManager() {\\n emit OwnershipPushed( _owner, address(0) );\\n _owner = address(0);\\n }\\n\\n function pushManagement( address newOwner_ ) public virtual override onlyManager() {\\n require( newOwner_ != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipPushed( _owner, newOwner_ );\\n _newOwner = newOwner_;\\n }\\n\\n function pullManagement() public virtual override {\\n require( msg.sender == _newOwner, \\\"Ownable: must be new owner to pull\\\");\\n emit OwnershipPulled( _owner, _newOwner );\\n _owner = _newOwner;\\n }\\n}\\n\\ncontract sOlympus is ERC20Permit, Ownable {\\n\\n using SafeMath for uint256;\\n\\n modifier onlyStakingContract() {\\n require( msg.sender == stakingContract );\\n _;\\n }\\n\\n address public stakingContract;\\n address public initializer;\\n\\n event LogSupply(uint256 indexed epoch, uint256 timestamp, uint256 totalSupply );\\n event LogRebase( uint256 indexed epoch, uint256 rebase, uint256 index );\\n event LogStakingContractUpdated( address stakingContract );\\n\\n struct Rebase {\\n uint epoch;\\n uint rebase; // 18 decimals\\n uint totalStakedBefore;\\n uint totalStakedAfter;\\n uint amountRebased;\\n uint index;\\n uint blockNumberOccured;\\n }\\n Rebase[] public rebases;\\n\\n uint public INDEX;\\n\\n uint256 private constant MAX_UINT256 = ~uint256(0);\\n uint256 private constant INITIAL_FRAGMENTS_SUPPLY = 5000000 * 10**9;\\n\\n // TOTAL_GONS is a multiple of INITIAL_FRAGMENTS_SUPPLY so that _gonsPerFragment is an integer.\\n // Use the highest value that fits in a uint256 for max granularity.\\n uint256 private constant TOTAL_GONS = MAX_UINT256 - (MAX_UINT256 % INITIAL_FRAGMENTS_SUPPLY);\\n\\n // MAX_SUPPLY = maximum integer < (sqrt(4*TOTAL_GONS + 1) - 1) / 2\\n uint256 private constant MAX_SUPPLY = ~uint128(0); // (2^128) - 1\\n\\n uint256 private _gonsPerFragment;\\n mapping(address => uint256) private _gonBalances;\\n\\n mapping ( address => mapping ( address => uint256 ) ) private _allowedValue;\\n\\n constructor(string memory _name, string memory _symbol) ERC20(_name, _symbol, 9) ERC20Permit() {\\n initializer = msg.sender;\\n _totalSupply = INITIAL_FRAGMENTS_SUPPLY;\\n _gonsPerFragment = TOTAL_GONS.div(_totalSupply);\\n }\\n\\n function initialize( address stakingContract_ ) external returns ( bool ) {\\n require( msg.sender == initializer );\\n require( stakingContract_ != address(0) );\\n stakingContract = stakingContract_;\\n _gonBalances[ stakingContract ] = TOTAL_GONS;\\n\\n emit Transfer( address(0x0), stakingContract, _totalSupply );\\n emit LogStakingContractUpdated( stakingContract_ );\\n\\n initializer = address(0);\\n return true;\\n }\\n\\n function setIndex( uint _INDEX ) external onlyManager() returns ( bool ) {\\n require( INDEX == 0 );\\n INDEX = gonsForBalance( _INDEX );\\n return true;\\n }\\n\\n /**\\n @notice increases sOHM supply to increase staking balances relative to profit_\\n @param profit_ uint256\\n @return uint256\\n */\\n function rebase( uint256 profit_, uint epoch_ ) public onlyStakingContract() returns ( uint256 ) {\\n uint256 rebaseAmount;\\n uint256 circulatingSupply_ = circulatingSupply();\\n\\n if ( profit_ == 0 ) {\\n emit LogSupply( epoch_, block.timestamp, _totalSupply );\\n emit LogRebase( epoch_, 0, index() );\\n return _totalSupply;\\n } else if ( circulatingSupply_ > 0 ){\\n rebaseAmount = profit_.mul( _totalSupply ).div( circulatingSupply_ );\\n } else {\\n rebaseAmount = profit_;\\n }\\n\\n _totalSupply = _totalSupply.add( rebaseAmount );\\n\\n if ( _totalSupply > MAX_SUPPLY ) {\\n _totalSupply = MAX_SUPPLY;\\n }\\n\\n _gonsPerFragment = TOTAL_GONS.div( _totalSupply );\\n\\n _storeRebase( circulatingSupply_, profit_, epoch_ );\\n\\n return _totalSupply;\\n }\\n\\n /**\\n @notice emits event with data about rebase\\n @param previousCirculating_ uint\\n @param profit_ uint\\n @param epoch_ uint\\n @return bool\\n */\\n function _storeRebase( uint previousCirculating_, uint profit_, uint epoch_ ) internal returns ( bool ) {\\n uint rebasePercent = profit_.mul( 1e18 ).div( previousCirculating_ );\\n\\n rebases.push( Rebase ( {\\n epoch: epoch_,\\n rebase: rebasePercent, // 18 decimals\\n totalStakedBefore: previousCirculating_,\\n totalStakedAfter: circulatingSupply(),\\n amountRebased: profit_,\\n index: index(),\\n blockNumberOccured: block.number\\n }));\\n\\n emit LogSupply( epoch_, block.timestamp, _totalSupply );\\n emit LogRebase( epoch_, rebasePercent, index() );\\n\\n return true;\\n }\\n\\n function balanceOf( address who ) public view override returns ( uint256 ) {\\n return _gonBalances[ who ].div( _gonsPerFragment );\\n }\\n\\n function gonsForBalance( uint amount ) public view returns ( uint ) {\\n return amount.mul( _gonsPerFragment );\\n }\\n\\n function balanceForGons( uint gons ) public view returns ( uint ) {\\n return gons.div( _gonsPerFragment );\\n }\\n\\n // Staking contract holds excess sOHM\\n function circulatingSupply() public view returns ( uint ) {\\n return _totalSupply.sub( balanceOf( stakingContract ) );\\n }\\n\\n function index() public view returns ( uint ) {\\n return balanceForGons( INDEX );\\n }\\n\\n function transfer( address to, uint256 value ) public override returns (bool) {\\n uint256 gonValue = value.mul( _gonsPerFragment );\\n _gonBalances[ msg.sender ] = _gonBalances[ msg.sender ].sub( gonValue );\\n _gonBalances[ to ] = _gonBalances[ to ].add( gonValue );\\n emit Transfer( msg.sender, to, value );\\n return true;\\n }\\n\\n function allowance( address owner_, address spender ) public view override returns ( uint256 ) {\\n return _allowedValue[ owner_ ][ spender ];\\n }\\n\\n function transferFrom( address from, address to, uint256 value ) public override returns ( bool ) {\\n _allowedValue[ from ][ msg.sender ] = _allowedValue[ from ][ msg.sender ].sub( value );\\n emit Approval( from, msg.sender, _allowedValue[ from ][ msg.sender ] );\\n\\n uint256 gonValue = gonsForBalance( value );\\n _gonBalances[ from ] = _gonBalances[from].sub( gonValue );\\n _gonBalances[ to ] = _gonBalances[to].add( gonValue );\\n emit Transfer( from, to, value );\\n\\n return true;\\n }\\n\\n function approve( address spender, uint256 value ) public override returns (bool) {\\n _allowedValue[ msg.sender ][ spender ] = value;\\n emit Approval( msg.sender, spender, value );\\n return true;\\n }\\n\\n // What gets called in a permit\\n function _approve( address owner, address spender, uint256 value ) internal override virtual {\\n _allowedValue[owner][spender] = value;\\n emit Approval( owner, spender, value );\\n }\\n\\n function increaseAllowance( address spender, uint256 addedValue ) public override returns (bool) {\\n _allowedValue[ msg.sender ][ spender ] = _allowedValue[ msg.sender ][ spender ].add( addedValue );\\n emit Approval( msg.sender, spender, _allowedValue[ msg.sender ][ spender ] );\\n return true;\\n }\\n\\n function decreaseAllowance( address spender, uint256 subtractedValue ) public override returns (bool) {\\n uint256 oldValue = _allowedValue[ msg.sender ][ spender ];\\n if (subtractedValue >= oldValue) {\\n _allowedValue[ msg.sender ][ spender ] = 0;\\n } else {\\n _allowedValue[ msg.sender ][ spender ] = oldValue.sub( subtractedValue );\\n }\\n emit Approval( msg.sender, spender, _allowedValue[ msg.sender ][ spender ] );\\n return true;\\n }\\n}\",\"keccak256\":\"0xa97a72e3cf0c2c1c61117569983d829c6e373700615936d590bd35227b58c457\",\"license\":\"AGPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b506040516200341f3803806200341f833981810160405260408110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b838201915060208201858111156200006f57600080fd5b82518660018202830111640100000000821117156200008d57600080fd5b8083526020830192505050908051906020019080838360005b83811015620000c3578082015181840152602081019050620000a6565b50505050905090810190601f168015620000f15780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200011557600080fd5b838201915060208201858111156200012c57600080fd5b82518660018202830111640100000000821117156200014a57600080fd5b8083526020830192505050908051906020019080838360005b838110156200018057808201518184015260208101905062000163565b50505050905090810190601f168015620001ae5780820380516001836020036101000a031916815260200191505b50604052505050818160098260039080519060200190620001d1929190620005f5565b508160049080519060200190620001ea929190620005f5565b5080600560006101000a81548160ff021916908360ff16021790555050505060004690507f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6200023f6200043260201b60201c565b805190602001206040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250805190602001208330604051602001808681526020018581526020018481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200195505050505050604051602081830303815290604052805190602001206007819055505033600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a333600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506611c37937e08000600281905550620004246002546611c37937e08000600019816200040b57fe5b0660001903620004d860201b620026f21790919060201c565b600e819055505050620006ab565b606060038054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620004ce5780601f10620004a257610100808354040283529160200191620004ce565b820191906000526020600020905b815481529060010190602001808311620004b057829003601f168201915b5050505050905090565b60006200052283836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506200052a60201b60201c565b905092915050565b60008083118290620005da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156200059e57808201518184015260208101905062000581565b50505050905090810190601f168015620005cc5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581620005e757fe5b049050809150509392505050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200062d576000855562000679565b82601f106200064857805160ff191683800117855562000679565b8280016001018555821562000679579182015b82811115620006785782518255916020019190600101906200065b565b5b5090506200068891906200068c565b5090565b5b80821115620006a75760008160009055506001016200068d565b5090565b612d6480620006bb6000396000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c8063481c6a751161010457806395d89b41116100a2578063c4d66de811610071578063c4d66de8146108be578063d505accf14610918578063dd62ed3e146109b1578063ee99205c14610a29576101da565b806395d89b411461073f5780639ce110d7146107c2578063a457c2d7146107f6578063a9059cbb1461085a576101da565b806373c69eb7116100de57806373c69eb71461061b5780637965d56d146106875780637ecebe00146106c95780639358928b14610721576101da565b8063481c6a75146105855780635a96ac0a146105b957806370a08231146105c3576101da565b80632986c0e51161017c5780633644e5151161014b5780633644e5151461047b578063395093511461049957806340a5737f146104fd57806346f68ee914610541576101da565b80632986c0e5146104005780632df75cb11461041e57806330adf81f1461043c578063313ce5671461045a576101da565b8063095ea7b3116101b8578063095ea7b3146102b857806318160ddd1461031c5780631bd396741461033a57806323b872dd1461037c576101da565b8063058ecdb4146101df57806306fdde031461022b578063089208d8146102ae575b600080fd5b610215600480360360408110156101f557600080fd5b810190808035906020019092919080359060200190929190505050610a5d565b6040518082815260200191505060405180910390f35b610233610c40565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610273578082015181840152602081019050610258565b50505050905090810190601f1680156102a05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102b6610ce2565b005b610304600480360360408110156102ce57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610e66565b60405180821515815260200191505060405180910390f35b610324610f58565b6040518082815260200191505060405180910390f35b6103666004803603602081101561035057600080fd5b8101908080359060200190929190505050610f62565b6040518082815260200191505060405180910390f35b6103e86004803603606081101561039257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610f80565b60405180821515815260200191505060405180910390f35b61040861131a565b6040518082815260200191505060405180910390f35b61042661132c565b6040518082815260200191505060405180910390f35b610444611332565b6040518082815260200191505060405180910390f35b610462611359565b604051808260ff16815260200191505060405180910390f35b610483611370565b6040518082815260200191505060405180910390f35b6104e5600480360360408110156104af57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611376565b60405180821515815260200191505060405180910390f35b6105296004803603602081101561051357600080fd5b8101908080359060200190929190505050611572565b60405180821515815260200191505060405180910390f35b6105836004803603602081101561055757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061165e565b005b61058d611867565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6105c1611891565b005b610605600480360360208110156105d957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611a3a565b6040518082815260200191505060405180910390f35b6106476004803603602081101561063157600080fd5b8101908080359060200190929190505050611a97565b6040518088815260200187815260200186815260200185815260200184815260200183815260200182815260200197505050505050505060405180910390f35b6106b36004803603602081101561069d57600080fd5b8101908080359060200190929190505050611ae9565b6040518082815260200191505060405180910390f35b61070b600480360360208110156106df57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611b07565b6040518082815260200191505060405180910390f35b610729611b57565b6040518082815260200191505060405180910390f35b610747611b9d565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561078757808201518184015260208101905061076c565b50505050905090810190601f1680156107b45780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6107ca611c3f565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6108426004803603604081101561080c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611c65565b60405180821515815260200191505060405180910390f35b6108a66004803603604081101561087057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611ef5565b60405180821515815260200191505060405180910390f35b610900600480360360208110156108d457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506120a9565b60405180821515815260200191505060405180910390f35b6109af600480360360e081101561092e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190803560ff169060200190929190803590602001909291908035906020019092919050505061231e565b005b610a13600480360360408110156109c757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612645565b6040518082815260200191505060405180910390f35b610a316126cc565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ab957600080fd5b600080610ac4611b57565b90506000851415610b6557837f917acfbe39be6509ccf7fecb66a7e42ce2be1083c2d7dd3b9b7491dabddb8da442600254604051808381526020018281526020019250505060405180910390a2837f6012dbce857565c4a40974aa5de8373a761fc429077ef0c8c8611d1e20d63fb26000610b3d61131a565b604051808381526020018281526020019250505060405180910390a260025492505050610c3a565b6000811115610b9c57610b9581610b876002548861273c90919063ffffffff16565b6126f290919063ffffffff16565b9150610ba0565b8491505b610bb5826002546127c290919063ffffffff16565b6002819055506000196fffffffffffffffffffffffffffffffff166002541115610bf5576000196fffffffffffffffffffffffffffffffff166002819055505b610c206002546611c37937e0800060001981610c0d57fe5b06600019036126f290919063ffffffff16565b600e81905550610c3181868661284a565b50600254925050505b92915050565b606060038054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610cd85780601f10610cad57610100808354040283529160200191610cd8565b820191906000526020600020905b815481529060010190602001808311610cbb57829003601f168201915b5050505050905090565b3373ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610da5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a36000600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600081601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b6000600254905090565b6000610f79600e548361273c90919063ffffffff16565b9050919050565b600061101182601060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546129c590919063ffffffff16565b601060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925601060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040518082815260200191505060405180910390a3600061117d83610f62565b90506111d181600f60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546129c590919063ffffffff16565b600f60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061126681600f60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546127c290919063ffffffff16565b600f60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a360019150509392505050565b6000611327600d54611ae9565b905090565b600d5481565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c960001b81565b6000600560009054906101000a900460ff16905090565b60075481565b600061140782601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546127c290919063ffffffff16565b601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040518082815260200191505060405180910390a36001905092915050565b60003373ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611637576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6000600d541461164657600080fd5b61164f82610f62565b600d8190555060019050919050565b3373ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611721576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156117a7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180612ca56026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a380600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611937576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180612ccb6022913960400191505060405180910390fd5b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167faa151555690c956fc3ea32f106bb9f119b5237a061eaa8557cff3e51e3792c8d60405160405180910390a3600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6000611a90600e54600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546126f290919063ffffffff16565b9050919050565b600c8181548110611aa757600080fd5b90600052602060002090600702016000915090508060000154908060010154908060020154908060030154908060040154908060050154908060060154905087565b6000611b00600e54836126f290919063ffffffff16565b9050919050565b6000611b50600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612a0f565b9050919050565b6000611b98611b87600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16611a3a565b6002546129c590919063ffffffff16565b905090565b606060048054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611c355780601f10611c0a57610100808354040283529160200191611c35565b820191906000526020600020905b815481529060010190602001808311611c1857829003601f168201915b5050505050905090565b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050808310611d75576000601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611e09565b611d8883826129c590919063ffffffff16565b601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b8373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040518082815260200191505060405180910390a3600191505092915050565b600080611f0d600e548461273c90919063ffffffff16565b9050611f6181600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546129c590919063ffffffff16565b600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611ff681600f60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546127c290919063ffffffff16565b600f60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a3600191505092915050565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461210557600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561213f57600080fd5b81600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506611c37937e080006000198161219257fe5b0660001903600f6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6002546040518082815260200191505060405180910390a37f817c653428858ed536dc085c5d8273734c517b55de44b55f5c5877a75e3373a182604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a16000600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060019050919050565b83421115612394576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f5065726d69743a206578706972656420646561646c696e65000000000000000081525060200191505060405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c960001b888888612404600660008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612a0f565b89604051602001808781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018381526020018281526020019650505050505050604051602081830303815290604052805190602001209050600061190160075483604051602001808461ffff1660f01b81526002018381526020018281526020019350505050604051602081830303815290604052805190602001209050600060018287878760405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa15801561251e573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561259257508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b6125e7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612ced6021913960400191505060405180910390fd5b61262e600660008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612a1d565b6126398a8a8a612a33565b50505050505050505050565b6000601060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600061273483836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612b1e565b905092915050565b60008083141561274f57600090506127bc565b600082840290508284828161276057fe5b04146127b7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612d0e6021913960400191505060405180910390fd5b809150505b92915050565b600080828401905083811015612840576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b60008061287a8561286c670de0b6b3a76400008761273c90919063ffffffff16565b6126f290919063ffffffff16565b9050600c6040518060e001604052808581526020018381526020018781526020016128a3611b57565b81526020018681526020016128b661131a565b8152602001438152509080600181540180825580915050600190039060005260206000209060070201600090919091909150600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c082015181600601555050827f917acfbe39be6509ccf7fecb66a7e42ce2be1083c2d7dd3b9b7491dabddb8da442600254604051808381526020018281526020019250505060405180910390a2827f6012dbce857565c4a40974aa5de8373a761fc429077ef0c8c8611d1e20d63fb28261299d61131a565b604051808381526020018281526020019250505060405180910390a260019150509392505050565b6000612a0783836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612be4565b905092915050565b600081600001549050919050565b6001816000016000828254019250508190555050565b80601060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b60008083118290612bca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612b8f578082015181840152602081019050612b74565b50505050905090810190601f168015612bbc5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581612bd657fe5b049050809150509392505050565b6000838311158290612c91576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612c56578082015181840152602081019050612c3b565b50505050905090810190601f168015612c835780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838503905080915050939250505056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a206d757374206265206e6577206f776e657220746f2070756c6c5a65726f537761705065726d69743a20496e76616c6964207369676e6174757265536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a264697066735822122084072c8f76b3df74282c1e23f10b0d5ed0184791b81a4efae4bae306e423103564736f6c63430007050033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101da5760003560e01c8063481c6a751161010457806395d89b41116100a2578063c4d66de811610071578063c4d66de8146108be578063d505accf14610918578063dd62ed3e146109b1578063ee99205c14610a29576101da565b806395d89b411461073f5780639ce110d7146107c2578063a457c2d7146107f6578063a9059cbb1461085a576101da565b806373c69eb7116100de57806373c69eb71461061b5780637965d56d146106875780637ecebe00146106c95780639358928b14610721576101da565b8063481c6a75146105855780635a96ac0a146105b957806370a08231146105c3576101da565b80632986c0e51161017c5780633644e5151161014b5780633644e5151461047b578063395093511461049957806340a5737f146104fd57806346f68ee914610541576101da565b80632986c0e5146104005780632df75cb11461041e57806330adf81f1461043c578063313ce5671461045a576101da565b8063095ea7b3116101b8578063095ea7b3146102b857806318160ddd1461031c5780631bd396741461033a57806323b872dd1461037c576101da565b8063058ecdb4146101df57806306fdde031461022b578063089208d8146102ae575b600080fd5b610215600480360360408110156101f557600080fd5b810190808035906020019092919080359060200190929190505050610a5d565b6040518082815260200191505060405180910390f35b610233610c40565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610273578082015181840152602081019050610258565b50505050905090810190601f1680156102a05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102b6610ce2565b005b610304600480360360408110156102ce57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610e66565b60405180821515815260200191505060405180910390f35b610324610f58565b6040518082815260200191505060405180910390f35b6103666004803603602081101561035057600080fd5b8101908080359060200190929190505050610f62565b6040518082815260200191505060405180910390f35b6103e86004803603606081101561039257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610f80565b60405180821515815260200191505060405180910390f35b61040861131a565b6040518082815260200191505060405180910390f35b61042661132c565b6040518082815260200191505060405180910390f35b610444611332565b6040518082815260200191505060405180910390f35b610462611359565b604051808260ff16815260200191505060405180910390f35b610483611370565b6040518082815260200191505060405180910390f35b6104e5600480360360408110156104af57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611376565b60405180821515815260200191505060405180910390f35b6105296004803603602081101561051357600080fd5b8101908080359060200190929190505050611572565b60405180821515815260200191505060405180910390f35b6105836004803603602081101561055757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061165e565b005b61058d611867565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6105c1611891565b005b610605600480360360208110156105d957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611a3a565b6040518082815260200191505060405180910390f35b6106476004803603602081101561063157600080fd5b8101908080359060200190929190505050611a97565b6040518088815260200187815260200186815260200185815260200184815260200183815260200182815260200197505050505050505060405180910390f35b6106b36004803603602081101561069d57600080fd5b8101908080359060200190929190505050611ae9565b6040518082815260200191505060405180910390f35b61070b600480360360208110156106df57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611b07565b6040518082815260200191505060405180910390f35b610729611b57565b6040518082815260200191505060405180910390f35b610747611b9d565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561078757808201518184015260208101905061076c565b50505050905090810190601f1680156107b45780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6107ca611c3f565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6108426004803603604081101561080c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611c65565b60405180821515815260200191505060405180910390f35b6108a66004803603604081101561087057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611ef5565b60405180821515815260200191505060405180910390f35b610900600480360360208110156108d457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506120a9565b60405180821515815260200191505060405180910390f35b6109af600480360360e081101561092e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190803560ff169060200190929190803590602001909291908035906020019092919050505061231e565b005b610a13600480360360408110156109c757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612645565b6040518082815260200191505060405180910390f35b610a316126cc565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ab957600080fd5b600080610ac4611b57565b90506000851415610b6557837f917acfbe39be6509ccf7fecb66a7e42ce2be1083c2d7dd3b9b7491dabddb8da442600254604051808381526020018281526020019250505060405180910390a2837f6012dbce857565c4a40974aa5de8373a761fc429077ef0c8c8611d1e20d63fb26000610b3d61131a565b604051808381526020018281526020019250505060405180910390a260025492505050610c3a565b6000811115610b9c57610b9581610b876002548861273c90919063ffffffff16565b6126f290919063ffffffff16565b9150610ba0565b8491505b610bb5826002546127c290919063ffffffff16565b6002819055506000196fffffffffffffffffffffffffffffffff166002541115610bf5576000196fffffffffffffffffffffffffffffffff166002819055505b610c206002546611c37937e0800060001981610c0d57fe5b06600019036126f290919063ffffffff16565b600e81905550610c3181868661284a565b50600254925050505b92915050565b606060038054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610cd85780601f10610cad57610100808354040283529160200191610cd8565b820191906000526020600020905b815481529060010190602001808311610cbb57829003601f168201915b5050505050905090565b3373ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610da5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a36000600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600081601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b6000600254905090565b6000610f79600e548361273c90919063ffffffff16565b9050919050565b600061101182601060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546129c590919063ffffffff16565b601060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925601060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040518082815260200191505060405180910390a3600061117d83610f62565b90506111d181600f60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546129c590919063ffffffff16565b600f60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061126681600f60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546127c290919063ffffffff16565b600f60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a360019150509392505050565b6000611327600d54611ae9565b905090565b600d5481565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c960001b81565b6000600560009054906101000a900460ff16905090565b60075481565b600061140782601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546127c290919063ffffffff16565b601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040518082815260200191505060405180910390a36001905092915050565b60003373ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611637576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6000600d541461164657600080fd5b61164f82610f62565b600d8190555060019050919050565b3373ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611721576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156117a7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180612ca56026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a380600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611937576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180612ccb6022913960400191505060405180910390fd5b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167faa151555690c956fc3ea32f106bb9f119b5237a061eaa8557cff3e51e3792c8d60405160405180910390a3600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6000611a90600e54600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546126f290919063ffffffff16565b9050919050565b600c8181548110611aa757600080fd5b90600052602060002090600702016000915090508060000154908060010154908060020154908060030154908060040154908060050154908060060154905087565b6000611b00600e54836126f290919063ffffffff16565b9050919050565b6000611b50600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612a0f565b9050919050565b6000611b98611b87600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16611a3a565b6002546129c590919063ffffffff16565b905090565b606060048054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611c355780601f10611c0a57610100808354040283529160200191611c35565b820191906000526020600020905b815481529060010190602001808311611c1857829003601f168201915b5050505050905090565b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050808310611d75576000601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611e09565b611d8883826129c590919063ffffffff16565b601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b8373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040518082815260200191505060405180910390a3600191505092915050565b600080611f0d600e548461273c90919063ffffffff16565b9050611f6181600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546129c590919063ffffffff16565b600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611ff681600f60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546127c290919063ffffffff16565b600f60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a3600191505092915050565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461210557600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561213f57600080fd5b81600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506611c37937e080006000198161219257fe5b0660001903600f6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6002546040518082815260200191505060405180910390a37f817c653428858ed536dc085c5d8273734c517b55de44b55f5c5877a75e3373a182604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a16000600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060019050919050565b83421115612394576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f5065726d69743a206578706972656420646561646c696e65000000000000000081525060200191505060405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c960001b888888612404600660008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612a0f565b89604051602001808781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018381526020018281526020019650505050505050604051602081830303815290604052805190602001209050600061190160075483604051602001808461ffff1660f01b81526002018381526020018281526020019350505050604051602081830303815290604052805190602001209050600060018287878760405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa15801561251e573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561259257508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b6125e7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612ced6021913960400191505060405180910390fd5b61262e600660008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612a1d565b6126398a8a8a612a33565b50505050505050505050565b6000601060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600061273483836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612b1e565b905092915050565b60008083141561274f57600090506127bc565b600082840290508284828161276057fe5b04146127b7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612d0e6021913960400191505060405180910390fd5b809150505b92915050565b600080828401905083811015612840576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b60008061287a8561286c670de0b6b3a76400008761273c90919063ffffffff16565b6126f290919063ffffffff16565b9050600c6040518060e001604052808581526020018381526020018781526020016128a3611b57565b81526020018681526020016128b661131a565b8152602001438152509080600181540180825580915050600190039060005260206000209060070201600090919091909150600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c082015181600601555050827f917acfbe39be6509ccf7fecb66a7e42ce2be1083c2d7dd3b9b7491dabddb8da442600254604051808381526020018281526020019250505060405180910390a2827f6012dbce857565c4a40974aa5de8373a761fc429077ef0c8c8611d1e20d63fb28261299d61131a565b604051808381526020018281526020019250505060405180910390a260019150509392505050565b6000612a0783836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612be4565b905092915050565b600081600001549050919050565b6001816000016000828254019250508190555050565b80601060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b60008083118290612bca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612b8f578082015181840152602081019050612b74565b50505050905090810190601f168015612bbc5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581612bd657fe5b049050809150509392505050565b6000838311158290612c91576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612c56578082015181840152602081019050612c3b565b50505050905090810190601f168015612c835780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838503905080915050939250505056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a206d757374206265206e6577206f776e657220746f2070756c6c5a65726f537761705065726d69743a20496e76616c6964207369676e6174757265536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a264697066735822122084072c8f76b3df74282c1e23f10b0d5ed0184791b81a4efae4bae306e423103564736f6c63430007050033", + "devdoc": { + "kind": "dev", + "methods": { + "decimals()": { + "details": "Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5,05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is called. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}." + }, + "decreaseAllowance(address,uint256)": { + "details": "Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`." + }, + "increaseAllowance(address,uint256)": { + "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address." + }, + "name()": { + "details": "Returns the name of the token." + }, + "nonces(address)": { + "details": "See {IERC2612Permit-nonces}." + }, + "permit(address,address,uint256,uint256,uint8,bytes32,bytes32)": { + "details": "See {IERC2612Permit-permit}." + }, + "rebase(uint256,uint256)": { + "params": { + "profit_": "uint256" + }, + "returns": { + "_0": "uint256" + } + }, + "symbol()": { + "details": "Returns the symbol of the token, usually a shorter version of the name." + }, + "totalSupply()": { + "details": "See {IERC20-totalSupply}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "rebase(uint256,uint256)": { + "notice": "increases sOHM supply to increase staking balances relative to profit_" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 3221, + "contract": "contracts/sOlympusERC20.sol:sOlympus", + "label": "_balances", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 3227, + "contract": "contracts/sOlympusERC20.sol:sOlympus", + "label": "_allowances", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 3229, + "contract": "contracts/sOlympusERC20.sol:sOlympus", + "label": "_totalSupply", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 3231, + "contract": "contracts/sOlympusERC20.sol:sOlympus", + "label": "_name", + "offset": 0, + "slot": "3", + "type": "t_string_storage" + }, + { + "astId": 3233, + "contract": "contracts/sOlympusERC20.sol:sOlympus", + "label": "_symbol", + "offset": 0, + "slot": "4", + "type": "t_string_storage" + }, + { + "astId": 3235, + "contract": "contracts/sOlympusERC20.sol:sOlympus", + "label": "_decimals", + "offset": 0, + "slot": "5", + "type": "t_uint8" + }, + { + "astId": 3782, + "contract": "contracts/sOlympusERC20.sol:sOlympus", + "label": "_nonces", + "offset": 0, + "slot": "6", + "type": "t_mapping(t_address,t_struct(Counter)3704_storage)" + }, + { + "astId": 3787, + "contract": "contracts/sOlympusERC20.sol:sOlympus", + "label": "DOMAIN_SEPARATOR", + "offset": 0, + "slot": "7", + "type": "t_bytes32" + }, + { + "astId": 3957, + "contract": "contracts/sOlympusERC20.sol:sOlympus", + "label": "_owner", + "offset": 0, + "slot": "8", + "type": "t_address" + }, + { + "astId": 3959, + "contract": "contracts/sOlympusERC20.sol:sOlympus", + "label": "_newOwner", + "offset": 0, + "slot": "9", + "type": "t_address" + }, + { + "astId": 4102, + "contract": "contracts/sOlympusERC20.sol:sOlympus", + "label": "stakingContract", + "offset": 0, + "slot": "10", + "type": "t_address" + }, + { + "astId": 4104, + "contract": "contracts/sOlympusERC20.sol:sOlympus", + "label": "initializer", + "offset": 0, + "slot": "11", + "type": "t_address" + }, + { + "astId": 4142, + "contract": "contracts/sOlympusERC20.sol:sOlympus", + "label": "rebases", + "offset": 0, + "slot": "12", + "type": "t_array(t_struct(Rebase)4139_storage)dyn_storage" + }, + { + "astId": 4144, + "contract": "contracts/sOlympusERC20.sol:sOlympus", + "label": "INDEX", + "offset": 0, + "slot": "13", + "type": "t_uint256" + }, + { + "astId": 4175, + "contract": "contracts/sOlympusERC20.sol:sOlympus", + "label": "_gonsPerFragment", + "offset": 0, + "slot": "14", + "type": "t_uint256" + }, + { + "astId": 4179, + "contract": "contracts/sOlympusERC20.sol:sOlympus", + "label": "_gonBalances", + "offset": 0, + "slot": "15", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 4185, + "contract": "contracts/sOlympusERC20.sol:sOlympus", + "label": "_allowedValue", + "offset": 0, + "slot": "16", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_struct(Rebase)4139_storage)dyn_storage": { + "base": "t_struct(Rebase)4139_storage", + "encoding": "dynamic_array", + "label": "struct sOlympus.Rebase[]", + "numberOfBytes": "32" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_struct(Counter)3704_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct Counters.Counter)", + "numberOfBytes": "32", + "value": "t_struct(Counter)3704_storage" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_struct(Counter)3704_storage": { + "encoding": "inplace", + "label": "struct Counters.Counter", + "members": [ + { + "astId": 3703, + "contract": "contracts/sOlympusERC20.sol:sOlympus", + "label": "_value", + "offset": 0, + "slot": "0", + "type": "t_uint256" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Rebase)4139_storage": { + "encoding": "inplace", + "label": "struct sOlympus.Rebase", + "members": [ + { + "astId": 4126, + "contract": "contracts/sOlympusERC20.sol:sOlympus", + "label": "epoch", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 4128, + "contract": "contracts/sOlympusERC20.sol:sOlympus", + "label": "rebase", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 4130, + "contract": "contracts/sOlympusERC20.sol:sOlympus", + "label": "totalStakedBefore", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 4132, + "contract": "contracts/sOlympusERC20.sol:sOlympus", + "label": "totalStakedAfter", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 4134, + "contract": "contracts/sOlympusERC20.sol:sOlympus", + "label": "amountRebased", + "offset": 0, + "slot": "4", + "type": "t_uint256" + }, + { + "astId": 4136, + "contract": "contracts/sOlympusERC20.sol:sOlympus", + "label": "index", + "offset": 0, + "slot": "5", + "type": "t_uint256" + }, + { + "astId": 4138, + "contract": "contracts/sOlympusERC20.sol:sOlympus", + "label": "blockNumberOccured", + "offset": 0, + "slot": "6", + "type": "t_uint256" + } + ], + "numberOfBytes": "224" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/src/abi/rinkeby/solcInputs/77788eae31d169a831f4a6df224e3de9.json b/src/abi/rinkeby/solcInputs/77788eae31d169a831f4a6df224e3de9.json new file mode 100644 index 0000000000..a0198cee11 --- /dev/null +++ b/src/abi/rinkeby/solcInputs/77788eae31d169a831f4a6df224e3de9.json @@ -0,0 +1,53 @@ +{ + "language": "Solidity", + "sources": { + "contracts/mocks/WrappedToken.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity 0.7.5;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20Pausable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/utils/Context.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\n\ncontract WrappedToken is ERC20, ERC20Pausable {\n // Error Code: No error.\n uint256 public constant ERR_NO_ERROR = 0x0;\n\n // Error Code: Non-zero value expected to perform the function.\n uint256 public constant ERR_INVALID_ZERO_VALUE = 0x01;\n\n constructor (string memory name_, string memory symbol_) ERC20(name_, symbol_) {}\n\n function name() public view override returns (string memory) {\n return \"Wrapped Token\";\n }\n\n function symbol() public view override returns (string memory) {\n return \"WTOKEN\";\n }\n\n function decimals() public view override returns (uint8) {\n return 18;\n }\n\n // deposit wraps received FTM tokens as wFTM in 1:1 ratio by minting\n // the received amount of FTMs in wFTM on the sender's address.\n function deposit() public whenNotPaused payable returns (uint256) {\n // there has to be some value to be converted\n if (msg.value == 0) {\n return ERR_INVALID_ZERO_VALUE;\n }\n\n // we already received FTMs, mint the appropriate amount of wFTM\n _mint(msg.sender, msg.value);\n\n // all went well here\n return ERR_NO_ERROR;\n }\n\n // withdraw unwraps FTM tokens by burning specified amount\n // of wFTM from the caller address and sending the same amount\n // of FTMs back in exchange.\n function withdraw(uint256 amount) public whenNotPaused returns (uint256) {\n // there has to be some value to be converted\n if (amount == 0) {\n return ERR_INVALID_ZERO_VALUE;\n }\n\n // burn wFTM from the sender first to prevent re-entrance issue\n _burn(msg.sender, amount);\n\n // if wFTM were burned, transfer native tokens back to the sender\n msg.sender.transfer(amount);\n\n // all went well here\n return ERR_NO_ERROR;\n }\n\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal override(ERC20, ERC20Pausable) {\n super._beforeTokenTransfer(from, to, amount);\n }\n}" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20 {\n using SafeMath for uint256;\n\n mapping (address => uint256) private _balances;\n\n mapping (address => mapping (address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory name_, string memory symbol_) public {\n _name = name_;\n _symbol = symbol_;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\n * called.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for ``sender``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal virtual {\n _decimals = decimals_;\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20Pausable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./ERC20.sol\";\nimport \"../../utils/Pausable.sol\";\n\n/**\n * @dev ERC20 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n */\nabstract contract ERC20Pausable is ERC20, Pausable {\n /**\n * @dev See {ERC20-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {\n super._beforeTokenTransfer(from, to, amount);\n\n require(!paused(), \"ERC20Pausable: token transfer while paused\");\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/math/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n\n /**\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b <= a, \"SafeMath: subtraction overflow\");\n return a - b;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a == 0) return 0;\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b > 0, \"SafeMath: division by zero\");\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b > 0, \"SafeMath: modulo by zero\");\n return a % b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n return a - b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryDiv}.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Pausable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./Context.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n constructor () internal {\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n require(!paused(), \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n require(paused(), \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/src/abi/rinkeby/solcInputs/778fd7df05b9b5e245a90ea93cf9b329.json b/src/abi/rinkeby/solcInputs/778fd7df05b9b5e245a90ea93cf9b329.json new file mode 100644 index 0000000000..ab45be1b9d --- /dev/null +++ b/src/abi/rinkeby/solcInputs/778fd7df05b9b5e245a90ea93cf9b329.json @@ -0,0 +1,59 @@ +{ + "language": "Solidity", + "sources": { + "contracts/BondDepository.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity 0.7.5;\n\ninterface IOwnable {\n function policy() external view returns (address);\n\n function renounceManagement() external;\n \n function pushManagement( address newOwner_ ) external;\n \n function pullManagement() external;\n}\n\ncontract Ownable is IOwnable {\n\n address internal _owner;\n address internal _newOwner;\n\n event OwnershipPushed(address indexed previousOwner, address indexed newOwner);\n event OwnershipPulled(address indexed previousOwner, address indexed newOwner);\n\n constructor () {\n _owner = msg.sender;\n emit OwnershipPushed( address(0), _owner );\n }\n\n function policy() public view override returns (address) {\n return _owner;\n }\n\n modifier onlyPolicy() {\n require( _owner == msg.sender, \"Ownable: caller is not the owner\" );\n _;\n }\n\n function renounceManagement() public virtual override onlyPolicy() {\n emit OwnershipPushed( _owner, address(0) );\n _owner = address(0);\n }\n\n function pushManagement( address newOwner_ ) public virtual override onlyPolicy() {\n require( newOwner_ != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipPushed( _owner, newOwner_ );\n _newOwner = newOwner_;\n }\n \n function pullManagement() public virtual override {\n require( msg.sender == _newOwner, \"Ownable: must be new owner to pull\");\n emit OwnershipPulled( _owner, _newOwner );\n _owner = _newOwner;\n }\n}\n\nlibrary SafeMath {\n\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n return c;\n }\n\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n\n function sqrrt(uint256 a) internal pure returns (uint c) {\n if (a > 3) {\n c = a;\n uint b = add( div( a, 2), 1 );\n while (b < c) {\n c = b;\n b = div( add( div( a, b ), b), 2 );\n }\n } else if (a != 0) {\n c = 1;\n }\n }\n}\n\nlibrary Address {\n\n function isContract(address account) internal view returns (bool) {\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return _functionCallWithValue(target, data, 0, errorMessage);\n }\n\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n if (returndata.length > 0) {\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n function addressToString(address _address) internal pure returns(string memory) {\n bytes32 _bytes = bytes32(uint256(_address));\n bytes memory HEX = \"0123456789abcdef\";\n bytes memory _addr = new bytes(42);\n\n _addr[0] = '0';\n _addr[1] = 'x';\n\n for(uint256 i = 0; i < 20; i++) {\n _addr[2+i*2] = HEX[uint8(_bytes[i + 12] >> 4)];\n _addr[3+i*2] = HEX[uint8(_bytes[i + 12] & 0x0f)];\n }\n\n return string(_addr);\n\n }\n}\n\ninterface IERC20 {\n function decimals() external view returns (uint8);\n\n function totalSupply() external view returns (uint256);\n\n function balanceOf(address account) external view returns (uint256);\n\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n function allowance(address owner, address spender) external view returns (uint256);\n\n function approve(address spender, uint256 amount) external returns (bool);\n\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n\nabstract contract ERC20 is IERC20 {\n\n using SafeMath for uint256;\n\n // TODO comment actual hash value.\n bytes32 constant private ERC20TOKEN_ERC1820_INTERFACE_ID = keccak256( \"ERC20Token\" );\n \n mapping (address => uint256) internal _balances;\n\n mapping (address => mapping (address => uint256)) internal _allowances;\n\n uint256 internal _totalSupply;\n\n string internal _name;\n \n string internal _symbol;\n \n uint8 internal _decimals;\n\n constructor (string memory name_, string memory symbol_, uint8 decimals_) {\n _name = name_;\n _symbol = symbol_;\n _decimals = decimals_;\n }\n\n function name() public view returns (string memory) {\n return _name;\n }\n\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimals;\n }\n\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(msg.sender, recipient, amount);\n return true;\n }\n\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(msg.sender, spender, amount);\n return true;\n }\n\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n function _mint(address account_, uint256 ammount_) internal virtual {\n require(account_ != address(0), \"ERC20: mint to the zero address\");\n _beforeTokenTransfer(address( this ), account_, ammount_);\n _totalSupply = _totalSupply.add(ammount_);\n _balances[account_] = _balances[account_].add(ammount_);\n emit Transfer(address( this ), account_, ammount_);\n }\n\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n function _beforeTokenTransfer( address from_, address to_, uint256 amount_ ) internal virtual { }\n}\n\ninterface IERC2612Permit {\n\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n function nonces(address owner) external view returns (uint256);\n}\n\nlibrary Counters {\n using SafeMath for uint256;\n\n struct Counter {\n\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n counter._value += 1;\n }\n\n function decrement(Counter storage counter) internal {\n counter._value = counter._value.sub(1);\n }\n}\n\nabstract contract ERC20Permit is ERC20, IERC2612Permit {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n\n bytes32 public DOMAIN_SEPARATOR;\n\n constructor() {\n uint256 chainID;\n assembly {\n chainID := chainid()\n }\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name())),\n keccak256(bytes(\"1\")), // Version\n chainID,\n address(this)\n )\n );\n }\n\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"Permit: expired deadline\");\n\n bytes32 hashStruct =\n keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, amount, _nonces[owner].current(), deadline));\n\n bytes32 _hash = keccak256(abi.encodePacked(uint16(0x1901), DOMAIN_SEPARATOR, hashStruct));\n\n address signer = ecrecover(_hash, v, r, s);\n require(signer != address(0) && signer == owner, \"ZeroSwapPermit: Invalid signature\");\n\n _nonces[owner].increment();\n _approve(owner, spender, amount);\n }\n\n function nonces(address owner) public view override returns (uint256) {\n return _nonces[owner].current();\n }\n}\n\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n\nlibrary FullMath {\n function fullMul(uint256 x, uint256 y) private pure returns (uint256 l, uint256 h) {\n uint256 mm = mulmod(x, y, uint256(-1));\n l = x * y;\n h = mm - l;\n if (mm < l) h -= 1;\n }\n\n function fullDiv(\n uint256 l,\n uint256 h,\n uint256 d\n ) private pure returns (uint256) {\n uint256 pow2 = d & -d;\n d /= pow2;\n l /= pow2;\n l += h * ((-pow2) / pow2 + 1);\n uint256 r = 1;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n return l * r;\n }\n\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 d\n ) internal pure returns (uint256) {\n (uint256 l, uint256 h) = fullMul(x, y);\n uint256 mm = mulmod(x, y, d);\n if (mm > l) h -= 1;\n l -= mm;\n require(h < d, 'FullMath::mulDiv: overflow');\n return fullDiv(l, h, d);\n }\n}\n\nlibrary FixedPoint {\n\n struct uq112x112 {\n uint224 _x;\n }\n\n struct uq144x112 {\n uint256 _x;\n }\n\n uint8 private constant RESOLUTION = 112;\n uint256 private constant Q112 = 0x10000000000000000000000000000;\n uint256 private constant Q224 = 0x100000000000000000000000000000000000000000000000000000000;\n uint256 private constant LOWER_MASK = 0xffffffffffffffffffffffffffff; // decimal of UQ*x112 (lower 112 bits)\n\n function decode(uq112x112 memory self) internal pure returns (uint112) {\n return uint112(self._x >> RESOLUTION);\n }\n\n function decode112with18(uq112x112 memory self) internal pure returns (uint) {\n\n return uint(self._x) / 5192296858534827;\n }\n\n function fraction(uint256 numerator, uint256 denominator) internal pure returns (uq112x112 memory) {\n require(denominator > 0, 'FixedPoint::fraction: division by zero');\n if (numerator == 0) return FixedPoint.uq112x112(0);\n\n if (numerator <= uint144(-1)) {\n uint256 result = (numerator << RESOLUTION) / denominator;\n require(result <= uint224(-1), 'FixedPoint::fraction: overflow');\n return uq112x112(uint224(result));\n } else {\n uint256 result = FullMath.mulDiv(numerator, Q112, denominator);\n require(result <= uint224(-1), 'FixedPoint::fraction: overflow');\n return uq112x112(uint224(result));\n }\n }\n}\n\ninterface ITreasury {\n function deposit( uint _amount, address _token, uint _profit ) external returns ( bool );\n function valueOf( address _token, uint _amount ) external view returns ( uint value_ );\n}\n\ninterface IBondCalculator {\n function valuation( address _LP, uint _amount ) external view returns ( uint );\n function markdown( address _LP ) external view returns ( uint );\n}\n\ninterface IStaking {\n function stake( uint _amount, address _recipient ) external returns ( bool );\n}\n\ninterface IStakingHelper {\n function stake( uint _amount, address _recipient ) external;\n}\n\ncontract OlympusBondDepository is Ownable {\n\n using FixedPoint for *;\n using SafeERC20 for IERC20;\n using SafeMath for uint;\n\n\n\n\n /* ======== EVENTS ======== */\n\n event BondCreated( uint deposit, uint indexed payout, uint indexed expires, uint indexed priceInUSD );\n event BondRedeemed( address indexed recipient, uint payout, uint remaining );\n event BondPriceChanged( uint indexed priceInUSD, uint indexed internalPrice, uint indexed debtRatio );\n event ControlVariableAdjustment( uint initialBCV, uint newBCV, uint adjustment, bool addition );\n\n\n\n\n /* ======== STATE VARIABLES ======== */\n\n address public immutable OHM; // token given as payment for bond\n address public immutable principle; // token used to create bond\n address public immutable treasury; // mints OHM when receives principle\n address public immutable DAO; // receives profit share from bond\n\n bool public immutable isLiquidityBond; // LP and Reserve bonds are treated slightly different\n address public immutable bondCalculator; // calculates value of LP tokens\n\n address public staking; // to auto-stake payout\n address public stakingHelper; // to stake and claim if no staking warmup\n bool public useHelper;\n\n Terms public terms; // stores terms for new bonds\n Adjust public adjustment; // stores adjustment to BCV data\n\n mapping( address => Bond ) public bondInfo; // stores bond information for depositors\n\n uint public totalDebt; // total value of outstanding bonds; used for pricing\n uint public lastDecay; // reference block timestamp for debt decay\n\n\n\n\n /* ======== STRUCTS ======== */\n\n // Info for creating new bonds\n struct Terms {\n uint controlVariable; // scaling variable for price\n uint vestingTerm; // in seconds\n uint minimumPrice; // vs principle value\n uint maxPayout; // in thousandths of a %. i.e. 500 = 0.5%\n uint fee; // as % of bond payout, in hundreths. ( 500 = 5% = 0.05 for every 1 paid)\n uint maxDebt; // 9 decimal debt ratio, max % total supply created as debt\n }\n\n // Info for bond holder\n struct Bond {\n uint payout; // OHM remaining to be paid\n uint vesting; // Blocks left to vest\n uint lastTime; // Last interaction\n uint pricePaid; // In DAI, for front end viewing\n }\n\n // Info for incremental adjustments to control variable\n struct Adjust {\n bool add; // addition or subtraction\n uint rate; // increment\n uint target; // BCV when adjustment finished\n uint buffer; // minimum length (in seconds) between adjustments\n uint lastTime; // time when last adjustment made\n }\n\n\n\n\n /* ======== INITIALIZATION ======== */\n\n constructor ( \n address _OHM,\n address _principle,\n address _treasury, \n address _DAO, \n address _bondCalculator\n ) {\n require( _OHM != address(0) );\n OHM = _OHM;\n require( _principle != address(0) );\n principle = _principle;\n require( _treasury != address(0) );\n treasury = _treasury;\n require( _DAO != address(0) );\n DAO = _DAO;\n // bondCalculator should be address(0) if not LP bond\n bondCalculator = _bondCalculator;\n isLiquidityBond = ( _bondCalculator != address(0) );\n }\n\n /**\n * @notice initializes bond parameters\n * @param _controlVariable uint\n * @param _vestingTerm uint\n * @param _minimumPrice uint\n * @param _maxPayout uint\n * @param _fee uint\n * @param _maxDebt uint\n * @param _initialDebt uint\n */\n function initializeBondTerms( \n uint _controlVariable, \n uint _vestingTerm,\n uint _minimumPrice,\n uint _maxPayout,\n uint _fee,\n uint _maxDebt,\n uint _initialDebt\n ) external onlyPolicy() {\n require( terms.controlVariable == 0, \"Bonds must be initialized from 0\" );\n terms = Terms ({\n controlVariable: _controlVariable,\n vestingTerm: _vestingTerm,\n minimumPrice: _minimumPrice,\n maxPayout: _maxPayout,\n fee: _fee,\n maxDebt: _maxDebt\n });\n totalDebt = _initialDebt;\n lastDecay = block.timestamp;\n }\n\n\n\n\n /* ======== POLICY FUNCTIONS ======== */\n\n enum PARAMETER { VESTING, PAYOUT, FEE, DEBT }\n /**\n * @notice set parameters for new bonds\n * @param _parameter PARAMETER\n * @param _input uint\n */\n function setBondTerms ( PARAMETER _parameter, uint _input ) external onlyPolicy() {\n if ( _parameter == PARAMETER.VESTING ) { // 0\n require( _input >= 129600, \"Vesting must be longer than 36 hours\" );\n terms.vestingTerm = _input;\n } else if ( _parameter == PARAMETER.PAYOUT ) { // 1\n require( _input <= 1000, \"Payout cannot be above 1 percent\" );\n terms.maxPayout = _input;\n } else if ( _parameter == PARAMETER.FEE ) { // 2\n require( _input <= 10000, \"DAO fee cannot exceed payout\" );\n terms.fee = _input;\n } else if ( _parameter == PARAMETER.DEBT ) { // 3\n terms.maxDebt = _input;\n }\n }\n\n /**\n * @notice set control variable adjustment\n * @param _addition bool\n * @param _increment uint\n * @param _target uint\n * @param _buffer uint\n */\n function setAdjustment ( \n bool _addition,\n uint _increment, \n uint _target,\n uint _buffer \n ) external onlyPolicy() {\n require( _increment <= terms.controlVariable.mul( 25 ).div( 1000 ), \"Increment too large\" );\n\n adjustment = Adjust({\n add: _addition,\n rate: _increment,\n target: _target,\n buffer: _buffer,\n lastTime: block.timestamp\n });\n }\n\n /**\n * @notice set contract for auto stake\n * @param _staking address\n * @param _helper bool\n */\n function setStaking( address _staking, bool _helper ) external onlyPolicy() {\n require( _staking != address(0) );\n if ( _helper ) {\n useHelper = true;\n stakingHelper = _staking;\n } else {\n useHelper = false;\n staking = _staking;\n }\n }\n\n\n \n\n /* ======== USER FUNCTIONS ======== */\n\n /**\n * @notice deposit bond\n * @param _amount uint\n * @param _maxPrice uint\n * @param _depositor address\n * @return uint\n */\n function deposit( \n uint _amount, \n uint _maxPrice,\n address _depositor\n ) external returns ( uint ) {\n require( _depositor != address(0), \"Invalid address\" );\n\n decayDebt();\n require( totalDebt <= terms.maxDebt, \"Max capacity reached\" );\n \n uint priceInUSD = bondPriceInUSD(); // Stored in bond info\n uint nativePrice = _bondPrice();\n\n require( _maxPrice >= nativePrice, \"Slippage limit: more than max price\" ); // slippage protection\n\n uint value = ITreasury( treasury ).valueOf( principle, _amount );\n uint payout = payoutFor( value ); // payout to bonder is computed\n\n require( payout >= 10000000, \"Bond too small\" ); // must be > 0.01 OHM ( underflow protection )\n require( payout <= maxPayout(), \"Bond too large\"); // size protection because there is no slippage\n\n // profits are calculated\n uint fee = payout.mul( terms.fee ).div( 10000 );\n uint profit = value.sub( payout ).sub( fee );\n\n /**\n principle is transferred in\n approved and\n deposited into the treasury, returning (_amount - profit) OHM\n */\n IERC20( principle ).safeTransferFrom( msg.sender, address(this), _amount );\n IERC20( principle ).approve( address( treasury ), _amount );\n ITreasury( treasury ).deposit( _amount, principle, profit );\n \n if ( fee != 0 ) { // fee is transferred to dao \n IERC20( OHM ).safeTransfer( DAO, fee ); \n }\n \n // total debt is increased\n totalDebt = totalDebt.add( value ); \n \n // depositor info is stored\n bondInfo[ _depositor ] = Bond({ \n payout: bondInfo[ _depositor ].payout.add( payout ),\n vesting: terms.vestingTerm,\n lastTime: block.timestamp,\n pricePaid: priceInUSD\n });\n\n // indexed events are emitted\n emit BondCreated( _amount, payout, block.timestamp.add( terms.vestingTerm ), priceInUSD );\n emit BondPriceChanged( bondPriceInUSD(), _bondPrice(), debtRatio() );\n\n adjust(); // control variable is adjusted\n return payout; \n }\n\n /** \n * @notice redeem bond for user\n * @param _recipient address\n * @param _stake bool\n * @return uint\n */ \n function redeem( address _recipient, bool _stake ) external returns ( uint ) { \n Bond memory info = bondInfo[ _recipient ];\n uint percentVested = percentVestedFor( _recipient ); // (blocks since last interaction / vesting term remaining)\n\n if ( percentVested >= 10000 ) { // if fully vested\n delete bondInfo[ _recipient ]; // delete user info\n emit BondRedeemed( _recipient, info.payout, 0 ); // emit bond data\n return stakeOrSend( _recipient, _stake, info.payout ); // pay user everything due\n\n } else { // if unfinished\n // calculate payout vested\n uint payout = info.payout.mul( percentVested ).div( 10000 );\n\n // store updated deposit info\n bondInfo[ _recipient ] = Bond({\n payout: info.payout.sub( payout ),\n vesting: info.vesting.sub( block.timestamp.sub( info.lastTime ) ),\n lastTime: block.timestamp,\n pricePaid: info.pricePaid\n });\n\n emit BondRedeemed( _recipient, payout, bondInfo[ _recipient ].payout );\n return stakeOrSend( _recipient, _stake, payout );\n }\n }\n\n\n\n \n /* ======== INTERNAL HELPER FUNCTIONS ======== */\n\n /**\n * @notice allow user to stake payout automatically\n * @param _stake bool\n * @param _amount uint\n * @return uint\n */\n function stakeOrSend( address _recipient, bool _stake, uint _amount ) internal returns ( uint ) {\n if ( !_stake ) { // if user does not want to stake\n IERC20( OHM ).transfer( _recipient, _amount ); // send payout\n } else { // if user wants to stake\n if ( useHelper ) { // use if staking warmup is 0\n IERC20( OHM ).approve( stakingHelper, _amount );\n IStakingHelper( stakingHelper ).stake( _amount, _recipient );\n } else {\n IERC20( OHM ).approve( staking, _amount );\n IStaking( staking ).stake( _amount, _recipient );\n }\n }\n return _amount;\n }\n\n /**\n * @notice makes incremental adjustment to control variable\n */\n function adjust() internal {\n uint timeCanAdjust = adjustment.lastTime.add( adjustment.buffer );\n if( adjustment.rate != 0 && block.timestamp >= timeCanAdjust ) {\n uint initial = terms.controlVariable;\n if ( adjustment.add ) {\n terms.controlVariable = terms.controlVariable.add( adjustment.rate );\n if ( terms.controlVariable >= adjustment.target ) {\n adjustment.rate = 0;\n }\n } else {\n terms.controlVariable = terms.controlVariable.sub( adjustment.rate );\n if ( terms.controlVariable <= adjustment.target ) {\n adjustment.rate = 0;\n }\n }\n adjustment.lastTime = block.timestamp;\n emit ControlVariableAdjustment( initial, terms.controlVariable, adjustment.rate, adjustment.add );\n }\n }\n\n /**\n * @notice reduce total debt\n */\n function decayDebt() internal {\n totalDebt = totalDebt.sub( debtDecay() );\n lastDecay = block.timestamp;\n }\n\n\n\n\n /* ======== VIEW FUNCTIONS ======== */\n\n /**\n * @notice determine maximum bond size\n * @return uint\n */\n function maxPayout() public view returns ( uint ) {\n return IERC20( OHM ).totalSupply().mul( terms.maxPayout ).div( 100000 );\n }\n\n /**\n * @notice calculate interest due for new bond\n * @param _value uint\n * @return uint\n */\n function payoutFor( uint _value ) public view returns ( uint ) {\n return FixedPoint.fraction( _value, bondPrice() ).decode112with18().div( 1e16 );\n }\n\n\n /**\n * @notice calculate current bond premium\n * @return price_ uint\n */\n function bondPrice() public view returns ( uint price_ ) { \n price_ = terms.controlVariable.mul( debtRatio() ).add( 1000000000 ).div( 1e7 );\n if ( price_ < terms.minimumPrice ) {\n price_ = terms.minimumPrice;\n }\n }\n\n /**\n * @notice calculate current bond price and remove floor if above\n * @return price_ uint\n */\n function _bondPrice() internal returns ( uint price_ ) {\n price_ = terms.controlVariable.mul( debtRatio() ).add( 1000000000 ).div( 1e7 );\n if ( price_ < terms.minimumPrice ) {\n price_ = terms.minimumPrice; \n } else if ( terms.minimumPrice != 0 ) {\n terms.minimumPrice = 0;\n }\n }\n\n /**\n * @notice converts bond price to DAI value\n * @return price_ uint\n */\n function bondPriceInUSD() public view returns ( uint price_ ) {\n if( isLiquidityBond ) {\n price_ = bondPrice().mul( IBondCalculator( bondCalculator ).markdown( principle ) ).div( 100 );\n } else {\n price_ = bondPrice().mul( 10 ** IERC20( principle ).decimals() ).div( 100 );\n }\n }\n\n\n /**\n * @notice calculate current ratio of debt to OHM supply\n * @return debtRatio_ uint\n */\n function debtRatio() public view returns ( uint debtRatio_ ) { \n uint supply = IERC20( OHM ).totalSupply();\n debtRatio_ = FixedPoint.fraction( \n currentDebt().mul( 1e9 ), \n supply\n ).decode112with18().div( 1e18 );\n }\n\n /**\n * @notice debt ratio in same terms for reserve or liquidity bonds\n * @return uint\n */\n function standardizedDebtRatio() external view returns ( uint ) {\n if ( isLiquidityBond ) {\n return debtRatio().mul( IBondCalculator( bondCalculator ).markdown( principle ) ).div( 1e9 );\n } else {\n return debtRatio();\n }\n }\n\n /**\n * @notice calculate debt factoring in decay\n * @return uint\n */\n function currentDebt() public view returns ( uint ) {\n return totalDebt.sub( debtDecay() );\n }\n\n /**\n * @notice amount to decay total debt by\n * @return decay_ uint\n */\n function debtDecay() public view returns ( uint decay_ ) {\n uint timeSinceLast = block.timestamp.sub( lastDecay );\n decay_ = totalDebt.mul( timeSinceLast ).div( terms.vestingTerm );\n if ( decay_ > totalDebt ) {\n decay_ = totalDebt;\n }\n }\n\n\n /**\n * @notice calculate how far into vesting a depositor is\n * @param _depositor address\n * @return percentVested_ uint\n */\n function percentVestedFor( address _depositor ) public view returns ( uint percentVested_ ) {\n Bond memory bond = bondInfo[ _depositor ];\n uint secondsSinceLast = block.timestamp.sub( bond.lastTime );\n uint vesting = bond.vesting;\n\n if ( vesting > 0 ) {\n percentVested_ = secondsSinceLast.mul( 10000 ).div( vesting );\n } else {\n percentVested_ = 0;\n }\n }\n\n /**\n * @notice calculate amount of OHM available for claim by depositor\n * @param _depositor address\n * @return pendingPayout_ uint\n */\n function pendingPayoutFor( address _depositor ) external view returns ( uint pendingPayout_ ) {\n uint percentVested = percentVestedFor( _depositor );\n uint payout = bondInfo[ _depositor ].payout;\n\n if ( percentVested >= 10000 ) {\n pendingPayout_ = payout;\n } else {\n pendingPayout_ = payout.mul( percentVested ).div( 10000 );\n }\n }\n\n\n\n\n /* ======= AUXILLIARY ======= */\n\n /**\n * @notice allow anyone to send lost tokens (excluding principle or OHM) to the DAO\n * @return bool\n */\n function recoverLostToken( address _token ) external returns ( bool ) {\n require( _token != OHM );\n require( _token != principle );\n IERC20( _token ).safeTransfer( DAO, IERC20( _token ).balanceOf( address(this) ) );\n return true;\n }\n}" + }, + "contracts/mocks/WrappedFtm.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity 0.7.5;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20Pausable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/utils/Context.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\n\nabstract contract WrappedFtm is ERC20, ERC20Pausable {\n // Error Code: No error.\n uint256 public constant ERR_NO_ERROR = 0x0;\n\n // Error Code: Non-zero value expected to perform the function.\n uint256 public constant ERR_INVALID_ZERO_VALUE = 0x01;\n\n // create instance of the wFTM token\n constructor (string memory name_, string memory symbol_) {}\n\n function name() public view override returns (string memory) {\n return \"Wrapped Fantom\";\n }\n\n function symbol() public view override returns (string memory) {\n return \"WFTM\";\n }\n\n function decimals() public view override returns (uint8) {\n return 18;\n }\n\n // deposit wraps received FTM tokens as wFTM in 1:1 ratio by minting\n // the received amount of FTMs in wFTM on the sender's address.\n function deposit() public whenNotPaused payable returns (uint256) {\n // there has to be some value to be converted\n if (msg.value == 0) {\n return ERR_INVALID_ZERO_VALUE;\n }\n\n // we already received FTMs, mint the appropriate amount of wFTM\n _mint(msg.sender, msg.value);\n\n // all went well here\n return ERR_NO_ERROR;\n }\n\n // withdraw unwraps FTM tokens by burning specified amount\n // of wFTM from the caller address and sending the same amount\n // of FTMs back in exchange.\n function withdraw(uint256 amount) public whenNotPaused returns (uint256) {\n // there has to be some value to be converted\n if (amount == 0) {\n return ERR_INVALID_ZERO_VALUE;\n }\n\n // burn wFTM from the sender first to prevent re-entrance issue\n _burn(msg.sender, amount);\n\n // if wFTM were burned, transfer native tokens back to the sender\n msg.sender.transfer(amount);\n\n // all went well here\n return ERR_NO_ERROR;\n }\n\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal override(ERC20, ERC20Pausable) {\n super._beforeTokenTransfer(from, to, amount);\n }\n}" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20 {\n using SafeMath for uint256;\n\n mapping (address => uint256) private _balances;\n\n mapping (address => mapping (address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory name_, string memory symbol_) public {\n _name = name_;\n _symbol = symbol_;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\n * called.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for ``sender``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal virtual {\n _decimals = decimals_;\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20Pausable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./ERC20.sol\";\nimport \"../../utils/Pausable.sol\";\n\n/**\n * @dev ERC20 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n */\nabstract contract ERC20Pausable is ERC20, Pausable {\n /**\n * @dev See {ERC20-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {\n super._beforeTokenTransfer(from, to, amount);\n\n require(!paused(), \"ERC20Pausable: token transfer while paused\");\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/math/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n\n /**\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b <= a, \"SafeMath: subtraction overflow\");\n return a - b;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a == 0) return 0;\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b > 0, \"SafeMath: division by zero\");\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b > 0, \"SafeMath: modulo by zero\");\n return a % b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n return a - b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryDiv}.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Pausable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./Context.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n constructor () internal {\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n require(!paused(), \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n require(paused(), \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n" + }, + "contracts/wETHBondDepository.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity 0.7.5;\n\ninterface IOwnable {\n function policy() external view returns (address);\n\n function renounceManagement() external;\n \n function pushManagement( address newOwner_ ) external;\n \n function pullManagement() external;\n}\n\ncontract Ownable is IOwnable {\n\n address internal _owner;\n address internal _newOwner;\n\n event OwnershipPushed(address indexed previousOwner, address indexed newOwner);\n event OwnershipPulled(address indexed previousOwner, address indexed newOwner);\n\n constructor () {\n _owner = msg.sender;\n emit OwnershipPushed( address(0), _owner );\n }\n\n function policy() public view override returns (address) {\n return _owner;\n }\n\n modifier onlyPolicy() {\n require( _owner == msg.sender, \"Ownable: caller is not the owner\" );\n _;\n }\n\n function renounceManagement() public virtual override onlyPolicy() {\n emit OwnershipPushed( _owner, address(0) );\n _owner = address(0);\n }\n\n function pushManagement( address newOwner_ ) public virtual override onlyPolicy() {\n require( newOwner_ != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipPushed( _owner, newOwner_ );\n _newOwner = newOwner_;\n }\n \n function pullManagement() public virtual override {\n require( msg.sender == _newOwner, \"Ownable: must be new owner to pull\");\n emit OwnershipPulled( _owner, _newOwner );\n _owner = _newOwner;\n }\n}\n\nlibrary SafeMath {\n\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n return c;\n }\n\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n\n function sqrrt(uint256 a) internal pure returns (uint c) {\n if (a > 3) {\n c = a;\n uint b = add( div( a, 2), 1 );\n while (b < c) {\n c = b;\n b = div( add( div( a, b ), b), 2 );\n }\n } else if (a != 0) {\n c = 1;\n }\n }\n}\n\nlibrary Address {\n\n function isContract(address account) internal view returns (bool) {\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return _functionCallWithValue(target, data, 0, errorMessage);\n }\n\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n if (returndata.length > 0) {\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n function addressToString(address _address) internal pure returns(string memory) {\n bytes32 _bytes = bytes32(uint256(_address));\n bytes memory HEX = \"0123456789abcdef\";\n bytes memory _addr = new bytes(42);\n\n _addr[0] = '0';\n _addr[1] = 'x';\n\n for(uint256 i = 0; i < 20; i++) {\n _addr[2+i*2] = HEX[uint8(_bytes[i + 12] >> 4)];\n _addr[3+i*2] = HEX[uint8(_bytes[i + 12] & 0x0f)];\n }\n\n return string(_addr);\n\n }\n}\n\ninterface IERC20 {\n function decimals() external view returns (uint8);\n\n function totalSupply() external view returns (uint256);\n\n function balanceOf(address account) external view returns (uint256);\n\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n function allowance(address owner, address spender) external view returns (uint256);\n\n function approve(address spender, uint256 amount) external returns (bool);\n\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n\nabstract contract ERC20 is IERC20 {\n\n using SafeMath for uint256;\n\n // TODO comment actual hash value.\n bytes32 constant private ERC20TOKEN_ERC1820_INTERFACE_ID = keccak256( \"ERC20Token\" );\n \n mapping (address => uint256) internal _balances;\n\n mapping (address => mapping (address => uint256)) internal _allowances;\n\n uint256 internal _totalSupply;\n\n string internal _name;\n \n string internal _symbol;\n \n uint8 internal _decimals;\n\n constructor (string memory name_, string memory symbol_, uint8 decimals_) {\n _name = name_;\n _symbol = symbol_;\n _decimals = decimals_;\n }\n\n function name() public view returns (string memory) {\n return _name;\n }\n\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimals;\n }\n\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(msg.sender, recipient, amount);\n return true;\n }\n\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(msg.sender, spender, amount);\n return true;\n }\n\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n function _mint(address account_, uint256 ammount_) internal virtual {\n require(account_ != address(0), \"ERC20: mint to the zero address\");\n _beforeTokenTransfer(address( this ), account_, ammount_);\n _totalSupply = _totalSupply.add(ammount_);\n _balances[account_] = _balances[account_].add(ammount_);\n emit Transfer(address( this ), account_, ammount_);\n }\n\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n function _beforeTokenTransfer( address from_, address to_, uint256 amount_ ) internal virtual { }\n}\n\ninterface IERC2612Permit {\n\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n function nonces(address owner) external view returns (uint256);\n}\n\nlibrary Counters {\n using SafeMath for uint256;\n\n struct Counter {\n\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n counter._value += 1;\n }\n\n function decrement(Counter storage counter) internal {\n counter._value = counter._value.sub(1);\n }\n}\n\nabstract contract ERC20Permit is ERC20, IERC2612Permit {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n\n bytes32 public DOMAIN_SEPARATOR;\n\n constructor() {\n uint256 chainID;\n assembly {\n chainID := chainid()\n }\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name())),\n keccak256(bytes(\"1\")), // Version\n chainID,\n address(this)\n )\n );\n }\n\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"Permit: expired deadline\");\n\n bytes32 hashStruct =\n keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, amount, _nonces[owner].current(), deadline));\n\n bytes32 _hash = keccak256(abi.encodePacked(uint16(0x1901), DOMAIN_SEPARATOR, hashStruct));\n\n address signer = ecrecover(_hash, v, r, s);\n require(signer != address(0) && signer == owner, \"ZeroSwapPermit: Invalid signature\");\n\n _nonces[owner].increment();\n _approve(owner, spender, amount);\n }\n\n function nonces(address owner) public view override returns (uint256) {\n return _nonces[owner].current();\n }\n}\n\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n\nlibrary FullMath {\n function fullMul(uint256 x, uint256 y) private pure returns (uint256 l, uint256 h) {\n uint256 mm = mulmod(x, y, uint256(-1));\n l = x * y;\n h = mm - l;\n if (mm < l) h -= 1;\n }\n\n function fullDiv(\n uint256 l,\n uint256 h,\n uint256 d\n ) private pure returns (uint256) {\n uint256 pow2 = d & -d;\n d /= pow2;\n l /= pow2;\n l += h * ((-pow2) / pow2 + 1);\n uint256 r = 1;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n return l * r;\n }\n\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 d\n ) internal pure returns (uint256) {\n (uint256 l, uint256 h) = fullMul(x, y);\n uint256 mm = mulmod(x, y, d);\n if (mm > l) h -= 1;\n l -= mm;\n require(h < d, 'FullMath::mulDiv: overflow');\n return fullDiv(l, h, d);\n }\n}\n\nlibrary FixedPoint {\n\n struct uq112x112 {\n uint224 _x;\n }\n\n struct uq144x112 {\n uint256 _x;\n }\n\n uint8 private constant RESOLUTION = 112;\n uint256 private constant Q112 = 0x10000000000000000000000000000;\n uint256 private constant Q224 = 0x100000000000000000000000000000000000000000000000000000000;\n uint256 private constant LOWER_MASK = 0xffffffffffffffffffffffffffff; // decimal of UQ*x112 (lower 112 bits)\n\n function decode(uq112x112 memory self) internal pure returns (uint112) {\n return uint112(self._x >> RESOLUTION);\n }\n\n function decode112with18(uq112x112 memory self) internal pure returns (uint) {\n\n return uint(self._x) / 5192296858534827;\n }\n\n function fraction(uint256 numerator, uint256 denominator) internal pure returns (uq112x112 memory) {\n require(denominator > 0, 'FixedPoint::fraction: division by zero');\n if (numerator == 0) return FixedPoint.uq112x112(0);\n\n if (numerator <= uint144(-1)) {\n uint256 result = (numerator << RESOLUTION) / denominator;\n require(result <= uint224(-1), 'FixedPoint::fraction: overflow');\n return uq112x112(uint224(result));\n } else {\n uint256 result = FullMath.mulDiv(numerator, Q112, denominator);\n require(result <= uint224(-1), 'FixedPoint::fraction: overflow');\n return uq112x112(uint224(result));\n }\n }\n}\n\ninterface AggregatorV3Interface {\n\n function decimals() external view returns (uint8);\n function description() external view returns (string memory);\n function version() external view returns (uint256);\n\n // getRoundData and latestRoundData should both raise \"No data present\"\n // if they do not have data to report, instead of returning unset values\n // which could be misinterpreted as actual reported values.\n function getRoundData(uint80 _roundId)\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n function latestRoundData()\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n}\n\ninterface ITreasury {\n function deposit( uint _amount, address _token, uint _profit ) external returns ( bool );\n function valueOf( address _token, uint _amount ) external view returns ( uint value_ );\n function mintRewards( address _recipient, uint _amount ) external;\n}\n\ninterface IStaking {\n function stake( uint _amount, address _recipient ) external returns ( bool );\n}\n\ninterface IStakingHelper {\n function stake( uint _amount, address _recipient ) external;\n}\n\ncontract OlympusBondDepository is Ownable {\n\n using FixedPoint for *;\n using SafeERC20 for IERC20;\n using SafeMath for uint;\n\n\n\n\n /* ======== EVENTS ======== */\n\n event BondCreated( uint deposit, uint indexed payout, uint indexed expires, uint indexed priceInUSD );\n event BondRedeemed( address indexed recipient, uint payout, uint remaining );\n event BondPriceChanged( uint indexed priceInUSD, uint indexed internalPrice, uint indexed debtRatio );\n event ControlVariableAdjustment( uint initialBCV, uint newBCV, uint adjustment, bool addition );\n\n\n\n\n /* ======== STATE VARIABLES ======== */\n\n address public immutable OHM; // token given as payment for bond\n address public immutable principle; // token used to create bond\n address public immutable treasury; // mints OHM when receives principle\n address public immutable DAO; // receives profit share from bond\n\n AggregatorV3Interface internal priceFeed;\n\n address public staking; // to auto-stake payout\n address public stakingHelper; // to stake and claim if no staking warmup\n bool public useHelper;\n\n Terms public terms; // stores terms for new bonds\n Adjust public adjustment; // stores adjustment to BCV data\n\n mapping( address => Bond ) public bondInfo; // stores bond information for depositors\n\n uint public totalDebt; // total value of outstanding bonds; used for pricing\n uint public lastDecay; // reference time for debt decay\n\n\n\n\n /* ======== STRUCTS ======== */\n\n // Info for creating new bonds\n struct Terms {\n uint controlVariable; // scaling variable for price\n uint vestingTerm; // in seconds\n uint minimumPrice; // vs principle value. 4 decimals (1500 = 0.15)\n uint maxPayout; // in thousandths of a %. i.e. 500 = 0.5%\n uint maxDebt; // 9 decimal debt ratio, max % total supply created as debt\n }\n\n // Info for bond holder\n struct Bond {\n uint payout; // OHM remaining to be paid\n uint vesting; // seconds left to vest\n uint lastTime; // Last interaction\n uint pricePaid; // In DAI, for front end viewing\n }\n\n // Info for incremental adjustments to control variable\n struct Adjust {\n bool add; // addition or subtraction\n uint rate; // increment\n uint target; // BCV when adjustment finished\n uint buffer; // minimum length (in seconds) between adjustments\n uint lastTime; // time when last adjustment made\n }\n\n\n\n\n /* ======== INITIALIZATION ======== */\n\n constructor ( \n address _OHM,\n address _principle,\n address _treasury, \n address _DAO,\n address _feed\n ) {\n require( _OHM != address(0) );\n OHM = _OHM;\n require( _principle != address(0) );\n principle = _principle;\n require( _treasury != address(0) );\n treasury = _treasury;\n require( _DAO != address(0) );\n DAO = _DAO;\n require( _feed != address(0) );\n priceFeed = AggregatorV3Interface( _feed );\n }\n\n /**\n * @notice initializes bond parameters\n * @param _controlVariable uint\n * @param _vestingTerm uint\n * @param _minimumPrice uint\n * @param _maxPayout uint\n * @param _maxDebt uint\n * @param _initialDebt uint\n */\n function initializeBondTerms( \n uint _controlVariable, \n uint _vestingTerm,\n uint _minimumPrice,\n uint _maxPayout,\n uint _maxDebt,\n uint _initialDebt\n ) external onlyPolicy() {\n require( currentDebt() == 0, \"Debt must be 0 for initialization\" );\n terms = Terms ({\n controlVariable: _controlVariable,\n vestingTerm: _vestingTerm,\n minimumPrice: _minimumPrice,\n maxPayout: _maxPayout,\n maxDebt: _maxDebt\n });\n totalDebt = _initialDebt;\n lastDecay = block.timestamp;\n }\n\n\n\n \n /* ======== POLICY FUNCTIONS ======== */\n\n enum PARAMETER { VESTING, PAYOUT, DEBT }\n /**\n * @notice set parameters for new bonds\n * @param _parameter PARAMETER\n * @param _input uint\n */\n function setBondTerms ( PARAMETER _parameter, uint _input ) external onlyPolicy() {\n if ( _parameter == PARAMETER.VESTING ) { // 0\n require( _input >= 129600, \"Vesting must be longer than 36 hours\" );\n terms.vestingTerm = _input;\n } else if ( _parameter == PARAMETER.PAYOUT ) { // 1\n require( _input <= 1000, \"Payout cannot be above 1 percent\" );\n terms.maxPayout = _input;\n } else if ( _parameter == PARAMETER.DEBT ) { // 3\n terms.maxDebt = _input;\n }\n }\n\n /**\n * @notice set control variable adjustment\n * @param _addition bool\n * @param _increment uint\n * @param _target uint\n * @param _buffer uint\n */\n function setAdjustment ( \n bool _addition,\n uint _increment, \n uint _target,\n uint _buffer \n ) external onlyPolicy() {\n require( _increment <= terms.controlVariable.mul( 25 ).div( 1000 ), \"Increment too large\" );\n\n adjustment = Adjust({\n add: _addition,\n rate: _increment,\n target: _target,\n buffer: _buffer,\n lastTime: block.timestamp\n });\n }\n\n /**\n * @notice set contract for auto stake\n * @param _staking address\n * @param _helper bool\n */\n function setStaking( address _staking, bool _helper ) external onlyPolicy() {\n require( _staking != address(0) );\n if ( _helper ) {\n useHelper = true;\n stakingHelper = _staking;\n } else {\n useHelper = false;\n staking = _staking;\n }\n }\n\n\n \n\n /* ======== USER FUNCTIONS ======== */\n\n /**\n * @notice deposit bond\n * @param _amount uint\n * @param _maxPrice uint\n * @param _depositor address\n * @return uint\n */\n function deposit( \n uint _amount, \n uint _maxPrice,\n address _depositor\n ) external returns ( uint ) {\n require( _depositor != address(0), \"Invalid address\" );\n\n decayDebt();\n require( totalDebt <= terms.maxDebt, \"Max capacity reached\" );\n \n uint priceInUSD = bondPriceInUSD(); // Stored in bond info\n uint nativePrice = _bondPrice();\n\n require( _maxPrice >= nativePrice, \"Slippage limit: more than max price\" ); // slippage protection\n\n uint value = ITreasury( treasury ).valueOf( principle, _amount );\n uint payout = payoutFor( value ); // payout to bonder is computed\n\n require( payout >= 10000000, \"Bond too small\" ); // must be > 0.01 OHM ( underflow protection )\n require( payout <= maxPayout(), \"Bond too large\"); // size protection because there is no slippage\n\n /**\n asset carries risk and is not minted against\n asset transfered to treasury and rewards minted as payout\n */\n IERC20( principle ).safeTransferFrom( msg.sender, treasury, _amount );\n ITreasury( treasury ).mintRewards( address(this), payout );\n \n // total debt is increased\n totalDebt = totalDebt.add( value ); \n \n // depositor info is stored\n bondInfo[ _depositor ] = Bond({ \n payout: bondInfo[ _depositor ].payout.add( payout ),\n vesting: terms.vestingTerm,\n lastTime: block.timestamp,\n pricePaid: priceInUSD\n });\n\n // indexed events are emitted\n emit BondCreated( _amount, payout, block.timestamp.add( terms.vestingTerm ), priceInUSD );\n emit BondPriceChanged( bondPriceInUSD(), _bondPrice(), debtRatio() );\n\n adjust(); // control variable is adjusted\n return payout; \n }\n\n /** \n * @notice redeem bond for user\n * @param _recipient address\n * @param _stake bool\n * @return uint\n */ \n function redeem( address _recipient, bool _stake ) external returns ( uint ) { \n Bond memory info = bondInfo[ _recipient ];\n uint percentVested = percentVestedFor( _recipient ); // (time since last interaction / vesting term remaining)\n\n if ( percentVested >= 10000 ) { // if fully vested\n delete bondInfo[ _recipient ]; // delete user info\n emit BondRedeemed( _recipient, info.payout, 0 ); // emit bond data\n return stakeOrSend( _recipient, _stake, info.payout ); // pay user everything due\n\n } else { // if unfinished\n // calculate payout vested\n uint payout = info.payout.mul( percentVested ).div( 10000 );\n\n // store updated deposit info\n bondInfo[ _recipient ] = Bond({\n payout: info.payout.sub( payout ),\n vesting: info.vesting.sub( block.timestamp.sub( info.lastTime ) ),\n lastTime: block.timestamp,\n pricePaid: info.pricePaid\n });\n\n emit BondRedeemed( _recipient, payout, bondInfo[ _recipient ].payout );\n return stakeOrSend( _recipient, _stake, payout );\n }\n }\n\n\n\n \n /* ======== INTERNAL HELPER FUNCTIONS ======== */\n\n /**\n * @notice allow user to stake payout automatically\n * @param _stake bool\n * @param _amount uint\n * @return uint\n */\n function stakeOrSend( address _recipient, bool _stake, uint _amount ) internal returns ( uint ) {\n if ( !_stake ) { // if user does not want to stake\n IERC20( OHM ).transfer( _recipient, _amount ); // send payout\n } else { // if user wants to stake\n if ( useHelper ) { // use if staking warmup is 0\n IERC20( OHM ).approve( stakingHelper, _amount );\n IStakingHelper( stakingHelper ).stake( _amount, _recipient );\n } else {\n IERC20( OHM ).approve( staking, _amount );\n IStaking( staking ).stake( _amount, _recipient );\n }\n }\n return _amount;\n }\n\n /**\n * @notice makes incremental adjustment to control variable\n */\n function adjust() internal {\n uint timeCanAdjust = adjustment.lastTime.add( adjustment.buffer );\n if( adjustment.rate != 0 && block.timestamp >= timeCanAdjust ) {\n uint initial = terms.controlVariable;\n if ( adjustment.add ) {\n terms.controlVariable = terms.controlVariable.add( adjustment.rate );\n if ( terms.controlVariable >= adjustment.target ) {\n adjustment.rate = 0;\n }\n } else {\n terms.controlVariable = terms.controlVariable.sub( adjustment.rate );\n if ( terms.controlVariable <= adjustment.target ) {\n adjustment.rate = 0;\n }\n }\n adjustment.lastTime = block.timestamp;\n emit ControlVariableAdjustment( initial, terms.controlVariable, adjustment.rate, adjustment.add );\n }\n }\n\n /**\n * @notice reduce total debt\n */\n function decayDebt() internal {\n totalDebt = totalDebt.sub( debtDecay() );\n lastDecay = block.timestamp;\n }\n\n\n\n\n /* ======== VIEW FUNCTIONS ======== */\n\n /**\n * @notice determine maximum bond size\n * @return uint\n */\n function maxPayout() public view returns ( uint ) {\n return IERC20( OHM ).totalSupply().mul( terms.maxPayout ).div( 100000 );\n }\n\n /**\n * @notice calculate interest due for new bond\n * @param _value uint\n * @return uint\n */\n function payoutFor( uint _value ) public view returns ( uint ) {\n return FixedPoint.fraction( _value, bondPrice() ).decode112with18().div( 1e14 );\n }\n\n\n /**\n * @notice calculate current bond premium\n * @return price_ uint\n */\n function bondPrice() public view returns ( uint price_ ) { \n price_ = terms.controlVariable.mul( debtRatio() ).div( 1e5 );\n if ( price_ < terms.minimumPrice ) {\n price_ = terms.minimumPrice;\n }\n }\n\n /**\n * @notice calculate current bond price and remove floor if above\n * @return price_ uint\n */\n function _bondPrice() internal returns ( uint price_ ) {\n price_ = terms.controlVariable.mul( debtRatio() ).div( 1e5 );\n if ( price_ < terms.minimumPrice ) {\n price_ = terms.minimumPrice; \n } else if ( terms.minimumPrice != 0 ) {\n terms.minimumPrice = 0;\n }\n }\n\n /**\n * @notice get asset price from chainlink\n */\n function assetPrice() public view returns (int) {\n ( , int price, , , ) = priceFeed.latestRoundData();\n return price;\n }\n\n /**\n * @notice converts bond price to DAI value\n * @return price_ uint\n */\n function bondPriceInUSD() public view returns ( uint price_ ) {\n price_ = bondPrice().mul( uint( assetPrice() ) ).mul( 1e6 );\n }\n\n\n /**\n * @notice calculate current ratio of debt to OHM supply\n * @return debtRatio_ uint\n */\n function debtRatio() public view returns ( uint debtRatio_ ) { \n uint supply = IERC20( OHM ).totalSupply();\n debtRatio_ = FixedPoint.fraction( \n currentDebt().mul( 1e9 ), \n supply\n ).decode112with18().div( 1e18 );\n }\n\n /**\n * @notice debt ratio in same terms as reserve bonds\n * @return uint\n */\n function standardizedDebtRatio() external view returns ( uint ) {\n return debtRatio().mul( uint( assetPrice() ) ).div( 1e8 ); // ETH feed is 8 decimals\n }\n\n /**\n * @notice calculate debt factoring in decay\n * @return uint\n */\n function currentDebt() public view returns ( uint ) {\n return totalDebt.sub( debtDecay() );\n }\n\n /**\n * @notice amount to decay total debt by\n * @return decay_ uint\n */\n function debtDecay() public view returns ( uint decay_ ) {\n uint timeSinceLast = block.timestamp.sub( lastDecay );\n decay_ = totalDebt.mul( timeSinceLast ).div( terms.vestingTerm );\n if ( decay_ > totalDebt ) {\n decay_ = totalDebt;\n }\n }\n\n\n /**\n * @notice calculate how far into vesting a depositor is\n * @param _depositor address\n * @return percentVested_ uint\n */\n function percentVestedFor( address _depositor ) public view returns ( uint percentVested_ ) {\n Bond memory bond = bondInfo[ _depositor ];\n uint timeSinceLast = block.timestamp.sub( bond.lastTime );\n uint vesting = bond.vesting;\n\n if ( vesting > 0 ) {\n percentVested_ = timeSinceLast.mul( 10000 ).div( vesting );\n } else {\n percentVested_ = 0;\n }\n }\n\n /**\n * @notice calculate amount of OHM available for claim by depositor\n * @param _depositor address\n * @return pendingPayout_ uint\n */\n function pendingPayoutFor( address _depositor ) external view returns ( uint pendingPayout_ ) {\n uint percentVested = percentVestedFor( _depositor );\n uint payout = bondInfo[ _depositor ].payout;\n\n if ( percentVested >= 10000 ) {\n pendingPayout_ = payout;\n } else {\n pendingPayout_ = payout.mul( percentVested ).div( 10000 );\n }\n }\n\n\n\n\n /* ======= AUXILLIARY ======= */\n\n /**\n * @notice allow anyone to send lost tokens (excluding principle or OHM) to the DAO\n * @return bool\n */\n function recoverLostToken( address _token ) external returns ( bool ) {\n require( _token != OHM );\n require( _token != principle );\n IERC20( _token ).safeTransfer( DAO, IERC20( _token ).balanceOf( address(this) ) );\n return true;\n }\n}" + } + }, + "settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/src/abi/rinkeby/solcInputs/80205d7caa85cf7d901b88f836b16309.json b/src/abi/rinkeby/solcInputs/80205d7caa85cf7d901b88f836b16309.json new file mode 100644 index 0000000000..e3ef73d67d --- /dev/null +++ b/src/abi/rinkeby/solcInputs/80205d7caa85cf7d901b88f836b16309.json @@ -0,0 +1,38 @@ +{ + "language": "Solidity", + "sources": { + "contracts/Staking.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity 0.7.5;\n\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n}\n\ninterface IERC20 {\n function decimals() external view returns (uint8);\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies in extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain`call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return _functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.3._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.3._\n */\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n function addressToString(address _address) internal pure returns(string memory) {\n bytes32 _bytes = bytes32(uint256(_address));\n bytes memory HEX = \"0123456789abcdef\";\n bytes memory _addr = new bytes(42);\n\n _addr[0] = '0';\n _addr[1] = 'x';\n\n for(uint256 i = 0; i < 20; i++) {\n _addr[2+i*2] = HEX[uint8(_bytes[i + 12] >> 4)];\n _addr[3+i*2] = HEX[uint8(_bytes[i + 12] & 0x0f)];\n }\n\n return string(_addr);\n\n }\n}\n\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n // solhint-disable-next-line max-line-length\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n\ninterface IOwnable {\n function manager() external view returns (address);\n\n function renounceManagement() external;\n \n function pushManagement( address newOwner_ ) external;\n \n function pullManagement() external;\n}\n\ncontract Ownable is IOwnable {\n\n address internal _owner;\n address internal _newOwner;\n\n event OwnershipPushed(address indexed previousOwner, address indexed newOwner);\n event OwnershipPulled(address indexed previousOwner, address indexed newOwner);\n\n constructor () {\n _owner = msg.sender;\n emit OwnershipPushed( address(0), _owner );\n }\n\n function manager() public view override returns (address) {\n return _owner;\n }\n\n modifier onlyManager() {\n require( _owner == msg.sender, \"Ownable: caller is not the owner\" );\n _;\n }\n\n function renounceManagement() public virtual override onlyManager() {\n emit OwnershipPushed( _owner, address(0) );\n _owner = address(0);\n }\n\n function pushManagement( address newOwner_ ) public virtual override onlyManager() {\n require( newOwner_ != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipPushed( _owner, newOwner_ );\n _newOwner = newOwner_;\n }\n \n function pullManagement() public virtual override {\n require( msg.sender == _newOwner, \"Ownable: must be new owner to pull\");\n emit OwnershipPulled( _owner, _newOwner );\n _owner = _newOwner;\n }\n}\n\ninterface IsOHM {\n function rebase( uint256 ohmProfit_, uint epoch_) external returns (uint256);\n\n function circulatingSupply() external view returns (uint256);\n\n function balanceOf(address who) external view returns (uint256);\n\n function gonsForBalance( uint amount ) external view returns ( uint );\n\n function balanceForGons( uint gons ) external view returns ( uint );\n \n function index() external view returns ( uint );\n}\n\ninterface IWarmup {\n function retrieve( address staker_, uint amount_ ) external;\n}\n\ninterface IDistributor {\n function distribute() external returns ( bool );\n}\n\ncontract OlympusStaking is Ownable {\n\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n address public immutable OHM;\n address public immutable sOHM;\n\n struct Epoch {\n uint length;\n uint number;\n uint endTime;\n uint distribute;\n }\n Epoch public epoch;\n\n address public distributor;\n\n address public locker;\n uint public totalBonus;\n\n address public warmupContract;\n uint public warmupPeriod;\n\n constructor (\n address _OHM,\n address _sOHM,\n uint _epochLength,\n uint _firstEpochNumber,\n uint _firstEpochTime\n ) {\n require( _OHM != address(0) );\n OHM = _OHM;\n require( _sOHM != address(0) );\n sOHM = _sOHM;\n\n epoch = Epoch({\n length: _epochLength,\n number: _firstEpochNumber,\n endTime: _firstEpochTime,\n distribute: 0\n });\n }\n\n struct Claim {\n uint deposit;\n uint gons;\n uint expiry;\n bool lock; // prevents malicious delays\n }\n mapping( address => Claim ) public warmupInfo;\n\n /**\n @notice stake OHM to enter warmup\n @param _amount uint\n @return bool\n */\n function stake( uint _amount, address _recipient ) external returns ( bool ) {\n rebase();\n \n IERC20( OHM ).safeTransferFrom( msg.sender, address(this), _amount );\n\n Claim memory info = warmupInfo[ _recipient ];\n require( !info.lock, \"Deposits for account are locked\" );\n\n warmupInfo[ _recipient ] = Claim ({\n deposit: info.deposit.add( _amount ),\n gons: info.gons.add( IsOHM( sOHM ).gonsForBalance( _amount ) ),\n expiry: epoch.number.add( warmupPeriod ),\n lock: false\n });\n \n IERC20( sOHM ).safeTransfer( warmupContract, _amount );\n return true;\n }\n\n /**\n @notice retrieve sOHM from warmup\n @param _recipient address\n */\n function claim ( address _recipient ) public {\n Claim memory info = warmupInfo[ _recipient ];\n if ( epoch.number >= info.expiry && info.expiry != 0 ) {\n delete warmupInfo[ _recipient ];\n IWarmup( warmupContract ).retrieve( _recipient, IsOHM( sOHM ).balanceForGons( info.gons ) );\n }\n }\n\n /**\n @notice forfeit sOHM in warmup and retrieve OHM\n */\n function forfeit() external {\n Claim memory info = warmupInfo[ msg.sender ];\n delete warmupInfo[ msg.sender ];\n\n IWarmup( warmupContract ).retrieve( address(this), IsOHM( sOHM ).balanceForGons( info.gons ) );\n IERC20( OHM ).safeTransfer( msg.sender, info.deposit );\n }\n\n /**\n @notice prevent new deposits to address (protection from malicious activity)\n */\n function toggleDepositLock() external {\n warmupInfo[ msg.sender ].lock = !warmupInfo[ msg.sender ].lock;\n }\n\n /**\n @notice redeem sOHM for OHM\n @param _amount uint\n @param _trigger bool\n */\n function unstake( uint _amount, bool _trigger ) external {\n if ( _trigger ) {\n rebase();\n }\n IERC20( sOHM ).safeTransferFrom( msg.sender, address(this), _amount );\n IERC20( OHM ).safeTransfer( msg.sender, _amount );\n }\n\n /**\n @notice returns the sOHM index, which tracks rebase growth\n @return uint\n */\n function index() public view returns ( uint ) {\n return IsOHM( sOHM ).index();\n }\n\n /**\n @notice trigger rebase if epoch over\n */\n function rebase() public {\n if( epoch.endTime <= block.timestamp ) {\n\n IsOHM( sOHM ).rebase( epoch.distribute, epoch.number );\n\n epoch.endTime = epoch.endTime.add( epoch.length );\n epoch.number++;\n\n if ( distributor != address(0) ) {\n IDistributor( distributor ).distribute();\n }\n\n uint balance = contractBalance();\n uint staked = IsOHM( sOHM ).circulatingSupply();\n\n if( balance <= staked ) {\n epoch.distribute = 0;\n } else {\n epoch.distribute = balance.sub( staked );\n }\n }\n }\n\n /**\n @notice returns contract OHM holdings, including bonuses provided\n @return uint\n */\n function contractBalance() public view returns ( uint ) {\n return IERC20( OHM ).balanceOf( address(this) ).add( totalBonus );\n }\n\n /**\n @notice provide bonus to locked staking contract\n @param _amount uint\n */\n function giveLockBonus( uint _amount ) external {\n require( msg.sender == locker );\n totalBonus = totalBonus.add( _amount );\n IERC20( sOHM ).safeTransfer( locker, _amount );\n }\n\n /**\n @notice reclaim bonus from locked staking contract\n @param _amount uint\n */\n function returnLockBonus( uint _amount ) external {\n require( msg.sender == locker );\n totalBonus = totalBonus.sub( _amount );\n IERC20( sOHM ).safeTransferFrom( locker, address(this), _amount );\n }\n\n enum CONTRACTS { DISTRIBUTOR, WARMUP, LOCKER }\n\n /**\n @notice sets the contract address for LP staking\n @param _contract address\n */\n function setContract( CONTRACTS _contract, address _address ) external onlyManager() {\n if( _contract == CONTRACTS.DISTRIBUTOR ) { // 0\n distributor = _address;\n } else if ( _contract == CONTRACTS.WARMUP ) { // 1\n require( warmupContract == address( 0 ), \"Warmup cannot be set more than once\" );\n warmupContract = _address;\n } else if ( _contract == CONTRACTS.LOCKER ) { // 2\n require( locker == address(0), \"Locker cannot be set more than once\" );\n locker = _address;\n }\n }\n \n /**\n * @notice set warmup period for new stakers\n * @param _warmupPeriod uint\n */\n function setWarmup( uint _warmupPeriod ) external onlyManager() {\n warmupPeriod = _warmupPeriod;\n }\n}" + }, + "contracts/StakingDistributor.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\n\npragma solidity 0.7.5;\n\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n\nlibrary SafeMath {\n\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n\n // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)\n function sqrrt(uint256 a) internal pure returns (uint c) {\n if (a > 3) {\n c = a;\n uint b = add( div( a, 2), 1 );\n while (b < c) {\n c = b;\n b = div( add( div( a, b ), b), 2 );\n }\n } else if (a != 0) {\n c = 1;\n }\n }\n\n function percentageAmount( uint256 total_, uint8 percentage_ ) internal pure returns ( uint256 percentAmount_ ) {\n return div( mul( total_, percentage_ ), 1000 );\n }\n\n function substractPercentage( uint256 total_, uint8 percentageToSub_ ) internal pure returns ( uint256 result_ ) {\n return sub( total_, div( mul( total_, percentageToSub_ ), 1000 ) );\n }\n\n function percentageOfTotal( uint256 part_, uint256 total_ ) internal pure returns ( uint256 percent_ ) {\n return div( mul(part_, 100) , total_ );\n }\n\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow, so we distribute\n return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);\n }\n\n function quadraticPricing( uint256 payment_, uint256 multiplier_ ) internal pure returns (uint256) {\n return sqrrt( mul( multiplier_, payment_ ) );\n }\n\n function bondingCurve( uint256 supply_, uint256 multiplier_ ) internal pure returns (uint256) {\n return mul( multiplier_, supply_ );\n }\n}\n\ninterface IERC20 {\n\n function totalSupply() external view returns (uint256);\n\n function balanceOf(address account) external view returns (uint256);\n\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n function allowance(address owner, address spender) external view returns (uint256);\n\n function approve(address spender, uint256 amount) external returns (bool);\n\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n\nlibrary Address {\n\n function isContract(address account) internal view returns (bool) {\n // This method relies in extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return _functionCallWithValue(target, data, 0, errorMessage);\n }\n\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n if (returndata.length > 0) {\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n function addressToString(address _address) internal pure returns(string memory) {\n bytes32 _bytes = bytes32(uint256(_address));\n bytes memory HEX = \"0123456789abcdef\";\n bytes memory _addr = new bytes(42);\n\n _addr[0] = '0';\n _addr[1] = 'x';\n\n for(uint256 i = 0; i < 20; i++) {\n _addr[2+i*2] = HEX[uint8(_bytes[i + 12] >> 4)];\n _addr[3+i*2] = HEX[uint8(_bytes[i + 12] & 0x0f)];\n }\n\n return string(_addr);\n\n }\n}\n\n\ninterface IPolicy {\n\n function policy() external view returns (address);\n\n function renouncePolicy() external;\n\n function pushPolicy( address newPolicy_ ) external;\n\n function pullPolicy() external;\n}\n\ncontract Policy is IPolicy {\n\n address internal _policy;\n address internal _newPolicy;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n constructor () {\n _policy = msg.sender;\n emit OwnershipTransferred( address(0), _policy );\n }\n\n function policy() public view override returns (address) {\n return _policy;\n }\n\n modifier onlyPolicy() {\n require( _policy == msg.sender, \"Ownable: caller is not the owner\" );\n _;\n }\n\n function renouncePolicy() public virtual override onlyPolicy() {\n emit OwnershipTransferred( _policy, address(0) );\n _policy = address(0);\n }\n\n function pushPolicy( address newPolicy_ ) public virtual override onlyPolicy() {\n require( newPolicy_ != address(0), \"Ownable: new owner is the zero address\");\n _newPolicy = newPolicy_;\n }\n\n function pullPolicy() public virtual override {\n require( msg.sender == _newPolicy );\n emit OwnershipTransferred( _policy, _newPolicy );\n _policy = _newPolicy;\n }\n}\n\ninterface ITreasury {\n function mintRewards( address _recipient, uint _amount ) external;\n}\n\ncontract Distributor is Policy {\n using SafeMath for uint;\n using SafeERC20 for IERC20;\n\n\n\n /* ====== VARIABLES ====== */\n\n address public immutable OHM;\n address public immutable treasury;\n\n uint public immutable epochLength;\n uint public nextEpochTime;\n\n mapping( uint => Adjust ) public adjustments;\n\n\n /* ====== STRUCTS ====== */\n\n struct Info {\n uint rate; // in ten-thousandths ( 5000 = 0.5% )\n address recipient;\n }\n Info[] public info;\n\n struct Adjust {\n bool add;\n uint rate;\n uint target;\n }\n\n\n\n /* ====== CONSTRUCTOR ====== */\n\n constructor( address _treasury, address _ohm, uint _epochLength, uint _nextEpochTime ) {\n require( _treasury != address(0) );\n treasury = _treasury;\n require( _ohm != address(0) );\n OHM = _ohm;\n epochLength = _epochLength;\n nextEpochTime = _nextEpochTime;\n }\n\n\n\n /* ====== PUBLIC FUNCTIONS ====== */\n\n /**\n @notice send epoch reward to staking contract\n */\n function distribute() external returns ( bool ) {\n if ( nextEpochTime <= block.timestamp ) {\n nextEpochTime = nextEpochTime.add( epochLength ); // set next epoch time\n\n // distribute rewards to each recipient\n for ( uint i = 0; i < info.length; i++ ) {\n if ( info[ i ].rate > 0 ) {\n ITreasury( treasury ).mintRewards( // mint and send from treasury\n info[ i ].recipient,\n nextRewardAt( info[ i ].rate )\n );\n adjust( i ); // check for adjustment\n }\n }\n return true;\n } else {\n return false;\n }\n }\n\n\n\n /* ====== INTERNAL FUNCTIONS ====== */\n\n /**\n @notice increment reward rate for collector\n */\n function adjust( uint _index ) internal {\n Adjust memory adjustment = adjustments[ _index ];\n if ( adjustment.rate != 0 ) {\n if ( adjustment.add ) { // if rate should increase\n info[ _index ].rate = info[ _index ].rate.add( adjustment.rate ); // raise rate\n if ( info[ _index ].rate >= adjustment.target ) { // if target met\n adjustments[ _index ].rate = 0; // turn off adjustment\n }\n } else { // if rate should decrease\n info[ _index ].rate = info[ _index ].rate.sub( adjustment.rate ); // lower rate\n if ( info[ _index ].rate <= adjustment.target ) { // if target met\n adjustments[ _index ].rate = 0; // turn off adjustment\n }\n }\n }\n }\n\n\n\n /* ====== VIEW FUNCTIONS ====== */\n\n /**\n @notice view function for next reward at given rate\n @param _rate uint\n @return uint\n */\n function nextRewardAt( uint _rate ) public view returns ( uint ) {\n return IERC20( OHM ).totalSupply().mul( _rate ).div( 1000000 );\n }\n\n /**\n @notice view function for next reward for specified address\n @param _recipient address\n @return uint\n */\n function nextRewardFor( address _recipient ) public view returns ( uint ) {\n uint reward;\n for ( uint i = 0; i < info.length; i++ ) {\n if ( info[ i ].recipient == _recipient ) {\n reward = nextRewardAt( info[ i ].rate );\n }\n }\n return reward;\n }\n\n\n\n /* ====== POLICY FUNCTIONS ====== */\n\n /**\n @notice adds recipient for distributions\n @param _recipient address\n @param _rewardRate uint\n */\n function addRecipient( address _recipient, uint _rewardRate ) external onlyPolicy() {\n require( _recipient != address(0) );\n info.push( Info({\n recipient: _recipient,\n rate: _rewardRate\n }));\n }\n\n /**\n @notice removes recipient for distributions\n @param _index uint\n @param _recipient address\n */\n function removeRecipient( uint _index, address _recipient ) external onlyPolicy() {\n require( _recipient == info[ _index ].recipient );\n info[ _index ].recipient = address(0);\n info[ _index ].rate = 0;\n }\n\n /**\n @notice set adjustment info for a collector's reward rate\n @param _index uint\n @param _add bool\n @param _rate uint\n @param _target uint\n */\n function setAdjustment( uint _index, bool _add, uint _rate, uint _target ) external onlyPolicy() {\n adjustments[ _index ] = Adjust({\n add: _add,\n rate: _rate,\n target: _target\n });\n }\n}" + } + }, + "settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/src/abi/rinkeby/solcInputs/8d3774b312edc15e04c44a56a82de7d8.json b/src/abi/rinkeby/solcInputs/8d3774b312edc15e04c44a56a82de7d8.json new file mode 100644 index 0000000000..3901fdb003 --- /dev/null +++ b/src/abi/rinkeby/solcInputs/8d3774b312edc15e04c44a56a82de7d8.json @@ -0,0 +1,83 @@ +{ + "language": "Solidity", + "sources": { + "contracts/BondDepository.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity 0.7.5;\n\ninterface IOwnable {\n function policy() external view returns (address);\n\n function renounceManagement() external;\n \n function pushManagement( address newOwner_ ) external;\n \n function pullManagement() external;\n}\n\ncontract Ownable is IOwnable {\n\n address internal _owner;\n address internal _newOwner;\n\n event OwnershipPushed(address indexed previousOwner, address indexed newOwner);\n event OwnershipPulled(address indexed previousOwner, address indexed newOwner);\n\n constructor () {\n _owner = msg.sender;\n emit OwnershipPushed( address(0), _owner );\n }\n\n function policy() public view override returns (address) {\n return _owner;\n }\n\n modifier onlyPolicy() {\n require( _owner == msg.sender, \"Ownable: caller is not the owner\" );\n _;\n }\n\n function renounceManagement() public virtual override onlyPolicy() {\n emit OwnershipPushed( _owner, address(0) );\n _owner = address(0);\n }\n\n function pushManagement( address newOwner_ ) public virtual override onlyPolicy() {\n require( newOwner_ != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipPushed( _owner, newOwner_ );\n _newOwner = newOwner_;\n }\n \n function pullManagement() public virtual override {\n require( msg.sender == _newOwner, \"Ownable: must be new owner to pull\");\n emit OwnershipPulled( _owner, _newOwner );\n _owner = _newOwner;\n }\n}\n\nlibrary SafeMath {\n\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n return c;\n }\n\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n\n function sqrrt(uint256 a) internal pure returns (uint c) {\n if (a > 3) {\n c = a;\n uint b = add( div( a, 2), 1 );\n while (b < c) {\n c = b;\n b = div( add( div( a, b ), b), 2 );\n }\n } else if (a != 0) {\n c = 1;\n }\n }\n}\n\nlibrary Address {\n\n function isContract(address account) internal view returns (bool) {\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return _functionCallWithValue(target, data, 0, errorMessage);\n }\n\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n if (returndata.length > 0) {\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n function addressToString(address _address) internal pure returns(string memory) {\n bytes32 _bytes = bytes32(uint256(_address));\n bytes memory HEX = \"0123456789abcdef\";\n bytes memory _addr = new bytes(42);\n\n _addr[0] = '0';\n _addr[1] = 'x';\n\n for(uint256 i = 0; i < 20; i++) {\n _addr[2+i*2] = HEX[uint8(_bytes[i + 12] >> 4)];\n _addr[3+i*2] = HEX[uint8(_bytes[i + 12] & 0x0f)];\n }\n\n return string(_addr);\n\n }\n}\n\ninterface IERC20 {\n function decimals() external view returns (uint8);\n\n function totalSupply() external view returns (uint256);\n\n function balanceOf(address account) external view returns (uint256);\n\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n function allowance(address owner, address spender) external view returns (uint256);\n\n function approve(address spender, uint256 amount) external returns (bool);\n\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n\nabstract contract ERC20 is IERC20 {\n\n using SafeMath for uint256;\n\n // TODO comment actual hash value.\n bytes32 constant private ERC20TOKEN_ERC1820_INTERFACE_ID = keccak256( \"ERC20Token\" );\n \n mapping (address => uint256) internal _balances;\n\n mapping (address => mapping (address => uint256)) internal _allowances;\n\n uint256 internal _totalSupply;\n\n string internal _name;\n \n string internal _symbol;\n \n uint8 internal _decimals;\n\n constructor (string memory name_, string memory symbol_, uint8 decimals_) {\n _name = name_;\n _symbol = symbol_;\n _decimals = decimals_;\n }\n\n function name() public view returns (string memory) {\n return _name;\n }\n\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimals;\n }\n\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(msg.sender, recipient, amount);\n return true;\n }\n\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(msg.sender, spender, amount);\n return true;\n }\n\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n function _mint(address account_, uint256 ammount_) internal virtual {\n require(account_ != address(0), \"ERC20: mint to the zero address\");\n _beforeTokenTransfer(address( this ), account_, ammount_);\n _totalSupply = _totalSupply.add(ammount_);\n _balances[account_] = _balances[account_].add(ammount_);\n emit Transfer(address( this ), account_, ammount_);\n }\n\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n function _beforeTokenTransfer( address from_, address to_, uint256 amount_ ) internal virtual { }\n}\n\ninterface IERC2612Permit {\n\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n function nonces(address owner) external view returns (uint256);\n}\n\nlibrary Counters {\n using SafeMath for uint256;\n\n struct Counter {\n\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n counter._value += 1;\n }\n\n function decrement(Counter storage counter) internal {\n counter._value = counter._value.sub(1);\n }\n}\n\nabstract contract ERC20Permit is ERC20, IERC2612Permit {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n\n bytes32 public DOMAIN_SEPARATOR;\n\n constructor() {\n uint256 chainID;\n assembly {\n chainID := chainid()\n }\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name())),\n keccak256(bytes(\"1\")), // Version\n chainID,\n address(this)\n )\n );\n }\n\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"Permit: expired deadline\");\n\n bytes32 hashStruct =\n keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, amount, _nonces[owner].current(), deadline));\n\n bytes32 _hash = keccak256(abi.encodePacked(uint16(0x1901), DOMAIN_SEPARATOR, hashStruct));\n\n address signer = ecrecover(_hash, v, r, s);\n require(signer != address(0) && signer == owner, \"ZeroSwapPermit: Invalid signature\");\n\n _nonces[owner].increment();\n _approve(owner, spender, amount);\n }\n\n function nonces(address owner) public view override returns (uint256) {\n return _nonces[owner].current();\n }\n}\n\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n\nlibrary FullMath {\n function fullMul(uint256 x, uint256 y) private pure returns (uint256 l, uint256 h) {\n uint256 mm = mulmod(x, y, uint256(-1));\n l = x * y;\n h = mm - l;\n if (mm < l) h -= 1;\n }\n\n function fullDiv(\n uint256 l,\n uint256 h,\n uint256 d\n ) private pure returns (uint256) {\n uint256 pow2 = d & -d;\n d /= pow2;\n l /= pow2;\n l += h * ((-pow2) / pow2 + 1);\n uint256 r = 1;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n return l * r;\n }\n\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 d\n ) internal pure returns (uint256) {\n (uint256 l, uint256 h) = fullMul(x, y);\n uint256 mm = mulmod(x, y, d);\n if (mm > l) h -= 1;\n l -= mm;\n require(h < d, 'FullMath::mulDiv: overflow');\n return fullDiv(l, h, d);\n }\n}\n\nlibrary FixedPoint {\n\n struct uq112x112 {\n uint224 _x;\n }\n\n struct uq144x112 {\n uint256 _x;\n }\n\n uint8 private constant RESOLUTION = 112;\n uint256 private constant Q112 = 0x10000000000000000000000000000;\n uint256 private constant Q224 = 0x100000000000000000000000000000000000000000000000000000000;\n uint256 private constant LOWER_MASK = 0xffffffffffffffffffffffffffff; // decimal of UQ*x112 (lower 112 bits)\n\n function decode(uq112x112 memory self) internal pure returns (uint112) {\n return uint112(self._x >> RESOLUTION);\n }\n\n function decode112with18(uq112x112 memory self) internal pure returns (uint) {\n\n return uint(self._x) / 5192296858534827;\n }\n\n function fraction(uint256 numerator, uint256 denominator) internal pure returns (uq112x112 memory) {\n require(denominator > 0, 'FixedPoint::fraction: division by zero');\n if (numerator == 0) return FixedPoint.uq112x112(0);\n\n if (numerator <= uint144(-1)) {\n uint256 result = (numerator << RESOLUTION) / denominator;\n require(result <= uint224(-1), 'FixedPoint::fraction: overflow');\n return uq112x112(uint224(result));\n } else {\n uint256 result = FullMath.mulDiv(numerator, Q112, denominator);\n require(result <= uint224(-1), 'FixedPoint::fraction: overflow');\n return uq112x112(uint224(result));\n }\n }\n}\n\ninterface ITreasury {\n function deposit( uint _amount, address _token, uint _profit ) external returns ( bool );\n function valueOf( address _token, uint _amount ) external view returns ( uint value_ );\n}\n\ninterface IBondCalculator {\n function valuation( address _LP, uint _amount ) external view returns ( uint );\n function markdown( address _LP ) external view returns ( uint );\n}\n\ninterface IStaking {\n function stake( uint _amount, address _recipient ) external returns ( bool );\n}\n\ninterface IStakingHelper {\n function stake( uint _amount, address _recipient ) external;\n}\n\ncontract OlympusBondDepository is Ownable {\n\n using FixedPoint for *;\n using SafeERC20 for IERC20;\n using SafeMath for uint;\n\n\n\n\n /* ======== EVENTS ======== */\n\n event BondCreated( uint deposit, uint indexed payout, uint indexed expires, uint indexed priceInUSD );\n event BondRedeemed( address indexed recipient, uint payout, uint remaining );\n event BondPriceChanged( uint indexed priceInUSD, uint indexed internalPrice, uint indexed debtRatio );\n event ControlVariableAdjustment( uint initialBCV, uint newBCV, uint adjustment, bool addition );\n\n\n\n\n /* ======== STATE VARIABLES ======== */\n\n address public immutable OHM; // token given as payment for bond\n address public immutable principle; // token used to create bond\n address public immutable treasury; // mints OHM when receives principle\n address public immutable DAO; // receives profit share from bond\n\n bool public immutable isLiquidityBond; // LP and Reserve bonds are treated slightly different\n address public immutable bondCalculator; // calculates value of LP tokens\n\n address public staking; // to auto-stake payout\n address public stakingHelper; // to stake and claim if no staking warmup\n bool public useHelper;\n\n Terms public terms; // stores terms for new bonds\n Adjust public adjustment; // stores adjustment to BCV data\n\n mapping( address => Bond ) public bondInfo; // stores bond information for depositors\n\n uint public totalDebt; // total value of outstanding bonds; used for pricing\n uint public lastDecay; // reference block for debt decay\n\n\n\n\n /* ======== STRUCTS ======== */\n\n // Info for creating new bonds\n struct Terms {\n uint controlVariable; // scaling variable for price\n uint vestingTerm; // in blocks\n uint minimumPrice; // vs principle value\n uint maxPayout; // in thousandths of a %. i.e. 500 = 0.5%\n uint fee; // as % of bond payout, in hundreths. ( 500 = 5% = 0.05 for every 1 paid)\n uint maxDebt; // 9 decimal debt ratio, max % total supply created as debt\n }\n\n // Info for bond holder\n struct Bond {\n uint payout; // OHM remaining to be paid\n uint vesting; // Blocks left to vest\n uint lastBlock; // Last interaction\n uint pricePaid; // In DAI, for front end viewing\n }\n\n // Info for incremental adjustments to control variable \n struct Adjust {\n bool add; // addition or subtraction\n uint rate; // increment\n uint target; // BCV when adjustment finished\n uint buffer; // minimum length (in blocks) between adjustments\n uint lastBlock; // block when last adjustment made\n }\n\n\n\n\n /* ======== INITIALIZATION ======== */\n\n constructor ( \n address _OHM,\n address _principle,\n address _treasury, \n address _DAO, \n address _bondCalculator\n ) {\n require( _OHM != address(0) );\n OHM = _OHM;\n require( _principle != address(0) );\n principle = _principle;\n require( _treasury != address(0) );\n treasury = _treasury;\n require( _DAO != address(0) );\n DAO = _DAO;\n // bondCalculator should be address(0) if not LP bond\n bondCalculator = _bondCalculator;\n isLiquidityBond = ( _bondCalculator != address(0) );\n }\n\n /**\n * @notice initializes bond parameters\n * @param _controlVariable uint\n * @param _vestingTerm uint\n * @param _minimumPrice uint\n * @param _maxPayout uint\n * @param _fee uint\n * @param _maxDebt uint\n * @param _initialDebt uint\n */\n function initializeBondTerms( \n uint _controlVariable, \n uint _vestingTerm,\n uint _minimumPrice,\n uint _maxPayout,\n uint _fee,\n uint _maxDebt,\n uint _initialDebt\n ) external onlyPolicy() {\n require( terms.controlVariable == 0, \"Bonds must be initialized from 0\" );\n terms = Terms ({\n controlVariable: _controlVariable,\n vestingTerm: _vestingTerm,\n minimumPrice: _minimumPrice,\n maxPayout: _maxPayout,\n fee: _fee,\n maxDebt: _maxDebt\n });\n totalDebt = _initialDebt;\n lastDecay = block.number;\n }\n\n\n\n \n /* ======== POLICY FUNCTIONS ======== */\n\n enum PARAMETER { VESTING, PAYOUT, FEE, DEBT }\n /**\n * @notice set parameters for new bonds\n * @param _parameter PARAMETER\n * @param _input uint\n */\n function setBondTerms ( PARAMETER _parameter, uint _input ) external onlyPolicy() {\n if ( _parameter == PARAMETER.VESTING ) { // 0\n require( _input >= 10000, \"Vesting must be longer than 36 hours\" );\n terms.vestingTerm = _input;\n } else if ( _parameter == PARAMETER.PAYOUT ) { // 1\n require( _input <= 1000, \"Payout cannot be above 1 percent\" );\n terms.maxPayout = _input;\n } else if ( _parameter == PARAMETER.FEE ) { // 2\n require( _input <= 10000, \"DAO fee cannot exceed payout\" );\n terms.fee = _input;\n } else if ( _parameter == PARAMETER.DEBT ) { // 3\n terms.maxDebt = _input;\n }\n }\n\n /**\n * @notice set control variable adjustment\n * @param _addition bool\n * @param _increment uint\n * @param _target uint\n * @param _buffer uint\n */\n function setAdjustment ( \n bool _addition,\n uint _increment, \n uint _target,\n uint _buffer \n ) external onlyPolicy() {\n require( _increment <= terms.controlVariable.mul( 25 ).div( 1000 ), \"Increment too large\" );\n\n adjustment = Adjust({\n add: _addition,\n rate: _increment,\n target: _target,\n buffer: _buffer,\n lastBlock: block.number\n });\n }\n\n /**\n * @notice set contract for auto stake\n * @param _staking address\n * @param _helper bool\n */\n function setStaking( address _staking, bool _helper ) external onlyPolicy() {\n require( _staking != address(0) );\n if ( _helper ) {\n useHelper = true;\n stakingHelper = _staking;\n } else {\n useHelper = false;\n staking = _staking;\n }\n }\n\n\n \n\n /* ======== USER FUNCTIONS ======== */\n\n /**\n * @notice deposit bond\n * @param _amount uint\n * @param _maxPrice uint\n * @param _depositor address\n * @return uint\n */\n function deposit( \n uint _amount, \n uint _maxPrice,\n address _depositor\n ) external returns ( uint ) {\n require( _depositor != address(0), \"Invalid address\" );\n\n decayDebt();\n require( totalDebt <= terms.maxDebt, \"Max capacity reached\" );\n \n uint priceInUSD = bondPriceInUSD(); // Stored in bond info\n uint nativePrice = _bondPrice();\n\n require( _maxPrice >= nativePrice, \"Slippage limit: more than max price\" ); // slippage protection\n\n uint value = ITreasury( treasury ).valueOf( principle, _amount );\n uint payout = payoutFor( value ); // payout to bonder is computed\n\n require( payout >= 10000000, \"Bond too small\" ); // must be > 0.01 OHM ( underflow protection )\n require( payout <= maxPayout(), \"Bond too large\"); // size protection because there is no slippage\n\n // profits are calculated\n uint fee = payout.mul( terms.fee ).div( 10000 );\n uint profit = value.sub( payout ).sub( fee );\n\n /**\n principle is transferred in\n approved and\n deposited into the treasury, returning (_amount - profit) OHM\n */\n IERC20( principle ).safeTransferFrom( msg.sender, address(this), _amount );\n IERC20( principle ).approve( address( treasury ), _amount );\n ITreasury( treasury ).deposit( _amount, principle, profit );\n \n if ( fee != 0 ) { // fee is transferred to dao \n IERC20( OHM ).safeTransfer( DAO, fee ); \n }\n \n // total debt is increased\n totalDebt = totalDebt.add( value ); \n \n // depositor info is stored\n bondInfo[ _depositor ] = Bond({ \n payout: bondInfo[ _depositor ].payout.add( payout ),\n vesting: terms.vestingTerm,\n lastBlock: block.number,\n pricePaid: priceInUSD\n });\n\n // indexed events are emitted\n emit BondCreated( _amount, payout, block.number.add( terms.vestingTerm ), priceInUSD );\n emit BondPriceChanged( bondPriceInUSD(), _bondPrice(), debtRatio() );\n\n adjust(); // control variable is adjusted\n return payout; \n }\n\n /** \n * @notice redeem bond for user\n * @param _recipient address\n * @param _stake bool\n * @return uint\n */ \n function redeem( address _recipient, bool _stake ) external returns ( uint ) { \n Bond memory info = bondInfo[ _recipient ];\n uint percentVested = percentVestedFor( _recipient ); // (blocks since last interaction / vesting term remaining)\n\n if ( percentVested >= 10000 ) { // if fully vested\n delete bondInfo[ _recipient ]; // delete user info\n emit BondRedeemed( _recipient, info.payout, 0 ); // emit bond data\n return stakeOrSend( _recipient, _stake, info.payout ); // pay user everything due\n\n } else { // if unfinished\n // calculate payout vested\n uint payout = info.payout.mul( percentVested ).div( 10000 );\n\n // store updated deposit info\n bondInfo[ _recipient ] = Bond({\n payout: info.payout.sub( payout ),\n vesting: info.vesting.sub( block.number.sub( info.lastBlock ) ),\n lastBlock: block.number,\n pricePaid: info.pricePaid\n });\n\n emit BondRedeemed( _recipient, payout, bondInfo[ _recipient ].payout );\n return stakeOrSend( _recipient, _stake, payout );\n }\n }\n\n\n\n \n /* ======== INTERNAL HELPER FUNCTIONS ======== */\n\n /**\n * @notice allow user to stake payout automatically\n * @param _stake bool\n * @param _amount uint\n * @return uint\n */\n function stakeOrSend( address _recipient, bool _stake, uint _amount ) internal returns ( uint ) {\n if ( !_stake ) { // if user does not want to stake\n IERC20( OHM ).transfer( _recipient, _amount ); // send payout\n } else { // if user wants to stake\n if ( useHelper ) { // use if staking warmup is 0\n IERC20( OHM ).approve( stakingHelper, _amount );\n IStakingHelper( stakingHelper ).stake( _amount, _recipient );\n } else {\n IERC20( OHM ).approve( staking, _amount );\n IStaking( staking ).stake( _amount, _recipient );\n }\n }\n return _amount;\n }\n\n /**\n * @notice makes incremental adjustment to control variable\n */\n function adjust() internal {\n uint blockCanAdjust = adjustment.lastBlock.add( adjustment.buffer );\n if( adjustment.rate != 0 && block.number >= blockCanAdjust ) {\n uint initial = terms.controlVariable;\n if ( adjustment.add ) {\n terms.controlVariable = terms.controlVariable.add( adjustment.rate );\n if ( terms.controlVariable >= adjustment.target ) {\n adjustment.rate = 0;\n }\n } else {\n terms.controlVariable = terms.controlVariable.sub( adjustment.rate );\n if ( terms.controlVariable <= adjustment.target ) {\n adjustment.rate = 0;\n }\n }\n adjustment.lastBlock = block.number;\n emit ControlVariableAdjustment( initial, terms.controlVariable, adjustment.rate, adjustment.add );\n }\n }\n\n /**\n * @notice reduce total debt\n */\n function decayDebt() internal {\n totalDebt = totalDebt.sub( debtDecay() );\n lastDecay = block.number;\n }\n\n\n\n\n /* ======== VIEW FUNCTIONS ======== */\n\n /**\n * @notice determine maximum bond size\n * @return uint\n */\n function maxPayout() public view returns ( uint ) {\n return IERC20( OHM ).totalSupply().mul( terms.maxPayout ).div( 100000 );\n }\n\n /**\n * @notice calculate interest due for new bond\n * @param _value uint\n * @return uint\n */\n function payoutFor( uint _value ) public view returns ( uint ) {\n return FixedPoint.fraction( _value, bondPrice() ).decode112with18().div( 1e16 );\n }\n\n\n /**\n * @notice calculate current bond premium\n * @return price_ uint\n */\n function bondPrice() public view returns ( uint price_ ) { \n price_ = terms.controlVariable.mul( debtRatio() ).add( 1000000000 ).div( 1e7 );\n if ( price_ < terms.minimumPrice ) {\n price_ = terms.minimumPrice;\n }\n }\n\n /**\n * @notice calculate current bond price and remove floor if above\n * @return price_ uint\n */\n function _bondPrice() internal returns ( uint price_ ) {\n price_ = terms.controlVariable.mul( debtRatio() ).add( 1000000000 ).div( 1e7 );\n if ( price_ < terms.minimumPrice ) {\n price_ = terms.minimumPrice; \n } else if ( terms.minimumPrice != 0 ) {\n terms.minimumPrice = 0;\n }\n }\n\n /**\n * @notice converts bond price to DAI value\n * @return price_ uint\n */\n function bondPriceInUSD() public view returns ( uint price_ ) {\n if( isLiquidityBond ) {\n price_ = bondPrice().mul( IBondCalculator( bondCalculator ).markdown( principle ) ).div( 100 );\n } else {\n price_ = bondPrice().mul( 10 ** IERC20( principle ).decimals() ).div( 100 );\n }\n }\n\n\n /**\n * @notice calculate current ratio of debt to OHM supply\n * @return debtRatio_ uint\n */\n function debtRatio() public view returns ( uint debtRatio_ ) { \n uint supply = IERC20( OHM ).totalSupply();\n debtRatio_ = FixedPoint.fraction( \n currentDebt().mul( 1e9 ), \n supply\n ).decode112with18().div( 1e18 );\n }\n\n /**\n * @notice debt ratio in same terms for reserve or liquidity bonds\n * @return uint\n */\n function standardizedDebtRatio() external view returns ( uint ) {\n if ( isLiquidityBond ) {\n return debtRatio().mul( IBondCalculator( bondCalculator ).markdown( principle ) ).div( 1e9 );\n } else {\n return debtRatio();\n }\n }\n\n /**\n * @notice calculate debt factoring in decay\n * @return uint\n */\n function currentDebt() public view returns ( uint ) {\n return totalDebt.sub( debtDecay() );\n }\n\n /**\n * @notice amount to decay total debt by\n * @return decay_ uint\n */\n function debtDecay() public view returns ( uint decay_ ) {\n uint blocksSinceLast = block.number.sub( lastDecay );\n decay_ = totalDebt.mul( blocksSinceLast ).div( terms.vestingTerm );\n if ( decay_ > totalDebt ) {\n decay_ = totalDebt;\n }\n }\n\n\n /**\n * @notice calculate how far into vesting a depositor is\n * @param _depositor address\n * @return percentVested_ uint\n */\n function percentVestedFor( address _depositor ) public view returns ( uint percentVested_ ) {\n Bond memory bond = bondInfo[ _depositor ];\n uint blocksSinceLast = block.number.sub( bond.lastBlock );\n uint vesting = bond.vesting;\n\n if ( vesting > 0 ) {\n percentVested_ = blocksSinceLast.mul( 10000 ).div( vesting );\n } else {\n percentVested_ = 0;\n }\n }\n\n /**\n * @notice calculate amount of OHM available for claim by depositor\n * @param _depositor address\n * @return pendingPayout_ uint\n */\n function pendingPayoutFor( address _depositor ) external view returns ( uint pendingPayout_ ) {\n uint percentVested = percentVestedFor( _depositor );\n uint payout = bondInfo[ _depositor ].payout;\n\n if ( percentVested >= 10000 ) {\n pendingPayout_ = payout;\n } else {\n pendingPayout_ = payout.mul( percentVested ).div( 10000 );\n }\n }\n\n\n\n\n /* ======= AUXILLIARY ======= */\n\n /**\n * @notice allow anyone to send lost tokens (excluding principle or OHM) to the DAO\n * @return bool\n */\n function recoverLostToken( address _token ) external returns ( bool ) {\n require( _token != OHM );\n require( _token != principle );\n IERC20( _token ).safeTransfer( DAO, IERC20( _token ).balanceOf( address(this) ) );\n return true;\n }\n}" + }, + "contracts/CVXBondDepository.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity 0.7.5;\n\ninterface IOwnable {\n function policy() external view returns (address);\n\n function renounceManagement() external;\n \n function pushManagement( address newOwner_ ) external;\n \n function pullManagement() external;\n}\n\ncontract Ownable is IOwnable {\n\n address internal _owner;\n address internal _newOwner;\n\n event OwnershipPushed(address indexed previousOwner, address indexed newOwner);\n event OwnershipPulled(address indexed previousOwner, address indexed newOwner);\n\n constructor () {\n _owner = msg.sender;\n emit OwnershipPushed( address(0), _owner );\n }\n\n function policy() public view override returns (address) {\n return _owner;\n }\n\n modifier onlyPolicy() {\n require( _owner == msg.sender, \"Ownable: caller is not the owner\" );\n _;\n }\n\n function renounceManagement() public virtual override onlyPolicy() {\n emit OwnershipPushed( _owner, address(0) );\n _owner = address(0);\n }\n\n function pushManagement( address newOwner_ ) public virtual override onlyPolicy() {\n require( newOwner_ != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipPushed( _owner, newOwner_ );\n _newOwner = newOwner_;\n }\n \n function pullManagement() public virtual override {\n require( msg.sender == _newOwner, \"Ownable: must be new owner to pull\");\n emit OwnershipPulled( _owner, _newOwner );\n _owner = _newOwner;\n }\n}\n\nlibrary SafeMath {\n\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n return c;\n }\n\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n\n function sqrrt(uint256 a) internal pure returns (uint c) {\n if (a > 3) {\n c = a;\n uint b = add( div( a, 2), 1 );\n while (b < c) {\n c = b;\n b = div( add( div( a, b ), b), 2 );\n }\n } else if (a != 0) {\n c = 1;\n }\n }\n}\n\nlibrary Address {\n\n function isContract(address account) internal view returns (bool) {\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return _functionCallWithValue(target, data, 0, errorMessage);\n }\n\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n if (returndata.length > 0) {\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n function addressToString(address _address) internal pure returns(string memory) {\n bytes32 _bytes = bytes32(uint256(_address));\n bytes memory HEX = \"0123456789abcdef\";\n bytes memory _addr = new bytes(42);\n\n _addr[0] = '0';\n _addr[1] = 'x';\n\n for(uint256 i = 0; i < 20; i++) {\n _addr[2+i*2] = HEX[uint8(_bytes[i + 12] >> 4)];\n _addr[3+i*2] = HEX[uint8(_bytes[i + 12] & 0x0f)];\n }\n\n return string(_addr);\n\n }\n}\n\ninterface IERC20 {\n function decimals() external view returns (uint8);\n\n function totalSupply() external view returns (uint256);\n\n function balanceOf(address account) external view returns (uint256);\n\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n function allowance(address owner, address spender) external view returns (uint256);\n\n function approve(address spender, uint256 amount) external returns (bool);\n\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n\nlibrary FullMath {\n function fullMul(uint256 x, uint256 y) private pure returns (uint256 l, uint256 h) {\n uint256 mm = mulmod(x, y, uint256(-1));\n l = x * y;\n h = mm - l;\n if (mm < l) h -= 1;\n }\n\n function fullDiv(\n uint256 l,\n uint256 h,\n uint256 d\n ) private pure returns (uint256) {\n uint256 pow2 = d & -d;\n d /= pow2;\n l /= pow2;\n l += h * ((-pow2) / pow2 + 1);\n uint256 r = 1;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n return l * r;\n }\n\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 d\n ) internal pure returns (uint256) {\n (uint256 l, uint256 h) = fullMul(x, y);\n uint256 mm = mulmod(x, y, d);\n if (mm > l) h -= 1;\n l -= mm;\n require(h < d, 'FullMath::mulDiv: overflow');\n return fullDiv(l, h, d);\n }\n}\n\nlibrary FixedPoint {\n\n struct uq112x112 {\n uint224 _x;\n }\n\n struct uq144x112 {\n uint256 _x;\n }\n\n uint8 private constant RESOLUTION = 112;\n uint256 private constant Q112 = 0x10000000000000000000000000000;\n uint256 private constant Q224 = 0x100000000000000000000000000000000000000000000000000000000;\n uint256 private constant LOWER_MASK = 0xffffffffffffffffffffffffffff; // decimal of UQ*x112 (lower 112 bits)\n\n function decode(uq112x112 memory self) internal pure returns (uint112) {\n return uint112(self._x >> RESOLUTION);\n }\n\n function decode112with18(uq112x112 memory self) internal pure returns (uint) {\n\n return uint(self._x) / 5192296858534827;\n }\n\n function fraction(uint256 numerator, uint256 denominator) internal pure returns (uq112x112 memory) {\n require(denominator > 0, 'FixedPoint::fraction: division by zero');\n if (numerator == 0) return FixedPoint.uq112x112(0);\n\n if (numerator <= uint144(-1)) {\n uint256 result = (numerator << RESOLUTION) / denominator;\n require(result <= uint224(-1), 'FixedPoint::fraction: overflow');\n return uq112x112(uint224(result));\n } else {\n uint256 result = FullMath.mulDiv(numerator, Q112, denominator);\n require(result <= uint224(-1), 'FixedPoint::fraction: overflow');\n return uq112x112(uint224(result));\n }\n }\n}\n\ninterface ITreasury {\n function deposit( uint _amount, address _token, uint _profit ) external returns ( bool );\n function valueOf( address _token, uint _amount ) external view returns ( uint value_ );\n function mintRewards( address _recipient, uint _amount ) external;\n}\n\ninterface IStaking {\n function stake( uint _amount, address _recipient ) external returns ( bool );\n}\n\ninterface IStakingHelper {\n function stake( uint _amount, address _recipient ) external;\n}\n\ncontract OlympusCVXBondDepository is Ownable {\n\n using FixedPoint for *;\n using SafeERC20 for IERC20;\n using SafeMath for uint;\n\n /* ======== EVENTS ======== */\n\n event BondCreated( uint deposit, uint indexed payout, uint indexed expires, uint indexed priceInUSD );\n event BondRedeemed( address indexed recipient, uint payout, uint remaining );\n event BondPriceChanged( uint indexed internalPrice, uint indexed debtRatio );\n event ControlVariableAdjustment( uint initialBCV, uint newBCV, uint adjustment, bool addition );\n\n\n /* ======== STATE VARIABLES ======== */\n\n address public immutable OHM; // token given as payment for bond\n address public immutable principal; // token used to create bond\n address public immutable treasury; // mints OHM when receives principal\n address public immutable DAO; // receives profit share from bond\n\n address public staking; // to auto-stake payout\n address public stakingHelper; // to stake and claim if no staking warmup\n bool public useHelper;\n\n Terms public terms; // stores terms for new bonds\n Adjust public adjustment; // stores adjustment to BCV data\n\n mapping( address => Bond ) public bondInfo; // stores bond information for depositors\n\n uint public totalDebt; // total value of outstanding bonds; used for pricing\n uint public lastDecay; // reference block for debt decay\n \n\n /* ======== STRUCTS ======== */\n\n // Info for creating new bonds\n struct Terms {\n uint controlVariable; // scaling variable for price\n uint vestingTerm; // in blocks\n uint minimumPrice; // vs principal value. 4 decimals (1500 = 0.15)\n uint maxPayout; // in thousandths of a %. i.e. 500 = 0.5%\n uint maxDebt; // 9 decimal debt ratio, max % total supply created as debt\n }\n\n // Info for bond holder\n struct Bond {\n uint payout; // OHM remaining to be paid\n uint vesting; // Blocks left to vest\n uint lastBlock; // Last interaction\n uint pricePaid; // In DAI, for front end viewing\n }\n\n // Info for incremental adjustments to control variable \n struct Adjust {\n bool add; // addition or subtraction\n uint rate; // increment\n uint target; // BCV when adjustment finished\n uint buffer; // minimum length (in blocks) between adjustments\n uint lastBlock; // block when last adjustment made\n }\n\n\n /* ======== INITIALIZATION ======== */\n\n constructor ( \n address _OHM,\n address _principal,\n address _treasury, \n address _DAO\n ) {\n require( _OHM != address(0) );\n OHM = _OHM;\n require( _principal != address(0) );\n principal = _principal;\n require( _treasury != address(0) );\n treasury = _treasury;\n require( _DAO != address(0) );\n DAO = _DAO;\n }\n\n /**\n * @notice initializes bond parameters\n * @param _controlVariable uint\n * @param _vestingTerm uint\n * @param _minimumPrice uint\n * @param _maxPayout uint\n * @param _maxDebt uint\n * @param _initialDebt uint\n */\n function initializeBondTerms( \n uint _controlVariable, \n uint _vestingTerm,\n uint _minimumPrice,\n uint _maxPayout,\n uint _maxDebt,\n uint _initialDebt\n ) external onlyPolicy() {\n require( currentDebt() == 0, \"Debt must be 0 for initialization\" );\n terms = Terms ({\n controlVariable: _controlVariable,\n vestingTerm: _vestingTerm,\n minimumPrice: _minimumPrice,\n maxPayout: _maxPayout,\n maxDebt: _maxDebt\n });\n totalDebt = _initialDebt;\n lastDecay = block.number;\n }\n\n\n\n \n /* ======== POLICY FUNCTIONS ======== */\n\n enum PARAMETER { VESTING, PAYOUT, DEBT }\n /**\n * @notice set parameters for new bonds\n * @param _parameter PARAMETER\n * @param _input uint\n */\n function setBondTerms ( PARAMETER _parameter, uint _input ) external onlyPolicy() {\n if ( _parameter == PARAMETER.VESTING ) { // 0\n require( _input >= 10000, \"Vesting must be longer than 36 hours\" );\n terms.vestingTerm = _input;\n } else if ( _parameter == PARAMETER.PAYOUT ) { // 1\n require( _input <= 1000, \"Payout cannot be above 1 percent\" );\n terms.maxPayout = _input;\n } else if ( _parameter == PARAMETER.DEBT ) { // 3\n terms.maxDebt = _input;\n }\n }\n\n /**\n * @notice set control variable adjustment\n * @param _addition bool\n * @param _increment uint\n * @param _target uint\n * @param _buffer uint\n */\n function setAdjustment ( \n bool _addition,\n uint _increment, \n uint _target,\n uint _buffer \n ) external onlyPolicy() {\n require( _increment <= terms.controlVariable.mul( 25 ).div( 1000 ), \"Increment too large\" );\n\n adjustment = Adjust({\n add: _addition,\n rate: _increment,\n target: _target,\n buffer: _buffer,\n lastBlock: block.number\n });\n }\n\n /**\n * @notice set contract for auto stake\n * @param _staking address\n * @param _helper bool\n */\n function setStaking( address _staking, bool _helper ) external onlyPolicy() {\n require( _staking != address(0) );\n if ( _helper ) {\n useHelper = true;\n stakingHelper = _staking;\n } else {\n useHelper = false;\n staking = _staking;\n }\n }\n\n\n \n\n /* ======== USER FUNCTIONS ======== */\n\n /**\n * @notice deposit bond\n * @param _amount uint\n * @param _maxPrice uint\n * @param _depositor address\n * @return uint\n */\n function deposit( \n uint _amount, \n uint _maxPrice,\n address _depositor\n ) external returns ( uint ) {\n require( _depositor != address(0), \"Invalid address\" );\n\n decayDebt();\n require( totalDebt <= terms.maxDebt, \"Max capacity reached\" );\n \n uint nativePrice = _bondPrice();\n\n require( _maxPrice >= nativePrice, \"Slippage limit: more than max price\" ); // slippage protection\n\n uint value = ITreasury( treasury ).valueOf( principal, _amount );\n uint payout = payoutFor( value ); // payout to bonder is computed\n\n require( payout >= 10000000, \"Bond too small\" ); // must be > 0.01 OHM ( underflow protection )\n require( payout <= maxPayout(), \"Bond too large\"); // size protection because there is no slippage\n\n /**\n asset carries risk and is not minted against\n asset transfered to treasury and rewards minted as payout\n */\n IERC20( principal ).safeTransferFrom( msg.sender, treasury, _amount );\n ITreasury( treasury ).mintRewards( address(this), payout );\n \n // total debt is increased\n totalDebt = totalDebt.add( value ); \n \n // depositor info is stored\n bondInfo[ _depositor ] = Bond({ \n payout: bondInfo[ _depositor ].payout.add( payout ),\n vesting: terms.vestingTerm,\n lastBlock: block.number,\n pricePaid: nativePrice\n });\n\n // indexed events are emitted\n emit BondCreated( _amount, payout, block.number.add( terms.vestingTerm ), nativePrice );\n emit BondPriceChanged( _bondPrice(), debtRatio() );\n\n adjust(); // control variable is adjusted\n return payout; \n }\n\n /** \n * @notice redeem bond for user\n * @param _recipient address\n * @param _stake bool\n * @return uint\n */ \n function redeem( address _recipient, bool _stake ) external returns ( uint ) { \n Bond memory info = bondInfo[ _recipient ];\n uint percentVested = percentVestedFor( _recipient ); // (blocks since last interaction / vesting term remaining)\n\n if ( percentVested >= 10000 ) { // if fully vested\n delete bondInfo[ _recipient ]; // delete user info\n emit BondRedeemed( _recipient, info.payout, 0 ); // emit bond data\n return stakeOrSend( _recipient, _stake, info.payout ); // pay user everything due\n\n } else { // if unfinished\n // calculate payout vested\n uint payout = info.payout.mul( percentVested ).div( 10000 );\n\n // store updated deposit info\n bondInfo[ _recipient ] = Bond({\n payout: info.payout.sub( payout ),\n vesting: info.vesting.sub( block.number.sub( info.lastBlock ) ),\n lastBlock: block.number,\n pricePaid: info.pricePaid\n });\n\n emit BondRedeemed( _recipient, payout, bondInfo[ _recipient ].payout );\n return stakeOrSend( _recipient, _stake, payout );\n }\n }\n\n\n\n \n /* ======== INTERNAL HELPER FUNCTIONS ======== */\n\n /**\n * @notice allow user to stake payout automatically\n * @param _stake bool\n * @param _amount uint\n * @return uint\n */\n function stakeOrSend( address _recipient, bool _stake, uint _amount ) internal returns ( uint ) {\n if ( !_stake ) { // if user does not want to stake\n IERC20( OHM ).safeTransfer( _recipient, _amount ); // send payout\n } else { // if user wants to stake\n if ( useHelper ) { // use if staking warmup is 0\n IERC20( OHM ).approve( stakingHelper, _amount );\n IStakingHelper( stakingHelper ).stake( _amount, _recipient );\n } else {\n IERC20( OHM ).approve( staking, _amount );\n IStaking( staking ).stake( _amount, _recipient );\n }\n }\n return _amount;\n }\n\n /**\n * @notice makes incremental adjustment to control variable\n */\n function adjust() internal {\n uint blockCanAdjust = adjustment.lastBlock.add( adjustment.buffer );\n if( adjustment.rate != 0 && block.number >= blockCanAdjust ) {\n uint initial = terms.controlVariable;\n if ( adjustment.add ) {\n terms.controlVariable = terms.controlVariable.add( adjustment.rate );\n if ( terms.controlVariable >= adjustment.target ) {\n adjustment.rate = 0;\n }\n } else {\n terms.controlVariable = terms.controlVariable.sub( adjustment.rate );\n if ( terms.controlVariable <= adjustment.target ) {\n adjustment.rate = 0;\n }\n }\n adjustment.lastBlock = block.number;\n emit ControlVariableAdjustment( initial, terms.controlVariable, adjustment.rate, adjustment.add );\n }\n }\n\n /**\n * @notice reduce total debt\n */\n function decayDebt() internal {\n totalDebt = totalDebt.sub( debtDecay() );\n lastDecay = block.number;\n }\n\n\n\n\n /* ======== VIEW FUNCTIONS ======== */\n\n /**\n * @notice determine maximum bond size\n * @return uint\n */\n function maxPayout() public view returns ( uint ) {\n return IERC20( OHM ).totalSupply().mul( terms.maxPayout ).div( 100000 );\n }\n\n /**\n * @notice calculate interest due for new bond\n * @param _value uint\n * @return uint\n */\n function payoutFor( uint _value ) public view returns ( uint ) {\n return FixedPoint.fraction( _value, bondPrice() ).decode112with18().div( 1e14 );\n }\n\n\n /**\n * @notice calculate current bond premium\n * @return price_ uint\n */\n function bondPrice() public view returns ( uint price_ ) { \n price_ = terms.controlVariable.mul( debtRatio() ).div( 1e5 );\n if ( price_ < terms.minimumPrice ) {\n price_ = terms.minimumPrice;\n }\n }\n\n /**\n * @notice calculate current bond price and remove floor if above\n * @return price_ uint\n */\n function _bondPrice() internal returns ( uint price_ ) {\n price_ = terms.controlVariable.mul( debtRatio() ).div( 1e5 );\n if ( price_ < terms.minimumPrice ) {\n price_ = terms.minimumPrice; \n } else if ( terms.minimumPrice != 0 ) {\n terms.minimumPrice = 0;\n }\n }\n\n /**\n * @notice calculate current ratio of debt to OHM supply\n * @return debtRatio_ uint\n */\n function debtRatio() public view returns ( uint debtRatio_ ) { \n uint supply = IERC20( OHM ).totalSupply();\n debtRatio_ = FixedPoint.fraction( \n currentDebt().mul( 1e9 ), \n supply\n ).decode112with18().div( 1e18 );\n }\n\n /**\n * @notice calculate debt factoring in decay\n * @return uint\n */\n function currentDebt() public view returns ( uint ) {\n return totalDebt.sub( debtDecay() );\n }\n\n /**\n * @notice amount to decay total debt by\n * @return decay_ uint\n */\n function debtDecay() public view returns ( uint decay_ ) {\n uint blocksSinceLast = block.number.sub( lastDecay );\n decay_ = totalDebt.mul( blocksSinceLast ).div( terms.vestingTerm );\n if ( decay_ > totalDebt ) {\n decay_ = totalDebt;\n }\n }\n\n\n /**\n * @notice calculate how far into vesting a depositor is\n * @param _depositor address\n * @return percentVested_ uint\n */\n function percentVestedFor( address _depositor ) public view returns ( uint percentVested_ ) {\n Bond memory bond = bondInfo[ _depositor ];\n uint blocksSinceLast = block.number.sub( bond.lastBlock );\n uint vesting = bond.vesting;\n\n if ( vesting > 0 ) {\n percentVested_ = blocksSinceLast.mul( 10000 ).div( vesting );\n } else {\n percentVested_ = 0;\n }\n }\n\n /**\n * @notice calculate amount of OHM available for claim by depositor\n * @param _depositor address\n * @return pendingPayout_ uint\n */\n function pendingPayoutFor( address _depositor ) external view returns ( uint pendingPayout_ ) {\n uint percentVested = percentVestedFor( _depositor );\n uint payout = bondInfo[ _depositor ].payout;\n\n if ( percentVested >= 10000 ) {\n pendingPayout_ = payout;\n } else {\n pendingPayout_ = payout.mul( percentVested ).div( 10000 );\n }\n }\n\n /* ======= AUXILLIARY ======= */\n\n /**\n * @notice allow anyone to send lost tokens (excluding principal or OHM) to the DAO\n * @return bool\n */\n function recoverLostToken( address _token ) external returns ( bool ) {\n require( _token != OHM );\n require( _token != principal );\n IERC20( _token ).safeTransfer( DAO, IERC20( _token ).balanceOf( address(this) ) );\n return true;\n }\n}" + }, + "contracts/mocks/DAI.sol": { + "content": "pragma solidity 0.7.5;\n\n\ncontract LibNote {\n event LogNote(\n bytes4 indexed sig,\n address indexed usr,\n bytes32 indexed arg1,\n bytes32 indexed arg2,\n bytes data\n ) anonymous;\n\n modifier note {\n _;\n // assembly {\n // // log an 'anonymous' event with a constant 6 words of calldata\n // // and four indexed topics: selector, caller, arg1 and arg2\n // let mark := msize() // end of memory ensures zero\n // mstore(0x40, add(mark, 288)) // update free memory pointer\n // mstore(mark, 0x20) // bytes type data offset\n // mstore(add(mark, 0x20), 224) // bytes size (padded)\n // calldatacopy(add(mark, 0x40), 0, 224) // bytes payload\n // log4(mark, 288, // calldata\n // shl(224, shr(224, calldataload(0))), // msg.sig\n // caller(), // msg.sender\n // calldataload(4), // arg1\n // calldataload(36) // arg2\n // )\n // }\n }\n}\n\ninterface IDAI {\n\n\n // --- Auth ---\n function wards() external returns ( uint256 );\n\n function rely(address guy) external;\n\n function deny(address guy) external;\n\n // --- Token ---\n function transfer(address dst, uint wad) external returns (bool);\n\n function transferFrom(address src, address dst, uint wad) external returns (bool);\n\n function mint(address usr, uint wad) external;\n\n function burn(address usr, uint wad) external;\n\n function approve(address usr, uint wad) external returns (bool);\n\n // --- Alias ---\n function push(address usr, uint wad) external;\n\n function pull(address usr, uint wad) external;\n\n function move(address src, address dst, uint wad) external;\n\n // --- Approve by signature ---\n function permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s) external;\n}\n\n////// /nix/store/8xb41r4qd0cjb63wcrxf1qmfg88p0961-dss-6fd7de0/src/dai.sol\n// Copyright (C) 2017, 2018, 2019 dbrock, rain, mrchico\n\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\n/* pragma solidity 0.5.12; */\n\n/* import \"./lib.sol\"; */\n\ncontract DAI is LibNote {\n \n event Approval(address indexed src, address indexed guy, uint wad);\n event Transfer(address indexed src, address indexed dst, uint wad);\n \n // --- Auth ---\n mapping (address => uint) public wards;\n\n function rely(address guy) external note auth { wards[guy] = 1; }\n\n function deny(address guy) external note auth { wards[guy] = 0; }\n\n modifier auth {\n require(wards[msg.sender] == 1, \"Dai/not-authorized\");\n _;\n }\n\n // --- ERC20 Data ---\n string public constant name = \"Dai Stablecoin\";\n string public constant symbol = \"DAI\";\n string public constant version = \"1\";\n uint8 public constant decimals = 18;\n uint256 public totalSupply;\n uint public dailyDAILimit;\n\n mapping (address => uint) public balanceOf;\n mapping (address => mapping (address => uint)) private allowances;\n mapping (address => uint) public nonces;\n mapping (address => uint) public lastMintRestart;\n mapping (address => uint) public daiMintedToday;\n\n // event Approval(address indexed src, address indexed guy, uint wad);\n // event Transfer(address indexed src, address indexed dst, uint wad);\n\n // --- Math ---\n function add(uint x, uint y) internal pure returns (uint z) {\n require((z = x + y) >= x);\n }\n\n function sub(uint x, uint y) internal pure returns (uint z) {\n require((z = x - y) <= x);\n }\n\n // --- EIP712 niceties ---\n bytes32 public DOMAIN_SEPARATOR;\n // bytes32 public constant PERMIT_TYPEHASH = keccak256(\"Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)\");\n bytes32 public constant PERMIT_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb;\n\n constructor(uint256 chainId_) {\n wards[msg.sender] = 1;\n DOMAIN_SEPARATOR = keccak256(abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name)),\n keccak256(bytes(version)),\n chainId_,\n address(this)\n ));\n dailyDAILimit = 10000000000000000000000;\n }\n\n function allowance( address account_, address sender_ ) external view returns ( uint ) {\n return _allowance( account_, sender_ );\n }\n\n function _allowance( address account_, address sender_ ) internal view returns ( uint ) {\n \n return allowances[account_][sender_];\n }\n\n // --- Token ---\n function transfer(address dst, uint wad) external returns (bool) {\n return transferFrom(msg.sender, dst, wad);\n }\n\n function transferFrom(address src, address dst, uint wad) public returns (bool) {\n \n \n require(balanceOf[src] >= wad, \"Dai/insufficient-balance\");\n if (src != msg.sender && _allowance( src, msg.sender ) != uint(-1)) {\n require(_allowance( src, msg.sender ) >= wad, \"Dai/insufficient-allowance\");\n allowances[src][msg.sender] = sub(_allowance( src, msg.sender ), wad);\n }\n balanceOf[src] = sub(balanceOf[src], wad);\n balanceOf[dst] = add(balanceOf[dst], wad);\n emit Transfer(src, dst, wad);\n return true;\n }\n\n function addAuth(address usr) external auth {\n wards[usr] = 1;\n }\n\n function adjustDailyDAILimit(uint _limit) external auth {\n dailyDAILimit = _limit;\n }\n\n function mint(address usr, uint wad) external {\n\n if(wards[msg.sender] == 0) {\n require(add(wad, daiMintedToday[msg.sender]) <= dailyDAILimit || sub(block.number, lastMintRestart[msg.sender]) >= 6500 && wad <= dailyDAILimit, \"Over daily DAI Limit\");\n if( sub(block.number, lastMintRestart[msg.sender]) >= 6500 ) {\n daiMintedToday[msg.sender] = wad;\n lastMintRestart[msg.sender] = block.number;\n } else {\n daiMintedToday[msg.sender] = add(daiMintedToday[msg.sender], wad);\n }\n }\n \n balanceOf[usr] = add(balanceOf[usr], wad);\n \n totalSupply = add(totalSupply, wad);\n \n \n emit Transfer(address(0), usr, wad);\n }\n\n function burn(address usr, uint wad) external {\n require(balanceOf[usr] >= wad, \"Dai/insufficient-balance\");\n if (usr != msg.sender && _allowance( usr, msg.sender ) != uint(-1)) {\n require(_allowance( usr, msg.sender ) >= wad, \"Dai/insufficient-allowance\");\n allowances[usr][msg.sender] = sub(_allowance( usr, msg.sender ), wad);\n }\n balanceOf[usr] = sub(balanceOf[usr], wad);\n totalSupply = sub(totalSupply, wad);\n emit Transfer(usr, address(0), wad);\n }\n\n function _approve(address usr, uint wad) internal returns (bool) {\n \n allowances[msg.sender][usr] = wad;\n \n emit Approval(msg.sender, usr, wad);\n return true;\n }\n\n function approve(address usr_, uint wad_ ) external returns (bool) {\n \n return _approve( usr_, wad_ ) ;\n }\n\n // --- Alias ---\n function push(address usr, uint wad) external {\n transferFrom(msg.sender, usr, wad);\n }\n\n function pull(address usr, uint wad) external {\n transferFrom(usr, msg.sender, wad);\n }\n\n function move(address src, address dst, uint wad) external {\n transferFrom(src, dst, wad);\n }\n\n // --- Approve by signature ---\n function permit(address holder, address spender, uint256 nonce, uint256 expiry,\n bool allowed, uint8 v, bytes32 r, bytes32 s) external\n {\n bytes32 digest =\n keccak256(abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR,\n keccak256(abi.encode(PERMIT_TYPEHASH,\n holder,\n spender,\n nonce,\n expiry,\n allowed))\n ));\n\n require(holder != address(0), \"Dai/invalid-address-0\");\n require(holder == ecrecover(digest, v, r, s), \"Dai/invalid-permit\");\n require(expiry == 0 || block.timestamp <= expiry, \"Dai/permit-expired\");\n require(nonce == nonces[holder]++, \"Dai/invalid-nonce\");\n uint wad = allowed ? uint(-1) : 0;\n allowances[holder][spender] = wad;\n emit Approval(holder, spender, wad);\n }\n}" + }, + "contracts/mocks/Frax.sol": { + "content": "// SPDX-License-Identifier: Unlicensed\npragma solidity 0.7.5;\n\n\ncontract LibNote {\n event LogNote(\n bytes4 indexed sig,\n address indexed usr,\n bytes32 indexed arg1,\n bytes32 indexed arg2,\n bytes data\n ) anonymous;\n\n modifier note {\n _;\n // assembly {\n // // log an 'anonymous' event with a constant 6 words of calldata\n // // and four indexed topics: selector, caller, arg1 and arg2\n // let mark := msize() // end of memory ensures zero\n // mstore(0x40, add(mark, 288)) // update free memory pointer\n // mstore(mark, 0x20) // bytes type data offset\n // mstore(add(mark, 0x20), 224) // bytes size (padded)\n // calldatacopy(add(mark, 0x40), 0, 224) // bytes payload\n // log4(mark, 288, // calldata\n // shl(224, shr(224, calldataload(0))), // msg.sig\n // caller(), // msg.sender\n // calldataload(4), // arg1\n // calldataload(36) // arg2\n // )\n // }\n }\n}\n\ninterface IFRAX {\n\n\n // --- Auth ---\n function wards() external returns ( uint256 );\n\n function rely(address guy) external;\n\n function deny(address guy) external;\n\n // --- Token ---\n function transfer(address dst, uint wad) external returns (bool);\n\n function transferFrom(address src, address dst, uint wad) external returns (bool);\n\n function mint(address usr, uint wad) external;\n\n function burn(address usr, uint wad) external;\n\n function approve(address usr, uint wad) external returns (bool);\n\n // --- Alias ---\n function push(address usr, uint wad) external;\n\n function pull(address usr, uint wad) external;\n\n function move(address src, address dst, uint wad) external;\n\n // --- Approve by signature ---\n function permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s) external;\n}\n\n\ncontract FRAX is LibNote {\n \n event Approval(address indexed src, address indexed guy, uint wad);\n event Transfer(address indexed src, address indexed dst, uint wad);\n \n // --- Auth ---\n mapping (address => uint) public wards;\n\n function rely(address guy) external note auth { wards[guy] = 1; }\n\n function deny(address guy) external note auth { wards[guy] = 0; }\n\n modifier auth {\n require(wards[msg.sender] == 1, \"Frax/not-authorized\");\n _;\n }\n\n // --- ERC20 Data ---\n string public constant name = \"FRAX TOKEN\";\n string public constant symbol = \"FRAX\";\n string public constant version = \"1\";\n uint8 public constant decimals = 18;\n uint256 public totalSupply;\n uint public dailyFraxLimit;\n\n mapping (address => uint) public balanceOf;\n mapping (address => mapping (address => uint)) private allowances;\n mapping (address => uint) public nonces;\n mapping (address => uint) public lastMintRestart;\n mapping (address => uint) public fraxMintedToday;\n\n // event Approval(address indexed src, address indexed guy, uint wad);\n // event Transfer(address indexed src, address indexed dst, uint wad);\n\n // --- Math ---\n function add(uint x, uint y) internal pure returns (uint z) {\n require((z = x + y) >= x);\n }\n\n function sub(uint x, uint y) internal pure returns (uint z) {\n require((z = x - y) <= x);\n }\n\n // --- EIP712 niceties ---\n bytes32 public DOMAIN_SEPARATOR;\n // bytes32 public constant PERMIT_TYPEHASH = keccak256(\"Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)\");\n bytes32 public constant PERMIT_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb;\n\n constructor(uint256 chainId_) {\n wards[msg.sender] = 1;\n DOMAIN_SEPARATOR = keccak256(abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name)),\n keccak256(bytes(version)),\n chainId_,\n address(this)\n ));\n dailyFraxLimit = 10000000000000000000000;\n }\n\n function allowance( address account_, address sender_ ) external view returns ( uint ) {\n return _allowance( account_, sender_ );\n }\n\n function _allowance( address account_, address sender_ ) internal view returns ( uint ) {\n \n return allowances[account_][sender_];\n }\n\n // --- Token ---\n function transfer(address dst, uint wad) external returns (bool) {\n return transferFrom(msg.sender, dst, wad);\n }\n\n function transferFrom(address src, address dst, uint wad) public returns (bool) {\n \n \n require(balanceOf[src] >= wad, \"Frax/insufficient-balance\");\n if (src != msg.sender && _allowance( src, msg.sender ) != uint(-1)) {\n require(_allowance( src, msg.sender ) >= wad, \"Frax/insufficient-allowance\");\n allowances[src][msg.sender] = sub(_allowance( src, msg.sender ), wad);\n }\n balanceOf[src] = sub(balanceOf[src], wad);\n balanceOf[dst] = add(balanceOf[dst], wad);\n emit Transfer(src, dst, wad);\n return true;\n }\n\n function addAuth(address usr) external auth {\n wards[usr] = 1;\n }\n\n function adjustDailyFraxLimit(uint _limit) external auth {\n dailyFraxLimit = _limit;\n }\n\n function mint(address usr, uint wad) external {\n\n if(wards[msg.sender] == 0) {\n require(add(wad, fraxMintedToday[msg.sender]) <= dailyFraxLimit || sub(block.number, lastMintRestart[msg.sender]) >= 6500 && wad <= dailyFraxLimit, \"Over daily Frax Limit\");\n if( sub(block.number, lastMintRestart[msg.sender]) >= 6500 ) {\n fraxMintedToday[msg.sender] = wad;\n lastMintRestart[msg.sender] = block.number;\n } else {\n fraxMintedToday[msg.sender] = add(fraxMintedToday[msg.sender], wad);\n }\n }\n \n balanceOf[usr] = add(balanceOf[usr], wad);\n \n totalSupply = add(totalSupply, wad);\n \n \n emit Transfer(address(0), usr, wad);\n }\n\n function burn(address usr, uint wad) external {\n require(balanceOf[usr] >= wad, \"Frax/insufficient-balance\");\n if (usr != msg.sender && _allowance( usr, msg.sender ) != uint(-1)) {\n require(_allowance( usr, msg.sender ) >= wad, \"Frax/insufficient-allowance\");\n allowances[usr][msg.sender] = sub(_allowance( usr, msg.sender ), wad);\n }\n balanceOf[usr] = sub(balanceOf[usr], wad);\n totalSupply = sub(totalSupply, wad);\n emit Transfer(usr, address(0), wad);\n }\n\n function _approve(address usr, uint wad) internal returns (bool) {\n \n allowances[msg.sender][usr] = wad;\n \n emit Approval(msg.sender, usr, wad);\n return true;\n }\n\n function approve(address usr_, uint wad_ ) external returns (bool) {\n \n return _approve( usr_, wad_ ) ;\n }\n\n // --- Alias ---\n function push(address usr, uint wad) external {\n transferFrom(msg.sender, usr, wad);\n }\n\n function pull(address usr, uint wad) external {\n transferFrom(usr, msg.sender, wad);\n }\n\n function move(address src, address dst, uint wad) external {\n transferFrom(src, dst, wad);\n }\n\n // --- Approve by signature ---\n function permit(address holder, address spender, uint256 nonce, uint256 expiry,\n bool allowed, uint8 v, bytes32 r, bytes32 s) external\n {\n bytes32 digest =\n keccak256(abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR,\n keccak256(abi.encode(PERMIT_TYPEHASH,\n holder,\n spender,\n nonce,\n expiry,\n allowed))\n ));\n\n require(holder != address(0), \"Frax/invalid-address-0\");\n require(holder == ecrecover(digest, v, r, s), \"Frax/invalid-permit\");\n require(expiry == 0 || block.timestamp <= expiry, \"Frax/permit-expired\");\n require(nonce == nonces[holder]++, \"Frax/invalid-nonce\");\n uint wad = allowed ? uint(-1) : 0;\n allowances[holder][spender] = wad;\n emit Approval(holder, spender, wad);\n }\n}" + }, + "contracts/mocks/MockBondDepository.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity 0.7.5;\n\ninterface IOwnable {\n function policy() external view returns (address);\n\n function renounceManagement() external;\n\n function pushManagement(address newOwner_) external;\n\n function pullManagement() external;\n}\n\ncontract Ownable is IOwnable {\n address internal _owner;\n address internal _newOwner;\n\n event OwnershipPushed(\n address indexed previousOwner,\n address indexed newOwner\n );\n event OwnershipPulled(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n constructor() {\n _owner = msg.sender;\n emit OwnershipPushed(address(0), _owner);\n }\n\n function policy() public view override returns (address) {\n return _owner;\n }\n\n modifier onlyPolicy() {\n require(_owner == msg.sender, \"Ownable: caller is not the owner\");\n _;\n }\n\n function renounceManagement() public virtual override onlyPolicy {\n emit OwnershipPushed(_owner, address(0));\n _owner = address(0);\n }\n\n function pushManagement(address newOwner_)\n public\n virtual\n override\n onlyPolicy\n {\n require(newOwner_ != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipPushed(_owner, newOwner_);\n _newOwner = newOwner_;\n }\n\n function pullManagement() public virtual override {\n require(msg.sender == _newOwner, \"Ownable: must be new owner to pull\");\n emit OwnershipPulled(_owner, _newOwner);\n _owner = _newOwner;\n }\n}\n\nlibrary SafeMath {\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n function sub(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n function div(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n return c;\n }\n\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n function mod(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n\n function sqrrt(uint256 a) internal pure returns (uint256 c) {\n if (a > 3) {\n c = a;\n uint256 b = add(div(a, 2), 1);\n while (b < c) {\n c = b;\n b = div(add(div(a, b), b), 2);\n }\n } else if (a != 0) {\n c = 1;\n }\n }\n}\n\nlibrary Address {\n function isContract(address account) internal view returns (bool) {\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n size := extcodesize(account)\n }\n return size > 0;\n }\n\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(\n success,\n \"Address: unable to send value, recipient may have reverted\"\n );\n }\n\n function functionCall(address target, bytes memory data)\n internal\n returns (bytes memory)\n {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return _functionCallWithValue(target, data, 0, errorMessage);\n }\n\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return\n functionCallWithValue(\n target,\n data,\n value,\n \"Address: low-level call with value failed\"\n );\n }\n\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(\n address(this).balance >= value,\n \"Address: insufficient balance for call\"\n );\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _functionCallWithValue(\n address target,\n bytes memory data,\n uint256 weiValue,\n string memory errorMessage\n ) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{value: weiValue}(\n data\n );\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n function functionStaticCall(address target, bytes memory data)\n internal\n view\n returns (bytes memory)\n {\n return\n functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function functionDelegateCall(address target, bytes memory data)\n internal\n returns (bytes memory)\n {\n return\n functionDelegateCall(\n target,\n data,\n \"Address: low-level delegate call failed\"\n );\n }\n\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) private pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n if (returndata.length > 0) {\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n function addressToString(address _address)\n internal\n pure\n returns (string memory)\n {\n bytes32 _bytes = bytes32(uint256(_address));\n bytes memory HEX = \"0123456789abcdef\";\n bytes memory _addr = new bytes(42);\n\n _addr[0] = \"0\";\n _addr[1] = \"x\";\n\n for (uint256 i = 0; i < 20; i++) {\n _addr[2 + i * 2] = HEX[uint8(_bytes[i + 12] >> 4)];\n _addr[3 + i * 2] = HEX[uint8(_bytes[i + 12] & 0x0f)];\n }\n\n return string(_addr);\n }\n}\n\ninterface IERC20 {\n function decimals() external view returns (uint8);\n\n function totalSupply() external view returns (uint256);\n\n function balanceOf(address account) external view returns (uint256);\n\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n function allowance(address owner, address spender)\n external\n view\n returns (uint256);\n\n function approve(address spender, uint256 amount) external returns (bool);\n\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool);\n\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n\nabstract contract ERC20 is IERC20 {\n using SafeMath for uint256;\n\n // TODO comment actual hash value.\n bytes32 private constant ERC20TOKEN_ERC1820_INTERFACE_ID =\n keccak256(\"ERC20Token\");\n\n mapping(address => uint256) internal _balances;\n\n mapping(address => mapping(address => uint256)) internal _allowances;\n\n uint256 internal _totalSupply;\n\n string internal _name;\n\n string internal _symbol;\n\n uint8 internal _decimals;\n\n constructor(\n string memory name_,\n string memory symbol_,\n uint8 decimals_\n ) {\n _name = name_;\n _symbol = symbol_;\n _decimals = decimals_;\n }\n\n function name() public view returns (string memory) {\n return _name;\n }\n\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimals;\n }\n\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address account)\n public\n view\n virtual\n override\n returns (uint256)\n {\n return _balances[account];\n }\n\n function transfer(address recipient, uint256 amount)\n public\n virtual\n override\n returns (bool)\n {\n _transfer(msg.sender, recipient, amount);\n return true;\n }\n\n function allowance(address owner, address spender)\n public\n view\n virtual\n override\n returns (uint256)\n {\n return _allowances[owner][spender];\n }\n\n function approve(address spender, uint256 amount)\n public\n virtual\n override\n returns (bool)\n {\n _approve(msg.sender, spender, amount);\n return true;\n }\n\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(\n sender,\n msg.sender,\n _allowances[sender][msg.sender].sub(\n amount,\n \"ERC20: transfer amount exceeds allowance\"\n )\n );\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue)\n public\n virtual\n returns (bool)\n {\n _approve(\n msg.sender,\n spender,\n _allowances[msg.sender][spender].add(addedValue)\n );\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue)\n public\n virtual\n returns (bool)\n {\n _approve(\n msg.sender,\n spender,\n _allowances[msg.sender][spender].sub(\n subtractedValue,\n \"ERC20: decreased allowance below zero\"\n )\n );\n return true;\n }\n\n function _transfer(\n address sender,\n address recipient,\n uint256 amount\n ) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(\n amount,\n \"ERC20: transfer amount exceeds balance\"\n );\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n function _mint(address account_, uint256 ammount_) internal virtual {\n require(account_ != address(0), \"ERC20: mint to the zero address\");\n _beforeTokenTransfer(address(this), account_, ammount_);\n _totalSupply = _totalSupply.add(ammount_);\n _balances[account_] = _balances[account_].add(ammount_);\n emit Transfer(address(this), account_, ammount_);\n }\n\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(\n amount,\n \"ERC20: burn amount exceeds balance\"\n );\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n function _beforeTokenTransfer(\n address from_,\n address to_,\n uint256 amount_\n ) internal virtual {}\n}\n\ninterface IERC2612Permit {\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n function nonces(address owner) external view returns (uint256);\n}\n\nlibrary Counters {\n using SafeMath for uint256;\n\n struct Counter {\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n counter._value += 1;\n }\n\n function decrement(Counter storage counter) internal {\n counter._value = counter._value.sub(1);\n }\n}\n\nabstract contract ERC20Permit is ERC20, IERC2612Permit {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH =\n 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n\n bytes32 public DOMAIN_SEPARATOR;\n\n constructor() {\n uint256 chainID;\n assembly {\n chainID := chainid()\n }\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n ),\n keccak256(bytes(name())),\n keccak256(bytes(\"1\")), // Version\n chainID,\n address(this)\n )\n );\n }\n\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"Permit: expired deadline\");\n\n bytes32 hashStruct = keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n amount,\n _nonces[owner].current(),\n deadline\n )\n );\n\n bytes32 _hash = keccak256(\n abi.encodePacked(uint16(0x1901), DOMAIN_SEPARATOR, hashStruct)\n );\n\n address signer = ecrecover(_hash, v, r, s);\n require(\n signer != address(0) && signer == owner,\n \"ZeroSwapPermit: Invalid signature\"\n );\n\n _nonces[owner].increment();\n _approve(owner, spender, amount);\n }\n\n function nonces(address owner) public view override returns (uint256) {\n return _nonces[owner].current();\n }\n}\n\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(\n token,\n abi.encodeWithSelector(token.transfer.selector, to, value)\n );\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(\n token,\n abi.encodeWithSelector(token.transferFrom.selector, from, to, value)\n );\n }\n\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(\n token,\n abi.encodeWithSelector(token.approve.selector, spender, value)\n );\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(\n token,\n abi.encodeWithSelector(token.approve.selector, spender, newAllowance)\n );\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(\n value,\n \"SafeERC20: decreased allowance below zero\"\n );\n _callOptionalReturn(\n token,\n abi.encodeWithSelector(token.approve.selector, spender, newAllowance)\n );\n }\n\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n bytes memory returndata = address(token).functionCall(\n data,\n \"SafeERC20: low-level call failed\"\n );\n if (returndata.length > 0) {\n // Return data is optional\n // solhint-disable-next-line max-line-length\n require(\n abi.decode(returndata, (bool)),\n \"SafeERC20: ERC20 operation did not succeed\"\n );\n }\n }\n}\n\nlibrary FullMath {\n function fullMul(uint256 x, uint256 y)\n private\n pure\n returns (uint256 l, uint256 h)\n {\n uint256 mm = mulmod(x, y, uint256(-1));\n l = x * y;\n h = mm - l;\n if (mm < l) h -= 1;\n }\n\n function fullDiv(\n uint256 l,\n uint256 h,\n uint256 d\n ) private pure returns (uint256) {\n uint256 pow2 = d & -d;\n d /= pow2;\n l /= pow2;\n l += h * ((-pow2) / pow2 + 1);\n uint256 r = 1;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n return l * r;\n }\n\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 d\n ) internal pure returns (uint256) {\n (uint256 l, uint256 h) = fullMul(x, y);\n uint256 mm = mulmod(x, y, d);\n if (mm > l) h -= 1;\n l -= mm;\n require(h < d, \"FullMath::mulDiv: overflow\");\n return fullDiv(l, h, d);\n }\n}\n\nlibrary FixedPoint {\n struct uq112x112 {\n uint224 _x;\n }\n\n struct uq144x112 {\n uint256 _x;\n }\n\n uint8 private constant RESOLUTION = 112;\n uint256 private constant Q112 = 0x10000000000000000000000000000;\n uint256 private constant Q224 =\n 0x100000000000000000000000000000000000000000000000000000000;\n uint256 private constant LOWER_MASK = 0xffffffffffffffffffffffffffff; // decimal of UQ*x112 (lower 112 bits)\n\n function decode(uq112x112 memory self) internal pure returns (uint112) {\n return uint112(self._x >> RESOLUTION);\n }\n\n function decode112with18(uq112x112 memory self)\n internal\n pure\n returns (uint256)\n {\n return uint256(self._x) / 5192296858534827;\n }\n\n function fraction(uint256 numerator, uint256 denominator)\n internal\n pure\n returns (uq112x112 memory)\n {\n require(denominator > 0, \"FixedPoint::fraction: division by zero\");\n if (numerator == 0) return FixedPoint.uq112x112(0);\n\n if (numerator <= uint144(-1)) {\n uint256 result = (numerator << RESOLUTION) / denominator;\n require(result <= uint224(-1), \"FixedPoint::fraction: overflow\");\n return uq112x112(uint224(result));\n } else {\n uint256 result = FullMath.mulDiv(numerator, Q112, denominator);\n require(result <= uint224(-1), \"FixedPoint::fraction: overflow\");\n return uq112x112(uint224(result));\n }\n }\n}\n\ninterface ITreasury {\n function deposit(\n uint256 _amount,\n address _token,\n uint256 _profit\n ) external returns (bool);\n\n function valueOfToken(address _token, uint256 _amount)\n external\n view\n returns (uint256 value_);\n}\n\ninterface IBondCalculator {\n function valuation(address _LP, uint256 _amount)\n external\n view\n returns (uint256);\n\n function markdown(address _LP) external view returns (uint256);\n}\n\ninterface IStaking {\n function stake(uint256 _amount, address _recipient) external returns (bool);\n}\n\ninterface IStakingHelper {\n function stake(uint256 _amount, address _recipient) external;\n}\n\ncontract MockOlympusBondDepository is Ownable {\n using FixedPoint for *;\n using SafeERC20 for IERC20;\n using SafeMath for uint256;\n\n /* ======== EVENTS ======== */\n\n event BondCreated(\n uint256 deposit,\n uint256 indexed payout,\n uint256 indexed expires,\n uint256 indexed priceInUSD\n );\n event BondRedeemed(\n address indexed recipient,\n uint256 payout,\n uint256 remaining\n );\n event BondPriceChanged(\n uint256 indexed priceInUSD,\n uint256 indexed internalPrice,\n uint256 indexed debtRatio\n );\n event ControlVariableAdjustment(\n uint256 initialBCV,\n uint256 newBCV,\n uint256 adjustment,\n bool addition\n );\n\n /* ======== STATE VARIABLES ======== */\n\n address public immutable OHM; // token given as payment for bond\n address public immutable principle; // token used to create bond\n address public immutable treasury; // mints OHM when receives principle\n address public immutable DAO; // receives profit share from bond\n\n bool public immutable isLiquidityBond; // LP and Reserve bonds are treated slightly different\n address public immutable bondCalculator; // calculates value of LP tokens\n\n address public staking; // to auto-stake payout\n address public stakingHelper; // to stake and claim if no staking warmup\n bool public useHelper;\n\n Terms public terms; // stores terms for new bonds\n Adjust public adjustment; // stores adjustment to BCV data\n\n mapping(address => Bond) public bondInfo; // stores bond information for depositors\n\n uint256 public totalDebt; // total value of outstanding bonds; used for pricing\n uint256 public lastDecay; // reference block for debt decay\n\n /* ======== STRUCTS ======== */\n\n // Info for creating new bonds\n struct Terms {\n uint256 controlVariable; // scaling variable for price\n uint256 vestingTerm; // in blocks\n uint256 minimumPrice; // vs principle value\n uint256 maxPayout; // in thousandths of a %. i.e. 500 = 0.5%\n uint256 fee; // as % of bond payout, in hundreths. ( 500 = 5% = 0.05 for every 1 paid)\n uint256 maxDebt; // 9 decimal debt ratio, max % total supply created as debt\n }\n\n // Info for bond holder\n struct Bond {\n uint256 payout; // OHM remaining to be paid\n uint256 vesting; // Blocks left to vest\n uint256 lastBlock; // Last interaction\n uint256 pricePaid; // In DAI, for front end viewing\n }\n\n // Info for incremental adjustments to control variable\n struct Adjust {\n bool add; // addition or subtraction\n uint256 rate; // increment\n uint256 target; // BCV when adjustment finished\n uint256 buffer; // minimum length (in blocks) between adjustments\n uint256 lastBlock; // block when last adjustment made\n }\n\n /* ======== INITIALIZATION ======== */\n\n constructor(\n address _OHM,\n address _principle,\n address _treasury,\n address _DAO,\n address _bondCalculator\n ) {\n require(_OHM != address(0));\n OHM = _OHM;\n require(_principle != address(0));\n principle = _principle;\n require(_treasury != address(0));\n treasury = _treasury;\n require(_DAO != address(0));\n DAO = _DAO;\n // bondCalculator should be address(0) if not LP bond\n bondCalculator = _bondCalculator;\n isLiquidityBond = (_bondCalculator != address(0));\n }\n\n /**\n * @notice initializes bond parameters\n * @param _controlVariable uint\n * @param _vestingTerm uint\n * @param _minimumPrice uint\n * @param _maxPayout uint\n * @param _fee uint\n * @param _maxDebt uint\n * @param _initialDebt uint\n */\n function initializeBondTerms(\n uint256 _controlVariable,\n uint256 _vestingTerm,\n uint256 _minimumPrice,\n uint256 _maxPayout,\n uint256 _fee,\n uint256 _maxDebt,\n uint256 _initialDebt\n ) external onlyPolicy {\n require(terms.controlVariable == 0, \"Bonds must be initialized from 0\");\n terms = Terms({\n controlVariable: _controlVariable,\n vestingTerm: _vestingTerm,\n minimumPrice: _minimumPrice,\n maxPayout: _maxPayout,\n fee: _fee,\n maxDebt: _maxDebt\n });\n totalDebt = _initialDebt;\n lastDecay = block.number;\n }\n\n /* ======== POLICY FUNCTIONS ======== */\n\n enum PARAMETER {\n VESTING,\n PAYOUT,\n FEE,\n DEBT\n }\n\n /**\n * @notice set parameters for new bonds\n * @param _parameter PARAMETER\n * @param _input uint\n */\n function setBondTerms(PARAMETER _parameter, uint256 _input)\n external\n onlyPolicy\n {\n if (_parameter == PARAMETER.VESTING) {\n // 0\n require(_input >= 10000, \"Vesting must be longer than 36 hours\");\n terms.vestingTerm = _input;\n } else if (_parameter == PARAMETER.PAYOUT) {\n // 1\n require(_input <= 1000, \"Payout cannot be above 1 percent\");\n terms.maxPayout = _input;\n } else if (_parameter == PARAMETER.FEE) {\n // 2\n require(_input <= 10000, \"DAO fee cannot exceed payout\");\n terms.fee = _input;\n } else if (_parameter == PARAMETER.DEBT) {\n // 3\n terms.maxDebt = _input;\n }\n }\n\n /**\n * @notice set control variable adjustment\n * @param _addition bool\n * @param _increment uint\n * @param _target uint\n * @param _buffer uint\n */\n function setAdjustment(\n bool _addition,\n uint256 _increment,\n uint256 _target,\n uint256 _buffer\n ) external onlyPolicy {\n require(\n _increment <= terms.controlVariable.mul(25).div(1000),\n \"Increment too large\"\n );\n\n adjustment = Adjust({\n add: _addition,\n rate: _increment,\n target: _target,\n buffer: _buffer,\n lastBlock: block.number\n });\n }\n\n /**\n * @notice set contract for auto stake\n * @param _staking address\n * @param _helper bool\n */\n function setStaking(address _staking, bool _helper) external onlyPolicy {\n require(_staking != address(0));\n if (_helper) {\n useHelper = true;\n stakingHelper = _staking;\n } else {\n useHelper = false;\n staking = _staking;\n }\n }\n\n /* ======== USER FUNCTIONS ======== */\n\n /**\n * @notice deposit bond\n * @param _amount uint\n * @param _maxPrice uint\n * @param _depositor address\n * @return uint\n */\n function deposit(\n uint256 _amount,\n uint256 _maxPrice,\n address _depositor\n ) external returns (uint256) {\n require(_depositor != address(0), \"Invalid address\");\n\n decayDebt();\n require(totalDebt <= terms.maxDebt, \"Max capacity reached\");\n\n uint256 priceInUSD = bondPriceInUSD(); // Stored in bond info\n uint256 nativePrice = _bondPrice();\n\n require(_maxPrice >= nativePrice, \"Slippage limit: more than max price\"); // slippage protection\n\n uint256 value = ITreasury(treasury).valueOfToken(principle, _amount);\n uint256 payout = payoutFor(value); // payout to bonder is computed\n\n require(payout >= 10000000, \"Bond too small\"); // must be > 0.01 OHM ( underflow protection )\n require(payout <= maxPayout(), \"Bond too large\"); // size protection because there is no slippage\n\n // profits are calculated\n uint256 fee = payout.mul(terms.fee).div(10000);\n uint256 profit = value.sub(payout).sub(fee);\n\n /**\n principle is transferred in\n approved and\n deposited into the treasury, returning (_amount - profit) OHM\n */\n IERC20(principle).safeTransferFrom(msg.sender, address(this), _amount);\n IERC20(principle).approve(address(treasury), _amount);\n ITreasury(treasury).deposit(_amount, principle, profit);\n\n if (fee != 0) {\n // fee is transferred to dao\n IERC20(OHM).safeTransfer(DAO, fee);\n }\n\n // total debt is increased\n totalDebt = totalDebt.add(value);\n\n // depositor info is stored\n bondInfo[_depositor] = Bond({\n payout: bondInfo[_depositor].payout.add(payout),\n vesting: terms.vestingTerm,\n lastBlock: block.number,\n pricePaid: priceInUSD\n });\n\n // indexed events are emitted\n emit BondCreated(\n _amount,\n payout,\n block.number.add(terms.vestingTerm),\n priceInUSD\n );\n emit BondPriceChanged(bondPriceInUSD(), _bondPrice(), debtRatio());\n\n adjust(); // control variable is adjusted\n return payout;\n }\n\n /**\n * @notice redeem bond for user\n * @param _recipient address\n * @param _stake bool\n * @return uint\n */\n function redeem(address _recipient, bool _stake) external returns (uint256) {\n Bond memory info = bondInfo[_recipient];\n uint256 percentVested = percentVestedFor(_recipient); // (blocks since last interaction / vesting term remaining)\n\n if (percentVested >= 10000) {\n // if fully vested\n delete bondInfo[_recipient]; // delete user info\n emit BondRedeemed(_recipient, info.payout, 0); // emit bond data\n return stakeOrSend(_recipient, _stake, info.payout); // pay user everything due\n } else {\n // if unfinished\n // calculate payout vested\n uint256 payout = info.payout.mul(percentVested).div(10000);\n\n // store updated deposit info\n bondInfo[_recipient] = Bond({\n payout: info.payout.sub(payout),\n vesting: info.vesting.sub(block.number.sub(info.lastBlock)),\n lastBlock: block.number,\n pricePaid: info.pricePaid\n });\n\n emit BondRedeemed(_recipient, payout, bondInfo[_recipient].payout);\n return stakeOrSend(_recipient, _stake, payout);\n }\n }\n\n /* ======== INTERNAL HELPER FUNCTIONS ======== */\n\n /**\n * @notice allow user to stake payout automatically\n * @param _stake bool\n * @param _amount uint\n * @return uint\n */\n function stakeOrSend(\n address _recipient,\n bool _stake,\n uint256 _amount\n ) internal returns (uint256) {\n if (!_stake) {\n // if user does not want to stake\n IERC20(OHM).transfer(_recipient, _amount); // send payout\n } else {\n // if user wants to stake\n if (useHelper) {\n // use if staking warmup is 0\n IERC20(OHM).approve(stakingHelper, _amount);\n IStakingHelper(stakingHelper).stake(_amount, _recipient);\n } else {\n IERC20(OHM).approve(staking, _amount);\n IStaking(staking).stake(_amount, _recipient);\n }\n }\n return _amount;\n }\n\n /**\n * @notice makes incremental adjustment to control variable\n */\n function adjust() internal {\n uint256 blockCanAdjust = adjustment.lastBlock.add(adjustment.buffer);\n if (adjustment.rate != 0 && block.number >= blockCanAdjust) {\n uint256 initial = terms.controlVariable;\n if (adjustment.add) {\n terms.controlVariable = terms.controlVariable.add(adjustment.rate);\n if (terms.controlVariable >= adjustment.target) {\n adjustment.rate = 0;\n }\n } else {\n terms.controlVariable = terms.controlVariable.sub(adjustment.rate);\n if (terms.controlVariable <= adjustment.target) {\n adjustment.rate = 0;\n }\n }\n adjustment.lastBlock = block.number;\n emit ControlVariableAdjustment(\n initial,\n terms.controlVariable,\n adjustment.rate,\n adjustment.add\n );\n }\n }\n\n /**\n * @notice reduce total debt\n */\n function decayDebt() internal {\n totalDebt = totalDebt.sub(debtDecay());\n lastDecay = block.number;\n }\n\n /* ======== VIEW FUNCTIONS ======== */\n\n /**\n * @notice determine maximum bond size\n * @return uint\n */\n function maxPayout() public view returns (uint256) {\n return IERC20(OHM).totalSupply().mul(terms.maxPayout).div(100000);\n }\n\n /**\n * @notice calculate interest due for new bond\n * @param _value uint\n * @return uint\n */\n function payoutFor(uint256 _value) public view returns (uint256) {\n return FixedPoint.fraction(_value, bondPrice()).decode112with18().div(1e16);\n }\n\n /**\n * @notice calculate current bond premium\n * @return price_ uint\n */\n function bondPrice() public view returns (uint256 price_) {\n price_ = terms.controlVariable.mul(debtRatio()).add(1000000000).div(1e7);\n if (price_ < terms.minimumPrice) {\n price_ = terms.minimumPrice;\n }\n }\n\n /**\n * @notice calculate current bond price and remove floor if above\n * @return price_ uint\n */\n function _bondPrice() internal returns (uint256 price_) {\n price_ = terms.controlVariable.mul(debtRatio()).add(1000000000).div(1e7);\n if (price_ < terms.minimumPrice) {\n price_ = terms.minimumPrice;\n } else if (terms.minimumPrice != 0) {\n terms.minimumPrice = 0;\n }\n }\n\n /**\n * @notice converts bond price to DAI value\n * @return price_ uint\n */\n function bondPriceInUSD() public view returns (uint256 price_) {\n if (isLiquidityBond) {\n price_ = bondPrice()\n .mul(IBondCalculator(bondCalculator).markdown(principle))\n .div(100);\n } else {\n price_ = bondPrice().mul(10**IERC20(principle).decimals()).div(100);\n }\n }\n\n /**\n * @notice calculate current ratio of debt to OHM supply\n * @return debtRatio_ uint\n */\n function debtRatio() public view returns (uint256 debtRatio_) {\n uint256 supply = IERC20(OHM).totalSupply();\n debtRatio_ = FixedPoint\n .fraction(currentDebt().mul(1e9), supply)\n .decode112with18()\n .div(1e18);\n }\n\n /**\n * @notice debt ratio in same terms for reserve or liquidity bonds\n * @return uint\n */\n function standardizedDebtRatio() external view returns (uint256) {\n if (isLiquidityBond) {\n return\n debtRatio()\n .mul(IBondCalculator(bondCalculator).markdown(principle))\n .div(1e9);\n } else {\n return debtRatio();\n }\n }\n\n /**\n * @notice calculate debt factoring in decay\n * @return uint\n */\n function currentDebt() public view returns (uint256) {\n return totalDebt.sub(debtDecay());\n }\n\n /**\n * @notice amount to decay total debt by\n * @return decay_ uint\n */\n function debtDecay() public view returns (uint256 decay_) {\n uint256 blocksSinceLast = block.number.sub(lastDecay);\n decay_ = totalDebt.mul(blocksSinceLast).div(terms.vestingTerm);\n if (decay_ > totalDebt) {\n decay_ = totalDebt;\n }\n }\n\n /**\n * @notice calculate how far into vesting a depositor is\n * @param _depositor address\n * @return percentVested_ uint\n */\n function percentVestedFor(address _depositor)\n public\n view\n returns (uint256 percentVested_)\n {\n Bond memory bond = bondInfo[_depositor];\n uint256 blocksSinceLast = block.number.sub(bond.lastBlock);\n uint256 vesting = bond.vesting;\n\n if (vesting > 0) {\n percentVested_ = blocksSinceLast.mul(10000).div(vesting);\n } else {\n percentVested_ = 0;\n }\n }\n\n /**\n * @notice calculate amount of OHM available for claim by depositor\n * @param _depositor address\n * @return pendingPayout_ uint\n */\n function pendingPayoutFor(address _depositor)\n external\n view\n returns (uint256 pendingPayout_)\n {\n uint256 percentVested = percentVestedFor(_depositor);\n uint256 payout = bondInfo[_depositor].payout;\n\n if (percentVested >= 10000) {\n pendingPayout_ = payout;\n } else {\n pendingPayout_ = payout.mul(percentVested).div(10000);\n }\n }\n\n /* ======= AUXILLIARY ======= */\n\n /**\n * @notice allow anyone to send lost tokens (excluding principle or OHM) to the DAO\n * @return bool\n */\n function recoverLostToken(address _token) external returns (bool) {\n require(_token != OHM);\n require(_token != principle);\n IERC20(_token).safeTransfer(DAO, IERC20(_token).balanceOf(address(this)));\n return true;\n }\n}\n" + }, + "contracts/mocks/MockTreasury.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity 0.7.5;\n\nlibrary SafeMath {\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n function sub(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n function div(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n return c;\n }\n}\n\nlibrary Address {\n function isContract(address account) internal view returns (bool) {\n // This method relies in extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n size := extcodesize(account)\n }\n return size > 0;\n }\n\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return _functionCallWithValue(target, data, 0, errorMessage);\n }\n\n function _functionCallWithValue(\n address target,\n bytes memory data,\n uint256 weiValue,\n string memory errorMessage\n ) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{value: weiValue}(\n data\n );\n if (success) {\n return returndata;\n } else {\n if (returndata.length > 0) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n function _verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) private pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n if (returndata.length > 0) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ninterface IOwnable {\n function manager() external view returns (address);\n\n function renounceManagement() external;\n\n function pushManagement(address newOwner_) external;\n\n function pullManagement() external;\n}\n\ncontract Ownable is IOwnable {\n address internal _owner;\n address internal _newOwner;\n\n event OwnershipPushed(\n address indexed previousOwner,\n address indexed newOwner\n );\n event OwnershipPulled(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n constructor() {\n _owner = msg.sender;\n emit OwnershipPushed(address(0), _owner);\n }\n\n function manager() public view override returns (address) {\n return _owner;\n }\n\n modifier onlyManager() {\n require(_owner == msg.sender, \"Ownable: caller is not the owner\");\n _;\n }\n\n function renounceManagement() public virtual override onlyManager {\n emit OwnershipPushed(_owner, address(0));\n _owner = address(0);\n }\n\n function pushManagement(address newOwner_)\n public\n virtual\n override\n onlyManager\n {\n require(newOwner_ != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipPushed(_owner, newOwner_);\n _newOwner = newOwner_;\n }\n\n function pullManagement() public virtual override {\n require(msg.sender == _newOwner, \"Ownable: must be new owner to pull\");\n emit OwnershipPulled(_owner, _newOwner);\n _owner = _newOwner;\n }\n}\n\ninterface IERC20 {\n function decimals() external view returns (uint8);\n\n function balanceOf(address account) external view returns (uint256);\n\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n function approve(address spender, uint256 amount) external returns (bool);\n\n function totalSupply() external view returns (uint256);\n\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool);\n\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(\n token,\n abi.encodeWithSelector(token.transfer.selector, to, value)\n );\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(\n token,\n abi.encodeWithSelector(token.transferFrom.selector, from, to, value)\n );\n }\n\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n bytes memory returndata = address(token).functionCall(\n data,\n \"SafeERC20: low-level call failed\"\n );\n if (returndata.length > 0) {\n // Return data is optional\n // solhint-disable-next-line max-line-length\n require(\n abi.decode(returndata, (bool)),\n \"SafeERC20: ERC20 operation did not succeed\"\n );\n }\n }\n}\n\ninterface IERC20Mintable {\n function mint(uint256 amount_) external;\n\n function mint(address account_, uint256 ammount_) external;\n}\n\ninterface IOHMERC20 {\n function burnFrom(address account_, uint256 amount_) external;\n}\n\ninterface IBondCalculator {\n function valuation(address pair_, uint256 amount_)\n external\n view\n returns (uint256 _value);\n}\n\ncontract MockOlympusTreasury is Ownable {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n event Deposit(address indexed token, uint256 amount, uint256 value);\n event Withdrawal(address indexed token, uint256 amount, uint256 value);\n event CreateDebt(\n address indexed debtor,\n address indexed token,\n uint256 amount,\n uint256 value\n );\n event RepayDebt(\n address indexed debtor,\n address indexed token,\n uint256 amount,\n uint256 value\n );\n event ReservesManaged(address indexed token, uint256 amount);\n event ReservesUpdated(uint256 indexed totalReserves);\n event ReservesAudited(uint256 indexed totalReserves);\n event RewardsMinted(\n address indexed caller,\n address indexed recipient,\n uint256 amount\n );\n event ChangeQueued(MANAGING indexed managing, address queued);\n event ChangeActivated(\n MANAGING indexed managing,\n address activated,\n bool result\n );\n\n enum MANAGING {\n RESERVEDEPOSITOR,\n RESERVESPENDER,\n RESERVETOKEN,\n RESERVEMANAGER,\n LIQUIDITYDEPOSITOR,\n LIQUIDITYTOKEN,\n LIQUIDITYMANAGER,\n DEBTOR,\n REWARDMANAGER,\n SOHM\n }\n\n address public immutable OHM;\n uint256 public immutable blocksNeededForQueue;\n\n address[] public reserveTokens; // Push only, beware false-positives.\n mapping(address => bool) public isReserveToken;\n mapping(address => uint256) public reserveTokenQueue; // Delays changes to mapping.\n\n address[] public reserveDepositors; // Push only, beware false-positives. Only for viewing.\n mapping(address => bool) public isReserveDepositor;\n mapping(address => uint256) public reserveDepositorQueue; // Delays changes to mapping.\n\n address[] public reserveSpenders; // Push only, beware false-positives. Only for viewing.\n mapping(address => bool) public isReserveSpender;\n mapping(address => uint256) public reserveSpenderQueue; // Delays changes to mapping.\n\n address[] public liquidityTokens; // Push only, beware false-positives.\n mapping(address => bool) public isLiquidityToken;\n mapping(address => uint256) public LiquidityTokenQueue; // Delays changes to mapping.\n\n address[] public liquidityDepositors; // Push only, beware false-positives. Only for viewing.\n mapping(address => bool) public isLiquidityDepositor;\n mapping(address => uint256) public LiquidityDepositorQueue; // Delays changes to mapping.\n\n mapping(address => address) public bondCalculator; // bond calculator for liquidity token\n\n address[] public reserveManagers; // Push only, beware false-positives. Only for viewing.\n mapping(address => bool) public isReserveManager;\n mapping(address => uint256) public ReserveManagerQueue; // Delays changes to mapping.\n\n address[] public liquidityManagers; // Push only, beware false-positives. Only for viewing.\n mapping(address => bool) public isLiquidityManager;\n mapping(address => uint256) public LiquidityManagerQueue; // Delays changes to mapping.\n\n address[] public debtors; // Push only, beware false-positives. Only for viewing.\n mapping(address => bool) public isDebtor;\n mapping(address => uint256) public debtorQueue; // Delays changes to mapping.\n mapping(address => uint256) public debtorBalance;\n\n address[] public rewardManagers; // Push only, beware false-positives. Only for viewing.\n mapping(address => bool) public isRewardManager;\n mapping(address => uint256) public rewardManagerQueue; // Delays changes to mapping.\n\n address public sOHM;\n uint256 public sOHMQueue; // Delays change to sOHM address\n\n uint256 public totalReserves; // Risk-free value of all assets\n uint256 public totalDebt;\n\n constructor(\n address _OHM,\n address _DAI,\n address _Frax,\n //address _OHMDAI,\n uint256 _blocksNeededForQueue\n ) {\n require(_OHM != address(0));\n OHM = _OHM;\n\n isReserveToken[_DAI] = true;\n reserveTokens.push(_DAI);\n\n isReserveToken[_Frax] = true;\n reserveTokens.push(_Frax);\n\n // isLiquidityToken[ _OHMDAI ] = true;\n // liquidityTokens.push( _OHMDAI );\n\n blocksNeededForQueue = _blocksNeededForQueue;\n }\n\n /**\n @notice allow approved address to deposit an asset for OHM\n @param _amount uint\n @param _token address\n @param _profit uint\n @return send_ uint\n */\n function deposit(\n uint256 _amount,\n address _token,\n uint256 _profit\n ) external returns (uint256 send_) {\n require(isReserveToken[_token] || isLiquidityToken[_token], \"Not accepted\");\n IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);\n\n if (isReserveToken[_token]) {\n require(isReserveDepositor[msg.sender], \"Not approved\");\n } else {\n require(isLiquidityDepositor[msg.sender], \"Not approved\");\n }\n\n uint256 value = valueOfToken(_token, _amount);\n (_token, _amount);\n // mint OHM needed and store amount of rewards for distribution\n send_ = value.sub(_profit);\n IERC20Mintable(OHM).mint(msg.sender, send_);\n\n totalReserves = totalReserves.add(value);\n emit ReservesUpdated(totalReserves);\n\n emit Deposit(_token, _amount, value);\n }\n\n /**\n @notice allow approved address to burn OHM for reserves\n @param _amount uint\n @param _token address\n */\n function withdraw(uint256 _amount, address _token) external {\n require(isReserveToken[_token], \"Not accepted\"); // Only reserves can be used for redemptions\n require(isReserveSpender[msg.sender] == true, \"Not approved\");\n\n uint256 value = valueOfToken(_token, _amount);\n IOHMERC20(OHM).burnFrom(msg.sender, value);\n\n totalReserves = totalReserves.sub(value);\n emit ReservesUpdated(totalReserves);\n\n IERC20(_token).safeTransfer(msg.sender, _amount);\n\n emit Withdrawal(_token, _amount, value);\n }\n\n /**\n @notice allow approved address to borrow reserves\n @param _amount uint\n @param _token address\n */\n function incurDebt(uint256 _amount, address _token) external {\n require(isDebtor[msg.sender], \"Not approved\");\n require(isReserveToken[_token], \"Not accepted\");\n\n uint256 value = valueOfToken(_token, _amount);\n\n uint256 maximumDebt = IERC20(sOHM).balanceOf(msg.sender); // Can only borrow against sOHM held\n uint256 availableDebt = maximumDebt.sub(debtorBalance[msg.sender]);\n require(value <= availableDebt, \"Exceeds debt limit\");\n\n debtorBalance[msg.sender] = debtorBalance[msg.sender].add(value);\n totalDebt = totalDebt.add(value);\n\n totalReserves = totalReserves.sub(value);\n emit ReservesUpdated(totalReserves);\n\n IERC20(_token).transfer(msg.sender, _amount);\n\n emit CreateDebt(msg.sender, _token, _amount, value);\n }\n\n /**\n @notice allow approved address to repay borrowed reserves with reserves\n @param _amount uint\n @param _token address\n */\n function repayDebtWithReserve(uint256 _amount, address _token) external {\n require(isDebtor[msg.sender], \"Not approved\");\n require(isReserveToken[_token], \"Not accepted\");\n\n IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);\n\n uint256 value = valueOfToken(_token, _amount);\n debtorBalance[msg.sender] = debtorBalance[msg.sender].sub(value);\n totalDebt = totalDebt.sub(value);\n\n totalReserves = totalReserves.add(value);\n emit ReservesUpdated(totalReserves);\n\n emit RepayDebt(msg.sender, _token, _amount, value);\n }\n\n /**\n @notice allow approved address to repay borrowed reserves with OHM\n @param _amount uint\n */\n function repayDebtWithOHM(uint256 _amount) external {\n require(isDebtor[msg.sender], \"Not approved\");\n\n IOHMERC20(OHM).burnFrom(msg.sender, _amount);\n\n debtorBalance[msg.sender] = debtorBalance[msg.sender].sub(_amount);\n totalDebt = totalDebt.sub(_amount);\n\n emit RepayDebt(msg.sender, OHM, _amount, _amount);\n }\n\n /**\n @notice allow approved address to withdraw assets\n @param _token address\n @param _amount uint\n */\n function manage(address _token, uint256 _amount) external {\n if (isLiquidityToken[_token]) {\n require(isLiquidityManager[msg.sender], \"Not approved\");\n } else {\n require(isReserveManager[msg.sender], \"Not approved\");\n }\n\n uint256 value = valueOfToken(_token, _amount);\n (_token, _amount);\n require(value <= excessReserves(), \"Insufficient reserves\");\n\n totalReserves = totalReserves.sub(value);\n emit ReservesUpdated(totalReserves);\n\n IERC20(_token).safeTransfer(msg.sender, _amount);\n\n emit ReservesManaged(_token, _amount);\n }\n\n /**\n @notice send epoch reward to staking contract\n */\n function mintRewards(address _recipient, uint256 _amount) external {\n require(isRewardManager[msg.sender], \"Not approved\");\n require(_amount <= excessReserves(), \"Insufficient reserves\");\n\n IERC20Mintable(OHM).mint(_recipient, _amount);\n\n emit RewardsMinted(msg.sender, _recipient, _amount);\n }\n\n /**\n @notice returns excess reserves not backing tokens\n @return uint\n */\n function excessReserves() public view returns (uint256) {\n return totalReserves.sub(IERC20(OHM).totalSupply().sub(totalDebt));\n }\n\n /**\n @notice takes inventory of all tracked assets\n @notice always consolidate to recognized reserves before audit\n */\n function auditReserves() external onlyManager {\n uint256 reserves;\n for (uint256 i = 0; i < reserveTokens.length; i++) {\n reserves = reserves.add(\n valueOfToken(\n reserveTokens[i],\n IERC20(reserveTokens[i]).balanceOf(address(this))\n )\n );\n }\n for (uint256 i = 0; i < liquidityTokens.length; i++) {\n reserves = reserves.add(\n valueOfToken(\n liquidityTokens[i],\n IERC20(liquidityTokens[i]).balanceOf(address(this))\n )\n );\n }\n totalReserves = reserves;\n emit ReservesUpdated(reserves);\n emit ReservesAudited(reserves);\n }\n\n /**\n @notice returns OHM valuation of asset\n @param _token address\n @param _amount uint\n @return value_ uint\n */\n function valueOfToken(address _token, uint256 _amount)\n public\n view\n returns (uint256 value_)\n {\n if (isReserveToken[_token]) {\n // convert amount to match OHM decimals\n value_ = _amount.mul(10**IERC20(OHM).decimals()).div(\n 10**IERC20(_token).decimals()\n );\n } else if (isLiquidityToken[_token]) {\n value_ = IBondCalculator(bondCalculator[_token]).valuation(\n _token,\n _amount\n );\n }\n }\n\n /**\n @notice queue address to change boolean in mapping\n @param _managing MANAGING\n @param _address address\n @return bool\n */\n function queue(MANAGING _managing, address _address)\n external\n onlyManager\n returns (bool)\n {\n require(_address != address(0));\n if (_managing == MANAGING.RESERVEDEPOSITOR) {\n // 0\n reserveDepositorQueue[_address] = block.number.add(blocksNeededForQueue);\n } else if (_managing == MANAGING.RESERVESPENDER) {\n // 1\n reserveSpenderQueue[_address] = block.number.add(blocksNeededForQueue);\n } else if (_managing == MANAGING.RESERVETOKEN) {\n // 2\n reserveTokenQueue[_address] = block.number.add(blocksNeededForQueue);\n } else if (_managing == MANAGING.RESERVEMANAGER) {\n // 3\n ReserveManagerQueue[_address] = block.number.add(\n blocksNeededForQueue.mul(2)\n );\n } else if (_managing == MANAGING.LIQUIDITYDEPOSITOR) {\n // 4\n LiquidityDepositorQueue[_address] = block.number.add(\n blocksNeededForQueue\n );\n } else if (_managing == MANAGING.LIQUIDITYTOKEN) {\n // 5\n LiquidityTokenQueue[_address] = block.number.add(blocksNeededForQueue);\n } else if (_managing == MANAGING.LIQUIDITYMANAGER) {\n // 6\n LiquidityManagerQueue[_address] = block.number.add(\n blocksNeededForQueue.mul(2)\n );\n } else if (_managing == MANAGING.DEBTOR) {\n // 7\n debtorQueue[_address] = block.number.add(blocksNeededForQueue);\n } else if (_managing == MANAGING.REWARDMANAGER) {\n // 8\n rewardManagerQueue[_address] = block.number.add(blocksNeededForQueue);\n } else if (_managing == MANAGING.SOHM) {\n // 9\n sOHMQueue = block.number.add(blocksNeededForQueue);\n } else return false;\n\n emit ChangeQueued(_managing, _address);\n return true;\n }\n\n /**\n @notice verify queue then set boolean in mapping\n @param _managing MANAGING\n @param _address address\n @param _calculator address\n @return bool\n */\n function toggle(\n MANAGING _managing,\n address _address,\n address _calculator\n ) external onlyManager returns (bool) {\n require(_address != address(0));\n bool result;\n if (_managing == MANAGING.RESERVEDEPOSITOR) {\n // 0\n if (requirements(reserveDepositorQueue, isReserveDepositor, _address)) {\n reserveDepositorQueue[_address] = 0;\n if (!listContains(reserveDepositors, _address)) {\n reserveDepositors.push(_address);\n }\n }\n result = !isReserveDepositor[_address];\n isReserveDepositor[_address] = result;\n } else if (_managing == MANAGING.RESERVESPENDER) {\n // 1\n if (requirements(reserveSpenderQueue, isReserveSpender, _address)) {\n reserveSpenderQueue[_address] = 0;\n if (!listContains(reserveSpenders, _address)) {\n reserveSpenders.push(_address);\n }\n }\n result = !isReserveSpender[_address];\n isReserveSpender[_address] = result;\n } else if (_managing == MANAGING.RESERVETOKEN) {\n // 2\n if (requirements(reserveTokenQueue, isReserveToken, _address)) {\n reserveTokenQueue[_address] = 0;\n if (!listContains(reserveTokens, _address)) {\n reserveTokens.push(_address);\n }\n }\n result = !isReserveToken[_address];\n isReserveToken[_address] = result;\n } else if (_managing == MANAGING.RESERVEMANAGER) {\n // 3\n if (requirements(ReserveManagerQueue, isReserveManager, _address)) {\n reserveManagers.push(_address);\n ReserveManagerQueue[_address] = 0;\n if (!listContains(reserveManagers, _address)) {\n reserveManagers.push(_address);\n }\n }\n result = !isReserveManager[_address];\n isReserveManager[_address] = result;\n } else if (_managing == MANAGING.LIQUIDITYDEPOSITOR) {\n // 4\n if (\n requirements(LiquidityDepositorQueue, isLiquidityDepositor, _address)\n ) {\n liquidityDepositors.push(_address);\n LiquidityDepositorQueue[_address] = 0;\n if (!listContains(liquidityDepositors, _address)) {\n liquidityDepositors.push(_address);\n }\n }\n result = !isLiquidityDepositor[_address];\n isLiquidityDepositor[_address] = result;\n } else if (_managing == MANAGING.LIQUIDITYTOKEN) {\n // 5\n if (requirements(LiquidityTokenQueue, isLiquidityToken, _address)) {\n LiquidityTokenQueue[_address] = 0;\n if (!listContains(liquidityTokens, _address)) {\n liquidityTokens.push(_address);\n }\n }\n result = !isLiquidityToken[_address];\n isLiquidityToken[_address] = result;\n bondCalculator[_address] = _calculator;\n } else if (_managing == MANAGING.LIQUIDITYMANAGER) {\n // 6\n if (requirements(LiquidityManagerQueue, isLiquidityManager, _address)) {\n LiquidityManagerQueue[_address] = 0;\n if (!listContains(liquidityManagers, _address)) {\n liquidityManagers.push(_address);\n }\n }\n result = !isLiquidityManager[_address];\n isLiquidityManager[_address] = result;\n } else if (_managing == MANAGING.DEBTOR) {\n // 7\n if (requirements(debtorQueue, isDebtor, _address)) {\n debtorQueue[_address] = 0;\n if (!listContains(debtors, _address)) {\n debtors.push(_address);\n }\n }\n result = !isDebtor[_address];\n isDebtor[_address] = result;\n } else if (_managing == MANAGING.REWARDMANAGER) {\n // 8\n if (requirements(rewardManagerQueue, isRewardManager, _address)) {\n rewardManagerQueue[_address] = 0;\n if (!listContains(rewardManagers, _address)) {\n rewardManagers.push(_address);\n }\n }\n result = !isRewardManager[_address];\n isRewardManager[_address] = result;\n } else if (_managing == MANAGING.SOHM) {\n // 9\n sOHMQueue = 0;\n sOHM = _address;\n result = true;\n } else return false;\n\n emit ChangeActivated(_managing, _address, result);\n return true;\n }\n\n /**\n @notice checks requirements and returns altered structs\n @param queue_ mapping( address => uint )\n @param status_ mapping( address => bool )\n @param _address address\n @return bool \n */\n function requirements(\n mapping(address => uint256) storage queue_,\n mapping(address => bool) storage status_,\n address _address\n ) internal view returns (bool) {\n if (!status_[_address]) {\n require(queue_[_address] != 0, \"Must queue\");\n require(queue_[_address] <= block.number, \"Queue not expired\");\n return true;\n }\n return false;\n }\n\n /**\n @notice checks array to ensure against duplicate\n @param _list address[]\n @param _token address\n @return bool\n */\n function listContains(address[] storage _list, address _token)\n internal\n view\n returns (bool)\n {\n for (uint256 i = 0; i < _list.length; i++) {\n if (_list[i] == _token) {\n return true;\n }\n }\n return false;\n }\n}\n" + }, + "contracts/OlympusERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity 0.7.5;\n\nlibrary EnumerableSet {\n\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n struct Set {\n // Storage of set values\n bytes32[] _values;\n\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) { // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\n }\n\n function _getValues( Set storage set_ ) private view returns ( bytes32[] storage ) {\n return set_._values;\n }\n\n // TODO needs insert function that maintains order.\n // TODO needs NatSpec documentation comment.\n /**\n * Inserts new value by moving existing value at provided index to end of array and setting provided value at provided index\n */\n function _insert(Set storage set_, uint256 index_, bytes32 valueToInsert_ ) private returns ( bool ) {\n require( set_._values.length > index_ );\n require( !_contains( set_, valueToInsert_ ), \"Remove value you wish to insert if you wish to reorder array.\" );\n bytes32 existingValue_ = _at( set_, index_ );\n set_._values[index_] = valueToInsert_;\n return _add( set_, existingValue_);\n }\n\n struct Bytes4Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes4Set storage set, bytes4 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes4Set storage set, bytes4 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes4Set storage set, bytes4 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(Bytes4Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes4Set storage set, uint256 index) internal view returns ( bytes4 ) {\n return bytes4( _at( set._inner, index ) );\n }\n\n function getValues( Bytes4Set storage set_ ) internal view returns ( bytes4[] memory ) {\n bytes4[] memory bytes4Array_;\n for( uint256 iteration_ = 0; _length( set_._inner ) > iteration_; iteration_++ ) {\n bytes4Array_[iteration_] = bytes4( _at( set_._inner, iteration_ ) );\n }\n return bytes4Array_;\n }\n\n function insert( Bytes4Set storage set_, uint256 index_, bytes4 valueToInsert_ ) internal returns ( bool ) {\n return _insert( set_._inner, index_, valueToInsert_ );\n }\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns ( bytes32 ) {\n return _at(set._inner, index);\n }\n\n function getValues( Bytes32Set storage set_ ) internal view returns ( bytes4[] memory ) {\n bytes4[] memory bytes4Array_;\n\n for( uint256 iteration_ = 0; _length( set_._inner ) >= iteration_; iteration_++ ){\n bytes4Array_[iteration_] = bytes4( at( set_, iteration_ ) );\n }\n\n return bytes4Array_;\n }\n\n function insert( Bytes32Set storage set_, uint256 index_, bytes32 valueToInsert_ ) internal returns ( bool ) {\n return _insert( set_._inner, index_, valueToInsert_ );\n }\n\n // AddressSet\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(value)));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(value)));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(value)));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint256(_at(set._inner, index)));\n }\n\n /**\n * TODO Might require explicit conversion of bytes32[] to address[].\n * Might require iteration.\n */\n function getValues( AddressSet storage set_ ) internal view returns ( address[] memory ) {\n\n address[] memory addressArray;\n\n for( uint256 iteration_ = 0; _length(set_._inner) >= iteration_; iteration_++ ){\n addressArray[iteration_] = at( set_, iteration_ );\n }\n\n return addressArray;\n }\n\n function insert(AddressSet storage set_, uint256 index_, address valueToInsert_ ) internal returns ( bool ) {\n return _insert( set_._inner, index_, bytes32(uint256(valueToInsert_)) );\n }\n\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n struct UInt256Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UInt256Set storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UInt256Set storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UInt256Set storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UInt256Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UInt256Set storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n}\n\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n\nlibrary SafeMath {\n\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n\n function sqrrt(uint256 a) internal pure returns (uint c) {\n if (a > 3) {\n c = a;\n uint b = add( div( a, 2), 1 );\n while (b < c) {\n c = b;\n b = div( add( div( a, b ), b), 2 );\n }\n } else if (a != 0) {\n c = 1;\n }\n }\n\n function percentageAmount( uint256 total_, uint8 percentage_ ) internal pure returns ( uint256 percentAmount_ ) {\n return div( mul( total_, percentage_ ), 1000 );\n }\n\n function substractPercentage( uint256 total_, uint8 percentageToSub_ ) internal pure returns ( uint256 result_ ) {\n return sub( total_, div( mul( total_, percentageToSub_ ), 1000 ) );\n }\n\n function percentageOfTotal( uint256 part_, uint256 total_ ) internal pure returns ( uint256 percent_ ) {\n return div( mul(part_, 100) , total_ );\n }\n\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow, so we distribute\n return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);\n }\n\n function quadraticPricing( uint256 payment_, uint256 multiplier_ ) internal pure returns (uint256) {\n return sqrrt( mul( multiplier_, payment_ ) );\n }\n\n function bondingCurve( uint256 supply_, uint256 multiplier_ ) internal pure returns (uint256) {\n return mul( multiplier_, supply_ );\n }\n}\n\nabstract contract ERC20 is IERC20 {\n\n using SafeMath for uint256;\n\n // TODO comment actual hash value.\n bytes32 constant private ERC20TOKEN_ERC1820_INTERFACE_ID = keccak256( \"ERC20Token\" );\n\n // Present in ERC777\n mapping (address => uint256) internal _balances;\n\n // Present in ERC777\n mapping (address => mapping (address => uint256)) internal _allowances;\n\n // Present in ERC777\n uint256 internal _totalSupply;\n\n // Present in ERC777\n string internal _name;\n\n // Present in ERC777\n string internal _symbol;\n\n // Present in ERC777\n uint8 internal _decimals;\n\n constructor (string memory name_, string memory symbol_, uint8 decimals_) {\n _name = name_;\n _symbol = symbol_;\n _decimals = decimals_;\n }\n\n function name() public view returns (string memory) {\n return _name;\n }\n\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n function decimals() public view returns (uint8) {\n return _decimals;\n }\n\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(msg.sender, recipient, amount);\n return true;\n }\n\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(msg.sender, spender, amount);\n return true;\n }\n\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n function _mint(address account_, uint256 amount_) internal virtual {\n require(account_ != address(0), \"ERC20: mint to the zero address\");\n _beforeTokenTransfer(address( this ), account_, amount_);\n _totalSupply = _totalSupply.add(amount_);\n _balances[account_] = _balances[account_].add(amount_);\n emit Transfer(address( this ), account_, amount_);\n }\n\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n function _beforeTokenTransfer( address from_, address to_, uint256 amount_ ) internal virtual { }\n}\n\nlibrary Counters {\n using SafeMath for uint256;\n\n struct Counter {\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n counter._value += 1;\n }\n\n function decrement(Counter storage counter) internal {\n counter._value = counter._value.sub(1);\n }\n}\n\ninterface IERC2612Permit {\n\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n function nonces(address owner) external view returns (uint256);\n}\n\nabstract contract ERC20Permit is ERC20, IERC2612Permit {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n\n bytes32 public DOMAIN_SEPARATOR;\n\n constructor() {\n uint256 chainID;\n assembly {\n chainID := chainid()\n }\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name())),\n keccak256(bytes(\"1\")), // Version\n chainID,\n address(this)\n )\n );\n }\n\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"Permit: expired deadline\");\n\n bytes32 hashStruct =\n keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, amount, _nonces[owner].current(), deadline));\n\n bytes32 _hash = keccak256(abi.encodePacked(uint16(0x1901), DOMAIN_SEPARATOR, hashStruct));\n\n address signer = ecrecover(_hash, v, r, s);\n require(signer != address(0) && signer == owner, \"ZeroSwapPermit: Invalid signature\");\n\n _nonces[owner].increment();\n _approve(owner, spender, amount);\n }\n\n function nonces(address owner) public view override returns (uint256) {\n return _nonces[owner].current();\n }\n}\n\ninterface IOwnable {\n function owner() external view returns (address);\n\n function renounceOwnership() external;\n\n function transferOwnership( address newOwner_ ) external;\n}\n\ncontract Ownable is IOwnable {\n\n address internal _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n constructor () {\n _owner = msg.sender;\n emit OwnershipTransferred( address(0), _owner );\n }\n\n function owner() public view override returns (address) {\n return _owner;\n }\n\n modifier onlyOwner() {\n require( _owner == msg.sender, \"Ownable: caller is not the owner\" );\n _;\n }\n\n function renounceOwnership() public virtual override onlyOwner() {\n emit OwnershipTransferred( _owner, address(0) );\n _owner = address(0);\n }\n\n function transferOwnership( address newOwner_ ) public virtual override onlyOwner() {\n require( newOwner_ != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipTransferred( _owner, newOwner_ );\n _owner = newOwner_;\n }\n}\n\ncontract VaultOwned is Ownable {\n\n address internal _vault;\n\n function setVault( address vault_ ) external onlyOwner() returns ( bool ) {\n _vault = vault_;\n\n return true;\n }\n\n function vault() public view returns (address) {\n return _vault;\n }\n\n modifier onlyVault() {\n require( _vault == msg.sender, \"VaultOwned: caller is not the Vault\" );\n _;\n }\n\n}\n\ncontract OlympusERC20Token is ERC20Permit, VaultOwned {\n\n using SafeMath for uint256;\n\n constructor() ERC20(\"Brick\", \"BRICK\", 9) {\n }\n\n function mint(address account_, uint256 amount_) external onlyVault() {\n _mint(account_, amount_);\n }\n\n function burn(uint256 amount) public virtual {\n _burn(msg.sender, amount);\n }\n\n function burnFrom(address account_, uint256 amount_) public virtual {\n _burnFrom(account_, amount_);\n }\n\n function _burnFrom(address account_, uint256 amount_) public virtual {\n uint256 decreasedAllowance_ =\n allowance(account_, msg.sender).sub(\n amount_,\n \"ERC20: burn amount exceeds allowance\"\n );\n\n _approve(account_, msg.sender, decreasedAllowance_);\n _burn(account_, amount_);\n }\n}" + }, + "contracts/RedeemHelper.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity 0.7.5;\n\ninterface IOwnable {\n function policy() external view returns (address);\n\n function renounceManagement() external;\n \n function pushManagement( address newOwner_ ) external;\n \n function pullManagement() external;\n}\n\ncontract Ownable is IOwnable {\n\n address internal _owner;\n address internal _newOwner;\n\n event OwnershipPushed(address indexed previousOwner, address indexed newOwner);\n event OwnershipPulled(address indexed previousOwner, address indexed newOwner);\n\n constructor () {\n _owner = msg.sender;\n emit OwnershipPushed( address(0), _owner );\n }\n\n function policy() public view override returns (address) {\n return _owner;\n }\n\n modifier onlyPolicy() {\n require( _owner == msg.sender, \"Ownable: caller is not the owner\" );\n _;\n }\n\n function renounceManagement() public virtual override onlyPolicy() {\n emit OwnershipPushed( _owner, address(0) );\n _owner = address(0);\n }\n\n function pushManagement( address newOwner_ ) public virtual override onlyPolicy() {\n require( newOwner_ != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipPushed( _owner, newOwner_ );\n _newOwner = newOwner_;\n }\n \n function pullManagement() public virtual override {\n require( msg.sender == _newOwner, \"Ownable: must be new owner to pull\");\n emit OwnershipPulled( _owner, _newOwner );\n _owner = _newOwner;\n }\n}\n\ninterface IBond {\n function redeem( address _recipient, bool _stake ) external returns ( uint );\n function pendingPayoutFor( address _depositor ) external view returns ( uint pendingPayout_ );\n}\n\ncontract RedeemHelper is Ownable {\n\n address[] public bonds;\n\n function redeemAll( address _recipient, bool _stake ) external {\n for( uint i = 0; i < bonds.length; i++ ) {\n if ( bonds[i] != address(0) ) {\n if ( IBond( bonds[i] ).pendingPayoutFor( _recipient ) > 0 ) {\n IBond( bonds[i] ).redeem( _recipient, _stake );\n }\n }\n }\n }\n\n function addBondContract( address _bond ) external onlyPolicy() {\n require( _bond != address(0) );\n bonds.push( _bond );\n }\n\n function removeBondContract( uint _index ) external onlyPolicy() {\n bonds[ _index ] = address(0);\n }\n}" + }, + "contracts/sOlympusERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity 0.7.5;\n\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n\n // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)\n function sqrrt(uint256 a) internal pure returns (uint c) {\n if (a > 3) {\n c = a;\n uint b = add( div( a, 2), 1 );\n while (b < c) {\n c = b;\n b = div( add( div( a, b ), b), 2 );\n }\n } else if (a != 0) {\n c = 1;\n }\n }\n\n /*\n * Expects percentage to be trailed by 00,\n */\n function percentageAmount( uint256 total_, uint8 percentage_ ) internal pure returns ( uint256 percentAmount_ ) {\n return div( mul( total_, percentage_ ), 1000 );\n }\n\n /*\n * Expects percentage to be trailed by 00,\n */\n function substractPercentage( uint256 total_, uint8 percentageToSub_ ) internal pure returns ( uint256 result_ ) {\n return sub( total_, div( mul( total_, percentageToSub_ ), 1000 ) );\n }\n\n function percentageOfTotal( uint256 part_, uint256 total_ ) internal pure returns ( uint256 percent_ ) {\n return div( mul(part_, 100) , total_ );\n }\n\n /**\n * Taken from Hypersonic https://github.com/M2629/HyperSonic/blob/main/Math.sol\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow, so we distribute\n return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);\n }\n\n function quadraticPricing( uint256 payment_, uint256 multiplier_ ) internal pure returns (uint256) {\n return sqrrt( mul( multiplier_, payment_ ) );\n }\n\n function bondingCurve( uint256 supply_, uint256 multiplier_ ) internal pure returns (uint256) {\n return mul( multiplier_, supply_ );\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies in extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain`call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return _functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n // function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n // require(address(this).balance >= value, \"Address: insufficient balance for call\");\n // return _functionCallWithValue(target, data, value, errorMessage);\n // }\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.3._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.3._\n */\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n function addressToString(address _address) internal pure returns(string memory) {\n bytes32 _bytes = bytes32(uint256(_address));\n bytes memory HEX = \"0123456789abcdef\";\n bytes memory _addr = new bytes(42);\n\n _addr[0] = '0';\n _addr[1] = 'x';\n\n for(uint256 i = 0; i < 20; i++) {\n _addr[2+i*2] = HEX[uint8(_bytes[i + 12] >> 4)];\n _addr[3+i*2] = HEX[uint8(_bytes[i + 12] & 0x0f)];\n }\n\n return string(_addr);\n\n }\n}\n\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n\nabstract contract ERC20\n is \n IERC20\n {\n\n using SafeMath for uint256;\n\n // TODO comment actual hash value.\n bytes32 constant private ERC20TOKEN_ERC1820_INTERFACE_ID = keccak256( \"ERC20Token\" );\n \n // Present in ERC777\n mapping (address => uint256) internal _balances;\n\n // Present in ERC777\n mapping (address => mapping (address => uint256)) internal _allowances;\n\n // Present in ERC777\n uint256 internal _totalSupply;\n\n // Present in ERC777\n string internal _name;\n \n // Present in ERC777\n string internal _symbol;\n \n // Present in ERC777\n uint8 internal _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory name_, string memory symbol_, uint8 decimals_) {\n _name = name_;\n _symbol = symbol_;\n _decimals = decimals_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n // Present in ERC777\n function name() public view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n // Present in ERC777\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\n * called.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n // Present in ERC777\n function decimals() public view returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n // Present in ERC777\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n // Present in ERC777\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n // Overrideen in ERC777\n // Confirm that this behavior changes \n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(msg.sender, recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n // Present in ERC777\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n // Present in ERC777\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(msg.sender, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for ``sender``'s tokens of at least\n * `amount`.\n */\n // Present in ERC777\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n */\n // Present in ERC777\n function _mint(address account_, uint256 ammount_) internal virtual {\n require(account_ != address(0), \"ERC20: mint to the zero address\");\n _beforeTokenTransfer(address( this ), account_, ammount_);\n _totalSupply = _totalSupply.add(ammount_);\n _balances[account_] = _balances[account_].add(ammount_);\n emit Transfer(address( this ), account_, ammount_);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n // Present in ERC777\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n // Present in ERC777\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n // Considering deprication to reduce size of bytecode as changing _decimals to internal acheived the same functionality.\n // function _setupDecimals(uint8 decimals_) internal {\n // _decimals = decimals_;\n // }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n // Present in ERC777\n function _beforeTokenTransfer( address from_, address to_, uint256 amount_ ) internal virtual { }\n}\n\nlibrary Counters {\n using SafeMath for uint256;\n\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n // The {SafeMath} overflow check can be skipped here, see the comment at the top\n counter._value += 1;\n }\n\n function decrement(Counter storage counter) internal {\n counter._value = counter._value.sub(1);\n }\n}\n\ninterface IERC2612Permit {\n /**\n * @dev Sets `amount` as the allowance of `spender` over `owner`'s tokens,\n * given `owner`'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current ERC2612 nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n}\n\nabstract contract ERC20Permit is ERC20, IERC2612Permit {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n\n bytes32 public DOMAIN_SEPARATOR;\n\n constructor() {\n\n uint256 chainID;\n assembly {\n chainID := chainid()\n }\n\n DOMAIN_SEPARATOR = keccak256(abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name())),\n keccak256(bytes(\"1\")), // Version\n chainID,\n address(this)\n ));\n }\n\n /**\n * @dev See {IERC2612Permit-permit}.\n *\n */\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"Permit: expired deadline\");\n\n bytes32 hashStruct =\n keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, amount, _nonces[owner].current(), deadline));\n\n bytes32 _hash = keccak256(abi.encodePacked(uint16(0x1901), DOMAIN_SEPARATOR, hashStruct));\n\n address signer = ecrecover(_hash, v, r, s);\n require(signer != address(0) && signer == owner, \"ZeroSwapPermit: Invalid signature\");\n\n _nonces[owner].increment();\n _approve(owner, spender, amount);\n }\n\n /**\n * @dev See {IERC2612Permit-nonces}.\n */\n function nonces(address owner) public view override returns (uint256) {\n return _nonces[owner].current();\n }\n}\n\ninterface IOwnable {\n function manager() external view returns (address);\n\n function renounceManagement() external;\n \n function pushManagement( address newOwner_ ) external;\n \n function pullManagement() external;\n}\n\ncontract Ownable is IOwnable {\n\n address internal _owner;\n address internal _newOwner;\n\n event OwnershipPushed(address indexed previousOwner, address indexed newOwner);\n event OwnershipPulled(address indexed previousOwner, address indexed newOwner);\n\n constructor () {\n _owner = msg.sender;\n emit OwnershipPushed( address(0), _owner );\n }\n\n function manager() public view override returns (address) {\n return _owner;\n }\n\n modifier onlyManager() {\n require( _owner == msg.sender, \"Ownable: caller is not the owner\" );\n _;\n }\n\n function renounceManagement() public virtual override onlyManager() {\n emit OwnershipPushed( _owner, address(0) );\n _owner = address(0);\n }\n\n function pushManagement( address newOwner_ ) public virtual override onlyManager() {\n require( newOwner_ != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipPushed( _owner, newOwner_ );\n _newOwner = newOwner_;\n }\n \n function pullManagement() public virtual override {\n require( msg.sender == _newOwner, \"Ownable: must be new owner to pull\");\n emit OwnershipPulled( _owner, _newOwner );\n _owner = _newOwner;\n }\n}\n\ncontract sOlympus is ERC20Permit, Ownable {\n\n using SafeMath for uint256;\n\n modifier onlyStakingContract() {\n require( msg.sender == stakingContract );\n _;\n }\n\n address public stakingContract;\n address public initializer;\n\n event LogSupply(uint256 indexed epoch, uint256 timestamp, uint256 totalSupply );\n event LogRebase( uint256 indexed epoch, uint256 rebase, uint256 index );\n event LogStakingContractUpdated( address stakingContract );\n\n struct Rebase {\n uint epoch;\n uint rebase; // 18 decimals\n uint totalStakedBefore;\n uint totalStakedAfter;\n uint amountRebased;\n uint index;\n uint blockNumberOccured;\n }\n Rebase[] public rebases;\n\n uint public INDEX;\n\n uint256 private constant MAX_UINT256 = ~uint256(0);\n uint256 private constant INITIAL_FRAGMENTS_SUPPLY = 5000000 * 10**9;\n\n // TOTAL_GONS is a multiple of INITIAL_FRAGMENTS_SUPPLY so that _gonsPerFragment is an integer.\n // Use the highest value that fits in a uint256 for max granularity.\n uint256 private constant TOTAL_GONS = MAX_UINT256 - (MAX_UINT256 % INITIAL_FRAGMENTS_SUPPLY);\n\n // MAX_SUPPLY = maximum integer < (sqrt(4*TOTAL_GONS + 1) - 1) / 2\n uint256 private constant MAX_SUPPLY = ~uint128(0); // (2^128) - 1\n\n uint256 private _gonsPerFragment;\n mapping(address => uint256) private _gonBalances;\n\n mapping ( address => mapping ( address => uint256 ) ) private _allowedValue;\n\n constructor() ERC20(\"Staked Olympus\", \"sOHM\", 9) ERC20Permit() {\n initializer = msg.sender;\n _totalSupply = INITIAL_FRAGMENTS_SUPPLY;\n _gonsPerFragment = TOTAL_GONS.div(_totalSupply);\n }\n\n function initialize( address stakingContract_ ) external returns ( bool ) {\n require( msg.sender == initializer );\n require( stakingContract_ != address(0) );\n stakingContract = stakingContract_;\n _gonBalances[ stakingContract ] = TOTAL_GONS;\n\n emit Transfer( address(0x0), stakingContract, _totalSupply );\n emit LogStakingContractUpdated( stakingContract_ );\n \n initializer = address(0);\n return true;\n }\n\n function setIndex( uint _INDEX ) external onlyManager() returns ( bool ) {\n require( INDEX == 0 );\n INDEX = gonsForBalance( _INDEX );\n return true;\n }\n\n /**\n @notice increases sOHM supply to increase staking balances relative to profit_\n @param profit_ uint256\n @return uint256\n */\n function rebase( uint256 profit_, uint epoch_ ) public onlyStakingContract() returns ( uint256 ) {\n uint256 rebaseAmount;\n uint256 circulatingSupply_ = circulatingSupply();\n\n if ( profit_ == 0 ) {\n emit LogSupply( epoch_, block.timestamp, _totalSupply );\n emit LogRebase( epoch_, 0, index() );\n return _totalSupply;\n } else if ( circulatingSupply_ > 0 ){\n rebaseAmount = profit_.mul( _totalSupply ).div( circulatingSupply_ );\n } else {\n rebaseAmount = profit_;\n }\n\n _totalSupply = _totalSupply.add( rebaseAmount );\n\n if ( _totalSupply > MAX_SUPPLY ) {\n _totalSupply = MAX_SUPPLY;\n }\n\n _gonsPerFragment = TOTAL_GONS.div( _totalSupply );\n\n _storeRebase( circulatingSupply_, profit_, epoch_ );\n\n return _totalSupply;\n }\n\n /**\n @notice emits event with data about rebase\n @param previousCirculating_ uint\n @param profit_ uint\n @param epoch_ uint\n @return bool\n */\n function _storeRebase( uint previousCirculating_, uint profit_, uint epoch_ ) internal returns ( bool ) {\n uint rebasePercent = profit_.mul( 1e18 ).div( previousCirculating_ );\n\n rebases.push( Rebase ( {\n epoch: epoch_,\n rebase: rebasePercent, // 18 decimals\n totalStakedBefore: previousCirculating_,\n totalStakedAfter: circulatingSupply(),\n amountRebased: profit_,\n index: index(),\n blockNumberOccured: block.number\n }));\n \n emit LogSupply( epoch_, block.timestamp, _totalSupply );\n emit LogRebase( epoch_, rebasePercent, index() );\n\n return true;\n }\n\n function balanceOf( address who ) public view override returns ( uint256 ) {\n return _gonBalances[ who ].div( _gonsPerFragment );\n }\n\n function gonsForBalance( uint amount ) public view returns ( uint ) {\n return amount.mul( _gonsPerFragment );\n }\n\n function balanceForGons( uint gons ) public view returns ( uint ) {\n return gons.div( _gonsPerFragment );\n }\n\n // Staking contract holds excess sOHM\n function circulatingSupply() public view returns ( uint ) {\n return _totalSupply.sub( balanceOf( stakingContract ) );\n }\n\n function index() public view returns ( uint ) {\n return balanceForGons( INDEX );\n }\n\n function transfer( address to, uint256 value ) public override returns (bool) {\n uint256 gonValue = value.mul( _gonsPerFragment );\n _gonBalances[ msg.sender ] = _gonBalances[ msg.sender ].sub( gonValue );\n _gonBalances[ to ] = _gonBalances[ to ].add( gonValue );\n emit Transfer( msg.sender, to, value );\n return true;\n }\n\n function allowance( address owner_, address spender ) public view override returns ( uint256 ) {\n return _allowedValue[ owner_ ][ spender ];\n }\n\n function transferFrom( address from, address to, uint256 value ) public override returns ( bool ) {\n _allowedValue[ from ][ msg.sender ] = _allowedValue[ from ][ msg.sender ].sub( value );\n emit Approval( from, msg.sender, _allowedValue[ from ][ msg.sender ] );\n\n uint256 gonValue = gonsForBalance( value );\n _gonBalances[ from ] = _gonBalances[from].sub( gonValue );\n _gonBalances[ to ] = _gonBalances[to].add( gonValue );\n emit Transfer( from, to, value );\n\n return true;\n }\n\n function approve( address spender, uint256 value ) public override returns (bool) {\n _allowedValue[ msg.sender ][ spender ] = value;\n emit Approval( msg.sender, spender, value );\n return true;\n }\n\n // What gets called in a permit\n function _approve( address owner, address spender, uint256 value ) internal override virtual {\n _allowedValue[owner][spender] = value;\n emit Approval( owner, spender, value );\n }\n\n function increaseAllowance( address spender, uint256 addedValue ) public override returns (bool) {\n _allowedValue[ msg.sender ][ spender ] = _allowedValue[ msg.sender ][ spender ].add( addedValue );\n emit Approval( msg.sender, spender, _allowedValue[ msg.sender ][ spender ] );\n return true;\n }\n\n function decreaseAllowance( address spender, uint256 subtractedValue ) public override returns (bool) {\n uint256 oldValue = _allowedValue[ msg.sender ][ spender ];\n if (subtractedValue >= oldValue) {\n _allowedValue[ msg.sender ][ spender ] = 0;\n } else {\n _allowedValue[ msg.sender ][ spender ] = oldValue.sub( subtractedValue );\n }\n emit Approval( msg.sender, spender, _allowedValue[ msg.sender ][ spender ] );\n return true;\n }\n}" + }, + "contracts/Staking.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity 0.7.5;\n\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n}\n\ninterface IERC20 {\n function decimals() external view returns (uint8);\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies in extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain`call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return _functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.3._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.3._\n */\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n function addressToString(address _address) internal pure returns(string memory) {\n bytes32 _bytes = bytes32(uint256(_address));\n bytes memory HEX = \"0123456789abcdef\";\n bytes memory _addr = new bytes(42);\n\n _addr[0] = '0';\n _addr[1] = 'x';\n\n for(uint256 i = 0; i < 20; i++) {\n _addr[2+i*2] = HEX[uint8(_bytes[i + 12] >> 4)];\n _addr[3+i*2] = HEX[uint8(_bytes[i + 12] & 0x0f)];\n }\n\n return string(_addr);\n\n }\n}\n\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n // solhint-disable-next-line max-line-length\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n\ninterface IOwnable {\n function manager() external view returns (address);\n\n function renounceManagement() external;\n \n function pushManagement( address newOwner_ ) external;\n \n function pullManagement() external;\n}\n\ncontract Ownable is IOwnable {\n\n address internal _owner;\n address internal _newOwner;\n\n event OwnershipPushed(address indexed previousOwner, address indexed newOwner);\n event OwnershipPulled(address indexed previousOwner, address indexed newOwner);\n\n constructor () {\n _owner = msg.sender;\n emit OwnershipPushed( address(0), _owner );\n }\n\n function manager() public view override returns (address) {\n return _owner;\n }\n\n modifier onlyManager() {\n require( _owner == msg.sender, \"Ownable: caller is not the owner\" );\n _;\n }\n\n function renounceManagement() public virtual override onlyManager() {\n emit OwnershipPushed( _owner, address(0) );\n _owner = address(0);\n }\n\n function pushManagement( address newOwner_ ) public virtual override onlyManager() {\n require( newOwner_ != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipPushed( _owner, newOwner_ );\n _newOwner = newOwner_;\n }\n \n function pullManagement() public virtual override {\n require( msg.sender == _newOwner, \"Ownable: must be new owner to pull\");\n emit OwnershipPulled( _owner, _newOwner );\n _owner = _newOwner;\n }\n}\n\ninterface IsOHM {\n function rebase( uint256 ohmProfit_, uint epoch_) external returns (uint256);\n\n function circulatingSupply() external view returns (uint256);\n\n function balanceOf(address who) external view returns (uint256);\n\n function gonsForBalance( uint amount ) external view returns ( uint );\n\n function balanceForGons( uint gons ) external view returns ( uint );\n \n function index() external view returns ( uint );\n}\n\ninterface IWarmup {\n function retrieve( address staker_, uint amount_ ) external;\n}\n\ninterface IDistributor {\n function distribute() external returns ( bool );\n}\n\ncontract OlympusStaking is Ownable {\n\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n address public immutable OHM;\n address public immutable sOHM;\n\n struct Epoch {\n uint length;\n uint number;\n uint endBlock;\n uint distribute;\n }\n Epoch public epoch;\n\n address public distributor;\n \n address public locker;\n uint public totalBonus;\n \n address public warmupContract;\n uint public warmupPeriod;\n \n constructor ( \n address _OHM, \n address _sOHM, \n uint _epochLength,\n uint _firstEpochNumber,\n uint _firstEpochBlock\n ) {\n require( _OHM != address(0) );\n OHM = _OHM;\n require( _sOHM != address(0) );\n sOHM = _sOHM;\n \n epoch = Epoch({\n length: _epochLength,\n number: _firstEpochNumber,\n endBlock: _firstEpochBlock,\n distribute: 0\n });\n }\n\n struct Claim {\n uint deposit;\n uint gons;\n uint expiry;\n bool lock; // prevents malicious delays\n }\n mapping( address => Claim ) public warmupInfo;\n\n /**\n @notice stake OHM to enter warmup\n @param _amount uint\n @return bool\n */\n function stake( uint _amount, address _recipient ) external returns ( bool ) {\n rebase();\n \n IERC20( OHM ).safeTransferFrom( msg.sender, address(this), _amount );\n\n Claim memory info = warmupInfo[ _recipient ];\n require( !info.lock, \"Deposits for account are locked\" );\n\n warmupInfo[ _recipient ] = Claim ({\n deposit: info.deposit.add( _amount ),\n gons: info.gons.add( IsOHM( sOHM ).gonsForBalance( _amount ) ),\n expiry: epoch.number.add( warmupPeriod ),\n lock: false\n });\n \n IERC20( sOHM ).safeTransfer( warmupContract, _amount );\n return true;\n }\n\n /**\n @notice retrieve sOHM from warmup\n @param _recipient address\n */\n function claim ( address _recipient ) public {\n Claim memory info = warmupInfo[ _recipient ];\n if ( epoch.number >= info.expiry && info.expiry != 0 ) {\n delete warmupInfo[ _recipient ];\n IWarmup( warmupContract ).retrieve( _recipient, IsOHM( sOHM ).balanceForGons( info.gons ) );\n }\n }\n\n /**\n @notice forfeit sOHM in warmup and retrieve OHM\n */\n function forfeit() external {\n Claim memory info = warmupInfo[ msg.sender ];\n delete warmupInfo[ msg.sender ];\n\n IWarmup( warmupContract ).retrieve( address(this), IsOHM( sOHM ).balanceForGons( info.gons ) );\n IERC20( OHM ).safeTransfer( msg.sender, info.deposit );\n }\n\n /**\n @notice prevent new deposits to address (protection from malicious activity)\n */\n function toggleDepositLock() external {\n warmupInfo[ msg.sender ].lock = !warmupInfo[ msg.sender ].lock;\n }\n\n /**\n @notice redeem sOHM for OHM\n @param _amount uint\n @param _trigger bool\n */\n function unstake( uint _amount, bool _trigger ) external {\n if ( _trigger ) {\n rebase();\n }\n IERC20( sOHM ).safeTransferFrom( msg.sender, address(this), _amount );\n IERC20( OHM ).safeTransfer( msg.sender, _amount );\n }\n\n /**\n @notice returns the sOHM index, which tracks rebase growth\n @return uint\n */\n function index() public view returns ( uint ) {\n return IsOHM( sOHM ).index();\n }\n\n /**\n @notice trigger rebase if epoch over\n */\n function rebase() public {\n if( epoch.endBlock <= block.number ) {\n\n IsOHM( sOHM ).rebase( epoch.distribute, epoch.number );\n\n epoch.endBlock = epoch.endBlock.add( epoch.length );\n epoch.number++;\n \n if ( distributor != address(0) ) {\n IDistributor( distributor ).distribute();\n }\n\n uint balance = contractBalance();\n uint staked = IsOHM( sOHM ).circulatingSupply();\n\n if( balance <= staked ) {\n epoch.distribute = 0;\n } else {\n epoch.distribute = balance.sub( staked );\n }\n }\n }\n\n /**\n @notice returns contract OHM holdings, including bonuses provided\n @return uint\n */\n function contractBalance() public view returns ( uint ) {\n return IERC20( OHM ).balanceOf( address(this) ).add( totalBonus );\n }\n\n /**\n @notice provide bonus to locked staking contract\n @param _amount uint\n */\n function giveLockBonus( uint _amount ) external {\n require( msg.sender == locker );\n totalBonus = totalBonus.add( _amount );\n IERC20( sOHM ).safeTransfer( locker, _amount );\n }\n\n /**\n @notice reclaim bonus from locked staking contract\n @param _amount uint\n */\n function returnLockBonus( uint _amount ) external {\n require( msg.sender == locker );\n totalBonus = totalBonus.sub( _amount );\n IERC20( sOHM ).safeTransferFrom( locker, address(this), _amount );\n }\n\n enum CONTRACTS { DISTRIBUTOR, WARMUP, LOCKER }\n\n /**\n @notice sets the contract address for LP staking\n @param _contract address\n */\n function setContract( CONTRACTS _contract, address _address ) external onlyManager() {\n if( _contract == CONTRACTS.DISTRIBUTOR ) { // 0\n distributor = _address;\n } else if ( _contract == CONTRACTS.WARMUP ) { // 1\n require( warmupContract == address( 0 ), \"Warmup cannot be set more than once\" );\n warmupContract = _address;\n } else if ( _contract == CONTRACTS.LOCKER ) { // 2\n require( locker == address(0), \"Locker cannot be set more than once\" );\n locker = _address;\n }\n }\n \n /**\n * @notice set warmup period for new stakers\n * @param _warmupPeriod uint\n */\n function setWarmup( uint _warmupPeriod ) external onlyManager() {\n warmupPeriod = _warmupPeriod;\n }\n}" + }, + "contracts/StakingDistributor.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\n\npragma solidity 0.7.5;\n\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n\nlibrary SafeMath {\n\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n\n // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)\n function sqrrt(uint256 a) internal pure returns (uint c) {\n if (a > 3) {\n c = a;\n uint b = add( div( a, 2), 1 );\n while (b < c) {\n c = b;\n b = div( add( div( a, b ), b), 2 );\n }\n } else if (a != 0) {\n c = 1;\n }\n }\n\n function percentageAmount( uint256 total_, uint8 percentage_ ) internal pure returns ( uint256 percentAmount_ ) {\n return div( mul( total_, percentage_ ), 1000 );\n }\n\n function substractPercentage( uint256 total_, uint8 percentageToSub_ ) internal pure returns ( uint256 result_ ) {\n return sub( total_, div( mul( total_, percentageToSub_ ), 1000 ) );\n }\n\n function percentageOfTotal( uint256 part_, uint256 total_ ) internal pure returns ( uint256 percent_ ) {\n return div( mul(part_, 100) , total_ );\n }\n\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow, so we distribute\n return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);\n }\n\n function quadraticPricing( uint256 payment_, uint256 multiplier_ ) internal pure returns (uint256) {\n return sqrrt( mul( multiplier_, payment_ ) );\n }\n\n function bondingCurve( uint256 supply_, uint256 multiplier_ ) internal pure returns (uint256) {\n return mul( multiplier_, supply_ );\n }\n}\n\ninterface IERC20 {\n\n function totalSupply() external view returns (uint256);\n\n function balanceOf(address account) external view returns (uint256);\n\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n function allowance(address owner, address spender) external view returns (uint256);\n\n function approve(address spender, uint256 amount) external returns (bool);\n\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n\nlibrary Address {\n\n function isContract(address account) internal view returns (bool) {\n // This method relies in extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return _functionCallWithValue(target, data, 0, errorMessage);\n }\n\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n if (returndata.length > 0) {\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n function addressToString(address _address) internal pure returns(string memory) {\n bytes32 _bytes = bytes32(uint256(_address));\n bytes memory HEX = \"0123456789abcdef\";\n bytes memory _addr = new bytes(42);\n\n _addr[0] = '0';\n _addr[1] = 'x';\n\n for(uint256 i = 0; i < 20; i++) {\n _addr[2+i*2] = HEX[uint8(_bytes[i + 12] >> 4)];\n _addr[3+i*2] = HEX[uint8(_bytes[i + 12] & 0x0f)];\n }\n\n return string(_addr);\n\n }\n}\n\n\ninterface IPolicy {\n\n function policy() external view returns (address);\n\n function renouncePolicy() external;\n \n function pushPolicy( address newPolicy_ ) external;\n\n function pullPolicy() external;\n}\n\ncontract Policy is IPolicy {\n \n address internal _policy;\n address internal _newPolicy;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n constructor () {\n _policy = msg.sender;\n emit OwnershipTransferred( address(0), _policy );\n }\n\n function policy() public view override returns (address) {\n return _policy;\n }\n\n modifier onlyPolicy() {\n require( _policy == msg.sender, \"Ownable: caller is not the owner\" );\n _;\n }\n\n function renouncePolicy() public virtual override onlyPolicy() {\n emit OwnershipTransferred( _policy, address(0) );\n _policy = address(0);\n }\n\n function pushPolicy( address newPolicy_ ) public virtual override onlyPolicy() {\n require( newPolicy_ != address(0), \"Ownable: new owner is the zero address\");\n _newPolicy = newPolicy_;\n }\n\n function pullPolicy() public virtual override {\n require( msg.sender == _newPolicy );\n emit OwnershipTransferred( _policy, _newPolicy );\n _policy = _newPolicy;\n }\n}\n\ninterface ITreasury {\n function mintRewards( address _recipient, uint _amount ) external;\n}\n\ncontract Distributor is Policy {\n using SafeMath for uint;\n using SafeERC20 for IERC20;\n \n \n \n /* ====== VARIABLES ====== */\n\n address public immutable OHM;\n address public immutable treasury;\n \n uint public immutable epochLength;\n uint public nextEpochBlock;\n \n mapping( uint => Adjust ) public adjustments;\n \n \n /* ====== STRUCTS ====== */\n \n struct Info {\n uint rate; // in ten-thousandths ( 5000 = 0.5% )\n address recipient;\n }\n Info[] public info;\n \n struct Adjust {\n bool add;\n uint rate;\n uint target;\n }\n \n \n \n /* ====== CONSTRUCTOR ====== */\n\n constructor( address _treasury, address _ohm, uint _epochLength, uint _nextEpochBlock ) { \n require( _treasury != address(0) );\n treasury = _treasury;\n require( _ohm != address(0) );\n OHM = _ohm;\n epochLength = _epochLength;\n nextEpochBlock = _nextEpochBlock;\n }\n \n \n \n /* ====== PUBLIC FUNCTIONS ====== */\n \n /**\n @notice send epoch reward to staking contract\n */\n function distribute() external returns ( bool ) {\n if ( nextEpochBlock <= block.number ) {\n nextEpochBlock = nextEpochBlock.add( epochLength ); // set next epoch block\n \n // distribute rewards to each recipient\n for ( uint i = 0; i < info.length; i++ ) {\n if ( info[ i ].rate > 0 ) {\n ITreasury( treasury ).mintRewards( // mint and send from treasury\n info[ i ].recipient, \n nextRewardAt( info[ i ].rate ) \n );\n adjust( i ); // check for adjustment\n }\n }\n return true;\n } else { \n return false; \n }\n }\n \n \n \n /* ====== INTERNAL FUNCTIONS ====== */\n\n /**\n @notice increment reward rate for collector\n */\n function adjust( uint _index ) internal {\n Adjust memory adjustment = adjustments[ _index ];\n if ( adjustment.rate != 0 ) {\n if ( adjustment.add ) { // if rate should increase\n info[ _index ].rate = info[ _index ].rate.add( adjustment.rate ); // raise rate\n if ( info[ _index ].rate >= adjustment.target ) { // if target met\n adjustments[ _index ].rate = 0; // turn off adjustment\n }\n } else { // if rate should decrease\n info[ _index ].rate = info[ _index ].rate.sub( adjustment.rate ); // lower rate\n if ( info[ _index ].rate <= adjustment.target ) { // if target met\n adjustments[ _index ].rate = 0; // turn off adjustment\n }\n }\n }\n }\n \n \n \n /* ====== VIEW FUNCTIONS ====== */\n\n /**\n @notice view function for next reward at given rate\n @param _rate uint\n @return uint\n */\n function nextRewardAt( uint _rate ) public view returns ( uint ) {\n return IERC20( OHM ).totalSupply().mul( _rate ).div( 1000000 );\n }\n\n /**\n @notice view function for next reward for specified address\n @param _recipient address\n @return uint\n */\n function nextRewardFor( address _recipient ) public view returns ( uint ) {\n uint reward;\n for ( uint i = 0; i < info.length; i++ ) {\n if ( info[ i ].recipient == _recipient ) {\n reward = nextRewardAt( info[ i ].rate );\n }\n }\n return reward;\n }\n \n \n \n /* ====== POLICY FUNCTIONS ====== */\n\n /**\n @notice adds recipient for distributions\n @param _recipient address\n @param _rewardRate uint\n */\n function addRecipient( address _recipient, uint _rewardRate ) external onlyPolicy() {\n require( _recipient != address(0) );\n info.push( Info({\n recipient: _recipient,\n rate: _rewardRate\n }));\n }\n\n /**\n @notice removes recipient for distributions\n @param _index uint\n @param _recipient address\n */\n function removeRecipient( uint _index, address _recipient ) external onlyPolicy() {\n require( _recipient == info[ _index ].recipient );\n info[ _index ].recipient = address(0);\n info[ _index ].rate = 0;\n }\n\n /**\n @notice set adjustment info for a collector's reward rate\n @param _index uint\n @param _add bool\n @param _rate uint\n @param _target uint\n */\n function setAdjustment( uint _index, bool _add, uint _rate, uint _target ) external onlyPolicy() {\n adjustments[ _index ] = Adjust({\n add: _add,\n rate: _rate,\n target: _target\n });\n }\n}" + }, + "contracts/StakingHelper.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity 0.7.5;\n\n\ninterface IERC20 {\n function decimals() external view returns (uint8);\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n\ninterface IStaking {\n function stake( uint _amount, address _recipient ) external returns ( bool );\n function claim( address _recipient ) external;\n}\n\ncontract StakingHelper {\n\n address public immutable staking;\n address public immutable OHM;\n\n constructor ( address _staking, address _OHM ) {\n require( _staking != address(0) );\n staking = _staking;\n require( _OHM != address(0) );\n OHM = _OHM;\n }\n\n function stake( uint _amount ) external {\n IERC20( OHM ).transferFrom( msg.sender, address(this), _amount );\n IERC20( OHM ).approve( staking, _amount );\n IStaking( staking ).stake( _amount, msg.sender );\n IStaking( staking ).claim( msg.sender );\n }\n}" + }, + "contracts/StakingWarmup.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity 0.7.5;\n\n\ninterface IERC20 {\n function decimals() external view returns (uint8);\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n\ncontract StakingWarmup {\n\n address public immutable staking;\n address public immutable sOHM;\n\n constructor ( address _staking, address _sOHM ) {\n require( _staking != address(0) );\n staking = _staking;\n require( _sOHM != address(0) );\n sOHM = _sOHM;\n }\n\n function retrieve( address _staker, uint _amount ) external {\n require( msg.sender == staking );\n IERC20( sOHM ).transfer( _staker, _amount );\n }\n}" + }, + "contracts/StandardBondingCalculator.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity 0.7.5;\n\nlibrary FullMath {\n function fullMul(uint256 x, uint256 y) private pure returns (uint256 l, uint256 h) {\n uint256 mm = mulmod(x, y, uint256(-1));\n l = x * y;\n h = mm - l;\n if (mm < l) h -= 1;\n }\n\n function fullDiv(\n uint256 l,\n uint256 h,\n uint256 d\n ) private pure returns (uint256) {\n uint256 pow2 = d & -d;\n d /= pow2;\n l /= pow2;\n l += h * ((-pow2) / pow2 + 1);\n uint256 r = 1;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n return l * r;\n }\n\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 d\n ) internal pure returns (uint256) {\n (uint256 l, uint256 h) = fullMul(x, y);\n uint256 mm = mulmod(x, y, d);\n if (mm > l) h -= 1;\n l -= mm;\n require(h < d, 'FullMath::mulDiv: overflow');\n return fullDiv(l, h, d);\n }\n}\n\nlibrary Babylonian {\n\n function sqrt(uint256 x) internal pure returns (uint256) {\n if (x == 0) return 0;\n\n uint256 xx = x;\n uint256 r = 1;\n if (xx >= 0x100000000000000000000000000000000) {\n xx >>= 128;\n r <<= 64;\n }\n if (xx >= 0x10000000000000000) {\n xx >>= 64;\n r <<= 32;\n }\n if (xx >= 0x100000000) {\n xx >>= 32;\n r <<= 16;\n }\n if (xx >= 0x10000) {\n xx >>= 16;\n r <<= 8;\n }\n if (xx >= 0x100) {\n xx >>= 8;\n r <<= 4;\n }\n if (xx >= 0x10) {\n xx >>= 4;\n r <<= 2;\n }\n if (xx >= 0x8) {\n r <<= 1;\n }\n r = (r + x / r) >> 1;\n r = (r + x / r) >> 1;\n r = (r + x / r) >> 1;\n r = (r + x / r) >> 1;\n r = (r + x / r) >> 1;\n r = (r + x / r) >> 1;\n r = (r + x / r) >> 1; // Seven iterations should be enough\n uint256 r1 = x / r;\n return (r < r1 ? r : r1);\n }\n}\n\nlibrary BitMath {\n\n function mostSignificantBit(uint256 x) internal pure returns (uint8 r) {\n require(x > 0, 'BitMath::mostSignificantBit: zero');\n\n if (x >= 0x100000000000000000000000000000000) {\n x >>= 128;\n r += 128;\n }\n if (x >= 0x10000000000000000) {\n x >>= 64;\n r += 64;\n }\n if (x >= 0x100000000) {\n x >>= 32;\n r += 32;\n }\n if (x >= 0x10000) {\n x >>= 16;\n r += 16;\n }\n if (x >= 0x100) {\n x >>= 8;\n r += 8;\n }\n if (x >= 0x10) {\n x >>= 4;\n r += 4;\n }\n if (x >= 0x4) {\n x >>= 2;\n r += 2;\n }\n if (x >= 0x2) r += 1;\n }\n}\n\nlibrary FixedPoint {\n // range: [0, 2**112 - 1]\n // resolution: 1 / 2**112\n struct uq112x112 {\n uint224 _x;\n }\n\n // range: [0, 2**144 - 1]\n // resolution: 1 / 2**112\n struct uq144x112 {\n uint256 _x;\n }\n\n uint8 private constant RESOLUTION = 112;\n uint256 private constant Q112 = 0x10000000000000000000000000000;\n uint256 private constant Q224 = 0x100000000000000000000000000000000000000000000000000000000;\n uint256 private constant LOWER_MASK = 0xffffffffffffffffffffffffffff; // decimal of UQ*x112 (lower 112 bits)\n\n // decode a UQ112x112 into a uint112 by truncating after the radix point\n function decode(uq112x112 memory self) internal pure returns (uint112) {\n return uint112(self._x >> RESOLUTION);\n }\n\n // decode a uq112x112 into a uint with 18 decimals of precision\n function decode112with18(uq112x112 memory self) internal pure returns (uint) {\n return uint(self._x) / 5192296858534827;\n }\n\n function fraction(uint256 numerator, uint256 denominator) internal pure returns (uq112x112 memory) {\n require(denominator > 0, 'FixedPoint::fraction: division by zero');\n if (numerator == 0) return FixedPoint.uq112x112(0);\n\n if (numerator <= uint144(-1)) {\n uint256 result = (numerator << RESOLUTION) / denominator;\n require(result <= uint224(-1), 'FixedPoint::fraction: overflow');\n return uq112x112(uint224(result));\n } else {\n uint256 result = FullMath.mulDiv(numerator, Q112, denominator);\n require(result <= uint224(-1), 'FixedPoint::fraction: overflow');\n return uq112x112(uint224(result));\n }\n }\n\n // square root of a UQ112x112\n // lossy between 0/1 and 40 bits\n function sqrt(uq112x112 memory self) internal pure returns (uq112x112 memory) {\n if (self._x <= uint144(-1)) {\n return uq112x112(uint224(Babylonian.sqrt(uint256(self._x) << 112)));\n }\n\n uint8 safeShiftBits = 255 - BitMath.mostSignificantBit(self._x);\n safeShiftBits -= safeShiftBits % 2;\n return uq112x112(uint224(Babylonian.sqrt(uint256(self._x) << safeShiftBits) << ((112 - safeShiftBits) / 2)));\n }\n}\n\nlibrary SafeMath {\n\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n function sqrrt(uint256 a) internal pure returns (uint c) {\n if (a > 3) {\n c = a;\n uint b = add( div( a, 2), 1 );\n while (b < c) {\n c = b;\n b = div( add( div( a, b ), b), 2 );\n }\n } else if (a != 0) {\n c = 1;\n }\n }\n}\n\ninterface IERC20 {\n function decimals() external view returns (uint8);\n}\n\ninterface IUniswapV2ERC20 {\n function totalSupply() external view returns (uint);\n}\n\ninterface IUniswapV2Pair is IUniswapV2ERC20 {\n function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n function token0() external view returns ( address );\n function token1() external view returns ( address );\n}\n\ninterface IBondingCalculator {\n function valuation( address pair_, uint amount_ ) external view returns ( uint _value );\n}\n\ncontract OlympusBondingCalculator is IBondingCalculator {\n\n using FixedPoint for *;\n using SafeMath for uint;\n using SafeMath for uint112;\n\n address public immutable OHM;\n\n constructor( address _OHM ) {\n require( _OHM != address(0) );\n OHM = _OHM;\n }\n\n function getKValue( address _pair ) public view returns( uint k_ ) {\n uint token0 = IERC20( IUniswapV2Pair( _pair ).token0() ).decimals();\n uint token1 = IERC20( IUniswapV2Pair( _pair ).token1() ).decimals();\n uint decimals = token0.add( token1 ).sub( IERC20( _pair ).decimals() );\n\n (uint reserve0, uint reserve1, ) = IUniswapV2Pair( _pair ).getReserves();\n k_ = reserve0.mul(reserve1).div( 10 ** decimals );\n }\n\n function getTotalValue( address _pair ) public view returns ( uint _value ) {\n _value = getKValue( _pair ).sqrrt().mul(2);\n }\n\n function valuation( address _pair, uint amount_ ) external view override returns ( uint _value ) {\n uint totalValue = getTotalValue( _pair );\n uint totalSupply = IUniswapV2Pair( _pair ).totalSupply();\n\n _value = totalValue.mul( FixedPoint.fraction( amount_, totalSupply ).decode112with18() ).div( 1e18 );\n }\n\n function markdown( address _pair ) external view returns ( uint ) {\n ( uint reserve0, uint reserve1, ) = IUniswapV2Pair( _pair ).getReserves();\n\n uint reserve;\n if ( IUniswapV2Pair( _pair ).token0() == OHM ) {\n reserve = reserve1;\n } else {\n reserve = reserve0;\n }\n return reserve.mul( 2 * ( 10 ** IERC20( OHM ).decimals() ) ).div( getTotalValue( _pair ) );\n }\n}\n" + }, + "contracts/Treasury.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity 0.7.5;\n\nlibrary SafeMath {\n\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n return c;\n }\n}\n\nlibrary Address {\n\n function isContract(address account) internal view returns (bool) {\n // This method relies in extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return _functionCallWithValue(target, data, 0, errorMessage);\n }\n\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\n if (success) {\n return returndata;\n } else {\n if (returndata.length > 0) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n if (returndata.length > 0) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ninterface IOwnable {\n function manager() external view returns (address);\n\n function renounceManagement() external;\n \n function pushManagement( address newOwner_ ) external;\n \n function pullManagement() external;\n}\n\ncontract Ownable is IOwnable {\n\n address internal _owner;\n address internal _newOwner;\n\n event OwnershipPushed(address indexed previousOwner, address indexed newOwner);\n event OwnershipPulled(address indexed previousOwner, address indexed newOwner);\n\n constructor () {\n _owner = msg.sender;\n emit OwnershipPushed( address(0), _owner );\n }\n\n function manager() public view override returns (address) {\n return _owner;\n }\n\n modifier onlyManager() {\n require( _owner == msg.sender, \"Ownable: caller is not the owner\" );\n _;\n }\n\n function renounceManagement() public virtual override onlyManager() {\n emit OwnershipPushed( _owner, address(0) );\n _owner = address(0);\n }\n\n function pushManagement( address newOwner_ ) public virtual override onlyManager() {\n require( newOwner_ != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipPushed( _owner, newOwner_ );\n _newOwner = newOwner_;\n }\n \n function pullManagement() public virtual override {\n require( msg.sender == _newOwner, \"Ownable: must be new owner to pull\");\n emit OwnershipPulled( _owner, _newOwner );\n _owner = _newOwner;\n }\n}\n\ninterface IERC20 {\n function decimals() external view returns (uint8);\n\n function balanceOf(address account) external view returns (uint256);\n\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n function approve(address spender, uint256 amount) external returns (bool);\n\n function totalSupply() external view returns (uint256);\n\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n\ninterface IERC20Mintable {\n function mint( uint256 amount_ ) external;\n\n function mint( address account_, uint256 ammount_ ) external;\n}\n\ninterface IOHMERC20 {\n function burnFrom(address account_, uint256 amount_) external;\n}\n\ninterface IBondCalculator {\n function valuation( address pair_, uint amount_ ) external view returns ( uint _value );\n}\n\ncontract OlympusTreasury is Ownable {\n\n using SafeMath for uint;\n using SafeERC20 for IERC20;\n\n event Deposit( address indexed token, uint amount, uint value );\n event Withdrawal( address indexed token, uint amount, uint value );\n event CreateDebt( address indexed debtor, address indexed token, uint amount, uint value );\n event RepayDebt( address indexed debtor, address indexed token, uint amount, uint value );\n event ReservesManaged( address indexed token, uint amount );\n event ReservesUpdated( uint indexed totalReserves );\n event ReservesAudited( uint indexed totalReserves );\n event RewardsMinted( address indexed caller, address indexed recipient, uint amount );\n event ChangeQueued( MANAGING indexed managing, address queued );\n event ChangeActivated( MANAGING indexed managing, address activated, bool result );\n\n enum MANAGING { RESERVEDEPOSITOR, RESERVESPENDER, RESERVETOKEN, RESERVEMANAGER, LIQUIDITYDEPOSITOR, LIQUIDITYTOKEN, LIQUIDITYMANAGER, DEBTOR, REWARDMANAGER, SOHM }\n\n address public immutable OHM;\n uint public immutable blocksNeededForQueue;\n\n address[] public reserveTokens; // Push only, beware false-positives.\n mapping( address => bool ) public isReserveToken;\n mapping( address => uint ) public reserveTokenQueue; // Delays changes to mapping.\n\n address[] public reserveDepositors; // Push only, beware false-positives. Only for viewing.\n mapping( address => bool ) public isReserveDepositor;\n mapping( address => uint ) public reserveDepositorQueue; // Delays changes to mapping.\n\n address[] public reserveSpenders; // Push only, beware false-positives. Only for viewing.\n mapping( address => bool ) public isReserveSpender;\n mapping( address => uint ) public reserveSpenderQueue; // Delays changes to mapping.\n\n address[] public liquidityTokens; // Push only, beware false-positives.\n mapping( address => bool ) public isLiquidityToken;\n mapping( address => uint ) public LiquidityTokenQueue; // Delays changes to mapping.\n\n address[] public liquidityDepositors; // Push only, beware false-positives. Only for viewing.\n mapping( address => bool ) public isLiquidityDepositor;\n mapping( address => uint ) public LiquidityDepositorQueue; // Delays changes to mapping.\n\n mapping( address => address ) public bondCalculator; // bond calculator for liquidity token\n\n address[] public reserveManagers; // Push only, beware false-positives. Only for viewing.\n mapping( address => bool ) public isReserveManager;\n mapping( address => uint ) public ReserveManagerQueue; // Delays changes to mapping.\n\n address[] public liquidityManagers; // Push only, beware false-positives. Only for viewing.\n mapping( address => bool ) public isLiquidityManager;\n mapping( address => uint ) public LiquidityManagerQueue; // Delays changes to mapping.\n\n address[] public debtors; // Push only, beware false-positives. Only for viewing.\n mapping( address => bool ) public isDebtor;\n mapping( address => uint ) public debtorQueue; // Delays changes to mapping.\n mapping( address => uint ) public debtorBalance;\n\n address[] public rewardManagers; // Push only, beware false-positives. Only for viewing.\n mapping( address => bool ) public isRewardManager;\n mapping( address => uint ) public rewardManagerQueue; // Delays changes to mapping.\n\n address public sOHM;\n uint public sOHMQueue; // Delays change to sOHM address\n \n uint public totalReserves; // Risk-free value of all assets\n uint public totalDebt;\n\n constructor (\n address _OHM,\n address _DAI,\n address _Frax,\n address _OHMDAI,\n uint _blocksNeededForQueue\n ) {\n require( _OHM != address(0) );\n OHM = _OHM;\n\n isReserveToken[ _DAI ] = true;\n reserveTokens.push( _DAI );\n\n isReserveToken[ _Frax] = true;\n reserveTokens.push( _Frax );\n\n isLiquidityToken[ _OHMDAI ] = true;\n liquidityTokens.push( _OHMDAI );\n\n blocksNeededForQueue = _blocksNeededForQueue;\n }\n\n /**\n @notice allow approved address to deposit an asset for OHM\n @param _amount uint\n @param _token address\n @param _profit uint\n @return send_ uint\n */\n function deposit( uint _amount, address _token, uint _profit ) external returns ( uint send_ ) {\n require( isReserveToken[ _token ] || isLiquidityToken[ _token ], \"Not accepted\" );\n IERC20( _token ).safeTransferFrom( msg.sender, address(this), _amount );\n\n if ( isReserveToken[ _token ] ) {\n require( isReserveDepositor[ msg.sender ], \"Not approved\" );\n } else {\n require( isLiquidityDepositor[ msg.sender ], \"Not approved\" );\n }\n\n uint value = valueOf(_token, _amount);\n // mint OHM needed and store amount of rewards for distribution\n send_ = value.sub( _profit );\n IERC20Mintable( OHM ).mint( msg.sender, send_ );\n\n totalReserves = totalReserves.add( value );\n emit ReservesUpdated( totalReserves );\n\n emit Deposit( _token, _amount, value );\n }\n\n /**\n @notice allow approved address to burn OHM for reserves\n @param _amount uint\n @param _token address\n */\n function withdraw( uint _amount, address _token ) external {\n require( isReserveToken[ _token ], \"Not accepted\" ); // Only reserves can be used for redemptions\n require( isReserveSpender[ msg.sender ] == true, \"Not approved\" );\n\n uint value = valueOf( _token, _amount );\n IOHMERC20( OHM ).burnFrom( msg.sender, value );\n\n totalReserves = totalReserves.sub( value );\n emit ReservesUpdated( totalReserves );\n\n IERC20( _token ).safeTransfer( msg.sender, _amount );\n\n emit Withdrawal( _token, _amount, value );\n }\n\n /**\n @notice allow approved address to borrow reserves\n @param _amount uint\n @param _token address\n */\n function incurDebt( uint _amount, address _token ) external {\n require( isDebtor[ msg.sender ], \"Not approved\" );\n require( isReserveToken[ _token ], \"Not accepted\" );\n\n uint value = valueOf( _token, _amount );\n\n uint maximumDebt = IERC20( sOHM ).balanceOf( msg.sender ); // Can only borrow against sOHM held\n uint availableDebt = maximumDebt.sub( debtorBalance[ msg.sender ] );\n require( value <= availableDebt, \"Exceeds debt limit\" );\n\n debtorBalance[ msg.sender ] = debtorBalance[ msg.sender ].add( value );\n totalDebt = totalDebt.add( value );\n\n totalReserves = totalReserves.sub( value );\n emit ReservesUpdated( totalReserves );\n\n IERC20( _token ).transfer( msg.sender, _amount );\n \n emit CreateDebt( msg.sender, _token, _amount, value );\n }\n\n /**\n @notice allow approved address to repay borrowed reserves with reserves\n @param _amount uint\n @param _token address\n */\n function repayDebtWithReserve( uint _amount, address _token ) external {\n require( isDebtor[ msg.sender ], \"Not approved\" );\n require( isReserveToken[ _token ], \"Not accepted\" );\n\n IERC20( _token ).safeTransferFrom( msg.sender, address(this), _amount );\n\n uint value = valueOf( _token, _amount );\n debtorBalance[ msg.sender ] = debtorBalance[ msg.sender ].sub( value );\n totalDebt = totalDebt.sub( value );\n\n totalReserves = totalReserves.add( value );\n emit ReservesUpdated( totalReserves );\n\n emit RepayDebt( msg.sender, _token, _amount, value );\n }\n\n /**\n @notice allow approved address to repay borrowed reserves with OHM\n @param _amount uint\n */\n function repayDebtWithOHM( uint _amount ) external {\n require( isDebtor[ msg.sender ], \"Not approved\" );\n\n IOHMERC20( OHM ).burnFrom( msg.sender, _amount );\n\n debtorBalance[ msg.sender ] = debtorBalance[ msg.sender ].sub( _amount );\n totalDebt = totalDebt.sub( _amount );\n\n emit RepayDebt( msg.sender, OHM, _amount, _amount );\n }\n\n /**\n @notice allow approved address to withdraw assets\n @param _token address\n @param _amount uint\n */\n function manage( address _token, uint _amount ) external {\n if( isLiquidityToken[ _token ] ) {\n require( isLiquidityManager[ msg.sender ], \"Not approved\" );\n } else {\n require( isReserveManager[ msg.sender ], \"Not approved\" );\n }\n\n uint value = valueOf(_token, _amount);\n require( value <= excessReserves(), \"Insufficient reserves\" );\n\n totalReserves = totalReserves.sub( value );\n emit ReservesUpdated( totalReserves );\n\n IERC20( _token ).safeTransfer( msg.sender, _amount );\n\n emit ReservesManaged( _token, _amount );\n }\n\n /**\n @notice send epoch reward to staking contract\n */\n function mintRewards( address _recipient, uint _amount ) external {\n require( isRewardManager[ msg.sender ], \"Not approved\" );\n require( _amount <= excessReserves(), \"Insufficient reserves\" );\n\n IERC20Mintable( OHM ).mint( _recipient, _amount );\n\n emit RewardsMinted( msg.sender, _recipient, _amount );\n } \n\n /**\n @notice returns excess reserves not backing tokens\n @return uint\n */\n function excessReserves() public view returns ( uint ) {\n return totalReserves.sub( IERC20( OHM ).totalSupply().sub( totalDebt ) );\n }\n\n /**\n @notice takes inventory of all tracked assets\n @notice always consolidate to recognized reserves before audit\n */\n function auditReserves() external onlyManager() {\n uint reserves;\n for( uint i = 0; i < reserveTokens.length; i++ ) {\n reserves = reserves.add ( \n valueOf( reserveTokens[ i ], IERC20( reserveTokens[ i ] ).balanceOf( address(this) ) )\n );\n }\n for( uint i = 0; i < liquidityTokens.length; i++ ) {\n reserves = reserves.add (\n valueOf( liquidityTokens[ i ], IERC20( liquidityTokens[ i ] ).balanceOf( address(this) ) )\n );\n }\n totalReserves = reserves;\n emit ReservesUpdated( reserves );\n emit ReservesAudited( reserves );\n }\n\n /**\n @notice returns OHM valuation of asset\n @param _token address\n @param _amount uint\n @return value_ uint\n */\n function valueOf( address _token, uint _amount ) public view returns ( uint value_ ) {\n if ( isReserveToken[ _token ] ) {\n // convert amount to match OHM decimals\n value_ = _amount.mul( 10 ** IERC20( OHM ).decimals() ).div( 10 ** IERC20( _token ).decimals() );\n } else if ( isLiquidityToken[ _token ] ) {\n value_ = IBondCalculator( bondCalculator[ _token ] ).valuation( _token, _amount );\n }\n }\n\n /**\n @notice queue address to change boolean in mapping\n @param _managing MANAGING\n @param _address address\n @return bool\n */\n function queue( MANAGING _managing, address _address ) external onlyManager() returns ( bool ) {\n require( _address != address(0) );\n if ( _managing == MANAGING.RESERVEDEPOSITOR ) { // 0\n reserveDepositorQueue[ _address ] = block.number.add( blocksNeededForQueue );\n } else if ( _managing == MANAGING.RESERVESPENDER ) { // 1\n reserveSpenderQueue[ _address ] = block.number.add( blocksNeededForQueue );\n } else if ( _managing == MANAGING.RESERVETOKEN ) { // 2\n reserveTokenQueue[ _address ] = block.number.add( blocksNeededForQueue );\n } else if ( _managing == MANAGING.RESERVEMANAGER ) { // 3\n ReserveManagerQueue[ _address ] = block.number.add( blocksNeededForQueue.mul( 2 ) );\n } else if ( _managing == MANAGING.LIQUIDITYDEPOSITOR ) { // 4\n LiquidityDepositorQueue[ _address ] = block.number.add( blocksNeededForQueue );\n } else if ( _managing == MANAGING.LIQUIDITYTOKEN ) { // 5\n LiquidityTokenQueue[ _address ] = block.number.add( blocksNeededForQueue );\n } else if ( _managing == MANAGING.LIQUIDITYMANAGER ) { // 6\n LiquidityManagerQueue[ _address ] = block.number.add( blocksNeededForQueue.mul( 2 ) );\n } else if ( _managing == MANAGING.DEBTOR ) { // 7\n debtorQueue[ _address ] = block.number.add( blocksNeededForQueue );\n } else if ( _managing == MANAGING.REWARDMANAGER ) { // 8\n rewardManagerQueue[ _address ] = block.number.add( blocksNeededForQueue );\n } else if ( _managing == MANAGING.SOHM ) { // 9\n sOHMQueue = block.number.add( blocksNeededForQueue );\n } else return false;\n\n emit ChangeQueued( _managing, _address );\n return true;\n }\n\n /**\n @notice verify queue then set boolean in mapping\n @param _managing MANAGING\n @param _address address\n @param _calculator address\n @return bool\n */\n function toggle( MANAGING _managing, address _address, address _calculator ) external onlyManager() returns ( bool ) {\n require( _address != address(0) );\n bool result;\n if ( _managing == MANAGING.RESERVEDEPOSITOR ) { // 0\n if ( requirements( reserveDepositorQueue, isReserveDepositor, _address ) ) {\n reserveDepositorQueue[ _address ] = 0;\n if( !listContains( reserveDepositors, _address ) ) {\n reserveDepositors.push( _address );\n }\n }\n result = !isReserveDepositor[ _address ];\n isReserveDepositor[ _address ] = result;\n \n } else if ( _managing == MANAGING.RESERVESPENDER ) { // 1\n if ( requirements( reserveSpenderQueue, isReserveSpender, _address ) ) {\n reserveSpenderQueue[ _address ] = 0;\n if( !listContains( reserveSpenders, _address ) ) {\n reserveSpenders.push( _address );\n }\n }\n result = !isReserveSpender[ _address ];\n isReserveSpender[ _address ] = result;\n\n } else if ( _managing == MANAGING.RESERVETOKEN ) { // 2\n if ( requirements( reserveTokenQueue, isReserveToken, _address ) ) {\n reserveTokenQueue[ _address ] = 0;\n if( !listContains( reserveTokens, _address ) ) {\n reserveTokens.push( _address );\n }\n }\n result = !isReserveToken[ _address ];\n isReserveToken[ _address ] = result;\n\n } else if ( _managing == MANAGING.RESERVEMANAGER ) { // 3\n if ( requirements( ReserveManagerQueue, isReserveManager, _address ) ) {\n reserveManagers.push( _address );\n ReserveManagerQueue[ _address ] = 0;\n if( !listContains( reserveManagers, _address ) ) {\n reserveManagers.push( _address );\n }\n }\n result = !isReserveManager[ _address ];\n isReserveManager[ _address ] = result;\n\n } else if ( _managing == MANAGING.LIQUIDITYDEPOSITOR ) { // 4\n if ( requirements( LiquidityDepositorQueue, isLiquidityDepositor, _address ) ) {\n liquidityDepositors.push( _address );\n LiquidityDepositorQueue[ _address ] = 0;\n if( !listContains( liquidityDepositors, _address ) ) {\n liquidityDepositors.push( _address );\n }\n }\n result = !isLiquidityDepositor[ _address ];\n isLiquidityDepositor[ _address ] = result;\n\n } else if ( _managing == MANAGING.LIQUIDITYTOKEN ) { // 5\n if ( requirements( LiquidityTokenQueue, isLiquidityToken, _address ) ) {\n LiquidityTokenQueue[ _address ] = 0;\n if( !listContains( liquidityTokens, _address ) ) {\n liquidityTokens.push( _address );\n }\n }\n result = !isLiquidityToken[ _address ];\n isLiquidityToken[ _address ] = result;\n bondCalculator[ _address ] = _calculator;\n\n } else if ( _managing == MANAGING.LIQUIDITYMANAGER ) { // 6\n if ( requirements( LiquidityManagerQueue, isLiquidityManager, _address ) ) {\n LiquidityManagerQueue[ _address ] = 0;\n if( !listContains( liquidityManagers, _address ) ) {\n liquidityManagers.push( _address );\n }\n }\n result = !isLiquidityManager[ _address ];\n isLiquidityManager[ _address ] = result;\n\n } else if ( _managing == MANAGING.DEBTOR ) { // 7\n if ( requirements( debtorQueue, isDebtor, _address ) ) {\n debtorQueue[ _address ] = 0;\n if( !listContains( debtors, _address ) ) {\n debtors.push( _address );\n }\n }\n result = !isDebtor[ _address ];\n isDebtor[ _address ] = result;\n\n } else if ( _managing == MANAGING.REWARDMANAGER ) { // 8\n if ( requirements( rewardManagerQueue, isRewardManager, _address ) ) {\n rewardManagerQueue[ _address ] = 0;\n if( !listContains( rewardManagers, _address ) ) {\n rewardManagers.push( _address );\n }\n }\n result = !isRewardManager[ _address ];\n isRewardManager[ _address ] = result;\n\n } else if ( _managing == MANAGING.SOHM ) { // 9\n sOHMQueue = 0;\n sOHM = _address;\n result = true;\n\n } else return false;\n\n emit ChangeActivated( _managing, _address, result );\n return true;\n }\n\n /**\n @notice checks requirements and returns altered structs\n @param queue_ mapping( address => uint )\n @param status_ mapping( address => bool )\n @param _address address\n @return bool \n */\n function requirements( \n mapping( address => uint ) storage queue_, \n mapping( address => bool ) storage status_, \n address _address \n ) internal view returns ( bool ) {\n if ( !status_[ _address ] ) {\n require( queue_[ _address ] != 0, \"Must queue\" );\n require( queue_[ _address ] <= block.number, \"Queue not expired\" );\n return true;\n } return false;\n }\n\n /**\n @notice checks array to ensure against duplicate\n @param _list address[]\n @param _token address\n @return bool\n */\n function listContains( address[] storage _list, address _token ) internal view returns ( bool ) {\n for( uint i = 0; i < _list.length; i++ ) {\n if( _list[ i ] == _token ) {\n return true;\n }\n }\n return false;\n }\n}" + }, + "contracts/wETHBondDepository.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity 0.7.5;\n\ninterface IOwnable {\n function policy() external view returns (address);\n\n function renounceManagement() external;\n \n function pushManagement( address newOwner_ ) external;\n \n function pullManagement() external;\n}\n\ncontract Ownable is IOwnable {\n\n address internal _owner;\n address internal _newOwner;\n\n event OwnershipPushed(address indexed previousOwner, address indexed newOwner);\n event OwnershipPulled(address indexed previousOwner, address indexed newOwner);\n\n constructor () {\n _owner = msg.sender;\n emit OwnershipPushed( address(0), _owner );\n }\n\n function policy() public view override returns (address) {\n return _owner;\n }\n\n modifier onlyPolicy() {\n require( _owner == msg.sender, \"Ownable: caller is not the owner\" );\n _;\n }\n\n function renounceManagement() public virtual override onlyPolicy() {\n emit OwnershipPushed( _owner, address(0) );\n _owner = address(0);\n }\n\n function pushManagement( address newOwner_ ) public virtual override onlyPolicy() {\n require( newOwner_ != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipPushed( _owner, newOwner_ );\n _newOwner = newOwner_;\n }\n \n function pullManagement() public virtual override {\n require( msg.sender == _newOwner, \"Ownable: must be new owner to pull\");\n emit OwnershipPulled( _owner, _newOwner );\n _owner = _newOwner;\n }\n}\n\nlibrary SafeMath {\n\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n return c;\n }\n\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n\n function sqrrt(uint256 a) internal pure returns (uint c) {\n if (a > 3) {\n c = a;\n uint b = add( div( a, 2), 1 );\n while (b < c) {\n c = b;\n b = div( add( div( a, b ), b), 2 );\n }\n } else if (a != 0) {\n c = 1;\n }\n }\n}\n\nlibrary Address {\n\n function isContract(address account) internal view returns (bool) {\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return _functionCallWithValue(target, data, 0, errorMessage);\n }\n\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n if (returndata.length > 0) {\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n function addressToString(address _address) internal pure returns(string memory) {\n bytes32 _bytes = bytes32(uint256(_address));\n bytes memory HEX = \"0123456789abcdef\";\n bytes memory _addr = new bytes(42);\n\n _addr[0] = '0';\n _addr[1] = 'x';\n\n for(uint256 i = 0; i < 20; i++) {\n _addr[2+i*2] = HEX[uint8(_bytes[i + 12] >> 4)];\n _addr[3+i*2] = HEX[uint8(_bytes[i + 12] & 0x0f)];\n }\n\n return string(_addr);\n\n }\n}\n\ninterface IERC20 {\n function decimals() external view returns (uint8);\n\n function totalSupply() external view returns (uint256);\n\n function balanceOf(address account) external view returns (uint256);\n\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n function allowance(address owner, address spender) external view returns (uint256);\n\n function approve(address spender, uint256 amount) external returns (bool);\n\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n\nabstract contract ERC20 is IERC20 {\n\n using SafeMath for uint256;\n\n // TODO comment actual hash value.\n bytes32 constant private ERC20TOKEN_ERC1820_INTERFACE_ID = keccak256( \"ERC20Token\" );\n \n mapping (address => uint256) internal _balances;\n\n mapping (address => mapping (address => uint256)) internal _allowances;\n\n uint256 internal _totalSupply;\n\n string internal _name;\n \n string internal _symbol;\n \n uint8 internal _decimals;\n\n constructor (string memory name_, string memory symbol_, uint8 decimals_) {\n _name = name_;\n _symbol = symbol_;\n _decimals = decimals_;\n }\n\n function name() public view returns (string memory) {\n return _name;\n }\n\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimals;\n }\n\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(msg.sender, recipient, amount);\n return true;\n }\n\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(msg.sender, spender, amount);\n return true;\n }\n\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n function _mint(address account_, uint256 ammount_) internal virtual {\n require(account_ != address(0), \"ERC20: mint to the zero address\");\n _beforeTokenTransfer(address( this ), account_, ammount_);\n _totalSupply = _totalSupply.add(ammount_);\n _balances[account_] = _balances[account_].add(ammount_);\n emit Transfer(address( this ), account_, ammount_);\n }\n\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n function _beforeTokenTransfer( address from_, address to_, uint256 amount_ ) internal virtual { }\n}\n\ninterface IERC2612Permit {\n\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n function nonces(address owner) external view returns (uint256);\n}\n\nlibrary Counters {\n using SafeMath for uint256;\n\n struct Counter {\n\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n counter._value += 1;\n }\n\n function decrement(Counter storage counter) internal {\n counter._value = counter._value.sub(1);\n }\n}\n\nabstract contract ERC20Permit is ERC20, IERC2612Permit {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n\n bytes32 public DOMAIN_SEPARATOR;\n\n constructor() {\n uint256 chainID;\n assembly {\n chainID := chainid()\n }\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name())),\n keccak256(bytes(\"1\")), // Version\n chainID,\n address(this)\n )\n );\n }\n\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"Permit: expired deadline\");\n\n bytes32 hashStruct =\n keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, amount, _nonces[owner].current(), deadline));\n\n bytes32 _hash = keccak256(abi.encodePacked(uint16(0x1901), DOMAIN_SEPARATOR, hashStruct));\n\n address signer = ecrecover(_hash, v, r, s);\n require(signer != address(0) && signer == owner, \"ZeroSwapPermit: Invalid signature\");\n\n _nonces[owner].increment();\n _approve(owner, spender, amount);\n }\n\n function nonces(address owner) public view override returns (uint256) {\n return _nonces[owner].current();\n }\n}\n\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n\nlibrary FullMath {\n function fullMul(uint256 x, uint256 y) private pure returns (uint256 l, uint256 h) {\n uint256 mm = mulmod(x, y, uint256(-1));\n l = x * y;\n h = mm - l;\n if (mm < l) h -= 1;\n }\n\n function fullDiv(\n uint256 l,\n uint256 h,\n uint256 d\n ) private pure returns (uint256) {\n uint256 pow2 = d & -d;\n d /= pow2;\n l /= pow2;\n l += h * ((-pow2) / pow2 + 1);\n uint256 r = 1;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n return l * r;\n }\n\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 d\n ) internal pure returns (uint256) {\n (uint256 l, uint256 h) = fullMul(x, y);\n uint256 mm = mulmod(x, y, d);\n if (mm > l) h -= 1;\n l -= mm;\n require(h < d, 'FullMath::mulDiv: overflow');\n return fullDiv(l, h, d);\n }\n}\n\nlibrary FixedPoint {\n\n struct uq112x112 {\n uint224 _x;\n }\n\n struct uq144x112 {\n uint256 _x;\n }\n\n uint8 private constant RESOLUTION = 112;\n uint256 private constant Q112 = 0x10000000000000000000000000000;\n uint256 private constant Q224 = 0x100000000000000000000000000000000000000000000000000000000;\n uint256 private constant LOWER_MASK = 0xffffffffffffffffffffffffffff; // decimal of UQ*x112 (lower 112 bits)\n\n function decode(uq112x112 memory self) internal pure returns (uint112) {\n return uint112(self._x >> RESOLUTION);\n }\n\n function decode112with18(uq112x112 memory self) internal pure returns (uint) {\n\n return uint(self._x) / 5192296858534827;\n }\n\n function fraction(uint256 numerator, uint256 denominator) internal pure returns (uq112x112 memory) {\n require(denominator > 0, 'FixedPoint::fraction: division by zero');\n if (numerator == 0) return FixedPoint.uq112x112(0);\n\n if (numerator <= uint144(-1)) {\n uint256 result = (numerator << RESOLUTION) / denominator;\n require(result <= uint224(-1), 'FixedPoint::fraction: overflow');\n return uq112x112(uint224(result));\n } else {\n uint256 result = FullMath.mulDiv(numerator, Q112, denominator);\n require(result <= uint224(-1), 'FixedPoint::fraction: overflow');\n return uq112x112(uint224(result));\n }\n }\n}\n\ninterface AggregatorV3Interface {\n\n function decimals() external view returns (uint8);\n function description() external view returns (string memory);\n function version() external view returns (uint256);\n\n // getRoundData and latestRoundData should both raise \"No data present\"\n // if they do not have data to report, instead of returning unset values\n // which could be misinterpreted as actual reported values.\n function getRoundData(uint80 _roundId)\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n function latestRoundData()\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n}\n\ninterface ITreasury {\n function deposit( uint _amount, address _token, uint _profit ) external returns ( bool );\n function valueOf( address _token, uint _amount ) external view returns ( uint value_ );\n function mintRewards( address _recipient, uint _amount ) external;\n}\n\ninterface IStaking {\n function stake( uint _amount, address _recipient ) external returns ( bool );\n}\n\ninterface IStakingHelper {\n function stake( uint _amount, address _recipient ) external;\n}\n\ncontract OlympusBondDepository is Ownable {\n\n using FixedPoint for *;\n using SafeERC20 for IERC20;\n using SafeMath for uint;\n\n\n\n\n /* ======== EVENTS ======== */\n\n event BondCreated( uint deposit, uint indexed payout, uint indexed expires, uint indexed priceInUSD );\n event BondRedeemed( address indexed recipient, uint payout, uint remaining );\n event BondPriceChanged( uint indexed priceInUSD, uint indexed internalPrice, uint indexed debtRatio );\n event ControlVariableAdjustment( uint initialBCV, uint newBCV, uint adjustment, bool addition );\n\n\n\n\n /* ======== STATE VARIABLES ======== */\n\n address public immutable OHM; // token given as payment for bond\n address public immutable principle; // token used to create bond\n address public immutable treasury; // mints OHM when receives principle\n address public immutable DAO; // receives profit share from bond\n\n AggregatorV3Interface internal priceFeed;\n\n address public staking; // to auto-stake payout\n address public stakingHelper; // to stake and claim if no staking warmup\n bool public useHelper;\n\n Terms public terms; // stores terms for new bonds\n Adjust public adjustment; // stores adjustment to BCV data\n\n mapping( address => Bond ) public bondInfo; // stores bond information for depositors\n\n uint public totalDebt; // total value of outstanding bonds; used for pricing\n uint public lastDecay; // reference block for debt decay\n\n\n\n\n /* ======== STRUCTS ======== */\n\n // Info for creating new bonds\n struct Terms {\n uint controlVariable; // scaling variable for price\n uint vestingTerm; // in blocks\n uint minimumPrice; // vs principle value. 4 decimals (1500 = 0.15)\n uint maxPayout; // in thousandths of a %. i.e. 500 = 0.5%\n uint maxDebt; // 9 decimal debt ratio, max % total supply created as debt\n }\n\n // Info for bond holder\n struct Bond {\n uint payout; // OHM remaining to be paid\n uint vesting; // Blocks left to vest\n uint lastBlock; // Last interaction\n uint pricePaid; // In DAI, for front end viewing\n }\n\n // Info for incremental adjustments to control variable \n struct Adjust {\n bool add; // addition or subtraction\n uint rate; // increment\n uint target; // BCV when adjustment finished\n uint buffer; // minimum length (in blocks) between adjustments\n uint lastBlock; // block when last adjustment made\n }\n\n\n\n\n /* ======== INITIALIZATION ======== */\n\n constructor ( \n address _OHM,\n address _principle,\n address _treasury, \n address _DAO,\n address _feed\n ) {\n require( _OHM != address(0) );\n OHM = _OHM;\n require( _principle != address(0) );\n principle = _principle;\n require( _treasury != address(0) );\n treasury = _treasury;\n require( _DAO != address(0) );\n DAO = _DAO;\n require( _feed != address(0) );\n priceFeed = AggregatorV3Interface( _feed );\n }\n\n /**\n * @notice initializes bond parameters\n * @param _controlVariable uint\n * @param _vestingTerm uint\n * @param _minimumPrice uint\n * @param _maxPayout uint\n * @param _maxDebt uint\n * @param _initialDebt uint\n */\n function initializeBondTerms( \n uint _controlVariable, \n uint _vestingTerm,\n uint _minimumPrice,\n uint _maxPayout,\n uint _maxDebt,\n uint _initialDebt\n ) external onlyPolicy() {\n require( currentDebt() == 0, \"Debt must be 0 for initialization\" );\n terms = Terms ({\n controlVariable: _controlVariable,\n vestingTerm: _vestingTerm,\n minimumPrice: _minimumPrice,\n maxPayout: _maxPayout,\n maxDebt: _maxDebt\n });\n totalDebt = _initialDebt;\n lastDecay = block.number;\n }\n\n\n\n \n /* ======== POLICY FUNCTIONS ======== */\n\n enum PARAMETER { VESTING, PAYOUT, DEBT }\n /**\n * @notice set parameters for new bonds\n * @param _parameter PARAMETER\n * @param _input uint\n */\n function setBondTerms ( PARAMETER _parameter, uint _input ) external onlyPolicy() {\n if ( _parameter == PARAMETER.VESTING ) { // 0\n require( _input >= 10000, \"Vesting must be longer than 36 hours\" );\n terms.vestingTerm = _input;\n } else if ( _parameter == PARAMETER.PAYOUT ) { // 1\n require( _input <= 1000, \"Payout cannot be above 1 percent\" );\n terms.maxPayout = _input;\n } else if ( _parameter == PARAMETER.DEBT ) { // 3\n terms.maxDebt = _input;\n }\n }\n\n /**\n * @notice set control variable adjustment\n * @param _addition bool\n * @param _increment uint\n * @param _target uint\n * @param _buffer uint\n */\n function setAdjustment ( \n bool _addition,\n uint _increment, \n uint _target,\n uint _buffer \n ) external onlyPolicy() {\n require( _increment <= terms.controlVariable.mul( 25 ).div( 1000 ), \"Increment too large\" );\n\n adjustment = Adjust({\n add: _addition,\n rate: _increment,\n target: _target,\n buffer: _buffer,\n lastBlock: block.number\n });\n }\n\n /**\n * @notice set contract for auto stake\n * @param _staking address\n * @param _helper bool\n */\n function setStaking( address _staking, bool _helper ) external onlyPolicy() {\n require( _staking != address(0) );\n if ( _helper ) {\n useHelper = true;\n stakingHelper = _staking;\n } else {\n useHelper = false;\n staking = _staking;\n }\n }\n\n\n \n\n /* ======== USER FUNCTIONS ======== */\n\n /**\n * @notice deposit bond\n * @param _amount uint\n * @param _maxPrice uint\n * @param _depositor address\n * @return uint\n */\n function deposit( \n uint _amount, \n uint _maxPrice,\n address _depositor\n ) external returns ( uint ) {\n require( _depositor != address(0), \"Invalid address\" );\n\n decayDebt();\n require( totalDebt <= terms.maxDebt, \"Max capacity reached\" );\n \n uint priceInUSD = bondPriceInUSD(); // Stored in bond info\n uint nativePrice = _bondPrice();\n\n require( _maxPrice >= nativePrice, \"Slippage limit: more than max price\" ); // slippage protection\n\n uint value = ITreasury( treasury ).valueOf( principle, _amount );\n uint payout = payoutFor( value ); // payout to bonder is computed\n\n require( payout >= 10000000, \"Bond too small\" ); // must be > 0.01 OHM ( underflow protection )\n require( payout <= maxPayout(), \"Bond too large\"); // size protection because there is no slippage\n\n /**\n asset carries risk and is not minted against\n asset transfered to treasury and rewards minted as payout\n */\n IERC20( principle ).safeTransferFrom( msg.sender, treasury, _amount );\n ITreasury( treasury ).mintRewards( address(this), payout );\n \n // total debt is increased\n totalDebt = totalDebt.add( value ); \n \n // depositor info is stored\n bondInfo[ _depositor ] = Bond({ \n payout: bondInfo[ _depositor ].payout.add( payout ),\n vesting: terms.vestingTerm,\n lastBlock: block.number,\n pricePaid: priceInUSD\n });\n\n // indexed events are emitted\n emit BondCreated( _amount, payout, block.number.add( terms.vestingTerm ), priceInUSD );\n emit BondPriceChanged( bondPriceInUSD(), _bondPrice(), debtRatio() );\n\n adjust(); // control variable is adjusted\n return payout; \n }\n\n /** \n * @notice redeem bond for user\n * @param _recipient address\n * @param _stake bool\n * @return uint\n */ \n function redeem( address _recipient, bool _stake ) external returns ( uint ) { \n Bond memory info = bondInfo[ _recipient ];\n uint percentVested = percentVestedFor( _recipient ); // (blocks since last interaction / vesting term remaining)\n\n if ( percentVested >= 10000 ) { // if fully vested\n delete bondInfo[ _recipient ]; // delete user info\n emit BondRedeemed( _recipient, info.payout, 0 ); // emit bond data\n return stakeOrSend( _recipient, _stake, info.payout ); // pay user everything due\n\n } else { // if unfinished\n // calculate payout vested\n uint payout = info.payout.mul( percentVested ).div( 10000 );\n\n // store updated deposit info\n bondInfo[ _recipient ] = Bond({\n payout: info.payout.sub( payout ),\n vesting: info.vesting.sub( block.number.sub( info.lastBlock ) ),\n lastBlock: block.number,\n pricePaid: info.pricePaid\n });\n\n emit BondRedeemed( _recipient, payout, bondInfo[ _recipient ].payout );\n return stakeOrSend( _recipient, _stake, payout );\n }\n }\n\n\n\n \n /* ======== INTERNAL HELPER FUNCTIONS ======== */\n\n /**\n * @notice allow user to stake payout automatically\n * @param _stake bool\n * @param _amount uint\n * @return uint\n */\n function stakeOrSend( address _recipient, bool _stake, uint _amount ) internal returns ( uint ) {\n if ( !_stake ) { // if user does not want to stake\n IERC20( OHM ).transfer( _recipient, _amount ); // send payout\n } else { // if user wants to stake\n if ( useHelper ) { // use if staking warmup is 0\n IERC20( OHM ).approve( stakingHelper, _amount );\n IStakingHelper( stakingHelper ).stake( _amount, _recipient );\n } else {\n IERC20( OHM ).approve( staking, _amount );\n IStaking( staking ).stake( _amount, _recipient );\n }\n }\n return _amount;\n }\n\n /**\n * @notice makes incremental adjustment to control variable\n */\n function adjust() internal {\n uint blockCanAdjust = adjustment.lastBlock.add( adjustment.buffer );\n if( adjustment.rate != 0 && block.number >= blockCanAdjust ) {\n uint initial = terms.controlVariable;\n if ( adjustment.add ) {\n terms.controlVariable = terms.controlVariable.add( adjustment.rate );\n if ( terms.controlVariable >= adjustment.target ) {\n adjustment.rate = 0;\n }\n } else {\n terms.controlVariable = terms.controlVariable.sub( adjustment.rate );\n if ( terms.controlVariable <= adjustment.target ) {\n adjustment.rate = 0;\n }\n }\n adjustment.lastBlock = block.number;\n emit ControlVariableAdjustment( initial, terms.controlVariable, adjustment.rate, adjustment.add );\n }\n }\n\n /**\n * @notice reduce total debt\n */\n function decayDebt() internal {\n totalDebt = totalDebt.sub( debtDecay() );\n lastDecay = block.number;\n }\n\n\n\n\n /* ======== VIEW FUNCTIONS ======== */\n\n /**\n * @notice determine maximum bond size\n * @return uint\n */\n function maxPayout() public view returns ( uint ) {\n return IERC20( OHM ).totalSupply().mul( terms.maxPayout ).div( 100000 );\n }\n\n /**\n * @notice calculate interest due for new bond\n * @param _value uint\n * @return uint\n */\n function payoutFor( uint _value ) public view returns ( uint ) {\n return FixedPoint.fraction( _value, bondPrice() ).decode112with18().div( 1e14 );\n }\n\n\n /**\n * @notice calculate current bond premium\n * @return price_ uint\n */\n function bondPrice() public view returns ( uint price_ ) { \n price_ = terms.controlVariable.mul( debtRatio() ).div( 1e5 );\n if ( price_ < terms.minimumPrice ) {\n price_ = terms.minimumPrice;\n }\n }\n\n /**\n * @notice calculate current bond price and remove floor if above\n * @return price_ uint\n */\n function _bondPrice() internal returns ( uint price_ ) {\n price_ = terms.controlVariable.mul( debtRatio() ).div( 1e5 );\n if ( price_ < terms.minimumPrice ) {\n price_ = terms.minimumPrice; \n } else if ( terms.minimumPrice != 0 ) {\n terms.minimumPrice = 0;\n }\n }\n\n /**\n * @notice get asset price from chainlink\n */\n function assetPrice() public view returns (int) {\n ( , int price, , , ) = priceFeed.latestRoundData();\n return price;\n }\n\n /**\n * @notice converts bond price to DAI value\n * @return price_ uint\n */\n function bondPriceInUSD() public view returns ( uint price_ ) {\n price_ = bondPrice().mul( uint( assetPrice() ) ).mul( 1e6 );\n }\n\n\n /**\n * @notice calculate current ratio of debt to OHM supply\n * @return debtRatio_ uint\n */\n function debtRatio() public view returns ( uint debtRatio_ ) { \n uint supply = IERC20( OHM ).totalSupply();\n debtRatio_ = FixedPoint.fraction( \n currentDebt().mul( 1e9 ), \n supply\n ).decode112with18().div( 1e18 );\n }\n\n /**\n * @notice debt ratio in same terms as reserve bonds\n * @return uint\n */\n function standardizedDebtRatio() external view returns ( uint ) {\n return debtRatio().mul( uint( assetPrice() ) ).div( 1e8 ); // ETH feed is 8 decimals\n }\n\n /**\n * @notice calculate debt factoring in decay\n * @return uint\n */\n function currentDebt() public view returns ( uint ) {\n return totalDebt.sub( debtDecay() );\n }\n\n /**\n * @notice amount to decay total debt by\n * @return decay_ uint\n */\n function debtDecay() public view returns ( uint decay_ ) {\n uint blocksSinceLast = block.number.sub( lastDecay );\n decay_ = totalDebt.mul( blocksSinceLast ).div( terms.vestingTerm );\n if ( decay_ > totalDebt ) {\n decay_ = totalDebt;\n }\n }\n\n\n /**\n * @notice calculate how far into vesting a depositor is\n * @param _depositor address\n * @return percentVested_ uint\n */\n function percentVestedFor( address _depositor ) public view returns ( uint percentVested_ ) {\n Bond memory bond = bondInfo[ _depositor ];\n uint blocksSinceLast = block.number.sub( bond.lastBlock );\n uint vesting = bond.vesting;\n\n if ( vesting > 0 ) {\n percentVested_ = blocksSinceLast.mul( 10000 ).div( vesting );\n } else {\n percentVested_ = 0;\n }\n }\n\n /**\n * @notice calculate amount of OHM available for claim by depositor\n * @param _depositor address\n * @return pendingPayout_ uint\n */\n function pendingPayoutFor( address _depositor ) external view returns ( uint pendingPayout_ ) {\n uint percentVested = percentVestedFor( _depositor );\n uint payout = bondInfo[ _depositor ].payout;\n\n if ( percentVested >= 10000 ) {\n pendingPayout_ = payout;\n } else {\n pendingPayout_ = payout.mul( percentVested ).div( 10000 );\n }\n }\n\n\n\n\n /* ======= AUXILLIARY ======= */\n\n /**\n * @notice allow anyone to send lost tokens (excluding principle or OHM) to the DAO\n * @return bool\n */\n function recoverLostToken( address _token ) external returns ( bool ) {\n require( _token != OHM );\n require( _token != principle );\n IERC20( _token ).safeTransfer( DAO, IERC20( _token ).balanceOf( address(this) ) );\n return true;\n }\n}" + }, + "contracts/wOHM.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.5;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies in extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain`call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return _functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n return _functionCallWithValue(target, data, value, errorMessage);\n }\n\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is IERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n mapping (address => uint256) private _balances;\n\n mapping (address => mapping (address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory name, string memory symbol) {\n _name = name;\n _symbol = symbol;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\n * called.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(msg.sender, recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(msg.sender, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20};\n *\n * Requirements:\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for ``sender``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements\n *\n * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal {\n _decimals = decimals_;\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\n}\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n // solhint-disable-next-line max-line-length\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n\ninterface IStaking {\n function stake( uint _amount, address _recipient ) external returns ( bool );\n\n function unstake( uint _amount, address _recipient ) external returns ( bool );\n\n function index() external view returns ( uint );\n}\n\ncontract wOHM is ERC20 {\n using SafeERC20 for ERC20;\n using Address for address;\n using SafeMath for uint;\n\n address public immutable staking;\n address public immutable OHM;\n address public immutable sOHM;\n\n constructor( address _staking, address _OHM, address _sOHM ) ERC20( 'Wrapped sOHM', 'wsOHM' ) {\n require( _staking != address(0) );\n staking = _staking;\n require( _OHM != address(0) );\n OHM = _OHM;\n require( _sOHM != address(0) );\n sOHM = _sOHM;\n }\n\n /**\n @notice stakes OHM and wraps sOHM\n @param _amount uint\n @return uint\n */\n function wrapFromOHM( uint _amount ) external returns ( uint ) {\n IERC20( OHM ).transferFrom( msg.sender, address(this), _amount );\n\n IERC20( OHM ).approve( staking, _amount ); // stake OHM for sOHM\n IStaking( staking ).stake( _amount, address(this) );\n\n uint value = wOHMValue( _amount );\n _mint( msg.sender, value );\n return value;\n }\n\n /**\n @notice unwrap sOHM and unstake OHM\n @param _amount uint\n @return uint\n */\n function unwrapToOHM( uint _amount ) external returns ( uint ) {\n _burn( msg.sender, _amount );\n \n uint value = sOHMValue( _amount );\n IERC20( sOHM ).approve( staking, value ); // unstake sOHM for OHM\n IStaking( staking ).unstake( value, address(this) );\n\n IERC20( OHM ).transfer( msg.sender, value );\n return value;\n }\n\n /**\n @notice wrap sOHM\n @param _amount uint\n @return uint\n */\n function wrapFromsOHM( uint _amount ) external returns ( uint ) {\n IERC20( sOHM ).transferFrom( msg.sender, address(this), _amount );\n \n uint value = wOHMValue( _amount );\n _mint( msg.sender, value );\n return value;\n }\n\n /**\n @notice unwrap sOHM\n @param _amount uint\n @return uint\n */\n function unwrapTosOHM( uint _amount ) external returns ( uint ) {\n _burn( msg.sender, _amount );\n\n uint value = sOHMValue( _amount );\n IERC20( sOHM ).transfer( msg.sender, value );\n return value;\n }\n\n /**\n @notice converts wOHM amount to sOHM\n @param _amount uint\n @return uint\n */\n function sOHMValue( uint _amount ) public view returns ( uint ) {\n return _amount.mul( IStaking( staking ).index() ).div( 10 ** decimals() );\n }\n\n /**\n @notice converts sOHM amount to wOHM\n @param _amount uint\n @return uint\n */\n function wOHMValue( uint _amount ) public view returns ( uint ) {\n return _amount.mul( 10 ** decimals() ).div( IStaking( staking ).index() );\n }\n\n}" + } + }, + "settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/src/abi/rinkeby/solcInputs/bbf3f95bcfbd20e9e9f7857af806cde4.json b/src/abi/rinkeby/solcInputs/bbf3f95bcfbd20e9e9f7857af806cde4.json new file mode 100644 index 0000000000..5b4b15ed78 --- /dev/null +++ b/src/abi/rinkeby/solcInputs/bbf3f95bcfbd20e9e9f7857af806cde4.json @@ -0,0 +1,35 @@ +{ + "language": "Solidity", + "sources": { + "contracts/BondDepository.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity 0.7.5;\n\ninterface IOwnable {\n function policy() external view returns (address);\n\n function renounceManagement() external;\n \n function pushManagement( address newOwner_ ) external;\n \n function pullManagement() external;\n}\n\ncontract Ownable is IOwnable {\n\n address internal _owner;\n address internal _newOwner;\n\n event OwnershipPushed(address indexed previousOwner, address indexed newOwner);\n event OwnershipPulled(address indexed previousOwner, address indexed newOwner);\n\n constructor () {\n _owner = msg.sender;\n emit OwnershipPushed( address(0), _owner );\n }\n\n function policy() public view override returns (address) {\n return _owner;\n }\n\n modifier onlyPolicy() {\n require( _owner == msg.sender, \"Ownable: caller is not the owner\" );\n _;\n }\n\n function renounceManagement() public virtual override onlyPolicy() {\n emit OwnershipPushed( _owner, address(0) );\n _owner = address(0);\n }\n\n function pushManagement( address newOwner_ ) public virtual override onlyPolicy() {\n require( newOwner_ != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipPushed( _owner, newOwner_ );\n _newOwner = newOwner_;\n }\n \n function pullManagement() public virtual override {\n require( msg.sender == _newOwner, \"Ownable: must be new owner to pull\");\n emit OwnershipPulled( _owner, _newOwner );\n _owner = _newOwner;\n }\n}\n\nlibrary SafeMath {\n\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n return c;\n }\n\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n\n function sqrrt(uint256 a) internal pure returns (uint c) {\n if (a > 3) {\n c = a;\n uint b = add( div( a, 2), 1 );\n while (b < c) {\n c = b;\n b = div( add( div( a, b ), b), 2 );\n }\n } else if (a != 0) {\n c = 1;\n }\n }\n}\n\nlibrary Address {\n\n function isContract(address account) internal view returns (bool) {\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return _functionCallWithValue(target, data, 0, errorMessage);\n }\n\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n if (returndata.length > 0) {\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n function addressToString(address _address) internal pure returns(string memory) {\n bytes32 _bytes = bytes32(uint256(_address));\n bytes memory HEX = \"0123456789abcdef\";\n bytes memory _addr = new bytes(42);\n\n _addr[0] = '0';\n _addr[1] = 'x';\n\n for(uint256 i = 0; i < 20; i++) {\n _addr[2+i*2] = HEX[uint8(_bytes[i + 12] >> 4)];\n _addr[3+i*2] = HEX[uint8(_bytes[i + 12] & 0x0f)];\n }\n\n return string(_addr);\n\n }\n}\n\ninterface IERC20 {\n function decimals() external view returns (uint8);\n\n function totalSupply() external view returns (uint256);\n\n function balanceOf(address account) external view returns (uint256);\n\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n function allowance(address owner, address spender) external view returns (uint256);\n\n function approve(address spender, uint256 amount) external returns (bool);\n\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n\nabstract contract ERC20 is IERC20 {\n\n using SafeMath for uint256;\n\n // TODO comment actual hash value.\n bytes32 constant private ERC20TOKEN_ERC1820_INTERFACE_ID = keccak256( \"ERC20Token\" );\n \n mapping (address => uint256) internal _balances;\n\n mapping (address => mapping (address => uint256)) internal _allowances;\n\n uint256 internal _totalSupply;\n\n string internal _name;\n \n string internal _symbol;\n \n uint8 internal _decimals;\n\n constructor (string memory name_, string memory symbol_, uint8 decimals_) {\n _name = name_;\n _symbol = symbol_;\n _decimals = decimals_;\n }\n\n function name() public view returns (string memory) {\n return _name;\n }\n\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimals;\n }\n\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(msg.sender, recipient, amount);\n return true;\n }\n\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(msg.sender, spender, amount);\n return true;\n }\n\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n function _mint(address account_, uint256 ammount_) internal virtual {\n require(account_ != address(0), \"ERC20: mint to the zero address\");\n _beforeTokenTransfer(address( this ), account_, ammount_);\n _totalSupply = _totalSupply.add(ammount_);\n _balances[account_] = _balances[account_].add(ammount_);\n emit Transfer(address( this ), account_, ammount_);\n }\n\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n function _beforeTokenTransfer( address from_, address to_, uint256 amount_ ) internal virtual { }\n}\n\ninterface IERC2612Permit {\n\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n function nonces(address owner) external view returns (uint256);\n}\n\nlibrary Counters {\n using SafeMath for uint256;\n\n struct Counter {\n\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n counter._value += 1;\n }\n\n function decrement(Counter storage counter) internal {\n counter._value = counter._value.sub(1);\n }\n}\n\nabstract contract ERC20Permit is ERC20, IERC2612Permit {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n\n bytes32 public DOMAIN_SEPARATOR;\n\n constructor() {\n uint256 chainID;\n assembly {\n chainID := chainid()\n }\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name())),\n keccak256(bytes(\"1\")), // Version\n chainID,\n address(this)\n )\n );\n }\n\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"Permit: expired deadline\");\n\n bytes32 hashStruct =\n keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, amount, _nonces[owner].current(), deadline));\n\n bytes32 _hash = keccak256(abi.encodePacked(uint16(0x1901), DOMAIN_SEPARATOR, hashStruct));\n\n address signer = ecrecover(_hash, v, r, s);\n require(signer != address(0) && signer == owner, \"ZeroSwapPermit: Invalid signature\");\n\n _nonces[owner].increment();\n _approve(owner, spender, amount);\n }\n\n function nonces(address owner) public view override returns (uint256) {\n return _nonces[owner].current();\n }\n}\n\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n\nlibrary FullMath {\n function fullMul(uint256 x, uint256 y) private pure returns (uint256 l, uint256 h) {\n uint256 mm = mulmod(x, y, uint256(-1));\n l = x * y;\n h = mm - l;\n if (mm < l) h -= 1;\n }\n\n function fullDiv(\n uint256 l,\n uint256 h,\n uint256 d\n ) private pure returns (uint256) {\n uint256 pow2 = d & -d;\n d /= pow2;\n l /= pow2;\n l += h * ((-pow2) / pow2 + 1);\n uint256 r = 1;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n r *= 2 - d * r;\n return l * r;\n }\n\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 d\n ) internal pure returns (uint256) {\n (uint256 l, uint256 h) = fullMul(x, y);\n uint256 mm = mulmod(x, y, d);\n if (mm > l) h -= 1;\n l -= mm;\n require(h < d, 'FullMath::mulDiv: overflow');\n return fullDiv(l, h, d);\n }\n}\n\nlibrary FixedPoint {\n\n struct uq112x112 {\n uint224 _x;\n }\n\n struct uq144x112 {\n uint256 _x;\n }\n\n uint8 private constant RESOLUTION = 112;\n uint256 private constant Q112 = 0x10000000000000000000000000000;\n uint256 private constant Q224 = 0x100000000000000000000000000000000000000000000000000000000;\n uint256 private constant LOWER_MASK = 0xffffffffffffffffffffffffffff; // decimal of UQ*x112 (lower 112 bits)\n\n function decode(uq112x112 memory self) internal pure returns (uint112) {\n return uint112(self._x >> RESOLUTION);\n }\n\n function decode112with18(uq112x112 memory self) internal pure returns (uint) {\n\n return uint(self._x) / 5192296858534827;\n }\n\n function fraction(uint256 numerator, uint256 denominator) internal pure returns (uq112x112 memory) {\n require(denominator > 0, 'FixedPoint::fraction: division by zero');\n if (numerator == 0) return FixedPoint.uq112x112(0);\n\n if (numerator <= uint144(-1)) {\n uint256 result = (numerator << RESOLUTION) / denominator;\n require(result <= uint224(-1), 'FixedPoint::fraction: overflow');\n return uq112x112(uint224(result));\n } else {\n uint256 result = FullMath.mulDiv(numerator, Q112, denominator);\n require(result <= uint224(-1), 'FixedPoint::fraction: overflow');\n return uq112x112(uint224(result));\n }\n }\n}\n\ninterface ITreasury {\n function deposit( uint _amount, address _token, uint _profit ) external returns ( bool );\n function valueOf( address _token, uint _amount ) external view returns ( uint value_ );\n}\n\ninterface IBondCalculator {\n function valuation( address _LP, uint _amount ) external view returns ( uint );\n function markdown( address _LP ) external view returns ( uint );\n}\n\ninterface IStaking {\n function stake( uint _amount, address _recipient ) external returns ( bool );\n}\n\ninterface IStakingHelper {\n function stake( uint _amount, address _recipient ) external;\n}\n\ncontract OlympusBondDepository is Ownable {\n\n using FixedPoint for *;\n using SafeERC20 for IERC20;\n using SafeMath for uint;\n\n\n\n\n /* ======== EVENTS ======== */\n\n event BondCreated( uint deposit, uint indexed payout, uint indexed expires, uint indexed priceInUSD );\n event BondRedeemed( address indexed recipient, uint payout, uint remaining );\n event BondPriceChanged( uint indexed priceInUSD, uint indexed internalPrice, uint indexed debtRatio );\n event ControlVariableAdjustment( uint initialBCV, uint newBCV, uint adjustment, bool addition );\n\n\n\n\n /* ======== STATE VARIABLES ======== */\n\n address public immutable OHM; // token given as payment for bond\n address public immutable principle; // token used to create bond\n address public immutable treasury; // mints OHM when receives principle\n address public immutable DAO; // receives profit share from bond\n\n bool public immutable isLiquidityBond; // LP and Reserve bonds are treated slightly different\n address public immutable bondCalculator; // calculates value of LP tokens\n\n address public staking; // to auto-stake payout\n address public stakingHelper; // to stake and claim if no staking warmup\n bool public useHelper;\n\n Terms public terms; // stores terms for new bonds\n Adjust public adjustment; // stores adjustment to BCV data\n\n mapping( address => Bond ) public bondInfo; // stores bond information for depositors\n\n uint public totalDebt; // total value of outstanding bonds; used for pricing\n uint public lastDecay; // reference block timestamp for debt decay\n\n\n\n\n /* ======== STRUCTS ======== */\n\n // Info for creating new bonds\n struct Terms {\n uint controlVariable; // scaling variable for price\n uint vestingTerm; // in seconds\n uint minimumPrice; // vs principle value\n uint maxPayout; // in thousandths of a %. i.e. 500 = 0.5%\n uint fee; // as % of bond payout, in hundreths. ( 500 = 5% = 0.05 for every 1 paid)\n uint maxDebt; // 9 decimal debt ratio, max % total supply created as debt\n }\n\n // Info for bond holder\n struct Bond {\n uint payout; // OHM remaining to be paid\n uint vesting; // Blocks left to vest\n uint lastTime; // Last interaction\n uint pricePaid; // In DAI, for front end viewing\n }\n\n // Info for incremental adjustments to control variable\n struct Adjust {\n bool add; // addition or subtraction\n uint rate; // increment\n uint target; // BCV when adjustment finished\n uint buffer; // minimum length (in seconds) between adjustments\n uint lastTime; // time when last adjustment made\n }\n\n\n\n\n /* ======== INITIALIZATION ======== */\n\n constructor ( \n address _OHM,\n address _principle,\n address _treasury, \n address _DAO, \n address _bondCalculator\n ) {\n require( _OHM != address(0) );\n OHM = _OHM;\n require( _principle != address(0) );\n principle = _principle;\n require( _treasury != address(0) );\n treasury = _treasury;\n require( _DAO != address(0) );\n DAO = _DAO;\n // bondCalculator should be address(0) if not LP bond\n bondCalculator = _bondCalculator;\n isLiquidityBond = ( _bondCalculator != address(0) );\n }\n\n /**\n * @notice initializes bond parameters\n * @param _controlVariable uint\n * @param _vestingTerm uint\n * @param _minimumPrice uint\n * @param _maxPayout uint\n * @param _fee uint\n * @param _maxDebt uint\n * @param _initialDebt uint\n */\n function initializeBondTerms( \n uint _controlVariable, \n uint _vestingTerm,\n uint _minimumPrice,\n uint _maxPayout,\n uint _fee,\n uint _maxDebt,\n uint _initialDebt\n ) external onlyPolicy() {\n require( terms.controlVariable == 0, \"Bonds must be initialized from 0\" );\n terms = Terms ({\n controlVariable: _controlVariable,\n vestingTerm: _vestingTerm,\n minimumPrice: _minimumPrice,\n maxPayout: _maxPayout,\n fee: _fee,\n maxDebt: _maxDebt\n });\n totalDebt = _initialDebt;\n lastDecay = block.timestamp;\n }\n\n\n\n\n /* ======== POLICY FUNCTIONS ======== */\n\n enum PARAMETER { VESTING, PAYOUT, FEE, DEBT }\n /**\n * @notice set parameters for new bonds\n * @param _parameter PARAMETER\n * @param _input uint\n */\n function setBondTerms ( PARAMETER _parameter, uint _input ) external onlyPolicy() {\n if ( _parameter == PARAMETER.VESTING ) { // 0\n require( _input >= 129600, \"Vesting must be longer than 36 hours\" );\n terms.vestingTerm = _input;\n } else if ( _parameter == PARAMETER.PAYOUT ) { // 1\n require( _input <= 1000, \"Payout cannot be above 1 percent\" );\n terms.maxPayout = _input;\n } else if ( _parameter == PARAMETER.FEE ) { // 2\n require( _input <= 10000, \"DAO fee cannot exceed payout\" );\n terms.fee = _input;\n } else if ( _parameter == PARAMETER.DEBT ) { // 3\n terms.maxDebt = _input;\n }\n }\n\n /**\n * @notice set control variable adjustment\n * @param _addition bool\n * @param _increment uint\n * @param _target uint\n * @param _buffer uint\n */\n function setAdjustment ( \n bool _addition,\n uint _increment, \n uint _target,\n uint _buffer \n ) external onlyPolicy() {\n require( _increment <= terms.controlVariable.mul( 25 ).div( 1000 ), \"Increment too large\" );\n\n adjustment = Adjust({\n add: _addition,\n rate: _increment,\n target: _target,\n buffer: _buffer,\n lastTime: block.timestamp\n });\n }\n\n /**\n * @notice set contract for auto stake\n * @param _staking address\n * @param _helper bool\n */\n function setStaking( address _staking, bool _helper ) external onlyPolicy() {\n require( _staking != address(0) );\n if ( _helper ) {\n useHelper = true;\n stakingHelper = _staking;\n } else {\n useHelper = false;\n staking = _staking;\n }\n }\n\n\n \n\n /* ======== USER FUNCTIONS ======== */\n\n /**\n * @notice deposit bond\n * @param _amount uint\n * @param _maxPrice uint\n * @param _depositor address\n * @return uint\n */\n function deposit( \n uint _amount, \n uint _maxPrice,\n address _depositor\n ) external returns ( uint ) {\n require( _depositor != address(0), \"Invalid address\" );\n\n decayDebt();\n require( totalDebt <= terms.maxDebt, \"Max capacity reached\" );\n \n uint priceInUSD = bondPriceInUSD(); // Stored in bond info\n uint nativePrice = _bondPrice();\n\n require( _maxPrice >= nativePrice, \"Slippage limit: more than max price\" ); // slippage protection\n\n uint value = ITreasury( treasury ).valueOf( principle, _amount );\n uint payout = payoutFor( value ); // payout to bonder is computed\n\n require( payout >= 10000000, \"Bond too small\" ); // must be > 0.01 OHM ( underflow protection )\n require( payout <= maxPayout(), \"Bond too large\"); // size protection because there is no slippage\n\n // profits are calculated\n uint fee = payout.mul( terms.fee ).div( 10000 );\n uint profit = value.sub( payout ).sub( fee );\n\n /**\n principle is transferred in\n approved and\n deposited into the treasury, returning (_amount - profit) OHM\n */\n IERC20( principle ).safeTransferFrom( msg.sender, address(this), _amount );\n IERC20( principle ).approve( address( treasury ), _amount );\n ITreasury( treasury ).deposit( _amount, principle, profit );\n \n if ( fee != 0 ) { // fee is transferred to dao \n IERC20( OHM ).safeTransfer( DAO, fee ); \n }\n \n // total debt is increased\n totalDebt = totalDebt.add( value ); \n \n // depositor info is stored\n bondInfo[ _depositor ] = Bond({ \n payout: bondInfo[ _depositor ].payout.add( payout ),\n vesting: terms.vestingTerm,\n lastTime: block.timestamp,\n pricePaid: priceInUSD\n });\n\n // indexed events are emitted\n emit BondCreated( _amount, payout, block.timestamp.add( terms.vestingTerm ), priceInUSD );\n emit BondPriceChanged( bondPriceInUSD(), _bondPrice(), debtRatio() );\n\n adjust(); // control variable is adjusted\n return payout; \n }\n\n /** \n * @notice redeem bond for user\n * @param _recipient address\n * @param _stake bool\n * @return uint\n */ \n function redeem( address _recipient, bool _stake ) external returns ( uint ) { \n Bond memory info = bondInfo[ _recipient ];\n uint percentVested = percentVestedFor( _recipient ); // (blocks since last interaction / vesting term remaining)\n\n if ( percentVested >= 10000 ) { // if fully vested\n delete bondInfo[ _recipient ]; // delete user info\n emit BondRedeemed( _recipient, info.payout, 0 ); // emit bond data\n return stakeOrSend( _recipient, _stake, info.payout ); // pay user everything due\n\n } else { // if unfinished\n // calculate payout vested\n uint payout = info.payout.mul( percentVested ).div( 10000 );\n\n // store updated deposit info\n bondInfo[ _recipient ] = Bond({\n payout: info.payout.sub( payout ),\n vesting: info.vesting.sub( block.timestamp.sub( info.lastTime ) ),\n lastTime: block.timestamp,\n pricePaid: info.pricePaid\n });\n\n emit BondRedeemed( _recipient, payout, bondInfo[ _recipient ].payout );\n return stakeOrSend( _recipient, _stake, payout );\n }\n }\n\n\n\n \n /* ======== INTERNAL HELPER FUNCTIONS ======== */\n\n /**\n * @notice allow user to stake payout automatically\n * @param _stake bool\n * @param _amount uint\n * @return uint\n */\n function stakeOrSend( address _recipient, bool _stake, uint _amount ) internal returns ( uint ) {\n if ( !_stake ) { // if user does not want to stake\n IERC20( OHM ).transfer( _recipient, _amount ); // send payout\n } else { // if user wants to stake\n if ( useHelper ) { // use if staking warmup is 0\n IERC20( OHM ).approve( stakingHelper, _amount );\n IStakingHelper( stakingHelper ).stake( _amount, _recipient );\n } else {\n IERC20( OHM ).approve( staking, _amount );\n IStaking( staking ).stake( _amount, _recipient );\n }\n }\n return _amount;\n }\n\n /**\n * @notice makes incremental adjustment to control variable\n */\n function adjust() internal {\n uint timeCanAdjust = adjustment.lastTime.add( adjustment.buffer );\n if( adjustment.rate != 0 && block.timestamp >= timeCanAdjust ) {\n uint initial = terms.controlVariable;\n if ( adjustment.add ) {\n terms.controlVariable = terms.controlVariable.add( adjustment.rate );\n if ( terms.controlVariable >= adjustment.target ) {\n adjustment.rate = 0;\n }\n } else {\n terms.controlVariable = terms.controlVariable.sub( adjustment.rate );\n if ( terms.controlVariable <= adjustment.target ) {\n adjustment.rate = 0;\n }\n }\n adjustment.lastTime = block.timestamp;\n emit ControlVariableAdjustment( initial, terms.controlVariable, adjustment.rate, adjustment.add );\n }\n }\n\n /**\n * @notice reduce total debt\n */\n function decayDebt() internal {\n totalDebt = totalDebt.sub( debtDecay() );\n lastDecay = block.timestamp;\n }\n\n\n\n\n /* ======== VIEW FUNCTIONS ======== */\n\n /**\n * @notice determine maximum bond size\n * @return uint\n */\n function maxPayout() public view returns ( uint ) {\n return IERC20( OHM ).totalSupply().mul( terms.maxPayout ).div( 100000 );\n }\n\n /**\n * @notice calculate interest due for new bond\n * @param _value uint\n * @return uint\n */\n function payoutFor( uint _value ) public view returns ( uint ) {\n return FixedPoint.fraction( _value, bondPrice() ).decode112with18().div( 1e16 );\n }\n\n\n /**\n * @notice calculate current bond premium\n * @return price_ uint\n */\n function bondPrice() public view returns ( uint price_ ) { \n price_ = terms.controlVariable.mul( debtRatio() ).add( 1000000000 ).div( 1e7 );\n if ( price_ < terms.minimumPrice ) {\n price_ = terms.minimumPrice;\n }\n }\n\n /**\n * @notice calculate current bond price and remove floor if above\n * @return price_ uint\n */\n function _bondPrice() internal returns ( uint price_ ) {\n price_ = terms.controlVariable.mul( debtRatio() ).add( 1000000000 ).div( 1e7 );\n if ( price_ < terms.minimumPrice ) {\n price_ = terms.minimumPrice; \n } else if ( terms.minimumPrice != 0 ) {\n terms.minimumPrice = 0;\n }\n }\n\n /**\n * @notice converts bond price to DAI value\n * @return price_ uint\n */\n function bondPriceInUSD() public view returns ( uint price_ ) {\n if( isLiquidityBond ) {\n price_ = bondPrice().mul( IBondCalculator( bondCalculator ).markdown( principle ) ).div( 100 );\n } else {\n price_ = bondPrice().mul( 10 ** IERC20( principle ).decimals() ).div( 100 );\n }\n }\n\n\n /**\n * @notice calculate current ratio of debt to OHM supply\n * @return debtRatio_ uint\n */\n function debtRatio() public view returns ( uint debtRatio_ ) { \n uint supply = IERC20( OHM ).totalSupply();\n debtRatio_ = FixedPoint.fraction( \n currentDebt().mul( 1e9 ), \n supply\n ).decode112with18().div( 1e18 );\n }\n\n /**\n * @notice debt ratio in same terms for reserve or liquidity bonds\n * @return uint\n */\n function standardizedDebtRatio() external view returns ( uint ) {\n if ( isLiquidityBond ) {\n return debtRatio().mul( IBondCalculator( bondCalculator ).markdown( principle ) ).div( 1e9 );\n } else {\n return debtRatio();\n }\n }\n\n /**\n * @notice calculate debt factoring in decay\n * @return uint\n */\n function currentDebt() public view returns ( uint ) {\n return totalDebt.sub( debtDecay() );\n }\n\n /**\n * @notice amount to decay total debt by\n * @return decay_ uint\n */\n function debtDecay() public view returns ( uint decay_ ) {\n uint timeSinceLast = block.timestamp.sub( lastDecay );\n decay_ = totalDebt.mul( timeSinceLast ).div( terms.vestingTerm );\n if ( decay_ > totalDebt ) {\n decay_ = totalDebt;\n }\n }\n\n\n /**\n * @notice calculate how far into vesting a depositor is\n * @param _depositor address\n * @return percentVested_ uint\n */\n function percentVestedFor( address _depositor ) public view returns ( uint percentVested_ ) {\n Bond memory bond = bondInfo[ _depositor ];\n uint secondsSinceLast = block.timestamp.sub( bond.lastTime );\n uint vesting = bond.vesting;\n\n if ( vesting > 0 ) {\n percentVested_ = secondsSinceLast.mul( 10000 ).div( vesting );\n } else {\n percentVested_ = 0;\n }\n }\n\n /**\n * @notice calculate amount of OHM available for claim by depositor\n * @param _depositor address\n * @return pendingPayout_ uint\n */\n function pendingPayoutFor( address _depositor ) external view returns ( uint pendingPayout_ ) {\n uint percentVested = percentVestedFor( _depositor );\n uint payout = bondInfo[ _depositor ].payout;\n\n if ( percentVested >= 10000 ) {\n pendingPayout_ = payout;\n } else {\n pendingPayout_ = payout.mul( percentVested ).div( 10000 );\n }\n }\n\n\n\n\n /* ======= AUXILLIARY ======= */\n\n /**\n * @notice allow anyone to send lost tokens (excluding principle or OHM) to the DAO\n * @return bool\n */\n function recoverLostToken( address _token ) external returns ( bool ) {\n require( _token != OHM );\n require( _token != principle );\n IERC20( _token ).safeTransfer( DAO, IERC20( _token ).balanceOf( address(this) ) );\n return true;\n }\n}" + } + }, + "settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/src/abi/rinkeby/solcInputs/c9b246e9781a79119b50bb31bf7fa5c6.json b/src/abi/rinkeby/solcInputs/c9b246e9781a79119b50bb31bf7fa5c6.json new file mode 100644 index 0000000000..a66be3c787 --- /dev/null +++ b/src/abi/rinkeby/solcInputs/c9b246e9781a79119b50bb31bf7fa5c6.json @@ -0,0 +1,35 @@ +{ + "language": "Solidity", + "sources": { + "contracts/wOHM.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.5;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies in extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain`call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return _functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n return _functionCallWithValue(target, data, value, errorMessage);\n }\n\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is IERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n mapping (address => uint256) private _balances;\n\n mapping (address => mapping (address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory name, string memory symbol) {\n _name = name;\n _symbol = symbol;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\n * called.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(msg.sender, recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(msg.sender, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20};\n *\n * Requirements:\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for ``sender``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements\n *\n * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal {\n _decimals = decimals_;\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\n}\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n // solhint-disable-next-line max-line-length\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n\ninterface IStaking {\n function stake( uint _amount, address _recipient ) external returns ( bool );\n\n function unstake( uint _amount, address _recipient ) external returns ( bool );\n\n function index() external view returns ( uint );\n}\n\ncontract wOHM is ERC20 {\n using SafeERC20 for ERC20;\n using Address for address;\n using SafeMath for uint;\n\n address public immutable staking;\n address public immutable OHM;\n address public immutable sOHM;\n\n constructor( address _staking, address _OHM, address _sOHM, string memory _name, string memory _symbol ) ERC20( _name, _symbol ) {\n require( _staking != address(0) );\n staking = _staking;\n require( _OHM != address(0) );\n OHM = _OHM;\n require( _sOHM != address(0) );\n sOHM = _sOHM;\n }\n\n /**\n @notice stakes OHM and wraps sOHM\n @param _amount uint\n @return uint\n */\n function wrapFromOHM( uint _amount ) external returns ( uint ) {\n IERC20( OHM ).transferFrom( msg.sender, address(this), _amount );\n\n IERC20( OHM ).approve( staking, _amount ); // stake OHM for sOHM\n IStaking( staking ).stake( _amount, address(this) );\n\n uint value = wOHMValue( _amount );\n _mint( msg.sender, value );\n return value;\n }\n\n /**\n @notice unwrap sOHM and unstake OHM\n @param _amount uint\n @return uint\n */\n function unwrapToOHM( uint _amount ) external returns ( uint ) {\n _burn( msg.sender, _amount );\n\n uint value = sOHMValue( _amount );\n IERC20( sOHM ).approve( staking, value ); // unstake sOHM for OHM\n IStaking( staking ).unstake( value, address(this) );\n\n IERC20( OHM ).transfer( msg.sender, value );\n return value;\n }\n\n /**\n @notice wrap sOHM\n @param _amount uint\n @return uint\n */\n function wrapFromsOHM( uint _amount ) external returns ( uint ) {\n IERC20( sOHM ).transferFrom( msg.sender, address(this), _amount );\n\n uint value = wOHMValue( _amount );\n _mint( msg.sender, value );\n return value;\n }\n\n /**\n @notice unwrap sOHM\n @param _amount uint\n @return uint\n */\n function unwrapTosOHM( uint _amount ) external returns ( uint ) {\n _burn( msg.sender, _amount );\n\n uint value = sOHMValue( _amount );\n IERC20( sOHM ).transfer( msg.sender, value );\n return value;\n }\n\n /**\n @notice converts wOHM amount to sOHM\n @param _amount uint\n @return uint\n */\n function sOHMValue( uint _amount ) public view returns ( uint ) {\n return _amount.mul( IStaking( staking ).index() ).div( 10 ** decimals() );\n }\n\n /**\n @notice converts sOHM amount to wOHM\n @param _amount uint\n @return uint\n */\n function wOHMValue( uint _amount ) public view returns ( uint ) {\n return _amount.mul( 10 ** decimals() ).div( IStaking( staking ).index() );\n }\n\n}" + } + }, + "settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/src/abi/rinkeby/solcInputs/d0f6f5ddb1e2301823073d2aeed57f8f.json b/src/abi/rinkeby/solcInputs/d0f6f5ddb1e2301823073d2aeed57f8f.json new file mode 100644 index 0000000000..77e7d55a27 --- /dev/null +++ b/src/abi/rinkeby/solcInputs/d0f6f5ddb1e2301823073d2aeed57f8f.json @@ -0,0 +1,35 @@ +{ + "language": "Solidity", + "sources": { + "contracts/Treasury.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity 0.7.5;\n\nlibrary SafeMath {\n\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n return c;\n }\n}\n\nlibrary Address {\n\n function isContract(address account) internal view returns (bool) {\n // This method relies in extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return _functionCallWithValue(target, data, 0, errorMessage);\n }\n\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\n if (success) {\n return returndata;\n } else {\n if (returndata.length > 0) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n if (returndata.length > 0) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ninterface IOwnable {\n function manager() external view returns (address);\n\n function renounceManagement() external;\n\n function pushManagement( address newOwner_ ) external;\n\n function pullManagement() external;\n}\n\ncontract Ownable is IOwnable {\n\n address internal _owner;\n address internal _newOwner;\n\n event OwnershipPushed(address indexed previousOwner, address indexed newOwner);\n event OwnershipPulled(address indexed previousOwner, address indexed newOwner);\n\n constructor () {\n _owner = msg.sender;\n emit OwnershipPushed( address(0), _owner );\n }\n\n function manager() public view override returns (address) {\n return _owner;\n }\n\n modifier onlyManager() {\n require( _owner == msg.sender, \"Ownable: caller is not the owner\" );\n _;\n }\n\n function renounceManagement() public virtual override onlyManager() {\n emit OwnershipPushed( _owner, address(0) );\n _owner = address(0);\n }\n\n function pushManagement( address newOwner_ ) public virtual override onlyManager() {\n require( newOwner_ != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipPushed( _owner, newOwner_ );\n _newOwner = newOwner_;\n }\n\n function pullManagement() public virtual override {\n require( msg.sender == _newOwner, \"Ownable: must be new owner to pull\");\n emit OwnershipPulled( _owner, _newOwner );\n _owner = _newOwner;\n }\n}\n\ninterface IERC20 {\n function decimals() external view returns (uint8);\n\n function balanceOf(address account) external view returns (uint256);\n\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n function approve(address spender, uint256 amount) external returns (bool);\n\n function totalSupply() external view returns (uint256);\n\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n\ninterface IERC20Mintable {\n function mint( uint256 amount_ ) external;\n\n function mint( address account_, uint256 ammount_ ) external;\n}\n\ninterface IOHMERC20 {\n function burnFrom(address account_, uint256 amount_) external;\n}\n\ninterface IBondCalculator {\n function valuation( address pair_, uint amount_ ) external view returns ( uint _value );\n}\n\ncontract OlympusTreasury is Ownable {\n\n using SafeMath for uint;\n using SafeERC20 for IERC20;\n\n event Deposit( address indexed token, uint amount, uint value );\n event Withdrawal( address indexed token, uint amount, uint value );\n event CreateDebt( address indexed debtor, address indexed token, uint amount, uint value );\n event RepayDebt( address indexed debtor, address indexed token, uint amount, uint value );\n event ReservesManaged( address indexed token, uint amount );\n event ReservesUpdated( uint indexed totalReserves );\n event ReservesAudited( uint indexed totalReserves );\n event RewardsMinted( address indexed caller, address indexed recipient, uint amount );\n event ChangeQueued( MANAGING indexed managing, address queued );\n event ChangeActivated( MANAGING indexed managing, address activated, bool result );\n\n enum MANAGING { RESERVEDEPOSITOR, RESERVESPENDER, RESERVETOKEN, RESERVEMANAGER, LIQUIDITYDEPOSITOR, LIQUIDITYTOKEN, LIQUIDITYMANAGER, DEBTOR, REWARDMANAGER, SOHM }\n\n address public immutable OHM;\n uint public immutable blocksNeededForQueue;\n\n address[] public reserveTokens; // Push only, beware false-positives.\n mapping( address => bool ) public isReserveToken;\n mapping( address => uint ) public reserveTokenQueue; // Delays changes to mapping.\n\n address[] public reserveDepositors; // Push only, beware false-positives. Only for viewing.\n mapping( address => bool ) public isReserveDepositor;\n mapping( address => uint ) public reserveDepositorQueue; // Delays changes to mapping.\n\n address[] public reserveSpenders; // Push only, beware false-positives. Only for viewing.\n mapping( address => bool ) public isReserveSpender;\n mapping( address => uint ) public reserveSpenderQueue; // Delays changes to mapping.\n\n address[] public liquidityTokens; // Push only, beware false-positives.\n mapping( address => bool ) public isLiquidityToken;\n mapping( address => uint ) public LiquidityTokenQueue; // Delays changes to mapping.\n\n address[] public liquidityDepositors; // Push only, beware false-positives. Only for viewing.\n mapping( address => bool ) public isLiquidityDepositor;\n mapping( address => uint ) public LiquidityDepositorQueue; // Delays changes to mapping.\n\n mapping( address => address ) public bondCalculator; // bond calculator for liquidity token\n\n address[] public reserveManagers; // Push only, beware false-positives. Only for viewing.\n mapping( address => bool ) public isReserveManager;\n mapping( address => uint ) public ReserveManagerQueue; // Delays changes to mapping.\n\n address[] public liquidityManagers; // Push only, beware false-positives. Only for viewing.\n mapping( address => bool ) public isLiquidityManager;\n mapping( address => uint ) public LiquidityManagerQueue; // Delays changes to mapping.\n\n address[] public debtors; // Push only, beware false-positives. Only for viewing.\n mapping( address => bool ) public isDebtor;\n mapping( address => uint ) public debtorQueue; // Delays changes to mapping.\n mapping( address => uint ) public debtorBalance;\n\n address[] public rewardManagers; // Push only, beware false-positives. Only for viewing.\n mapping( address => bool ) public isRewardManager;\n mapping( address => uint ) public rewardManagerQueue; // Delays changes to mapping.\n\n address public sOHM;\n uint public sOHMQueue; // Delays change to sOHM address\n\n uint public totalReserves; // Risk-free value of all assets\n uint public totalDebt;\n\n constructor (\n address _OHM,\n address _Frax,\n address _WrappedToken,\n uint _blocksNeededForQueue\n ) {\n require( _OHM != address(0) );\n OHM = _OHM;\n\n isReserveToken[ _Frax] = true;\n reserveTokens.push( _Frax );\n\n isReserveToken[ _WrappedToken] = true;\n reserveTokens.push( _WrappedToken );\n\n blocksNeededForQueue = _blocksNeededForQueue;\n }\n\n /**\n @notice allow approved address to deposit an asset for OHM\n @param _amount uint\n @param _token address\n @param _profit uint\n @return send_ uint\n */\n function deposit( uint _amount, address _token, uint _profit ) external returns ( uint send_ ) {\n require( isReserveToken[ _token ] || isLiquidityToken[ _token ], \"Not accepted\" );\n IERC20( _token ).safeTransferFrom( msg.sender, address(this), _amount );\n\n if ( isReserveToken[ _token ] ) {\n require( isReserveDepositor[ msg.sender ], \"Not approved\" );\n } else {\n require( isLiquidityDepositor[ msg.sender ], \"Not approved\" );\n }\n\n uint value = valueOf(_token, _amount);\n // mint OHM needed and store amount of rewards for distribution\n send_ = value.sub( _profit );\n IERC20Mintable( OHM ).mint( msg.sender, send_ );\n\n totalReserves = totalReserves.add( value );\n emit ReservesUpdated( totalReserves );\n\n emit Deposit( _token, _amount, value );\n }\n\n /**\n @notice allow approved address to burn OHM for reserves\n @param _amount uint\n @param _token address\n */\n function withdraw( uint _amount, address _token ) external {\n require( isReserveToken[ _token ], \"Not accepted\" ); // Only reserves can be used for redemptions\n require( isReserveSpender[ msg.sender ] == true, \"Not approved\" );\n\n uint value = valueOf( _token, _amount );\n IOHMERC20( OHM ).burnFrom( msg.sender, value );\n\n totalReserves = totalReserves.sub( value );\n emit ReservesUpdated( totalReserves );\n\n IERC20( _token ).safeTransfer( msg.sender, _amount );\n\n emit Withdrawal( _token, _amount, value );\n }\n\n /**\n @notice allow approved address to borrow reserves\n @param _amount uint\n @param _token address\n */\n function incurDebt( uint _amount, address _token ) external {\n require( isDebtor[ msg.sender ], \"Not approved\" );\n require( isReserveToken[ _token ], \"Not accepted\" );\n\n uint value = valueOf( _token, _amount );\n\n uint maximumDebt = IERC20( sOHM ).balanceOf( msg.sender ); // Can only borrow against sOHM held\n uint availableDebt = maximumDebt.sub( debtorBalance[ msg.sender ] );\n require( value <= availableDebt, \"Exceeds debt limit\" );\n\n debtorBalance[ msg.sender ] = debtorBalance[ msg.sender ].add( value );\n totalDebt = totalDebt.add( value );\n\n totalReserves = totalReserves.sub( value );\n emit ReservesUpdated( totalReserves );\n\n IERC20( _token ).transfer( msg.sender, _amount );\n\n emit CreateDebt( msg.sender, _token, _amount, value );\n }\n\n /**\n @notice allow approved address to repay borrowed reserves with reserves\n @param _amount uint\n @param _token address\n */\n function repayDebtWithReserve( uint _amount, address _token ) external {\n require( isDebtor[ msg.sender ], \"Not approved\" );\n require( isReserveToken[ _token ], \"Not accepted\" );\n\n IERC20( _token ).safeTransferFrom( msg.sender, address(this), _amount );\n\n uint value = valueOf( _token, _amount );\n debtorBalance[ msg.sender ] = debtorBalance[ msg.sender ].sub( value );\n totalDebt = totalDebt.sub( value );\n\n totalReserves = totalReserves.add( value );\n emit ReservesUpdated( totalReserves );\n\n emit RepayDebt( msg.sender, _token, _amount, value );\n }\n\n /**\n @notice allow approved address to repay borrowed reserves with OHM\n @param _amount uint\n */\n function repayDebtWithOHM( uint _amount ) external {\n require( isDebtor[ msg.sender ], \"Not approved\" );\n\n IOHMERC20( OHM ).burnFrom( msg.sender, _amount );\n\n debtorBalance[ msg.sender ] = debtorBalance[ msg.sender ].sub( _amount );\n totalDebt = totalDebt.sub( _amount );\n\n emit RepayDebt( msg.sender, OHM, _amount, _amount );\n }\n\n /**\n @notice allow approved address to withdraw assets\n @param _token address\n @param _amount uint\n */\n function manage( address _token, uint _amount ) external {\n if( isLiquidityToken[ _token ] ) {\n require( isLiquidityManager[ msg.sender ], \"Not approved\" );\n } else {\n require( isReserveManager[ msg.sender ], \"Not approved\" );\n }\n\n uint value = valueOf(_token, _amount);\n require( value <= excessReserves(), \"Insufficient reserves\" );\n\n totalReserves = totalReserves.sub( value );\n emit ReservesUpdated( totalReserves );\n\n IERC20( _token ).safeTransfer( msg.sender, _amount );\n\n emit ReservesManaged( _token, _amount );\n }\n\n /**\n @notice send epoch reward to staking contract\n */\n function mintRewards( address _recipient, uint _amount ) external {\n require( isRewardManager[ msg.sender ], \"Not approved\" );\n require( _amount <= excessReserves(), \"Insufficient reserves\" );\n\n IERC20Mintable( OHM ).mint( _recipient, _amount );\n\n emit RewardsMinted( msg.sender, _recipient, _amount );\n }\n\n /**\n @notice returns excess reserves not backing tokens\n @return uint\n */\n function excessReserves() public view returns ( uint ) {\n return totalReserves.sub( IERC20( OHM ).totalSupply().sub( totalDebt ) );\n }\n\n /**\n @notice takes inventory of all tracked assets\n @notice always consolidate to recognized reserves before audit\n */\n function auditReserves() external onlyManager() {\n uint reserves;\n for( uint i = 0; i < reserveTokens.length; i++ ) {\n reserves = reserves.add (\n valueOf( reserveTokens[ i ], IERC20( reserveTokens[ i ] ).balanceOf( address(this) ) )\n );\n }\n for( uint i = 0; i < liquidityTokens.length; i++ ) {\n reserves = reserves.add (\n valueOf( liquidityTokens[ i ], IERC20( liquidityTokens[ i ] ).balanceOf( address(this) ) )\n );\n }\n totalReserves = reserves;\n emit ReservesUpdated( reserves );\n emit ReservesAudited( reserves );\n }\n\n /**\n @notice returns OHM valuation of asset\n @param _token address\n @param _amount uint\n @return value_ uint\n */\n function valueOf( address _token, uint _amount ) public view returns ( uint value_ ) {\n if ( isReserveToken[ _token ] ) {\n // convert amount to match OHM decimals\n value_ = _amount.mul( 10 ** IERC20( OHM ).decimals() ).div( 10 ** IERC20( _token ).decimals() );\n } else if ( isLiquidityToken[ _token ] ) {\n value_ = IBondCalculator( bondCalculator[ _token ] ).valuation( _token, _amount );\n }\n }\n\n /**\n @notice queue address to change boolean in mapping\n @param _managing MANAGING\n @param _address address\n @return bool\n */\n function queue( MANAGING _managing, address _address ) external onlyManager() returns ( bool ) {\n require( _address != address(0) );\n if ( _managing == MANAGING.RESERVEDEPOSITOR ) { // 0\n reserveDepositorQueue[ _address ] = block.number.add( blocksNeededForQueue );\n } else if ( _managing == MANAGING.RESERVESPENDER ) { // 1\n reserveSpenderQueue[ _address ] = block.number.add( blocksNeededForQueue );\n } else if ( _managing == MANAGING.RESERVETOKEN ) { // 2\n reserveTokenQueue[ _address ] = block.number.add( blocksNeededForQueue );\n } else if ( _managing == MANAGING.RESERVEMANAGER ) { // 3\n ReserveManagerQueue[ _address ] = block.number.add( blocksNeededForQueue.mul( 2 ) );\n } else if ( _managing == MANAGING.LIQUIDITYDEPOSITOR ) { // 4\n LiquidityDepositorQueue[ _address ] = block.number.add( blocksNeededForQueue );\n } else if ( _managing == MANAGING.LIQUIDITYTOKEN ) { // 5\n LiquidityTokenQueue[ _address ] = block.number.add( blocksNeededForQueue );\n } else if ( _managing == MANAGING.LIQUIDITYMANAGER ) { // 6\n LiquidityManagerQueue[ _address ] = block.number.add( blocksNeededForQueue.mul( 2 ) );\n } else if ( _managing == MANAGING.DEBTOR ) { // 7\n debtorQueue[ _address ] = block.number.add( blocksNeededForQueue );\n } else if ( _managing == MANAGING.REWARDMANAGER ) { // 8\n rewardManagerQueue[ _address ] = block.number.add( blocksNeededForQueue );\n } else if ( _managing == MANAGING.SOHM ) { // 9\n sOHMQueue = block.number.add( blocksNeededForQueue );\n } else return false;\n\n emit ChangeQueued( _managing, _address );\n return true;\n }\n\n /**\n @notice verify queue then set boolean in mapping\n @param _managing MANAGING\n @param _address address\n @param _calculator address\n @return bool\n */\n function toggle( MANAGING _managing, address _address, address _calculator ) external onlyManager() returns ( bool ) {\n require( _address != address(0) );\n bool result;\n if ( _managing == MANAGING.RESERVEDEPOSITOR ) { // 0\n if ( requirements( reserveDepositorQueue, isReserveDepositor, _address ) ) {\n reserveDepositorQueue[ _address ] = 0;\n if( !listContains( reserveDepositors, _address ) ) {\n reserveDepositors.push( _address );\n }\n }\n result = !isReserveDepositor[ _address ];\n isReserveDepositor[ _address ] = result;\n\n } else if ( _managing == MANAGING.RESERVESPENDER ) { // 1\n if ( requirements( reserveSpenderQueue, isReserveSpender, _address ) ) {\n reserveSpenderQueue[ _address ] = 0;\n if( !listContains( reserveSpenders, _address ) ) {\n reserveSpenders.push( _address );\n }\n }\n result = !isReserveSpender[ _address ];\n isReserveSpender[ _address ] = result;\n\n } else if ( _managing == MANAGING.RESERVETOKEN ) { // 2\n if ( requirements( reserveTokenQueue, isReserveToken, _address ) ) {\n reserveTokenQueue[ _address ] = 0;\n if( !listContains( reserveTokens, _address ) ) {\n reserveTokens.push( _address );\n }\n }\n result = !isReserveToken[ _address ];\n isReserveToken[ _address ] = result;\n\n } else if ( _managing == MANAGING.RESERVEMANAGER ) { // 3\n if ( requirements( ReserveManagerQueue, isReserveManager, _address ) ) {\n reserveManagers.push( _address );\n ReserveManagerQueue[ _address ] = 0;\n if( !listContains( reserveManagers, _address ) ) {\n reserveManagers.push( _address );\n }\n }\n result = !isReserveManager[ _address ];\n isReserveManager[ _address ] = result;\n\n } else if ( _managing == MANAGING.LIQUIDITYDEPOSITOR ) { // 4\n if ( requirements( LiquidityDepositorQueue, isLiquidityDepositor, _address ) ) {\n liquidityDepositors.push( _address );\n LiquidityDepositorQueue[ _address ] = 0;\n if( !listContains( liquidityDepositors, _address ) ) {\n liquidityDepositors.push( _address );\n }\n }\n result = !isLiquidityDepositor[ _address ];\n isLiquidityDepositor[ _address ] = result;\n\n } else if ( _managing == MANAGING.LIQUIDITYTOKEN ) { // 5\n if ( requirements( LiquidityTokenQueue, isLiquidityToken, _address ) ) {\n LiquidityTokenQueue[ _address ] = 0;\n if( !listContains( liquidityTokens, _address ) ) {\n liquidityTokens.push( _address );\n }\n }\n result = !isLiquidityToken[ _address ];\n isLiquidityToken[ _address ] = result;\n bondCalculator[ _address ] = _calculator;\n\n } else if ( _managing == MANAGING.LIQUIDITYMANAGER ) { // 6\n if ( requirements( LiquidityManagerQueue, isLiquidityManager, _address ) ) {\n LiquidityManagerQueue[ _address ] = 0;\n if( !listContains( liquidityManagers, _address ) ) {\n liquidityManagers.push( _address );\n }\n }\n result = !isLiquidityManager[ _address ];\n isLiquidityManager[ _address ] = result;\n\n } else if ( _managing == MANAGING.DEBTOR ) { // 7\n if ( requirements( debtorQueue, isDebtor, _address ) ) {\n debtorQueue[ _address ] = 0;\n if( !listContains( debtors, _address ) ) {\n debtors.push( _address );\n }\n }\n result = !isDebtor[ _address ];\n isDebtor[ _address ] = result;\n\n } else if ( _managing == MANAGING.REWARDMANAGER ) { // 8\n if ( requirements( rewardManagerQueue, isRewardManager, _address ) ) {\n rewardManagerQueue[ _address ] = 0;\n if( !listContains( rewardManagers, _address ) ) {\n rewardManagers.push( _address );\n }\n }\n result = !isRewardManager[ _address ];\n isRewardManager[ _address ] = result;\n\n } else if ( _managing == MANAGING.SOHM ) { // 9\n sOHMQueue = 0;\n sOHM = _address;\n result = true;\n\n } else return false;\n\n emit ChangeActivated( _managing, _address, result );\n return true;\n }\n\n /**\n @notice checks requirements and returns altered structs\n @param queue_ mapping( address => uint )\n @param status_ mapping( address => bool )\n @param _address address\n @return bool\n */\n function requirements(\n mapping( address => uint ) storage queue_,\n mapping( address => bool ) storage status_,\n address _address\n ) internal view returns ( bool ) {\n if ( !status_[ _address ] ) {\n require( queue_[ _address ] != 0, \"Must queue\" );\n require( queue_[ _address ] <= block.number, \"Queue not expired\" );\n return true;\n } return false;\n }\n\n /**\n @notice checks array to ensure against duplicate\n @param _list address[]\n @param _token address\n @return bool\n */\n function listContains( address[] storage _list, address _token ) internal view returns ( bool ) {\n for( uint i = 0; i < _list.length; i++ ) {\n if( _list[ i ] == _token ) {\n return true;\n }\n }\n return false;\n }\n}" + } + }, + "settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/src/abi/rinkeby/solcInputs/fb3b81c61761bcfb33ca99488ac60a1b.json b/src/abi/rinkeby/solcInputs/fb3b81c61761bcfb33ca99488ac60a1b.json new file mode 100644 index 0000000000..a86c74e495 --- /dev/null +++ b/src/abi/rinkeby/solcInputs/fb3b81c61761bcfb33ca99488ac60a1b.json @@ -0,0 +1,38 @@ +{ + "language": "Solidity", + "sources": { + "contracts/OlympusERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity 0.7.5;\n\nlibrary EnumerableSet {\n\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n struct Set {\n // Storage of set values\n bytes32[] _values;\n\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) { // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\n }\n\n function _getValues( Set storage set_ ) private view returns ( bytes32[] storage ) {\n return set_._values;\n }\n\n // TODO needs insert function that maintains order.\n // TODO needs NatSpec documentation comment.\n /**\n * Inserts new value by moving existing value at provided index to end of array and setting provided value at provided index\n */\n function _insert(Set storage set_, uint256 index_, bytes32 valueToInsert_ ) private returns ( bool ) {\n require( set_._values.length > index_ );\n require( !_contains( set_, valueToInsert_ ), \"Remove value you wish to insert if you wish to reorder array.\" );\n bytes32 existingValue_ = _at( set_, index_ );\n set_._values[index_] = valueToInsert_;\n return _add( set_, existingValue_);\n }\n\n struct Bytes4Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes4Set storage set, bytes4 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes4Set storage set, bytes4 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes4Set storage set, bytes4 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(Bytes4Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes4Set storage set, uint256 index) internal view returns ( bytes4 ) {\n return bytes4( _at( set._inner, index ) );\n }\n\n function getValues( Bytes4Set storage set_ ) internal view returns ( bytes4[] memory ) {\n bytes4[] memory bytes4Array_;\n for( uint256 iteration_ = 0; _length( set_._inner ) > iteration_; iteration_++ ) {\n bytes4Array_[iteration_] = bytes4( _at( set_._inner, iteration_ ) );\n }\n return bytes4Array_;\n }\n\n function insert( Bytes4Set storage set_, uint256 index_, bytes4 valueToInsert_ ) internal returns ( bool ) {\n return _insert( set_._inner, index_, valueToInsert_ );\n }\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns ( bytes32 ) {\n return _at(set._inner, index);\n }\n\n function getValues( Bytes32Set storage set_ ) internal view returns ( bytes4[] memory ) {\n bytes4[] memory bytes4Array_;\n\n for( uint256 iteration_ = 0; _length( set_._inner ) >= iteration_; iteration_++ ){\n bytes4Array_[iteration_] = bytes4( at( set_, iteration_ ) );\n }\n\n return bytes4Array_;\n }\n\n function insert( Bytes32Set storage set_, uint256 index_, bytes32 valueToInsert_ ) internal returns ( bool ) {\n return _insert( set_._inner, index_, valueToInsert_ );\n }\n\n // AddressSet\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(value)));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(value)));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(value)));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint256(_at(set._inner, index)));\n }\n\n /**\n * TODO Might require explicit conversion of bytes32[] to address[].\n * Might require iteration.\n */\n function getValues( AddressSet storage set_ ) internal view returns ( address[] memory ) {\n\n address[] memory addressArray;\n\n for( uint256 iteration_ = 0; _length(set_._inner) >= iteration_; iteration_++ ){\n addressArray[iteration_] = at( set_, iteration_ );\n }\n\n return addressArray;\n }\n\n function insert(AddressSet storage set_, uint256 index_, address valueToInsert_ ) internal returns ( bool ) {\n return _insert( set_._inner, index_, bytes32(uint256(valueToInsert_)) );\n }\n\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n struct UInt256Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UInt256Set storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UInt256Set storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UInt256Set storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UInt256Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UInt256Set storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n}\n\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n\nlibrary SafeMath {\n\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n\n function sqrrt(uint256 a) internal pure returns (uint c) {\n if (a > 3) {\n c = a;\n uint b = add( div( a, 2), 1 );\n while (b < c) {\n c = b;\n b = div( add( div( a, b ), b), 2 );\n }\n } else if (a != 0) {\n c = 1;\n }\n }\n\n function percentageAmount( uint256 total_, uint8 percentage_ ) internal pure returns ( uint256 percentAmount_ ) {\n return div( mul( total_, percentage_ ), 1000 );\n }\n\n function substractPercentage( uint256 total_, uint8 percentageToSub_ ) internal pure returns ( uint256 result_ ) {\n return sub( total_, div( mul( total_, percentageToSub_ ), 1000 ) );\n }\n\n function percentageOfTotal( uint256 part_, uint256 total_ ) internal pure returns ( uint256 percent_ ) {\n return div( mul(part_, 100) , total_ );\n }\n\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow, so we distribute\n return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);\n }\n\n function quadraticPricing( uint256 payment_, uint256 multiplier_ ) internal pure returns (uint256) {\n return sqrrt( mul( multiplier_, payment_ ) );\n }\n\n function bondingCurve( uint256 supply_, uint256 multiplier_ ) internal pure returns (uint256) {\n return mul( multiplier_, supply_ );\n }\n}\n\nabstract contract ERC20 is IERC20 {\n\n using SafeMath for uint256;\n\n // TODO comment actual hash value.\n bytes32 constant private ERC20TOKEN_ERC1820_INTERFACE_ID = keccak256( \"ERC20Token\" );\n\n // Present in ERC777\n mapping (address => uint256) internal _balances;\n\n // Present in ERC777\n mapping (address => mapping (address => uint256)) internal _allowances;\n\n // Present in ERC777\n uint256 internal _totalSupply;\n\n // Present in ERC777\n string internal _name;\n\n // Present in ERC777\n string internal _symbol;\n\n // Present in ERC777\n uint8 internal _decimals;\n\n constructor (string memory name_, string memory symbol_, uint8 decimals_) {\n _name = name_;\n _symbol = symbol_;\n _decimals = decimals_;\n }\n\n function name() public view returns (string memory) {\n return _name;\n }\n\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n function decimals() public view returns (uint8) {\n return _decimals;\n }\n\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(msg.sender, recipient, amount);\n return true;\n }\n\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(msg.sender, spender, amount);\n return true;\n }\n\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n function _mint(address account_, uint256 amount_) internal virtual {\n require(account_ != address(0), \"ERC20: mint to the zero address\");\n _beforeTokenTransfer(address( this ), account_, amount_);\n _totalSupply = _totalSupply.add(amount_);\n _balances[account_] = _balances[account_].add(amount_);\n emit Transfer(address( this ), account_, amount_);\n }\n\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n function _beforeTokenTransfer( address from_, address to_, uint256 amount_ ) internal virtual { }\n}\n\nlibrary Counters {\n using SafeMath for uint256;\n\n struct Counter {\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n counter._value += 1;\n }\n\n function decrement(Counter storage counter) internal {\n counter._value = counter._value.sub(1);\n }\n}\n\ninterface IERC2612Permit {\n\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n function nonces(address owner) external view returns (uint256);\n}\n\nabstract contract ERC20Permit is ERC20, IERC2612Permit {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n\n bytes32 public DOMAIN_SEPARATOR;\n\n constructor() {\n uint256 chainID;\n assembly {\n chainID := chainid()\n }\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name())),\n keccak256(bytes(\"1\")), // Version\n chainID,\n address(this)\n )\n );\n }\n\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"Permit: expired deadline\");\n\n bytes32 hashStruct =\n keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, amount, _nonces[owner].current(), deadline));\n\n bytes32 _hash = keccak256(abi.encodePacked(uint16(0x1901), DOMAIN_SEPARATOR, hashStruct));\n\n address signer = ecrecover(_hash, v, r, s);\n require(signer != address(0) && signer == owner, \"ZeroSwapPermit: Invalid signature\");\n\n _nonces[owner].increment();\n _approve(owner, spender, amount);\n }\n\n function nonces(address owner) public view override returns (uint256) {\n return _nonces[owner].current();\n }\n}\n\ninterface IOwnable {\n function owner() external view returns (address);\n\n function renounceOwnership() external;\n\n function transferOwnership( address newOwner_ ) external;\n}\n\ncontract Ownable is IOwnable {\n\n address internal _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n constructor () {\n _owner = msg.sender;\n emit OwnershipTransferred( address(0), _owner );\n }\n\n function owner() public view override returns (address) {\n return _owner;\n }\n\n modifier onlyOwner() {\n require( _owner == msg.sender, \"Ownable: caller is not the owner\" );\n _;\n }\n\n function renounceOwnership() public virtual override onlyOwner() {\n emit OwnershipTransferred( _owner, address(0) );\n _owner = address(0);\n }\n\n function transferOwnership( address newOwner_ ) public virtual override onlyOwner() {\n require( newOwner_ != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipTransferred( _owner, newOwner_ );\n _owner = newOwner_;\n }\n}\n\ncontract VaultOwned is Ownable {\n\n address internal _vault;\n\n function setVault( address vault_ ) external onlyOwner() returns ( bool ) {\n _vault = vault_;\n\n return true;\n }\n\n function vault() public view returns (address) {\n return _vault;\n }\n\n modifier onlyVault() {\n require( _vault == msg.sender, \"VaultOwned: caller is not the Vault\" );\n _;\n }\n\n}\n\ncontract OlympusERC20Token is ERC20Permit, VaultOwned {\n\n using SafeMath for uint256;\n\n constructor(string memory _name, string memory _symbol) ERC20(_name, _symbol, 9) {\n }\n\n function mint(address account_, uint256 amount_) external onlyVault() {\n _mint(account_, amount_);\n }\n\n function burn(uint256 amount) public virtual {\n _burn(msg.sender, amount);\n }\n\n function burnFrom(address account_, uint256 amount_) public virtual {\n _burnFrom(account_, amount_);\n }\n\n function _burnFrom(address account_, uint256 amount_) public virtual {\n uint256 decreasedAllowance_ =\n allowance(account_, msg.sender).sub(\n amount_,\n \"ERC20: burn amount exceeds allowance\"\n );\n\n _approve(account_, msg.sender, decreasedAllowance_);\n _burn(account_, amount_);\n }\n}" + }, + "contracts/sOlympusERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity 0.7.5;\n\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n\n // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)\n function sqrrt(uint256 a) internal pure returns (uint c) {\n if (a > 3) {\n c = a;\n uint b = add( div( a, 2), 1 );\n while (b < c) {\n c = b;\n b = div( add( div( a, b ), b), 2 );\n }\n } else if (a != 0) {\n c = 1;\n }\n }\n\n /*\n * Expects percentage to be trailed by 00,\n */\n function percentageAmount( uint256 total_, uint8 percentage_ ) internal pure returns ( uint256 percentAmount_ ) {\n return div( mul( total_, percentage_ ), 1000 );\n }\n\n /*\n * Expects percentage to be trailed by 00,\n */\n function substractPercentage( uint256 total_, uint8 percentageToSub_ ) internal pure returns ( uint256 result_ ) {\n return sub( total_, div( mul( total_, percentageToSub_ ), 1000 ) );\n }\n\n function percentageOfTotal( uint256 part_, uint256 total_ ) internal pure returns ( uint256 percent_ ) {\n return div( mul(part_, 100) , total_ );\n }\n\n /**\n * Taken from Hypersonic https://github.com/M2629/HyperSonic/blob/main/Math.sol\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow, so we distribute\n return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);\n }\n\n function quadraticPricing( uint256 payment_, uint256 multiplier_ ) internal pure returns (uint256) {\n return sqrrt( mul( multiplier_, payment_ ) );\n }\n\n function bondingCurve( uint256 supply_, uint256 multiplier_ ) internal pure returns (uint256) {\n return mul( multiplier_, supply_ );\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies in extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain`call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return _functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n // function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n // require(address(this).balance >= value, \"Address: insufficient balance for call\");\n // return _functionCallWithValue(target, data, value, errorMessage);\n // }\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.3._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.3._\n */\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n\n function addressToString(address _address) internal pure returns(string memory) {\n bytes32 _bytes = bytes32(uint256(_address));\n bytes memory HEX = \"0123456789abcdef\";\n bytes memory _addr = new bytes(42);\n\n _addr[0] = '0';\n _addr[1] = 'x';\n\n for(uint256 i = 0; i < 20; i++) {\n _addr[2+i*2] = HEX[uint8(_bytes[i + 12] >> 4)];\n _addr[3+i*2] = HEX[uint8(_bytes[i + 12] & 0x0f)];\n }\n\n return string(_addr);\n\n }\n}\n\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n\nabstract contract ERC20\n is\n IERC20\n {\n\n using SafeMath for uint256;\n\n // TODO comment actual hash value.\n bytes32 constant private ERC20TOKEN_ERC1820_INTERFACE_ID = keccak256( \"ERC20Token\" );\n\n // Present in ERC777\n mapping (address => uint256) internal _balances;\n\n // Present in ERC777\n mapping (address => mapping (address => uint256)) internal _allowances;\n\n // Present in ERC777\n uint256 internal _totalSupply;\n\n // Present in ERC777\n string internal _name;\n\n // Present in ERC777\n string internal _symbol;\n\n // Present in ERC777\n uint8 internal _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory name_, string memory symbol_, uint8 decimals_) {\n _name = name_;\n _symbol = symbol_;\n _decimals = decimals_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n // Present in ERC777\n function name() public view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n // Present in ERC777\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\n * called.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n // Present in ERC777\n function decimals() public view returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n // Present in ERC777\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n // Present in ERC777\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n // Overrideen in ERC777\n // Confirm that this behavior changes\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(msg.sender, recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n // Present in ERC777\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n // Present in ERC777\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(msg.sender, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for ``sender``'s tokens of at least\n * `amount`.\n */\n // Present in ERC777\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n */\n // Present in ERC777\n function _mint(address account_, uint256 ammount_) internal virtual {\n require(account_ != address(0), \"ERC20: mint to the zero address\");\n _beforeTokenTransfer(address( this ), account_, ammount_);\n _totalSupply = _totalSupply.add(ammount_);\n _balances[account_] = _balances[account_].add(ammount_);\n emit Transfer(address( this ), account_, ammount_);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n // Present in ERC777\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n // Present in ERC777\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n // Considering deprication to reduce size of bytecode as changing _decimals to internal acheived the same functionality.\n // function _setupDecimals(uint8 decimals_) internal {\n // _decimals = decimals_;\n // }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n // Present in ERC777\n function _beforeTokenTransfer( address from_, address to_, uint256 amount_ ) internal virtual { }\n}\n\nlibrary Counters {\n using SafeMath for uint256;\n\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n // The {SafeMath} overflow check can be skipped here, see the comment at the top\n counter._value += 1;\n }\n\n function decrement(Counter storage counter) internal {\n counter._value = counter._value.sub(1);\n }\n}\n\ninterface IERC2612Permit {\n /**\n * @dev Sets `amount` as the allowance of `spender` over `owner`'s tokens,\n * given `owner`'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current ERC2612 nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n}\n\nabstract contract ERC20Permit is ERC20, IERC2612Permit {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n\n bytes32 public DOMAIN_SEPARATOR;\n\n constructor() {\n\n uint256 chainID;\n assembly {\n chainID := chainid()\n }\n\n DOMAIN_SEPARATOR = keccak256(abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name())),\n keccak256(bytes(\"1\")), // Version\n chainID,\n address(this)\n ));\n }\n\n /**\n * @dev See {IERC2612Permit-permit}.\n *\n */\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"Permit: expired deadline\");\n\n bytes32 hashStruct =\n keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, amount, _nonces[owner].current(), deadline));\n\n bytes32 _hash = keccak256(abi.encodePacked(uint16(0x1901), DOMAIN_SEPARATOR, hashStruct));\n\n address signer = ecrecover(_hash, v, r, s);\n require(signer != address(0) && signer == owner, \"ZeroSwapPermit: Invalid signature\");\n\n _nonces[owner].increment();\n _approve(owner, spender, amount);\n }\n\n /**\n * @dev See {IERC2612Permit-nonces}.\n */\n function nonces(address owner) public view override returns (uint256) {\n return _nonces[owner].current();\n }\n}\n\ninterface IOwnable {\n function manager() external view returns (address);\n\n function renounceManagement() external;\n\n function pushManagement( address newOwner_ ) external;\n\n function pullManagement() external;\n}\n\ncontract Ownable is IOwnable {\n\n address internal _owner;\n address internal _newOwner;\n\n event OwnershipPushed(address indexed previousOwner, address indexed newOwner);\n event OwnershipPulled(address indexed previousOwner, address indexed newOwner);\n\n constructor () {\n _owner = msg.sender;\n emit OwnershipPushed( address(0), _owner );\n }\n\n function manager() public view override returns (address) {\n return _owner;\n }\n\n modifier onlyManager() {\n require( _owner == msg.sender, \"Ownable: caller is not the owner\" );\n _;\n }\n\n function renounceManagement() public virtual override onlyManager() {\n emit OwnershipPushed( _owner, address(0) );\n _owner = address(0);\n }\n\n function pushManagement( address newOwner_ ) public virtual override onlyManager() {\n require( newOwner_ != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipPushed( _owner, newOwner_ );\n _newOwner = newOwner_;\n }\n\n function pullManagement() public virtual override {\n require( msg.sender == _newOwner, \"Ownable: must be new owner to pull\");\n emit OwnershipPulled( _owner, _newOwner );\n _owner = _newOwner;\n }\n}\n\ncontract sOlympus is ERC20Permit, Ownable {\n\n using SafeMath for uint256;\n\n modifier onlyStakingContract() {\n require( msg.sender == stakingContract );\n _;\n }\n\n address public stakingContract;\n address public initializer;\n\n event LogSupply(uint256 indexed epoch, uint256 timestamp, uint256 totalSupply );\n event LogRebase( uint256 indexed epoch, uint256 rebase, uint256 index );\n event LogStakingContractUpdated( address stakingContract );\n\n struct Rebase {\n uint epoch;\n uint rebase; // 18 decimals\n uint totalStakedBefore;\n uint totalStakedAfter;\n uint amountRebased;\n uint index;\n uint blockNumberOccured;\n }\n Rebase[] public rebases;\n\n uint public INDEX;\n\n uint256 private constant MAX_UINT256 = ~uint256(0);\n uint256 private constant INITIAL_FRAGMENTS_SUPPLY = 5000000 * 10**9;\n\n // TOTAL_GONS is a multiple of INITIAL_FRAGMENTS_SUPPLY so that _gonsPerFragment is an integer.\n // Use the highest value that fits in a uint256 for max granularity.\n uint256 private constant TOTAL_GONS = MAX_UINT256 - (MAX_UINT256 % INITIAL_FRAGMENTS_SUPPLY);\n\n // MAX_SUPPLY = maximum integer < (sqrt(4*TOTAL_GONS + 1) - 1) / 2\n uint256 private constant MAX_SUPPLY = ~uint128(0); // (2^128) - 1\n\n uint256 private _gonsPerFragment;\n mapping(address => uint256) private _gonBalances;\n\n mapping ( address => mapping ( address => uint256 ) ) private _allowedValue;\n\n constructor(string memory _name, string memory _symbol) ERC20(_name, _symbol, 9) ERC20Permit() {\n initializer = msg.sender;\n _totalSupply = INITIAL_FRAGMENTS_SUPPLY;\n _gonsPerFragment = TOTAL_GONS.div(_totalSupply);\n }\n\n function initialize( address stakingContract_ ) external returns ( bool ) {\n require( msg.sender == initializer );\n require( stakingContract_ != address(0) );\n stakingContract = stakingContract_;\n _gonBalances[ stakingContract ] = TOTAL_GONS;\n\n emit Transfer( address(0x0), stakingContract, _totalSupply );\n emit LogStakingContractUpdated( stakingContract_ );\n\n initializer = address(0);\n return true;\n }\n\n function setIndex( uint _INDEX ) external onlyManager() returns ( bool ) {\n require( INDEX == 0 );\n INDEX = gonsForBalance( _INDEX );\n return true;\n }\n\n /**\n @notice increases sOHM supply to increase staking balances relative to profit_\n @param profit_ uint256\n @return uint256\n */\n function rebase( uint256 profit_, uint epoch_ ) public onlyStakingContract() returns ( uint256 ) {\n uint256 rebaseAmount;\n uint256 circulatingSupply_ = circulatingSupply();\n\n if ( profit_ == 0 ) {\n emit LogSupply( epoch_, block.timestamp, _totalSupply );\n emit LogRebase( epoch_, 0, index() );\n return _totalSupply;\n } else if ( circulatingSupply_ > 0 ){\n rebaseAmount = profit_.mul( _totalSupply ).div( circulatingSupply_ );\n } else {\n rebaseAmount = profit_;\n }\n\n _totalSupply = _totalSupply.add( rebaseAmount );\n\n if ( _totalSupply > MAX_SUPPLY ) {\n _totalSupply = MAX_SUPPLY;\n }\n\n _gonsPerFragment = TOTAL_GONS.div( _totalSupply );\n\n _storeRebase( circulatingSupply_, profit_, epoch_ );\n\n return _totalSupply;\n }\n\n /**\n @notice emits event with data about rebase\n @param previousCirculating_ uint\n @param profit_ uint\n @param epoch_ uint\n @return bool\n */\n function _storeRebase( uint previousCirculating_, uint profit_, uint epoch_ ) internal returns ( bool ) {\n uint rebasePercent = profit_.mul( 1e18 ).div( previousCirculating_ );\n\n rebases.push( Rebase ( {\n epoch: epoch_,\n rebase: rebasePercent, // 18 decimals\n totalStakedBefore: previousCirculating_,\n totalStakedAfter: circulatingSupply(),\n amountRebased: profit_,\n index: index(),\n blockNumberOccured: block.number\n }));\n\n emit LogSupply( epoch_, block.timestamp, _totalSupply );\n emit LogRebase( epoch_, rebasePercent, index() );\n\n return true;\n }\n\n function balanceOf( address who ) public view override returns ( uint256 ) {\n return _gonBalances[ who ].div( _gonsPerFragment );\n }\n\n function gonsForBalance( uint amount ) public view returns ( uint ) {\n return amount.mul( _gonsPerFragment );\n }\n\n function balanceForGons( uint gons ) public view returns ( uint ) {\n return gons.div( _gonsPerFragment );\n }\n\n // Staking contract holds excess sOHM\n function circulatingSupply() public view returns ( uint ) {\n return _totalSupply.sub( balanceOf( stakingContract ) );\n }\n\n function index() public view returns ( uint ) {\n return balanceForGons( INDEX );\n }\n\n function transfer( address to, uint256 value ) public override returns (bool) {\n uint256 gonValue = value.mul( _gonsPerFragment );\n _gonBalances[ msg.sender ] = _gonBalances[ msg.sender ].sub( gonValue );\n _gonBalances[ to ] = _gonBalances[ to ].add( gonValue );\n emit Transfer( msg.sender, to, value );\n return true;\n }\n\n function allowance( address owner_, address spender ) public view override returns ( uint256 ) {\n return _allowedValue[ owner_ ][ spender ];\n }\n\n function transferFrom( address from, address to, uint256 value ) public override returns ( bool ) {\n _allowedValue[ from ][ msg.sender ] = _allowedValue[ from ][ msg.sender ].sub( value );\n emit Approval( from, msg.sender, _allowedValue[ from ][ msg.sender ] );\n\n uint256 gonValue = gonsForBalance( value );\n _gonBalances[ from ] = _gonBalances[from].sub( gonValue );\n _gonBalances[ to ] = _gonBalances[to].add( gonValue );\n emit Transfer( from, to, value );\n\n return true;\n }\n\n function approve( address spender, uint256 value ) public override returns (bool) {\n _allowedValue[ msg.sender ][ spender ] = value;\n emit Approval( msg.sender, spender, value );\n return true;\n }\n\n // What gets called in a permit\n function _approve( address owner, address spender, uint256 value ) internal override virtual {\n _allowedValue[owner][spender] = value;\n emit Approval( owner, spender, value );\n }\n\n function increaseAllowance( address spender, uint256 addedValue ) public override returns (bool) {\n _allowedValue[ msg.sender ][ spender ] = _allowedValue[ msg.sender ][ spender ].add( addedValue );\n emit Approval( msg.sender, spender, _allowedValue[ msg.sender ][ spender ] );\n return true;\n }\n\n function decreaseAllowance( address spender, uint256 subtractedValue ) public override returns (bool) {\n uint256 oldValue = _allowedValue[ msg.sender ][ spender ];\n if (subtractedValue >= oldValue) {\n _allowedValue[ msg.sender ][ spender ] = 0;\n } else {\n _allowedValue[ msg.sender ][ spender ] = oldValue.sub( subtractedValue );\n }\n emit Approval( msg.sender, spender, _allowedValue[ msg.sender ][ spender ] );\n return true;\n }\n}" + } + }, + "settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/src/abi/rinkeby/wOHM.json b/src/abi/rinkeby/wOHM.json new file mode 100644 index 0000000000..77db79c631 --- /dev/null +++ b/src/abi/rinkeby/wOHM.json @@ -0,0 +1,685 @@ +{ + "address": "0x8fa13d80D98A11F094843AaDab8129b42C49E186", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_staking", + "type": "address" + }, + { + "internalType": "address", + "name": "_OHM", + "type": "address" + }, + { + "internalType": "address", + "name": "_sOHM", + "type": "address" + }, + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "OHM", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sOHM", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "sOHMValue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "staking", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "unwrapToOHM", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "unwrapTosOHM", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "wOHMValue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "wrapFromOHM", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "wrapFromsOHM", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xee3c07783bc7345e3a8e6d70257f6f7ffdd011fd3a6d1e57455eb66edf51d935", + "receipt": { + "to": null, + "from": "0xA38F4E6718EdCF023a1d032a2193848CB932c8e3", + "contractAddress": "0x8fa13d80D98A11F094843AaDab8129b42C49E186", + "transactionIndex": 7, + "gasUsed": "2049757", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7fa4cbe5f9c67e3db876225fe488622f450df6fddf273b7d500b30772ac2065b", + "transactionHash": "0xee3c07783bc7345e3a8e6d70257f6f7ffdd011fd3a6d1e57455eb66edf51d935", + "logs": [], + "blockNumber": 9907144, + "cumulativeGasUsed": "4852934", + "status": 1, + "byzantium": true + }, + "args": [ + "0xbB8b39A92D916D4c1c46c67CA22920A366127A4B", + "0x9bb5E7183e6259183f8E79876eCC0228738C95F6", + "0x230a8dC3c34336372b75549915DeBAEAACCF129D", + "Wrapped sBRICK", + "wsBRICK" + ], + "solcInputHash": "c9b246e9781a79119b50bb31bf7fa5c6", + "metadata": "{\"compiler\":{\"version\":\"0.7.5+commit.eb77ed08\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_staking\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_OHM\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_sOHM\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"OHM\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sOHM\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"sOHMValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"staking\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"unwrapToOHM\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"unwrapTosOHM\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"wOHMValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"wrapFromOHM\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"wrapFromsOHM\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5,05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is called. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"name()\":{\"details\":\"Returns the name of the token.\"},\"sOHMValue(uint256)\":{\"params\":{\"_amount\":\"uint\"},\"returns\":{\"_0\":\"uint\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}; Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for ``sender``'s tokens of at least `amount`.\"},\"unwrapToOHM(uint256)\":{\"params\":{\"_amount\":\"uint\"},\"returns\":{\"_0\":\"uint\"}},\"unwrapTosOHM(uint256)\":{\"params\":{\"_amount\":\"uint\"},\"returns\":{\"_0\":\"uint\"}},\"wOHMValue(uint256)\":{\"params\":{\"_amount\":\"uint\"},\"returns\":{\"_0\":\"uint\"}},\"wrapFromOHM(uint256)\":{\"params\":{\"_amount\":\"uint\"},\"returns\":{\"_0\":\"uint\"}},\"wrapFromsOHM(uint256)\":{\"params\":{\"_amount\":\"uint\"},\"returns\":{\"_0\":\"uint\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"sOHMValue(uint256)\":{\"notice\":\"converts wOHM amount to sOHM\"},\"unwrapToOHM(uint256)\":{\"notice\":\"unwrap sOHM and unstake OHM\"},\"unwrapTosOHM(uint256)\":{\"notice\":\"unwrap sOHM\"},\"wOHMValue(uint256)\":{\"notice\":\"converts sOHM amount to wOHM\"},\"wrapFromOHM(uint256)\":{\"notice\":\"stakes OHM and wraps sOHM\"},\"wrapFromsOHM(uint256)\":{\"notice\":\"wrap sOHM\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/wOHM.sol\":\"wOHM\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/wOHM.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.5;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies in extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return _functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n return _functionCallWithValue(target, data, value, errorMessage);\\n }\\n\\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin guidelines: functions revert instead\\n * of returning `false` on failure. This behavior is nonetheless conventional\\n * and does not conflict with the expectations of ERC20 applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is IERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n mapping (address => uint256) private _balances;\\n\\n mapping (address => mapping (address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n uint8 private _decimals;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\\n * a default value of 18.\\n *\\n * To select a different value for {decimals}, use {_setupDecimals}.\\n *\\n * All three of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor (string memory name, string memory symbol) {\\n _name = name;\\n _symbol = symbol;\\n _decimals = 18;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\\n * called.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view returns (uint8) {\\n return _decimals;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(msg.sender, recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(msg.sender, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20};\\n *\\n * Requirements:\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Moves tokens `amount` from `sender` to `recipient`.\\n *\\n * This is internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements\\n *\\n * - `to` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply = _totalSupply.add(amount);\\n _balances[account] = _balances[account].add(amount);\\n emit Transfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Sets {decimals} to a value other than the default one of 18.\\n *\\n * WARNING: This function should only be called from the constructor. Most\\n * applications that interact with token contracts will not expect\\n * {decimals} to ever change, and may work incorrectly if it does.\\n */\\n function _setupDecimals(uint8 decimals_) internal {\\n _decimals = decimals_;\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be to transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\\n}\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require((value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\\ninterface IStaking {\\n function stake( uint _amount, address _recipient ) external returns ( bool );\\n\\n function unstake( uint _amount, address _recipient ) external returns ( bool );\\n\\n function index() external view returns ( uint );\\n}\\n\\ncontract wOHM is ERC20 {\\n using SafeERC20 for ERC20;\\n using Address for address;\\n using SafeMath for uint;\\n\\n address public immutable staking;\\n address public immutable OHM;\\n address public immutable sOHM;\\n\\n constructor( address _staking, address _OHM, address _sOHM, string memory _name, string memory _symbol ) ERC20( _name, _symbol ) {\\n require( _staking != address(0) );\\n staking = _staking;\\n require( _OHM != address(0) );\\n OHM = _OHM;\\n require( _sOHM != address(0) );\\n sOHM = _sOHM;\\n }\\n\\n /**\\n @notice stakes OHM and wraps sOHM\\n @param _amount uint\\n @return uint\\n */\\n function wrapFromOHM( uint _amount ) external returns ( uint ) {\\n IERC20( OHM ).transferFrom( msg.sender, address(this), _amount );\\n\\n IERC20( OHM ).approve( staking, _amount ); // stake OHM for sOHM\\n IStaking( staking ).stake( _amount, address(this) );\\n\\n uint value = wOHMValue( _amount );\\n _mint( msg.sender, value );\\n return value;\\n }\\n\\n /**\\n @notice unwrap sOHM and unstake OHM\\n @param _amount uint\\n @return uint\\n */\\n function unwrapToOHM( uint _amount ) external returns ( uint ) {\\n _burn( msg.sender, _amount );\\n\\n uint value = sOHMValue( _amount );\\n IERC20( sOHM ).approve( staking, value ); // unstake sOHM for OHM\\n IStaking( staking ).unstake( value, address(this) );\\n\\n IERC20( OHM ).transfer( msg.sender, value );\\n return value;\\n }\\n\\n /**\\n @notice wrap sOHM\\n @param _amount uint\\n @return uint\\n */\\n function wrapFromsOHM( uint _amount ) external returns ( uint ) {\\n IERC20( sOHM ).transferFrom( msg.sender, address(this), _amount );\\n\\n uint value = wOHMValue( _amount );\\n _mint( msg.sender, value );\\n return value;\\n }\\n\\n /**\\n @notice unwrap sOHM\\n @param _amount uint\\n @return uint\\n */\\n function unwrapTosOHM( uint _amount ) external returns ( uint ) {\\n _burn( msg.sender, _amount );\\n\\n uint value = sOHMValue( _amount );\\n IERC20( sOHM ).transfer( msg.sender, value );\\n return value;\\n }\\n\\n /**\\n @notice converts wOHM amount to sOHM\\n @param _amount uint\\n @return uint\\n */\\n function sOHMValue( uint _amount ) public view returns ( uint ) {\\n return _amount.mul( IStaking( staking ).index() ).div( 10 ** decimals() );\\n }\\n\\n /**\\n @notice converts sOHM amount to wOHM\\n @param _amount uint\\n @return uint\\n */\\n function wOHMValue( uint _amount ) public view returns ( uint ) {\\n return _amount.mul( 10 ** decimals() ).div( IStaking( staking ).index() );\\n }\\n\\n}\",\"keccak256\":\"0xbe1e149fd8d0c3d3305de95627fd3a6e0c0cc6677c8ce38fbdfdc35031eff438\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60e06040523480156200001157600080fd5b506040516200275a3803806200275a833981810160405260a08110156200003757600080fd5b81019080805190602001909291908051906020019092919080519060200190929190805160405193929190846401000000008211156200007657600080fd5b838201915060208201858111156200008d57600080fd5b8251866001820283011164010000000082111715620000ab57600080fd5b8083526020830192505050908051906020019080838360005b83811015620000e1578082015181840152602081019050620000c4565b50505050905090810190601f1680156200010f5780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200013357600080fd5b838201915060208201858111156200014a57600080fd5b82518660018202830111640100000000821117156200016857600080fd5b8083526020830192505050908051906020019080838360005b838110156200019e57808201518184015260208101905062000181565b50505050905090810190601f168015620001cc5780820380516001836020036101000a031916815260200191505b5060405250505081818160039080519060200190620001ed92919062000386565b5080600490805190602001906200020692919062000386565b506012600560006101000a81548160ff021916908360ff1602179055505050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614156200026057600080fd5b8473ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b81525050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415620002d257600080fd5b8373ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b81525050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156200034457600080fd5b8273ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff1660601b8152505050505050506200043c565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620003be57600085556200040a565b82601f10620003d957805160ff19168380011785556200040a565b828001600101855582156200040a579182015b8281111562000409578251825591602001919060010190620003ec565b5b5090506200041991906200041d565b5090565b5b80821115620004385760008160009055506001016200041e565b5090565b60805160601c60a05160601c60c05160601c6122ac620004ae6000398061083d52806108635280610a73528061136b525080610c2d5280610dce5280610eb95280611317525080610aaf5280610b605280610da85280610ef55280610fa6528061118252806114de52506122ac6000f3fe608060405234801561001057600080fd5b506004361061012c5760003560e01c806359da2b26116100ad578063a6c41fec11610071578063a6c41fec146105ee578063a9059cbb14610622578063b407402c14610686578063dd62ed3e146106c8578063e11fd9e5146107405761012c565b806359da2b261461042b57806370a082311461046d57806395d89b41146104c55780639ea3115114610548578063a457c2d71461058a5761012c565b806323b872dd116100f457806323b872dd146102ac578063313ce567146103305780633161442a1461035157806339509351146103935780634cf088d9146103f75761012c565b806306fdde0314610131578063095ea7b3146101b457806315079925146102185780631574949c1461024c57806318160ddd1461028e575b600080fd5b610139610782565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561017957808201518184015260208101905061015e565b50505050905090810190601f1680156101a65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610200600480360360408110156101ca57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610824565b60405180821515815260200191505060405180910390f35b61022061083b565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102786004803603602081101561026257600080fd5b810190808035906020019092919050505061085f565b6040518082815260200191505060405180910390f35b61029661096c565b6040518082815260200191505060405180910390f35b610318600480360360608110156102c257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610976565b60405180821515815260200191505060405180910390f35b610338610a41565b604051808260ff16815260200191505060405180910390f35b61037d6004803603602081101561036757600080fd5b8101908080359060200190929190505050610a58565b6040518082815260200191505060405180910390f35b6103df600480360360408110156103a957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610d01565b60405180821515815260200191505060405180910390f35b6103ff610da6565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6104576004803603602081101561044157600080fd5b8101908080359060200190929190505050610dca565b6040518082815260200191505060405180910390f35b6104af6004803603602081101561048357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611091565b6040518082815260200191505060405180910390f35b6104cd6110d9565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561050d5780820151818401526020810190506104f2565b50505050905090810190601f16801561053a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6105746004803603602081101561055e57600080fd5b810190808035906020019092919050505061117b565b6040518082815260200191505060405180910390f35b6105d6600480360360408110156105a057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611256565b60405180821515815260200191505060405180910390f35b6105f6611315565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61066e6004803603604081101561063857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611339565b60405180821515815260200191505060405180910390f35b6106b26004803603602081101561069c57600080fd5b8101908080359060200190929190505050611350565b6040518082815260200191505060405180910390f35b61072a600480360360408110156106de57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061143f565b6040518082815260200191505060405180910390f35b61076c6004803603602081101561075657600080fd5b81019080803590602001909291905050506114c6565b6040518082815260200191505060405180910390f35b606060038054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561081a5780601f106107ef5761010080835404028352916020019161081a565b820191906000526020600020905b8154815290600101906020018083116107fd57829003601f168201915b5050505050905090565b60006108313384846115a1565b6001905092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b15801561091057600080fd5b505af1158015610924573d6000803e3d6000fd5b505050506040513d602081101561093a57600080fd5b81019080805190602001909291905050505060006109578361117b565b90506109633382611798565b80915050919050565b6000600254905090565b600061098384848461195f565b610a368433610a31856040518060600160405280602881526020016121c060289139600160008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611c209092919063ffffffff16565b6115a1565b600190509392505050565b6000600560009054906101000a900460ff16905090565b6000610a643383611ce0565b6000610a6f836114c6565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b37f0000000000000000000000000000000000000000000000000000000000000000836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015610b2257600080fd5b505af1158015610b36573d6000803e3d6000fd5b505050506040513d6020811015610b4c57600080fd5b8101908080519060200190929190505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16638381e18282306040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b158015610bef57600080fd5b505af1158015610c03573d6000803e3d6000fd5b505050506040513d6020811015610c1957600080fd5b8101908080519060200190929190505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015610cbc57600080fd5b505af1158015610cd0573d6000803e3d6000fd5b505050506040513d6020811015610ce657600080fd5b81019080805190602001909291905050505080915050919050565b6000610d9c3384610d9785600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611ea490919063ffffffff16565b6115a1565b6001905092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015610e7b57600080fd5b505af1158015610e8f573d6000803e3d6000fd5b505050506040513d6020811015610ea557600080fd5b8101908080519060200190929190505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b37f0000000000000000000000000000000000000000000000000000000000000000846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015610f6857600080fd5b505af1158015610f7c573d6000803e3d6000fd5b505050506040513d6020811015610f9257600080fd5b8101908080519060200190929190505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637acb775783306040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b15801561103557600080fd5b505af1158015611049573d6000803e3d6000fd5b505050506040513d602081101561105f57600080fd5b810190808051906020019092919050505050600061107c8361117b565b90506110883382611798565b80915050919050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b606060048054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156111715780601f1061114657610100808354040283529160200191611171565b820191906000526020600020905b81548152906001019060200180831161115457829003601f168201915b5050505050905090565b600061124f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632986c0e56040518163ffffffff1660e01b815260040160206040518083038186803b1580156111e657600080fd5b505afa1580156111fa573d6000803e3d6000fd5b505050506040513d602081101561121057600080fd5b810190808051906020019092919050505061124161122c610a41565b60ff16600a0a85611f2c90919063ffffffff16565b611fb290919063ffffffff16565b9050919050565b600061130b33846113068560405180606001604052806025815260200161225260259139600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611c209092919063ffffffff16565b6115a1565b6001905092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600061134633848461195f565b6001905092915050565b600061135c3383611ce0565b6000611367836114c6565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156113fa57600080fd5b505af115801561140e573d6000803e3d6000fd5b505050506040513d602081101561142457600080fd5b81019080805190602001909291905050505080915050919050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600061159a6114d3610a41565b60ff16600a0a61158c7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632986c0e56040518163ffffffff1660e01b815260040160206040518083038186803b15801561154257600080fd5b505afa158015611556573d6000803e3d6000fd5b505050506040513d602081101561156c57600080fd5b810190808051906020019092919050505085611f2c90919063ffffffff16565b611fb290919063ffffffff16565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611627576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602481526020018061222e6024913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156116ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806121576022913960400191505060405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561183b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b61184760008383611ffc565b61185c81600254611ea490919063ffffffff16565b6002819055506118b3816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611ea490919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156119e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806122096025913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611a6b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806121126023913960400191505060405180910390fd5b611a76838383611ffc565b611ae181604051806060016040528060268152602001612179602691396000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611c209092919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611b74816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611ea490919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b6000838311158290611ccd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611c92578082015181840152602081019050611c77565b50505050905090810190601f168015611cbf5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611d66576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806121e86021913960400191505060405180910390fd5b611d7282600083611ffc565b611ddd81604051806060016040528060228152602001612135602291396000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611c209092919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611e348160025461200190919063ffffffff16565b600281905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b600080828401905083811015611f22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600080831415611f3f5760009050611fac565b6000828402905082848281611f5057fe5b0414611fa7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061219f6021913960400191505060405180910390fd5b809150505b92915050565b6000611ff483836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061204b565b905092915050565b505050565b600061204383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611c20565b905092915050565b600080831182906120f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156120bc5780820151818401526020810190506120a1565b50505050905090810190601f1680156120e95780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161210357fe5b04905080915050939250505056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa26469706673582212207799d77696b25a18036fc58c54ce10b7f0b2b24a5d91c26d37d5eb04a2e4bd5464736f6c63430007050033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061012c5760003560e01c806359da2b26116100ad578063a6c41fec11610071578063a6c41fec146105ee578063a9059cbb14610622578063b407402c14610686578063dd62ed3e146106c8578063e11fd9e5146107405761012c565b806359da2b261461042b57806370a082311461046d57806395d89b41146104c55780639ea3115114610548578063a457c2d71461058a5761012c565b806323b872dd116100f457806323b872dd146102ac578063313ce567146103305780633161442a1461035157806339509351146103935780634cf088d9146103f75761012c565b806306fdde0314610131578063095ea7b3146101b457806315079925146102185780631574949c1461024c57806318160ddd1461028e575b600080fd5b610139610782565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561017957808201518184015260208101905061015e565b50505050905090810190601f1680156101a65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610200600480360360408110156101ca57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610824565b60405180821515815260200191505060405180910390f35b61022061083b565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102786004803603602081101561026257600080fd5b810190808035906020019092919050505061085f565b6040518082815260200191505060405180910390f35b61029661096c565b6040518082815260200191505060405180910390f35b610318600480360360608110156102c257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610976565b60405180821515815260200191505060405180910390f35b610338610a41565b604051808260ff16815260200191505060405180910390f35b61037d6004803603602081101561036757600080fd5b8101908080359060200190929190505050610a58565b6040518082815260200191505060405180910390f35b6103df600480360360408110156103a957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610d01565b60405180821515815260200191505060405180910390f35b6103ff610da6565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6104576004803603602081101561044157600080fd5b8101908080359060200190929190505050610dca565b6040518082815260200191505060405180910390f35b6104af6004803603602081101561048357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611091565b6040518082815260200191505060405180910390f35b6104cd6110d9565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561050d5780820151818401526020810190506104f2565b50505050905090810190601f16801561053a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6105746004803603602081101561055e57600080fd5b810190808035906020019092919050505061117b565b6040518082815260200191505060405180910390f35b6105d6600480360360408110156105a057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611256565b60405180821515815260200191505060405180910390f35b6105f6611315565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61066e6004803603604081101561063857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611339565b60405180821515815260200191505060405180910390f35b6106b26004803603602081101561069c57600080fd5b8101908080359060200190929190505050611350565b6040518082815260200191505060405180910390f35b61072a600480360360408110156106de57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061143f565b6040518082815260200191505060405180910390f35b61076c6004803603602081101561075657600080fd5b81019080803590602001909291905050506114c6565b6040518082815260200191505060405180910390f35b606060038054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561081a5780601f106107ef5761010080835404028352916020019161081a565b820191906000526020600020905b8154815290600101906020018083116107fd57829003601f168201915b5050505050905090565b60006108313384846115a1565b6001905092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b15801561091057600080fd5b505af1158015610924573d6000803e3d6000fd5b505050506040513d602081101561093a57600080fd5b81019080805190602001909291905050505060006109578361117b565b90506109633382611798565b80915050919050565b6000600254905090565b600061098384848461195f565b610a368433610a31856040518060600160405280602881526020016121c060289139600160008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611c209092919063ffffffff16565b6115a1565b600190509392505050565b6000600560009054906101000a900460ff16905090565b6000610a643383611ce0565b6000610a6f836114c6565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b37f0000000000000000000000000000000000000000000000000000000000000000836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015610b2257600080fd5b505af1158015610b36573d6000803e3d6000fd5b505050506040513d6020811015610b4c57600080fd5b8101908080519060200190929190505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16638381e18282306040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b158015610bef57600080fd5b505af1158015610c03573d6000803e3d6000fd5b505050506040513d6020811015610c1957600080fd5b8101908080519060200190929190505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015610cbc57600080fd5b505af1158015610cd0573d6000803e3d6000fd5b505050506040513d6020811015610ce657600080fd5b81019080805190602001909291905050505080915050919050565b6000610d9c3384610d9785600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611ea490919063ffffffff16565b6115a1565b6001905092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015610e7b57600080fd5b505af1158015610e8f573d6000803e3d6000fd5b505050506040513d6020811015610ea557600080fd5b8101908080519060200190929190505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b37f0000000000000000000000000000000000000000000000000000000000000000846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015610f6857600080fd5b505af1158015610f7c573d6000803e3d6000fd5b505050506040513d6020811015610f9257600080fd5b8101908080519060200190929190505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637acb775783306040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b15801561103557600080fd5b505af1158015611049573d6000803e3d6000fd5b505050506040513d602081101561105f57600080fd5b810190808051906020019092919050505050600061107c8361117b565b90506110883382611798565b80915050919050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b606060048054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156111715780601f1061114657610100808354040283529160200191611171565b820191906000526020600020905b81548152906001019060200180831161115457829003601f168201915b5050505050905090565b600061124f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632986c0e56040518163ffffffff1660e01b815260040160206040518083038186803b1580156111e657600080fd5b505afa1580156111fa573d6000803e3d6000fd5b505050506040513d602081101561121057600080fd5b810190808051906020019092919050505061124161122c610a41565b60ff16600a0a85611f2c90919063ffffffff16565b611fb290919063ffffffff16565b9050919050565b600061130b33846113068560405180606001604052806025815260200161225260259139600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611c209092919063ffffffff16565b6115a1565b6001905092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600061134633848461195f565b6001905092915050565b600061135c3383611ce0565b6000611367836114c6565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156113fa57600080fd5b505af115801561140e573d6000803e3d6000fd5b505050506040513d602081101561142457600080fd5b81019080805190602001909291905050505080915050919050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600061159a6114d3610a41565b60ff16600a0a61158c7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632986c0e56040518163ffffffff1660e01b815260040160206040518083038186803b15801561154257600080fd5b505afa158015611556573d6000803e3d6000fd5b505050506040513d602081101561156c57600080fd5b810190808051906020019092919050505085611f2c90919063ffffffff16565b611fb290919063ffffffff16565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611627576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602481526020018061222e6024913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156116ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806121576022913960400191505060405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561183b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b61184760008383611ffc565b61185c81600254611ea490919063ffffffff16565b6002819055506118b3816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611ea490919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156119e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806122096025913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611a6b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806121126023913960400191505060405180910390fd5b611a76838383611ffc565b611ae181604051806060016040528060268152602001612179602691396000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611c209092919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611b74816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611ea490919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b6000838311158290611ccd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611c92578082015181840152602081019050611c77565b50505050905090810190601f168015611cbf5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611d66576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806121e86021913960400191505060405180910390fd5b611d7282600083611ffc565b611ddd81604051806060016040528060228152602001612135602291396000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611c209092919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611e348160025461200190919063ffffffff16565b600281905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b600080828401905083811015611f22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600080831415611f3f5760009050611fac565b6000828402905082848281611f5057fe5b0414611fa7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061219f6021913960400191505060405180910390fd5b809150505b92915050565b6000611ff483836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061204b565b905092915050565b505050565b600061204383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611c20565b905092915050565b600080831182906120f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156120bc5780820151818401526020810190506120a1565b50505050905090810190601f1680156120e95780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161210357fe5b04905080915050939250505056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa26469706673582212207799d77696b25a18036fc58c54ce10b7f0b2b24a5d91c26d37d5eb04a2e4bd5464736f6c63430007050033", + "devdoc": { + "kind": "dev", + "methods": { + "allowance(address,address)": { + "details": "See {IERC20-allowance}." + }, + "approve(address,uint256)": { + "details": "See {IERC20-approve}. Requirements: - `spender` cannot be the zero address." + }, + "balanceOf(address)": { + "details": "See {IERC20-balanceOf}." + }, + "decimals()": { + "details": "Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5,05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is called. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}." + }, + "decreaseAllowance(address,uint256)": { + "details": "Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`." + }, + "increaseAllowance(address,uint256)": { + "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address." + }, + "name()": { + "details": "Returns the name of the token." + }, + "sOHMValue(uint256)": { + "params": { + "_amount": "uint" + }, + "returns": { + "_0": "uint" + } + }, + "symbol()": { + "details": "Returns the symbol of the token, usually a shorter version of the name." + }, + "totalSupply()": { + "details": "See {IERC20-totalSupply}." + }, + "transfer(address,uint256)": { + "details": "See {IERC20-transfer}. Requirements: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`." + }, + "transferFrom(address,address,uint256)": { + "details": "See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}; Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for ``sender``'s tokens of at least `amount`." + }, + "unwrapToOHM(uint256)": { + "params": { + "_amount": "uint" + }, + "returns": { + "_0": "uint" + } + }, + "unwrapTosOHM(uint256)": { + "params": { + "_amount": "uint" + }, + "returns": { + "_0": "uint" + } + }, + "wOHMValue(uint256)": { + "params": { + "_amount": "uint" + }, + "returns": { + "_0": "uint" + } + }, + "wrapFromOHM(uint256)": { + "params": { + "_amount": "uint" + }, + "returns": { + "_0": "uint" + } + }, + "wrapFromsOHM(uint256)": { + "params": { + "_amount": "uint" + }, + "returns": { + "_0": "uint" + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "sOHMValue(uint256)": { + "notice": "converts wOHM amount to sOHM" + }, + "unwrapToOHM(uint256)": { + "notice": "unwrap sOHM and unstake OHM" + }, + "unwrapTosOHM(uint256)": { + "notice": "unwrap sOHM" + }, + "wOHMValue(uint256)": { + "notice": "converts sOHM amount to wOHM" + }, + "wrapFromOHM(uint256)": { + "notice": "stakes OHM and wraps sOHM" + }, + "wrapFromsOHM(uint256)": { + "notice": "wrap sOHM" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 477, + "contract": "contracts/wOHM.sol:wOHM", + "label": "_balances", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 483, + "contract": "contracts/wOHM.sol:wOHM", + "label": "_allowances", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 485, + "contract": "contracts/wOHM.sol:wOHM", + "label": "_totalSupply", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 487, + "contract": "contracts/wOHM.sol:wOHM", + "label": "_name", + "offset": 0, + "slot": "3", + "type": "t_string_storage" + }, + { + "astId": 489, + "contract": "contracts/wOHM.sol:wOHM", + "label": "_symbol", + "offset": 0, + "slot": "4", + "type": "t_string_storage" + }, + { + "astId": 491, + "contract": "contracts/wOHM.sol:wOHM", + "label": "_decimals", + "offset": 0, + "slot": "5", + "type": "t_uint8" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/src/constants.ts b/src/constants.ts index 4091745e2d..231c06fe29 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -39,27 +39,22 @@ export const addresses: IAddresses = { STAKING_HELPER_ADDRESS: "0x2663a2E5f4DF96b79377DA6B15e448b012838Cb8", // FraxBondDepository_ADDRESS: "0x38E4560A1DB2DAe89F78F98b308eE6F890b27712", // WftmBondDepository_ADDRESS: "0x1e0AD0F8DDFF84FDc938373E9aa66b8d994ea066", - REDEEM_HELPER_ADDRESS: "0xBd35d8b2FDc2b720842DB372f5E419d39B24781f", + REDEEM_HELPER_ADDRESS: "0x952A2D7BE42E04FCC622e4beB4c59d3AD4Ffbe4F", }, 4: { - FRAX_ADDRESS: "0xB2180448f8945C8Cc8AE9809E67D6bd27d8B2f2C", // duplicate - BRICK_ADDRESS: "0xC0b491daBf3709Ee5Eb79E603D73289Ca6060932", - STAKING_ADDRESS: "0xC5d3318C0d74a72cD7C55bdf844e24516796BaB2", - STAKING_HELPER_ADDRESS: "0xf73f23Bb0edCf4719b12ccEa8638355BF33604A1", - SBRICK_ADDRESS: "0x1Fecda1dE7b6951B248C0B62CaeBD5BAbedc2084", - DISTRIBUTOR_ADDRESS: "0x0626D5aD2a230E05Fb94DF035Abbd97F2f839C3a", - BONDINGCALC_ADDRESS: "0xaDBE4FA3c2fcf36412D618AfCfC519C869400CEB", - TREASURY_ADDRESS: "0x0d722D813601E48b7DAcb2DF9bae282cFd98c6E7", - REDEEM_HELPER_ADDRESS: "0xBd35d8b2FDc2b720842DB372f5E419d39B24781f", - PT_TOKEN_ADDRESS: "0x0a2d026bacc573a8b5a2b049f956bdf8e5256cfd", // 33T token address, taken from `ticket` function on PRIZE_STRATEGY_ADDRESS - PT_PRIZE_POOL_ADDRESS: "0xf9081132864ed5e4980CFae83bDB122d86619281", // NEW - PT_PRIZE_STRATEGY_ADDRESS: "0x2Df17EA8D6B68Ec444c9a698315AfB36425dac8b", // NEW - MIGRATOR_ADDRESS: "0x568c257BF4714864382b643fC8e6Ce5fbBcC6d3C", - GBRICK_ADDRESS: "0xcF2D6893A1CB459fD6B48dC9C41c6110B968611E", - OHM_V2: "0xd7B98050962ec7cC8D11a83446B3217257C754B7", - TREASURY_V2: "0x8dd0d811CEFb5CF41528C495E76638B2Ea39d2e6", - SOHM_V2: "0xebED323CEbe4FfF65F7D7612Ea04313F718E5A75", - STAKING_V2: "0x06984c3A9EB8e3A8df02A4C09770D5886185792D", + BRICK_ADDRESS: "0x9bb5E7183e6259183f8E79876eCC0228738C95F6", + FRAX_ADDRESS: "0x0B81a995b28254D76e5148d29E8eb4c5c26D3aC0", + WFTM_ADDRESS: "0xDd1875ddC7c832FA1CB82DfB8B34d3abD1F67a87", + BONDINGCALC_ADDRESS: "0x03E82c27761DaaA69852cF5238Bc2597a14592cd", + TREASURY_ADDRESS: "0x1e0AD0F8DDFF84FDc938373E9aa66b8d994ea066", + DISTRIBUTOR_ADDRESS: "0xAECEc67825F49AAD1962F0557266A6Ba501Ddcea", + SBRICK_ADDRESS: "0x230a8dC3c34336372b75549915DeBAEAACCF129D", + STAKING_ADDRESS: "0xbB8b39A92D916D4c1c46c67CA22920A366127A4B", + // StakingWarmup_ADDRESS: "0xB8408Fc5f5aE1980a6af4CaA6118E98F7c328A5d", + STAKING_HELPER_ADDRESS: "0x179C45D4c6F8370c68A53aF068b5Fa20e3fE2Af4", + // FraxBondDepository_ADDRESS: "0x38E4560A1DB2DAe89F78F98b308eE6F890b27712", + // WftmBondDepository_ADDRESS: "0x1e0AD0F8DDFF84FDc938373E9aa66b8d994ea066", + REDEEM_HELPER_ADDRESS: "0x1084A389cff0a8c378ddFbC673fb0E24C2442045", }, 1: { FRAX_ADDRESS: "0x6b175474e89094c44da98b954eedeac495271d0f", // duplicate diff --git a/src/helpers/AllBonds.ts b/src/helpers/AllBonds.ts index 5af35d5cce..3df08f9dc7 100644 --- a/src/helpers/AllBonds.ts +++ b/src/helpers/AllBonds.ts @@ -5,8 +5,8 @@ import { ReactComponent as FraxImg } from "src/assets/tokens/FRAX.svg"; import { ReactComponent as wFTMImg } from "src/assets/tokens/wFTM.svg"; // import { ReactComponent as OhmEthImg } from "src/assets/tokens/OHM-WETH.svg"; -import { abi as FraxBondContract } from "src/abi/ftmTestnet/FRAX.json"; -import { abi as wFTMBondContract } from "src/abi/ftmTestnet/WrappedToken.json"; +import { abi as FraxBondContract } from "src/abi/ftmTestnet/FraxBondDepository.json"; +import { abi as wFTMBondContract } from "src/abi/ftmTestnet/WftmBondDepository.json"; import { abi as ierc20Abi } from "src/abi/IERC20.json"; // import { getBondCalculator } from "src/helpers/BondCalculator"; @@ -40,8 +40,8 @@ export const frax = new StableBond({ // reserveAddress: "0x6b175474e89094c44da98b954eedeac495271d0f", // }, [NetworkID.Testnet]: { - bondAddress: "0xF651283543fB9D61A91f318b78385d187D300738", - reserveAddress: "0x2F7249cb599139e560f0c81c269Ab9b04799E453", + bondAddress: "0xd3D1aD79DC0eeF622f71E786270CFf53719D261C", + reserveAddress: "0x0B81a995b28254D76e5148d29E8eb4c5c26D3aC0", }, // [NetworkID.Fantom]: { // bondAddress: "0x575409F8d77c12B05feD8B455815f0e54797381c", @@ -49,7 +49,7 @@ export const frax = new StableBond({ // }, [NetworkID.FantomTestnet]: { bondAddress: "0x38E4560A1DB2DAe89F78F98b308eE6F890b27712", - reserveAddress: "0x6b175474e89094c44da98b954eedeac495271d0f", + reserveAddress: "0x9e008Cc93b4D2179dB48Fe5A0fed6B484aFf1739", }, }, }); @@ -82,8 +82,8 @@ export const ftm = new CustomBond({ // reserveAddress: "0x853d955acef822db058eb8505911ed77f175b99e", // }, [NetworkID.Testnet]: { - bondAddress: "0xF651283543fB9D61A91f318b78385d187D300738", - reserveAddress: "0x2F7249cb599139e560f0c81c269Ab9b04799E453", + bondAddress: "0x1e0AD0F8DDFF84FDc938373E9aa66b8d994ea066", + reserveAddress: "0xDd1875ddC7c832FA1CB82DfB8B34d3abD1F67a87", }, // [NetworkID.Fantom]: { // bondAddress: "0x575409F8d77c12B05feD8B455815f0e54797381c", @@ -91,7 +91,7 @@ export const ftm = new CustomBond({ // }, [NetworkID.FantomTestnet]: { bondAddress: "0x1e0AD0F8DDFF84FDc938373E9aa66b8d994ea066", - reserveAddress: "0x6b175474e89094c44da98b954eedeac495271d0f", + reserveAddress: "0x0Ae825CD631d5b59D56ACc635f1599ebb3390A6d", }, }, customTreasuryBalanceFunc: async function (this: CustomBond, networkID, provider) { diff --git a/src/helpers/index.tsx b/src/helpers/index.tsx index 24e9756ec4..b7652f613f 100644 --- a/src/helpers/index.tsx +++ b/src/helpers/index.tsx @@ -2,7 +2,7 @@ import { EPOCH_INTERVAL, BLOCK_RATE_SECONDS, addresses } from "../constants"; import { BigNumber, ethers } from "ethers"; import axios from "axios"; // import { abi as PairContractABI } from "../abi/PairContract.json"; -import { abi as RedeemHelperABI } from "../abi/RedeemHelper.json"; +import { abi as RedeemHelperABI } from "../abi/ftmTestnet/RedeemHelper.json"; import { SvgIcon } from "@material-ui/core"; import { ReactComponent as OhmImg } from "../assets/tokens/token_OHM.svg"; diff --git a/src/slices/AccountSlice.ts b/src/slices/AccountSlice.ts index f2756bbd82..3b415e05a4 100644 --- a/src/slices/AccountSlice.ts +++ b/src/slices/AccountSlice.ts @@ -107,11 +107,11 @@ export const getBalances = createAsyncThunk( interface IUserAccountDetails { staking: { - ohmStake: number; - ohmUnstake: number; + brickStake: number; + brickUnstake: number; }; wrapping: { - sohmWrap: number; + sbrickWrap: number; wsohmUnwrap: number; gOhmUnwrap: number; }; @@ -120,37 +120,37 @@ interface IUserAccountDetails { export const getMigrationAllowances = createAsyncThunk( "account/getMigrationAllowances", async ({ networkID, provider, address }: IBaseAddressAsyncThunk) => { - let ohmAllowance = BigNumber.from(0); - let sOhmAllowance = BigNumber.from(0); - let wsOhmAllowance = BigNumber.from(0); - let gOhmAllowance = BigNumber.from(0); + let brickAllowance = BigNumber.from(0); + let sbrickAllowance = BigNumber.from(0); + // let wsbrickAllowance = BigNumber.from(0); + // let gbrickAllowance = BigNumber.from(0); if (addresses[networkID].BRICK_ADDRESS) { const brickContract = IERC20__factory.connect(addresses[networkID].BRICK_ADDRESS, provider); - ohmAllowance = await brickContract.allowance(address, addresses[networkID].MIGRATOR_ADDRESS); + brickAllowance = await brickContract.allowance(address, addresses[networkID].MIGRATOR_ADDRESS); } if (addresses[networkID].SBRICK_ADDRESS) { const sBrickContract = IERC20__factory.connect(addresses[networkID].SBRICK_ADDRESS, provider); - sOhmAllowance = await sBrickContract.allowance(address, addresses[networkID].MIGRATOR_ADDRESS); + sbrickAllowance = await sBrickContract.allowance(address, addresses[networkID].MIGRATOR_ADDRESS); } - if (addresses[networkID].WSBRICK_ADDRESS) { - const wsBrickContract = IERC20__factory.connect(addresses[networkID].WSBRICK_ADDRESS, provider); - wsOhmAllowance = await wsBrickContract.allowance(address, addresses[networkID].MIGRATOR_ADDRESS); - } + // if (addresses[networkID].WSBRICK_ADDRESS) { + // const wsBrickContract = IERC20__factory.connect(addresses[networkID].WSBRICK_ADDRESS, provider); + // wsbrickAllowance = await wsBrickContract.allowance(address, addresses[networkID].MIGRATOR_ADDRESS); + // } - if (addresses[networkID].GBRICK_ADDRESS) { - const gBrickContract = IERC20__factory.connect(addresses[networkID].GBRICK_ADDRESS, provider); - gOhmAllowance = await gBrickContract.allowance(address, addresses[networkID].MIGRATOR_ADDRESS); - } + // if (addresses[networkID].GBRICK_ADDRESS) { + // const gBrickContract = IERC20__factory.connect(addresses[networkID].GBRICK_ADDRESS, provider); + // gbrickAllowance = await gBrickContract.allowance(address, addresses[networkID].MIGRATOR_ADDRESS); + // } return { migration: { - ohm: +ohmAllowance, - sohm: +sOhmAllowance, - wsohm: +wsOhmAllowance, - gohm: +gOhmAllowance, + ohm: +brickAllowance, + sohm: +sbrickAllowance, + // wsohm: +wsbrickAllowance, + // gohm: +gbrickAllowance, }, isMigrationComplete: false, }; @@ -200,11 +200,11 @@ export const loadAccountDetails = createAsyncThunk( return { staking: { - ohmStake: +stakeAllowance, - ohmUnstake: +unstakeAllowance, + brickStake: +stakeAllowance, + brickUnstake: +unstakeAllowance, }, wrapping: { - ohmWrap: Number(ethers.utils.formatUnits(wrapAllowance, "gwei")), + brickWrap: Number(ethers.utils.formatUnits(wrapAllowance, "gwei")), // ohmUnwrap: Number(ethers.utils.formatUnits(unwrapAllowance, "gwei")), // gOhmUnwrap: Number(ethers.utils.formatUnits(gOhmUnwrapAllowance, "ether")), }, @@ -286,8 +286,8 @@ interface IAccountSlice extends IUserAccountDetails, IUserBalances { }; loading: boolean; staking: { - ohmStake: number; - ohmUnstake: number; + brickStake: number; + brickUnstake: number; }; migration: { ohm: number; @@ -315,8 +315,8 @@ const initialState: IAccountSlice = { pool: "", wsohmAsSohm: "", }, - staking: { ohmStake: 0, ohmUnstake: 0 }, - wrapping: { sohmWrap: 0, wsohmUnwrap: 0, gOhmUnwrap: 0 }, + staking: { brickStake: 0, brickUnstake: 0 }, + wrapping: { sbrickWrap: 0, wsohmUnwrap: 0, gOhmUnwrap: 0 }, pooling: { sohmPool: 0 }, migration: { ohm: 0, sohm: 0, wsohm: 0, gohm: 0 }, }; diff --git a/src/slices/BondSlice.ts b/src/slices/BondSlice.ts index 36ac59cce3..234947b85a 100644 --- a/src/slices/BondSlice.ts +++ b/src/slices/BondSlice.ts @@ -67,11 +67,11 @@ export const changeApproval = createAsyncThunk( export interface IBondDetails { bond: string; bondDiscount: number; - // debtRatio: number; + debtRatio: number; bondQuote: number; purchased: number; - // vestingTerm: number; - // maxBondPrice: number; + vestingTerm: number; + maxBondPrice: number; bondPrice: number; marketPrice: number; } @@ -89,18 +89,17 @@ export const calcBondDetails = createAsyncThunk( bondQuote: BigNumberish = BigNumber.from(0); const bondContract = bond.getContractForBond(networkID, provider); const bondCalcContract = getBondCalculator(networkID, provider); - // console.log("bondContract", bondContract); - - // const terms = await bondContract.terms(); - // const maxBondPrice = await bondContract.maxPayout(); - // let debtRatio: BigNumberish; - // // TODO (appleseed): improve this logic - // if (bond.name === "cvx") { - // debtRatio = await bondContract.debtRatio(); - // } else { - // debtRatio = await bondContract.standardizedDebtRatio(); - // } - // debtRatio = Number(debtRatio.toString()) / Math.pow(10, 9); + + const terms = await bondContract.terms(); + const maxBondPrice = await bondContract.maxPayout(); + let debtRatio: BigNumberish; + // TODO (appleseed): improve this logic + if (bond.name === "cvx") { + debtRatio = await bondContract.debtRatio(); + } else { + debtRatio = await bondContract.standardizedDebtRatio(); + } + debtRatio = Number(debtRatio.toString()) / Math.pow(10, 9); let marketPrice: number = 0; try { @@ -157,14 +156,14 @@ export const calcBondDetails = createAsyncThunk( } } - // // Display error if user tries to exceed maximum. - // if (!!value && parseFloat(bondQuote.toString()) > Number(maxBondPrice.toString()) / Math.pow(10, 9)) { - // const errorString = - // "You're trying to bond more than the maximum payout available! The maximum bond payout is " + - // (Number(maxBondPrice.toString()) / Math.pow(10, 9)).toFixed(2).toString() + - // " BRICK."; - // dispatch(error(errorString)); - // } + // Display error if user tries to exceed maximum. + if (!!value && parseFloat(bondQuote.toString()) > Number(maxBondPrice.toString()) / Math.pow(10, 9)) { + const errorString = + "You're trying to bond more than the maximum payout available! The maximum bond payout is " + + (Number(maxBondPrice.toString()) / Math.pow(10, 9)).toFixed(2).toString() + + " BRICK."; + dispatch(error(errorString)); + } // Calculate bonds purchased let purchased = await bond.getTreasuryBalance(networkID, provider); @@ -172,11 +171,11 @@ export const calcBondDetails = createAsyncThunk( return { bond: bond.name, bondDiscount, - // debtRatio: Number(debtRatio.toString()), + debtRatio: Number(debtRatio.toString()), bondQuote: Number(bondQuote.toString()), purchased, - // vestingTerm: Number(terms.vestingTerm.toString()), - // maxBondPrice: Number(maxBondPrice.toString()) / Math.pow(10, 9), + vestingTerm: Number(terms.vestingTerm.toString()), + maxBondPrice: Number(maxBondPrice.toString()) / Math.pow(10, 9), bondPrice: Number(bondPrice.toString()) / Math.pow(10, 18), marketPrice: marketPrice, }; diff --git a/src/slices/StakeThunk.ts b/src/slices/StakeThunk.ts index b68125c08e..d4987edea5 100644 --- a/src/slices/StakeThunk.ts +++ b/src/slices/StakeThunk.ts @@ -67,8 +67,8 @@ export const changeApproval = createAsyncThunk( return dispatch( fetchAccountSuccess({ staking: { - ohmStake: +stakeAllowance, - ohmUnstake: +unstakeAllowance, + brickStake: +stakeAllowance, + brickUnstake: +unstakeAllowance, }, }), ); @@ -111,8 +111,8 @@ export const changeApproval = createAsyncThunk( return dispatch( fetchAccountSuccess({ staking: { - ohmStake: +stakeAllowance, - ohmUnstake: +unstakeAllowance, + brickStake: +stakeAllowance, + brickUnstake: +unstakeAllowance, }, }), ); diff --git a/src/slices/WrapThunk.ts b/src/slices/WrapThunk.ts index 566f03d7fc..9790c7f115 100644 --- a/src/slices/WrapThunk.ts +++ b/src/slices/WrapThunk.ts @@ -78,7 +78,7 @@ export const changeApproval = createAsyncThunk( return dispatch( fetchAccountSuccess({ wrapping: { - ohmWrap: +wrapAllowance, + brickWrap: +wrapAllowance, ohmUnwrap: +unwrapAllowance, }, }), diff --git a/src/views/Stake/Stake.tsx b/src/views/Stake/Stake.tsx index 2e725c0b96..5ed30389d9 100644 --- a/src/views/Stake/Stake.tsx +++ b/src/views/Stake/Stake.tsx @@ -88,10 +88,10 @@ function Stake() { return state.account.balances && state.account.balances.wsohmAsSohm; }); const stakeAllowance = useAppSelector(state => { - return (state.account.staking && state.account.staking.ohmStake) || 0; + return (state.account.staking && state.account.staking.brickStake) || 0; }); const unstakeAllowance = useAppSelector(state => { - return (state.account.staking && state.account.staking.ohmUnstake) || 0; + return (state.account.staking && state.account.staking.brickUnstake) || 0; }); const stakingRebase = useAppSelector(state => { return state.app.stakingRebase || 0; diff --git a/src/views/TreasuryDashboard/TreasuryDashboard.jsx b/src/views/TreasuryDashboard/TreasuryDashboard.jsx index 5b972eea39..db928b1325 100644 --- a/src/views/TreasuryDashboard/TreasuryDashboard.jsx +++ b/src/views/TreasuryDashboard/TreasuryDashboard.jsx @@ -9,7 +9,7 @@ import { MarketValueGraph, RiskFreeValueGraph, ProtocolOwnedLiquidityGraph, - OHMStakedGraph, + brickStakedGraph, RunwayAvailableGraph, } from "./components/Graph/Graph"; @@ -85,7 +85,7 @@ const TreasuryDashboard = memo(() => { - + diff --git a/src/views/TreasuryDashboard/TreasuryDashboard.tsx b/src/views/TreasuryDashboard/TreasuryDashboard.tsx index 459233ecef..cd101f03f2 100644 --- a/src/views/TreasuryDashboard/TreasuryDashboard.tsx +++ b/src/views/TreasuryDashboard/TreasuryDashboard.tsx @@ -9,7 +9,7 @@ import { MarketValueGraph, RiskFreeValueGraph, ProtocolOwnedLiquidityGraph, - OHMStakedGraph, + BrickStakedGraph, RunwayAvailableGraph, } from "./components/Graph/Graph"; @@ -91,7 +91,7 @@ const TreasuryDashboard = memo(() => { - + diff --git a/src/views/TreasuryDashboard/components/Graph/Graph.js b/src/views/TreasuryDashboard/components/Graph/Graph.js index 7346628f94..743fc9a3a8 100644 --- a/src/views/TreasuryDashboard/components/Graph/Graph.js +++ b/src/views/TreasuryDashboard/components/Graph/Graph.js @@ -112,7 +112,7 @@ export const ProtocolOwnedLiquidityGraph = () => { ); }; -export const OHMStakedGraph = () => { +export const BrickStakedGraph = () => { const theme = useTheme(); const { data } = useTreasuryMetrics({ refetchOnMount: false }); diff --git a/src/views/Wrap/Wrap.jsx b/src/views/Wrap/Wrap.jsx index b2e08110f8..bedd57fd9e 100644 --- a/src/views/Wrap/Wrap.jsx +++ b/src/views/Wrap/Wrap.jsx @@ -93,15 +93,15 @@ function Wrap() { return state.account.wrapping && state.account.wrapping.ohmUnwrap; }); - const migrateSohmAllowance = useSelector(state => { + const migrateSbrickAllowance = useSelector(state => { return state.account.migration && state.account.migration.sohm; }); - const migrateWsohmAllowance = useSelector(state => { + const migrateWsbrickAllowance = useSelector(state => { return state.account.migration && state.account.migration.wsohm; }); - const unwrapGohmAllowance = useSelector(state => { + const unwrapGbrickAllowance = useSelector(state => { return state.account.wrapping && state.account.wrapping.gOhmUnwrap; }); @@ -157,13 +157,13 @@ function Wrap() { }; const hasCorrectAllowance = useCallback(() => { - if (assetFrom === "sBRICK" && assetTo === "gBRICK") return migrateSohmAllowance > sohmBalance; - if (assetFrom === "wsBRICK" && assetTo === "gBRICK") return migrateWsohmAllowance > wsohmBalance; + if (assetFrom === "sBRICK" && assetTo === "gBRICK") return migrateSbrickAllowance > sohmBalance; + if (assetFrom === "wsBRICK" && assetTo === "gBRICK") return migrateWsbrickAllowance > wsohmBalance; if (assetFrom === "wsBRICK" && assetTo === "sBRICK") return unwrapAllowance > wsohmBalance; - if (assetFrom === "gBRICK") return unwrapGohmAllowance > gohmBalance; + if (assetFrom === "gBRICK") return unwrapGbrickAllowance > gohmBalance; return 0; - }, [unwrapAllowance, migrateSohmAllowance, migrateWsohmAllowance, assetTo, assetFrom]); + }, [unwrapAllowance, migrateSbrickAllowance, migrateWsbrickAllowance, assetTo, assetFrom]); const isAllowanceDataLoading = unwrapAllowance == null && currentAction === "Unwrap"; // const convertedQuantity = 0; From c350fc917dc4aebcb1cd87ab1d7c2fa1214d082e Mon Sep 17 00:00:00 2001 From: 0xKChau Date: Mon, 17 Jan 2022 15:39:50 +0800 Subject: [PATCH 02/13] Add mainnet and rinkeby network id --- src/components/Sidebar/NavContent.jsx | 2 +- src/helpers/AllBonds.ts | 40 +++++++++++++-------------- src/slices/AccountSlice.ts | 1 + 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/components/Sidebar/NavContent.jsx b/src/components/Sidebar/NavContent.jsx index 71c0137aae..c0e38948ac 100644 --- a/src/components/Sidebar/NavContent.jsx +++ b/src/components/Sidebar/NavContent.jsx @@ -57,7 +57,7 @@ function NavContent() {