Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0x991aEBBde29bFD8455c2AB6B1cD51Dd9ab70A336
Balance 0 ETH
Nonce 1
Code Size 11681 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

11681 bytes
0x608060405234801561001057600080fd5b50600436106101e55760003560e01c8063817b1cd21161010f578063cead0481116100a2578063e2fcf55011610071578063e2fcf5501461047c578063e9314c731461048f578063f7c618c1146104a2578063fe4b84df146104c957600080fd5b8063cead04811461043b578063da4086791461044e578063dc01f60d14610456578063de1ec4031461046957600080fd5b80639f1acf08116100de5780639f1acf08146103e2578063b07b709b146103f5578063b6b55f2514610408578063c24ab3bb1461041b57600080fd5b8063817b1cd2146103975780638da5cb5b146103a0578063926f7327146103c757806397a04d5a146103da57600080fd5b8063372500ab116101875780636e553f65116101565780636e553f65146102f15780636f307dc31461030457806375baf37f1461034357806379022a9f1461037057600080fd5b8063372500ab146102ba5780634a62c9fb146102c25780634ba9699e146102cb57806354438127146102de57600080fd5b80631ac40e66116101c35780631ac40e66146102755780632e1a7d4d1461027f57806331cc13ba14610292578063344ff1d0146102b257600080fd5b806316765391146101ea57806318160ddd1461022657806319ad0eba1461022f575b600080fd5b6102136101f83660046128d8565b6001600160a01b03166000908152600c602052604090205490565b6040519081526020015b60405180910390f35b61021360135481565b61024261023d3660046128d8565b6104dc565b60405161021d91908151815260208083015190820152604080830151908201526060918201519181019190915260800190565b61027d610518565b005b61027d61028d3660046128f3565b61058d565b6102a56102a03660046128d8565b610822565b60405161021d919061290c565b601354610213565b61021361091d565b610213600e5481565b61027d6102d9366004612964565b6109bc565b6102136102ec366004612997565b610a46565b61027d6102ff366004612997565b610c9d565b61032b7f0000000000000000000000001cce5169bde03f3d5ad0206f6bd057953539dae681565b6040516001600160a01b03909116815260200161021d565b604080518082018252600b81526a131bd8dad95915985d5b1d60aa1b6020820152905161021d91906129e7565b61032b7f0000000000000000000000009543b9f3450c17f1e5e558cc135fd8964dbef92a81565b61021360065481565b61032b7f00000000000000000000000078ecf97572c3890ed02221a611014f30219f621981565b61027d6103d5366004612a1a565b610ebc565b610213610ecb565b6102136103f03660046128d8565b610ee4565b61027d6104033660046128d8565b610ef0565b61027d6104163660046128f3565b610f8b565b61042e6104293660046128d8565b610f98565b60405161021d9190612a44565b61027d610449366004612ab4565b6110ff565b61027d611115565b6102136104643660046128d8565b611199565b610213610477366004612a1a565b611250565b61027d61048a366004612a1a565b61125e565b61027d61049d3660046128f3565b611269565b61032b7f00000000000000000000000070c4430f9d98b4184a4ef3e44ce10c320a8b738381565b61027d6104d73660046128f3565b6112e8565b6105076040518060800160405280600081526020016000815260200160008152602001600081525090565b6105126001836113fe565b92915050565b6006548015610586576000600854426105319190612b06565b905060008161053e610ecb565b6105489190612b19565b9050610554818461150c565b600760008282546105659190612b30565b92505081905550806009600082825461057e9190612b30565b909155505050505b5042600855565b600081815260116020908152604091829020825160a0810184528154815260018201549281019290925260028101549282019290925260038201546001600160a01b03908116606083018190526004909301541660808201529033146106455760405162461bcd60e51b815260206004820152602260248201527f6d61746368696e67207769746864726177616c20646f6573206e6f74206578696044820152611cdd60f21b60648201526084015b60405180910390fd5b42816020015111156106995760405162461bcd60e51b815260206004820152601b60248201527f6e6f2076616c69642070656e64696e67207769746864726177616c0000000000604482015260640161063c565b60408101516000906106d090601260ff7f00000000000000000000000000000000000000000000000000000000000000121661155f565b606083015160405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529192507f0000000000000000000000001cce5169bde03f3d5ad0206f6bd057953539dae6169063a9059cbb906044016020604051808303816000875af1158015610747573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076b9190612b43565b50600083815260116020908152604080832083815560018101849055600281018490556003810180546001600160a01b031990811690915560049091018054909116905560608501516001600160a01b03168352601090915290206107d090846115bc565b5081606001516001600160a01b0316837f096793b0307a8bedd30923ee6c6a84d492646dd968c25a0c714296a68c74aceb846040015160405161081591815260200190565b60405180910390a3505050565b6001600160a01b0381166000908152600560205260408120606091610846826115c8565b90508067ffffffffffffffff81111561086157610861612b65565b6040519080825280602002602001820160405280156108a657816020015b604080518082019091526000808252602082015281526020019060019003908161087f5790505b50925060005b81811015610915576000806108c185846115d3565b915091506040518060400160405280836001600160a01b03168152602001828152508684815181106108f5576108f5612b7b565b60200260200101819052505050808061090d90612b91565b9150506108ac565b505050919050565b600061092833610ef0565b336000908152600b60205260408120549081900361094857600091505090565b336000818152600b602052604080822091909155517f47cee97cb7acd717b3c0aa1435d004cd5b3c8c57d70dbceb4e4458bbd60e39d49061098c9084815260200190565b60405180910390a280600960008282546109a69190612b06565b909155506109b6905033826115f1565b91505090565b336001600160a01b037f00000000000000000000000078ecf97572c3890ed02221a611014f30219f62191614610a365760405163c55ddc9760e01b81523360048201526001600160a01b037f00000000000000000000000078ecf97572c3890ed02221a611014f30219f621916602482015260440161063c565b610a4183838361162d565b505050565b600080610a546001336113fe565b905060006001600160a01b03841615801590610a7957506001600160a01b0384163314155b905084826020015110158015610ab557508080610ab557503360009081526003602052604090205485908360200151610ab29190612b06565b10155b610b015760405162461bcd60e51b815260206004820152601860248201527f6e6f7420656e6f75676820746f20756e64656c65676174650000000000000000604482015260640161063c565b610b2a33868460200151610b159190612b06565b604085015160608601516001939291906116c4565b508015610b3c57610b3c338587611808565b8460136000828254610b4e9190612b06565b90915550610b5e9050338661189d565b60006040518060a001604052806012548152602001600f5442610b819190612b30565b815260208082018990523360408084018290526001600160a01b038a811660609586015285516000908152601185528281208751808255888701516001830155888501516002830155968801516003820180549185166001600160a01b031992831617905560808901516004909201805492909416911617909155918252601090925220919250610c12919061192f565b5060128054906000610c2383612b91565b919050555080608001516001600160a01b031681606001516001600160a01b031682600001517f20849eb8a3d11461c2f45d1330d7cdfdcf0359148aaa26d84af32b9596e32b9484602001518560400151604051610c8b929190918252602082015260400190565b60405180910390a45195945050505050565b6001600160a01b038116610ce85760405162461bcd60e51b815260206004820152601260248201527106e6f2064656c65676174696f6e20746f20360741b604482015260640161063c565b60008211610d385760405162461bcd60e51b815260206004820152601a60248201527f63616e6e6f74206465706f736974207a65726f20616d6f756e74000000000000604482015260640161063c565b6040516323b872dd60e01b81526001600160a01b037f0000000000000000000000001cce5169bde03f3d5ad0206f6bd057953539dae616906323b872dd90610d8890339030908790600401612baa565b6020604051808303816000875af1158015610da7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dcb9190612b43565b506000610dd96001336113fe565b90506000610e0c8460ff7f000000000000000000000000000000000000000000000000000000000000001216601261155f565b9050610e2233828460200151610b159190612b30565b506001600160a01b03831615801590610e4457506001600160a01b0383163314155b15610e5457610e5433848361193b565b8060136000828254610e669190612b30565b90915550610e7690503382611a0c565b6040518481526001600160a01b0384169033907f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f629060200160405180910390a350505050565b610ec733838361193b565b5050565b6000600e54421115610edd5750600090565b50600d5490565b60006105128242611250565b610ef8610518565b6007546001600160a01b0382166000908152600a6020526040902054610f4290610f229083612b06565b6001600160a01b0384166000908152600c60205260409020545b90611a94565b6001600160a01b0383166000908152600b602052604081208054909190610f6a908490612b30565b90915550506001600160a01b039091166000908152600a6020526040902055565b610f958133610c9d565b50565b6001600160a01b0381166000908152601060205260408120606091610fbc82611abd565b67ffffffffffffffff811115610fd457610fd4612b65565b60405190808252806020026020018201604052801561104957816020015b6110366040518060a0016040528060008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b031681525090565b815260200190600190039081610ff25790505b50905060005b61105883611abd565b8110156110f7576011600061106d8584611ac7565b81526020808201929092526040908101600020815160a0810183528154815260018201549381019390935260028101549183019190915260038101546001600160a01b03908116606084015260049091015416608082015282518390839081106110d9576110d9612b7b565b602002602001018190525080806110ef90612b91565b91505061104f565b509392505050565b61110a338483611808565b610a4133838361193b565b336001600160a01b037f00000000000000000000000078ecf97572c3890ed02221a611014f30219f6219161461118f5760405163c55ddc9760e01b81523360048201526001600160a01b037f00000000000000000000000078ecf97572c3890ed02221a611014f30219f621916602482015260440161063c565b611197611ad3565b565b60075460065460009190156111e1576111d4600654600854426111bc9190612b06565b6111c4610ecb565b6111ce9190612b19565b9061150c565b6111de9082612b30565b90505b6001600160a01b0383166000908152600a6020526040902054611226906112089083612b06565b6001600160a01b0385166000908152600c6020526040902054610f3c565b6001600160a01b0384166000908152600b60205260409020546112499190612b30565b9392505050565b600061124960018484611bfb565b610ec7338383611808565b336001600160a01b037f00000000000000000000000078ecf97572c3890ed02221a611014f30219f621916146112e35760405163c55ddc9760e01b81523360048201526001600160a01b037f00000000000000000000000078ecf97572c3890ed02221a611014f30219f621916602482015260440161063c565b600f55565b600054610100900460ff16158080156113085750600054600160ff909116105b806113225750303b158015611322575060005460ff166001145b6113855760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161063c565b6000805460ff1916600117905580156113a8576000805461ff0019166101001790555b600f8290556113b5610518565b8015610ec7576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6114296040518060800160405280600081526020016000815260200160008152602001600081525090565b6001600160a01b03821660009081526020848152604080832080548251818502810185019093528083529192909190849084015b828210156114b757838290600052602060002090600402016040518060800160405290816000820154815260200160018201548152602001600282015481526020016003820154815250508152602001906001019061145d565b50505050905080516000036114d6576114ce611cac565b915050610512565b80600182516114e59190612b06565b815181106114f5576114f5612b7b565b6020026020010151915050610512565b5092915050565b60008160000361152f57604051630a0c22c760e01b815260040160405180910390fd5b8260000361153f57506000610512565b6000611553670de0b6b3a764000085612b19565b90506114ce8382612bce565b600081830361156f575082611249565b8183101561159d576115818383612b06565b61158c90600a612ccc565b6115969085612b19565b9050611249565b6115a78284612b06565b6115b290600a612ccc565b6115969085612bce565b60006112498383611d08565b600061051282611dfb565b60008080806115e28686611e06565b909450925050505b9250929050565b60006116276001600160a01b037f00000000000000000000000070c4430f9d98b4184a4ef3e44ce10c320a8b7383168484611e31565b50919050565b611635610518565b61166a6001600160a01b037f00000000000000000000000070c4430f9d98b4184a4ef3e44ce10c320a8b738316843085611e94565b6116744282612b06565b61167e9083612bce565b600d55600e81905560408051838152602081018390527f76554fac4477e8876b3de3af392cf374cf4e9de02ae78fbade2373107381fe50910160405180910390a1505050565b6116ef6040518060800160405280600081526020016000815260200160008152602001600081525090565b6001600160a01b0385166000908152602087815260408083208151608081018352428152928301889052908201869052606082018590529161173189896113fe565b8051909150421480156117445750825415155b156117a95782548290849061175b90600190612b06565b8154811061176b5761176b612b7b565b9060005260206000209060040201600082015181600001556020820151816001015560408201518160020155606082015181600301559050506117fc565b6001600160a01b038816600090815260208a815260408083208054600181810183559185529383902086516004909502019384559185015191830191909155830151600282015560608301516003909101555b50979650505050505050565b6118156001848484611eb5565b6001600160a01b03831660009081526005602052604081206118379084612092565b9050818103611868576001600160a01b038416600090815260056020526040902061186290846120a7565b50611897565b611895836118768484612b06565b6001600160a01b038716600090815260056020526040902091906120bc565b505b50505050565b6118a682610ef0565b6001600160a01b0382166000908152600c6020526040812080548392906118ce908490612b06565b9250508190555080600660008282546118e79190612b06565b90915550506040518181526001600160a01b038316907f85082129d87b2fe11527cb1b3b7a520aeb5aa6913f88a3d8757fe40d1db02fdd906020015b60405180910390a25050565b600061124983836120d2565b6001600160a01b0382166119915760405162461bcd60e51b815260206004820152601c60248201527f63616e6e6f742064656c656761746520746f2030206164647265737300000000604482015260640161063c565b61199e6001848484612121565b6001600160a01b038316600090815260056020526040812081906119c290856122f2565b915091506000826119d357836119dd565b6119dd8483612b30565b6001600160a01b0387166000908152600560205260409020909150611a039086836120bc565b50505050505050565b611a1582610ef0565b8060066000828254611a279190612b30565b90915550506001600160a01b0382166000908152600c602052604081208054839290611a54908490612b30565b90915550506040518181526001600160a01b038316907febedb8b3c678666e7f36970bc8f57abf6d8fa2e828c0da91ea5b75bf68ed101a90602001611923565b600080611aa18385612b19565b9050611ab5670de0b6b3a764000082612bce565b949350505050565b6000610512825490565b6000611249838361230a565b611adb610518565b6009546040516370a0823160e01b8152306004820152600091906001600160a01b037f00000000000000000000000070c4430f9d98b4184a4ef3e44ce10c320a8b738316906370a0823190602401602060405180830381865afa158015611b46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b6a9190612cd8565b611b749190612b06565b9050611bca6001600160a01b037f00000000000000000000000070c4430f9d98b4184a4ef3e44ce10c320a8b7383167f0000000000000000000000009543b9f3450c17f1e5e558cc135fd8964dbef92a83611e31565b6000600e8190556040517fe5a0e15e63edb96a15ed99a9c2a3674e2e0bd1b10b65d0223cce19a6b54e7fb19190a150565b6001600160a01b03821660009081526020848152604080832080548251818502810185019093528083528493611c9793929190859084015b82821015611c8d578382906000526020600020906004020160405180608001604052908160008201548152602001600182015481526020016002820154815260200160038201548152505081526020019060010190611c33565b5050505084612334565b915050611ca38161237a565b95945050505050565b611cd76040518060800160405280600081526020016000815260200160008152602001600081525090565b60405180608001604052806000815260200160008152602001670de0b6b3a764000081526020016000815250905090565b60008181526001830160205260408120548015611df1576000611d2c600183612b06565b8554909150600090611d4090600190612b06565b9050818114611da5576000866000018281548110611d6057611d60612b7b565b9060005260206000200154905080876000018481548110611d8357611d83612b7b565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611db657611db6612cf1565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610512565b6000915050610512565b600061051282611abd565b60008080611e148585611ac7565b600081815260029690960160205260409095205494959350505050565b6040516001600160a01b038316602482015260448101829052610a4190849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526123a6565b611897846323b872dd60e01b858585604051602401611e5d93929190612baa565b6001600160a01b038084166000908152600186016020908152604080832093861683529290522054811115611f3e5760405162461bcd60e51b815260206004820152602960248201527f7573657220686173206e6f742064656c65676174656420656e6f75676820746f6044820152682064656c656761746560b81b606482015260840161063c565b6001600160a01b038216600090815260038501602052604081208054839290611f68908490612b06565b90915550506001600160a01b038316600090815260028501602052604081208054839290611f97908490612b06565b90915550506001600160a01b038084166000908152600186016020908152604080832093861683529290529081208054839290611fd5908490612b06565b9091555060009050611fe785856113fe565b9050612014848260200151836040015161200a888a61247890919063ffffffff16565b89939291906116c4565b50600061202186856113fe565b905061204e8482602001518360400151612044888b61247890919063ffffffff16565b8a939291906116c4565b507fde5aa493a93d4351631c1991a0aeecfd52d6b51cf1b61f1a3c48f97e2680865385858560405161208293929190612baa565b60405180910390a1505050505050565b6000611249836001600160a01b0384166124aa565b6000611249836001600160a01b03841661251a565b6000611ab5846001600160a01b03851684612537565b600081815260018301602052604081205461211957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610512565b506000610512565b600061212d85856113fe565b6001600160a01b03851660009081526002870160209081526040808320549084015191840151939450919261216191612554565b61216b9190612b06565b9050828110156121bd5760405162461bcd60e51b815260206004820181905260248201527f696e73756666696369656e742062616c616e636520746f2064656c6567617465604482015260640161063c565b6001600160a01b0384166000908152600387016020526040812080548592906121e7908490612b30565b90915550506001600160a01b038516600090815260028701602052604081208054859290612216908490612b30565b90915550506001600160a01b038086166000908152600188016020908152604080832093881683529290529081208054859290612254908490612b30565b9091555050602082015160408301516122739187916120448a84612478565b50600061228087866113fe565b90506122ad85826020015183604001516122a3898c61247890919063ffffffff16565b8b939291906116c4565b507fff825f9424124effc5ce1d9f4803d58ede8a2bda4da2324810f74834715c4c598686866040516122e193929190612baa565b60405180910390a150505050505050565b60008080806115e2866001600160a01b038716612573565b600082600001828154811061232157612321612b7b565b9060005260206000200154905092915050565b60006123616040518060800160405280600081526020016000815260200160008152602001600081525090565b61236f8484600087516125b5565b915091509250929050565b6000816060015161239c8360400151846020015161255490919063ffffffff16565b6105129190612d07565b60006123fb826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166127109092919063ffffffff16565b805190915015610a4157808060200190518101906124199190612b43565b610a415760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161063c565b6001600160a01b0381166000908152600283016020908152604080832054600386019092528220546112499190612d2f565b6000818152600283016020526040812054801515806124ce57506124ce848461271f565b6112495760405162461bcd60e51b815260206004820152601e60248201527f456e756d657261626c654d61703a206e6f6e6578697374656e74206b65790000604482015260640161063c565b6000818152600283016020526040812081905561124983836115bc565b60008281526002840160205260408120829055611ab5848461192f565b6000670de0b6b3a76400006125698385612b19565b6112499190612bce565b60008181526002830160205260408120548190806125a257612595858561271f565b9250600091506115ea9050565b6001925090506115ea565b509250929050565b60006125e26040518060800160405280600081526020016000815260200160008152602001600081525090565b8284106125fc5760006125f3611cac565b91509150612707565b6126068484612b06565b60010361265457600086858151811061262157612621612b7b565b602002602001015190508581600001511115612646576000612641611cac565b61264a565b6001815b9250925050612707565b600060026126628686612b30565b61266c9190612bce565b905060008761267c600184612b06565b8151811061268c5761268c612b7b565b6020026020010151905060008883815181106126aa576126aa612b7b565b60200260200101519050878260000151111580156126c85750805188105b156126db57506001935091506127079050565b805188106126fb576126ef898985896125b5565b94509450505050612707565b6126ef898989866125b5565b94509492505050565b6060611ab5848460008561272b565b60006112498383612806565b60608247101561278c5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161063c565b600080866001600160a01b031685876040516127a89190612d4f565b60006040518083038185875af1925050503d80600081146127e5576040519150601f19603f3d011682016040523d82523d6000602084013e6127ea565b606091505b50915091506127fb8783838761281e565b979650505050505050565b60008181526001830160205260408120541515611249565b6060831561288d578251600003612886576001600160a01b0385163b6128865760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161063c565b5081611ab5565b611ab583838151156128a25781518083602001fd5b8060405162461bcd60e51b815260040161063c91906129e7565b80356001600160a01b03811681146128d357600080fd5b919050565b6000602082840312156128ea57600080fd5b611249826128bc565b60006020828403121561290557600080fd5b5035919050565b602080825282518282018190526000919060409081850190868401855b8281101561295757815180516001600160a01b03168552860151868501529284019290850190600101612929565b5091979650505050505050565b60008060006060848603121561297957600080fd5b612982846128bc565b95602085013595506040909401359392505050565b600080604083850312156129aa57600080fd5b823591506129ba602084016128bc565b90509250929050565b60005b838110156129de5781810151838201526020016129c6565b50506000910152565b6020815260008251806020840152612a068160408501602087016129c3565b601f01601f19169190910160400192915050565b60008060408385031215612a2d57600080fd5b612a36836128bc565b946020939093013593505050565b602080825282518282018190526000919060409081850190868401855b8281101561295757815180518552868101518786015285810151868601526060808201516001600160a01b0390811691870191909152608091820151169085015260a09093019290850190600101612a61565b600080600060608486031215612ac957600080fd5b612ad2846128bc565b9250612ae0602085016128bc565b9150604084013590509250925092565b634e487b7160e01b600052601160045260246000fd5b8181038181111561051257610512612af0565b808202811582820484141761051257610512612af0565b8082018082111561051257610512612af0565b600060208284031215612b5557600080fd5b8151801515811461124957600080fd5b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600060018201612ba357612ba3612af0565b5060010190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b600082612beb57634e487b7160e01b600052601260045260246000fd5b500490565b600181815b808511156125ad578160001904821115612c1157612c11612af0565b80851615612c1e57918102915b93841c9390800290612bf5565b600082612c3a57506001610512565b81612c4757506000610512565b8160018114612c5d5760028114612c6757612c83565b6001915050610512565b60ff841115612c7857612c78612af0565b50506001821b610512565b5060208310610133831016604e8410600b8410161715612ca6575081810a610512565b612cb08383612bf0565b8060001904821115612cc457612cc4612af0565b029392505050565b60006112498383612c2b565b600060208284031215612cea57600080fd5b5051919050565b634e487b7160e01b600052603160045260246000fd5b8082018281126000831280158216821582161715612d2757612d27612af0565b505092915050565b818103600083128015838313168383128216171561150557611505612af0565b60008251612d618184602087016129c3565b919091019291505056fea26469706673582212209453fecd65dd45f07500703abd4f594f22b08bdf7a33c93ff7d1d32ef7dfe5e764736f6c63430008110033

Verified Source Code Partial Match

Compiler: v0.8.17+commit.8df45f5f EVM: london Optimization: Yes (200 runs)
LockedVault.sol 3335 lines
// SPDX-License-Identifier: GPL-3.0-or-later

// Sources flattened with hardhat v2.12.2 https://hardhat.org
// File libraries/ScaledMath.sol

pragma solidity ^0.8.17;

library ScaledMath {
    uint256 internal constant ONE = 1e18;

    function mulDown(uint256 a, uint256 b) internal pure returns (uint256) {
        return (a * b) / ONE;
    }

    function divDown(uint256 a, uint256 b) internal pure returns (uint256) {
        return (a * ONE) / b;
    }

    function changeScale(
        uint256 a,
        uint256 from,
        uint256 to
    ) internal pure returns (uint256) {
        if (from == to) return a;
        else if (from < to) return a * 10 ** (to - from);
        else return a / 10 ** (from - to);
    }
}


// File libraries/VotingPowerHistory.sol

pragma solidity ^0.8.17;

library VotingPowerHistory {
    using VotingPowerHistory for History;
    using VotingPowerHistory for Record;
    using ScaledMath for uint256;

    struct Record {
        uint256 at;
        uint256 baseVotingPower;
        uint256 multiplier;
        int256 netDelegatedVotes;
    }

    function zeroRecord() internal pure returns (Record memory) {
        return
            Record({
                at: 0,
                baseVotingPower: 0,
                multiplier: ScaledMath.ONE,
                netDelegatedVotes: 0
            });
    }

    function total(Record memory record) internal pure returns (uint256) {
        return
            uint256(
                int256(record.baseVotingPower.mulDown(record.multiplier)) +
                    record.netDelegatedVotes
            );
    }

    struct History {
        mapping(address => Record[]) votes;
        mapping(address => mapping(address => uint256)) _delegations;
        mapping(address => uint256) _delegatedToOthers;
        mapping(address => uint256) _delegatedToSelf;
    }

    event VotesDelegated(address from, address to, uint256 amount);
    event VotesUndelegated(address from, address to, uint256 amount);

    function updateVotingPower(
        History storage history,
        address for_,
        uint256 baseVotingPower,
        uint256 multiplier,
        int256 netDelegatedVotes
    ) internal returns (Record memory) {
        Record[] storage votesFor = history.votes[for_];
        Record memory updatedRecord = Record({
            at: block.timestamp,
            baseVotingPower: baseVotingPower,
            multiplier: multiplier,
            netDelegatedVotes: netDelegatedVotes
        });
        Record memory lastRecord = history.currentRecord(for_);
        if (lastRecord.at == block.timestamp && votesFor.length > 0) {
            votesFor[votesFor.length - 1] = updatedRecord;
        } else {
            history.votes[for_].push(updatedRecord);
        }
        return updatedRecord;
    }

    function getVotingPower(
        History storage history,
        address for_,
        uint256 at
    ) internal view returns (uint256) {
        (, Record memory record) = binarySearch(history.votes[for_], at);
        return record.total();
    }

    function currentRecord(
        History storage history,
        address for_
    ) internal view returns (Record memory) {
        Record[] memory records = history.votes[for_];
        if (records.length == 0) {
            return zeroRecord();
        } else {
            return records[records.length - 1];
        }
    }

    function binarySearch(
        Record[] memory records,
        uint256 at
    ) internal view returns (bool found, Record memory) {
        return _binarySearch(records, at, 0, records.length);
    }

    function _binarySearch(
        Record[] memory records,
        uint256 at,
        uint256 startIdx,
        uint256 endIdx
    ) internal view returns (bool found, Record memory) {
        if (startIdx >= endIdx) {
            return (false, zeroRecord());
        }

        if (endIdx - startIdx == 1) {
            Record memory rec = records[startIdx];
            return rec.at <= at ? (true, rec) : (false, zeroRecord());
        }

        uint256 midIdx = (endIdx + startIdx) / 2;
        Record memory lowerBound = records[midIdx - 1];
        Record memory upperBound = records[midIdx];
        if (lowerBound.at <= at && at < upperBound.at) {
            return (true, lowerBound);
        } else if (upperBound.at <= at) {
            return _binarySearch(records, at, midIdx, endIdx);
        } else {
            return _binarySearch(records, at, startIdx, midIdx);
        }
    }

    function delegateVote(
        History storage history,
        address from,
        address to,
        uint256 amount
    ) internal {
        Record memory fromCurrent = history.currentRecord(from);

        uint256 availableToDelegate = fromCurrent.baseVotingPower.mulDown(
            fromCurrent.multiplier
        ) - history._delegatedToOthers[from];
        require(
            availableToDelegate >= amount,
            "insufficient balance to delegate"
        );

        history._delegatedToSelf[to] += amount;
        history._delegatedToOthers[from] += amount;
        history._delegations[from][to] += amount;

        history.updateVotingPower(
            from,
            fromCurrent.baseVotingPower,
            fromCurrent.multiplier,
            history.netDelegatedVotingPower(from)
        );
        Record memory toCurrent = history.currentRecord(to);
        history.updateVotingPower(
            to,
            toCurrent.baseVotingPower,
            toCurrent.multiplier,
            history.netDelegatedVotingPower(to)
        );

        emit VotesDelegated(from, to, amount);
    }

    function undelegateVote(
        History storage history,
        address from,
        address to,
        uint256 amount
    ) internal {
        require(
            history._delegations[from][to] >= amount,
            "user has not delegated enough to delegate"
        );

        history._delegatedToSelf[to] -= amount;
        history._delegatedToOthers[from] -= amount;
        history._delegations[from][to] -= amount;

        Record memory fromCurrent = history.currentRecord(from);
        history.updateVotingPower(
            from,
            fromCurrent.baseVotingPower,
            fromCurrent.multiplier,
            history.netDelegatedVotingPower(from)
        );
        Record memory toCurrent = history.currentRecord(to);
        history.updateVotingPower(
            to,
            toCurrent.baseVotingPower,
            toCurrent.multiplier,
            history.netDelegatedVotingPower(to)
        );

        emit VotesUndelegated(from, to, amount);
    }

    function netDelegatedVotingPower(
        History storage history,
        address who
    ) internal view returns (int256) {
        return
            int256(history._delegatedToSelf[who]) -
            int256(history._delegatedToOthers[who]);
    }

    function delegatedVotingPower(
        History storage history,
        address who
    ) internal view returns (uint256) {
        return history._delegatedToOthers[who];
    }

    function updateMultiplier(
        History storage history,
        address who,
        uint256 multiplier
    ) internal {
        Record memory current = history.currentRecord(who);
        require(current.multiplier <= multiplier, "cannot decrease multiplier");
        history.updateVotingPower(
            who,
            current.baseVotingPower,
            multiplier,
            current.netDelegatedVotes
        );
    }
}


// File interfaces/ILockingVault.sol

pragma solidity ^0.8.17;

interface ILockingVault {
    function deposit(uint256 _amount) external;

    function deposit(uint256 _amount, address _delegate) external;

    event Deposit(
        address indexed from,
        address indexed delegate,
        uint256 amount
    );

    function initiateWithdrawal(
        uint256 _amount,
        address _delegate
    ) external returns (uint256);

    function withdraw(uint256 withdrawalId) external;

    event WithdrawalQueued(
        uint256 indexed id,
        address indexed to,
        address indexed delegate,
        uint256 withdrawalAt,
        uint256 amount
    );
    event WithdrawalCompleted(
        uint256 indexed id,
        address indexed to,
        uint256 amount
    );
}


// File @openzeppelin/contracts/utils/structs/[email protected]

// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.

pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 *
 * [WARNING]
 * ====
 * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
 * unusable.
 * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
 *
 * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
 * array of EnumerableSet.
 * ====
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;
        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping(bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) {
            // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            if (lastIndex != toDeleteIndex) {
                bytes32 lastValue = set._values[lastIndex];

                // Move the last value to the index where the value to delete is
                set._values[toDeleteIndex] = lastValue;
                // Update the index for the moved value
                set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex
            }

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        return set._values[index];
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function _values(Set storage set) private view returns (bytes32[] memory) {
        return set._values;
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
        bytes32[] memory store = _values(set._inner);
        bytes32[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(AddressSet storage set) internal view returns (address[] memory) {
        bytes32[] memory store = _values(set._inner);
        address[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(UintSet storage set) internal view returns (uint256[] memory) {
        bytes32[] memory store = _values(set._inner);
        uint256[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }
}


// File @openzeppelin/contracts/utils/structs/[email protected]

// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableMap.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableMap.js.

pragma solidity ^0.8.0;

/**
 * @dev Library for managing an enumerable variant of Solidity's
 * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]
 * type.
 *
 * Maps have the following properties:
 *
 * - Entries are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Entries are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableMap for EnumerableMap.UintToAddressMap;
 *
 *     // Declare a set state variable
 *     EnumerableMap.UintToAddressMap private myMap;
 * }
 * ```
 *
 * The following map types are supported:
 *
 * - `uint256 -> address` (`UintToAddressMap`) since v3.0.0
 * - `address -> uint256` (`AddressToUintMap`) since v4.6.0
 * - `bytes32 -> bytes32` (`Bytes32ToBytes32Map`) since v4.6.0
 * - `uint256 -> uint256` (`UintToUintMap`) since v4.7.0
 * - `bytes32 -> uint256` (`Bytes32ToUintMap`) since v4.7.0
 *
 * [WARNING]
 * ====
 * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
 * unusable.
 * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
 *
 * In order to clean an EnumerableMap, you can either remove all elements one by one or create a fresh instance using an
 * array of EnumerableMap.
 * ====
 */
library EnumerableMap {
    using EnumerableSet for EnumerableSet.Bytes32Set;

    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Map type with
    // bytes32 keys and values.
    // The Map implementation uses private functions, and user-facing
    // implementations (such as Uint256ToAddressMap) are just wrappers around
    // the underlying Map.
    // This means that we can only create new EnumerableMaps for types that fit
    // in bytes32.

    struct Bytes32ToBytes32Map {
        // Storage of keys
        EnumerableSet.Bytes32Set _keys;
        mapping(bytes32 => bytes32) _values;
    }

    /**
     * @dev Adds a key-value pair to a map, or updates the value for an existing
     * key. O(1).
     *
     * Returns true if the key was added to the map, that is if it was not
     * already present.
     */
    function set(
        Bytes32ToBytes32Map storage map,
        bytes32 key,
        bytes32 value
    ) internal returns (bool) {
        map._values[key] = value;
        return map._keys.add(key);
    }

    /**
     * @dev Removes a key-value pair from a map. O(1).
     *
     * Returns true if the key was removed from the map, that is if it was present.
     */
    function remove(Bytes32ToBytes32Map storage map, bytes32 key) internal returns (bool) {
        delete map._values[key];
        return map._keys.remove(key);
    }

    /**
     * @dev Returns true if the key is in the map. O(1).
     */
    function contains(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool) {
        return map._keys.contains(key);
    }

    /**
     * @dev Returns the number of key-value pairs in the map. O(1).
     */
    function length(Bytes32ToBytes32Map storage map) internal view returns (uint256) {
        return map._keys.length();
    }

    /**
     * @dev Returns the key-value pair stored at position `index` in the map. O(1).
     *
     * Note that there are no guarantees on the ordering of entries inside the
     * array, and it may change when more entries are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Bytes32ToBytes32Map storage map, uint256 index) internal view returns (bytes32, bytes32) {
        bytes32 key = map._keys.at(index);
        return (key, map._values[key]);
    }

    /**
     * @dev Tries to returns the value associated with `key`. O(1).
     * Does not revert if `key` is not in the map.
     */
    function tryGet(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool, bytes32) {
        bytes32 value = map._values[key];
        if (value == bytes32(0)) {
            return (contains(map, key), bytes32(0));
        } else {
            return (true, value);
        }
    }

    /**
     * @dev Returns the value associated with `key`. O(1).
     *
     * Requirements:
     *
     * - `key` must be in the map.
     */
    function get(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bytes32) {
        bytes32 value = map._values[key];
        require(value != 0 || contains(map, key), "EnumerableMap: nonexistent key");
        return value;
    }

    /**
     * @dev Same as {get}, with a custom error message when `key` is not in the map.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryGet}.
     */
    function get(
        Bytes32ToBytes32Map storage map,
        bytes32 key,
        string memory errorMessage
    ) internal view returns (bytes32) {
        bytes32 value = map._values[key];
        require(value != 0 || contains(map, key), errorMessage);
        return value;
    }

    // UintToUintMap

    struct UintToUintMap {
        Bytes32ToBytes32Map _inner;
    }

    /**
     * @dev Adds a key-value pair to a map, or updates the value for an existing
     * key. O(1).
     *
     * Returns true if the key was added to the map, that is if it was not
     * already present.
     */
    function set(
        UintToUintMap storage map,
        uint256 key,
        uint256 value
    ) internal returns (bool) {
        return set(map._inner, bytes32(key), bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the key was removed from the map, that is if it was present.
     */
    function remove(UintToUintMap storage map, uint256 key) internal returns (bool) {
        return remove(map._inner, bytes32(key));
    }

    /**
     * @dev Returns true if the key is in the map. O(1).
     */
    function contains(UintToUintMap storage map, uint256 key) internal view returns (bool) {
        return contains(map._inner, bytes32(key));
    }

    /**
     * @dev Returns the number of elements in the map. O(1).
     */
    function length(UintToUintMap storage map) internal view returns (uint256) {
        return length(map._inner);
    }

    /**
     * @dev Returns the element stored at position `index` in the set. O(1).
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(UintToUintMap storage map, uint256 index) internal view returns (uint256, uint256) {
        (bytes32 key, bytes32 value) = at(map._inner, index);
        return (uint256(key), uint256(value));
    }

    /**
     * @dev Tries to returns the value associated with `key`. O(1).
     * Does not revert if `key` is not in the map.
     */
    function tryGet(UintToUintMap storage map, uint256 key) internal view returns (bool, uint256) {
        (bool success, bytes32 value) = tryGet(map._inner, bytes32(key));
        return (success, uint256(value));
    }

    /**
     * @dev Returns the value associated with `key`. O(1).
     *
     * Requirements:
     *
     * - `key` must be in the map.
     */
    function get(UintToUintMap storage map, uint256 key) internal view returns (uint256) {
        return uint256(get(map._inner, bytes32(key)));
    }

    /**
     * @dev Same as {get}, with a custom error message when `key` is not in the map.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryGet}.
     */
    function get(
        UintToUintMap storage map,
        uint256 key,
        string memory errorMessage
    ) internal view returns (uint256) {
        return uint256(get(map._inner, bytes32(key), errorMessage));
    }

    // UintToAddressMap

    struct UintToAddressMap {
        Bytes32ToBytes32Map _inner;
    }

    /**
     * @dev Adds a key-value pair to a map, or updates the value for an existing
     * key. O(1).
     *
     * Returns true if the key was added to the map, that is if it was not
     * already present.
     */
    function set(
        UintToAddressMap storage map,
        uint256 key,
        address value
    ) internal returns (bool) {
        return set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the key was removed from the map, that is if it was present.
     */
    function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {
        return remove(map._inner, bytes32(key));
    }

    /**
     * @dev Returns true if the key is in the map. O(1).
     */
    function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {
        return contains(map._inner, bytes32(key));
    }

    /**
     * @dev Returns the number of elements in the map. O(1).
     */
    function length(UintToAddressMap storage map) internal view returns (uint256) {
        return length(map._inner);
    }

    /**
     * @dev Returns the element stored at position `index` in the set. O(1).
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {
        (bytes32 key, bytes32 value) = at(map._inner, index);
        return (uint256(key), address(uint160(uint256(value))));
    }

    /**
     * @dev Tries to returns the value associated with `key`. O(1).
     * Does not revert if `key` is not in the map.
     */
    function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {
        (bool success, bytes32 value) = tryGet(map._inner, bytes32(key));
        return (success, address(uint160(uint256(value))));
    }

    /**
     * @dev Returns the value associated with `key`. O(1).
     *
     * Requirements:
     *
     * - `key` must be in the map.
     */
    function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {
        return address(uint160(uint256(get(map._inner, bytes32(key)))));
    }

    /**
     * @dev Same as {get}, with a custom error message when `key` is not in the map.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryGet}.
     */
    function get(
        UintToAddressMap storage map,
        uint256 key,
        string memory errorMessage
    ) internal view returns (address) {
        return address(uint160(uint256(get(map._inner, bytes32(key), errorMessage))));
    }

    // AddressToUintMap

    struct AddressToUintMap {
        Bytes32ToBytes32Map _inner;
    }

    /**
     * @dev Adds a key-value pair to a map, or updates the value for an existing
     * key. O(1).
     *
     * Returns true if the key was added to the map, that is if it was not
     * already present.
     */
    function set(
        AddressToUintMap storage map,
        address key,
        uint256 value
    ) internal returns (bool) {
        return set(map._inner, bytes32(uint256(uint160(key))), bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the key was removed from the map, that is if it was present.
     */
    function remove(AddressToUintMap storage map, address key) internal returns (bool) {
        return remove(map._inner, bytes32(uint256(uint160(key))));
    }

    /**
     * @dev Returns true if the key is in the map. O(1).
     */
    function contains(AddressToUintMap storage map, address key) internal view returns (bool) {
        return contains(map._inner, bytes32(uint256(uint160(key))));
    }

    /**
     * @dev Returns the number of elements in the map. O(1).
     */
    function length(AddressToUintMap storage map) internal view returns (uint256) {
        return length(map._inner);
    }

    /**
     * @dev Returns the element stored at position `index` in the set. O(1).
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(AddressToUintMap storage map, uint256 index) internal view returns (address, uint256) {
        (bytes32 key, bytes32 value) = at(map._inner, index);
        return (address(uint160(uint256(key))), uint256(value));
    }

    /**
     * @dev Tries to returns the value associated with `key`. O(1).
     * Does not revert if `key` is not in the map.
     */
    function tryGet(AddressToUintMap storage map, address key) internal view returns (bool, uint256) {
        (bool success, bytes32 value) = tryGet(map._inner, bytes32(uint256(uint160(key))));
        return (success, uint256(value));
    }

    /**
     * @dev Returns the value associated with `key`. O(1).
     *
     * Requirements:
     *
     * - `key` must be in the map.
     */
    function get(AddressToUintMap storage map, address key) internal view returns (uint256) {
        return uint256(get(map._inner, bytes32(uint256(uint160(key)))));
    }

    /**
     * @dev Same as {get}, with a custom error message when `key` is not in the map.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryGet}.
     */
    function get(
        AddressToUintMap storage map,
        address key,
        string memory errorMessage
    ) internal view returns (uint256) {
        return uint256(get(map._inner, bytes32(uint256(uint160(key))), errorMessage));
    }

    // Bytes32ToUintMap

    struct Bytes32ToUintMap {
        Bytes32ToBytes32Map _inner;
    }

    /**
     * @dev Adds a key-value pair to a map, or updates the value for an existing
     * key. O(1).
     *
     * Returns true if the key was added to the map, that is if it was not
     * already present.
     */
    function set(
        Bytes32ToUintMap storage map,
        bytes32 key,
        uint256 value
    ) internal returns (bool) {
        return set(map._inner, key, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the key was removed from the map, that is if it was present.
     */
    function remove(Bytes32ToUintMap storage map, bytes32 key) internal returns (bool) {
        return remove(map._inner, key);
    }

    /**
     * @dev Returns true if the key is in the map. O(1).
     */
    function contains(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool) {
        return contains(map._inner, key);
    }

    /**
     * @dev Returns the number of elements in the map. O(1).
     */
    function length(Bytes32ToUintMap storage map) internal view returns (uint256) {
        return length(map._inner);
    }

    /**
     * @dev Returns the element stored at position `index` in the set. O(1).
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Bytes32ToUintMap storage map, uint256 index) internal view returns (bytes32, uint256) {
        (bytes32 key, bytes32 value) = at(map._inner, index);
        return (key, uint256(value));
    }

    /**
     * @dev Tries to returns the value associated with `key`. O(1).
     * Does not revert if `key` is not in the map.
     */
    function tryGet(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool, uint256) {
        (bool success, bytes32 value) = tryGet(map._inner, key);
        return (success, uint256(value));
    }

    /**
     * @dev Returns the value associated with `key`. O(1).
     *
     * Requirements:
     *
     * - `key` must be in the map.
     */
    function get(Bytes32ToUintMap storage map, bytes32 key) internal view returns (uint256) {
        return uint256(get(map._inner, key));
    }

    /**
     * @dev Same as {get}, with a custom error message when `key` is not in the map.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryGet}.
     */
    function get(
        Bytes32ToUintMap storage map,
        bytes32 key,
        string memory errorMessage
    ) internal view returns (uint256) {
        return uint256(get(map._inner, key, errorMessage));
    }
}


// File libraries/DataTypes.sol

pragma solidity ^0.8.17;

library DataTypes {
    enum Status {
        Undefined,
        Active,
        Rejected,
        Queued,
        Executed,
        Vetoed
    }

    struct ProposalAction {
        address target;
        bytes data;
    }

    struct Proposal {
        uint64 createdAt;
        uint64 executableAt;
        uint64 votingEndsAt;
        uint64 voteThreshold;
        uint64 quorum;
        uint16 id;
        uint8 actionLevel;
        address proposer;
        Status status;
        ProposalAction[] actions;
    }

    struct PendingWithdrawal {
        uint256 id;
        uint256 withdrawableAt;
        uint256 amount;
        address to;
        address delegate;
    }

    struct VaultWeightSchedule {
        VaultWeightConfiguration[] vaults;
        uint256 startsAt;
        uint256 endsAt;
    }

    struct VaultWeightConfiguration {
        address vaultAddress;
        uint256 initialWeight;
        uint256 targetWeight;
    }

    struct VaultWeight {
        address vaultAddress;
        uint256 currentWeight;
        uint256 initialWeight;
        uint256 targetWeight;
    }

    struct VaultVotingPower {
        address vaultAddress;
        uint256 votingPower;
    }

    struct Tier {
        uint64 quorum;
        uint64 proposalThreshold;
        uint64 voteThreshold;
        uint32 timeLockDuration;
        uint32 proposalLength;
        uint8 actionLevel;
    }

    struct EmergencyRecoveryProposal {
        uint64 createdAt;
        uint64 completesAt;
        Status status;
        bytes payload;
        EnumerableMap.AddressToUintMap vetos;
    }

    enum Ballot {
        Undefined,
        For,
        Against,
        Abstain
    }

    struct VoteTotals {
        VaultVotingPower[] _for;
        VaultVotingPower[] against;
        VaultVotingPower[] abstentions;
    }

    struct VaultSnapshot {
        address vaultAddress;
        uint256 weight;
        uint256 totalVotingPower;
    }

    enum ProposalOutcome {
        Undefined,
        QuorumNotMet,
        ThresholdNotMet,
        Successful
    }

    struct LimitUpgradeabilityParameters {
        uint8 actionLevelThreshold;
        uint256 emaThreshold;
        uint256 minBGYDSupply;
        address tierStrategy;
    }

    struct Delegation {
        address delegate;
        uint256 amount;
    }
}


// File interfaces/ILiquidityMining.sol

pragma solidity ^0.8.17;

interface ILiquidityMining {
    event Stake(address indexed account, uint256 amount);
    event Unstake(address indexed account, uint256 amount);
    event Claim(address indexed beneficiary, uint256 amount);

    event StartMining(uint256 amount, uint256 endTime);
    event StopMining();

    /// @notice claims rewards for caller
    function claimRewards() external returns (uint256);

    /// @notice returns the amount of claimable rewards by `beneficiary`
    function claimableRewards(
        address beneficiary
    ) external view returns (uint256);

    /// @notice the total amount of tokens staked in the contract
    function totalStaked() external view returns (uint256);

    /// @notice the amount of tokens staked by `account`
    function stakedBalanceOf(address account) external view returns (uint256);

    /// @notice returns the number of rewards token that will be given per second for the contract
    /// This emission will be given to all stakers in the contract proportionally to their stake
    function rewardsEmissionRate() external view returns (uint256);

    /// @notice time when rewards emission ends
    function rewardsEmissionEndTime() external view returns (uint256);

    /// @dev these functions will be called internally but can typically be called by anyone
    /// to update the internal tracking state of the contract
    function globalCheckpoint() external;

    function userCheckpoint(address account) external;

    /// @notice Deposit `amount` of the reward token from `rewardsFrom` and enable rewards until `endTime`. Typically governanceOnly. `amount` is spread evenly over the time period.
    function startMining(
        address rewardsFrom,
        uint256 amount,
        uint256 endTime
    ) external;

    /// @notice Stop liquidity mining early and reimburse leftover rewards to the DAO treasury.
    /// This may also be needed after the mining period has ended when we had `totalStaked() == 0` for a while, where no rewards accrue.
    function stopMining() external;
}


// File libraries/BalancerErrors.sol

pragma solidity ^0.8.17;

library BalancerErrors {
    string constant X_OUT_OF_BOUNDS = "X_OUT_OF_BOUNDS";
    string constant Y_OUT_OF_BOUNDS = "Y_OUT_OF_BOUNDS";
    string constant PRODUCT_OUT_OF_BOUNDS = "PRODUCT_OUT_OF_BOUNDS";
    string constant INVALID_EXPONENT = "INVALID_EXPONENT";
    string constant OUT_OF_BOUNDS = "OUT_OF_BOUNDS";
}


// File libraries/LogExpMath.sol

// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
// documentation files (the “Software”), to deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
// Software.

// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

pragma solidity ^0.8.17;
// Copied from:
// https://github.com/balancer-labs/balancer-v2-monorepo/blob/master/pkg/solidity-utils/contracts/math/LogExpMath.sol

/* solhint-disable */

/**
 * @dev Exponentiation and logarithm functions for 18 decimal fixed point numbers (both base and exponent/argument).
 *
 * Exponentiation and logarithm with arbitrary bases (x^y and log_x(y)) are implemented by conversion to natural
 * exponentiation and logarithm (where the base is Euler's number).
 *
 * @author Fernando Martinelli - @fernandomartinelli
 * @author Sergio Yuhjtman - @sergioyuhjtman
 * @author Daniel Fernandez - @dmf7z
 */
library LogExpMath {
    // All fixed point multiplications and divisions are inlined. This means we need to divide by ONE when multiplying
    // two numbers, and multiply by ONE when dividing them.

    // All arguments and return values are 18 decimal fixed point numbers.
    int256 constant ONE_18 = 1e18;

    // Internally, intermediate values are computed with higher precision as 20 decimal fixed point numbers, and in the
    // case of ln36, 36 decimals.
    int256 constant ONE_20 = 1e20;
    int256 constant ONE_36 = 1e36;

    // The domain of natural exponentiation is bound by the word size and number of decimals used.
    //
    // Because internally the result will be stored using 20 decimals, the largest possible result is
    // (2^255 - 1) / 10^20, which makes the largest exponent ln((2^255 - 1) / 10^20) = 130.700829182905140221.
    // The smallest possible result is 10^(-18), which makes largest negative argument
    // ln(10^(-18)) = -41.446531673892822312.
    // We use 130.0 and -41.0 to have some safety margin.
    int256 constant MAX_NATURAL_EXPONENT = 130e18;
    int256 constant MIN_NATURAL_EXPONENT = -41e18;

    // Bounds for ln_36's argument. Both ln(0.9) and ln(1.1) can be represented with 36 decimal places in a fixed point
    // 256 bit integer.
    int256 constant LN_36_LOWER_BOUND = ONE_18 - 1e17;
    int256 constant LN_36_UPPER_BOUND = ONE_18 + 1e17;

    uint256 constant MILD_EXPONENT_BOUND = 2 ** 254 / uint256(ONE_20);

    // 18 decimal constants
    int256 constant x0 = 128000000000000000000; // 2ˆ7
    int256 constant a0 =
        38877084059945950922200000000000000000000000000000000000; // eˆ(x0) (no decimals)
    int256 constant x1 = 64000000000000000000; // 2ˆ6
    int256 constant a1 = 6235149080811616882910000000; // eˆ(x1) (no decimals)

    // 20 decimal constants
    int256 constant x2 = 3200000000000000000000; // 2ˆ5
    int256 constant a2 = 7896296018268069516100000000000000; // eˆ(x2)
    int256 constant x3 = 1600000000000000000000; // 2ˆ4
    int256 constant a3 = 888611052050787263676000000; // eˆ(x3)
    int256 constant x4 = 800000000000000000000; // 2ˆ3
    int256 constant a4 = 298095798704172827474000; // eˆ(x4)
    int256 constant x5 = 400000000000000000000; // 2ˆ2
    int256 constant a5 = 5459815003314423907810; // eˆ(x5)
    int256 constant x6 = 200000000000000000000; // 2ˆ1
    int256 constant a6 = 738905609893065022723; // eˆ(x6)
    int256 constant x7 = 100000000000000000000; // 2ˆ0
    int256 constant a7 = 271828182845904523536; // eˆ(x7)
    int256 constant x8 = 50000000000000000000; // 2ˆ-1
    int256 constant a8 = 164872127070012814685; // eˆ(x8)
    int256 constant x9 = 25000000000000000000; // 2ˆ-2
    int256 constant a9 = 128402541668774148407; // eˆ(x9)
    int256 constant x10 = 12500000000000000000; // 2ˆ-3
    int256 constant a10 = 113314845306682631683; // eˆ(x10)
    int256 constant x11 = 6250000000000000000; // 2ˆ-4
    int256 constant a11 = 106449445891785942956; // eˆ(x11)

    /**
     * @dev Exponentiation (x^y) with unsigned 18 decimal fixed point base and exponent.
     *
     * Reverts if ln(x) * y is smaller than `MIN_NATURAL_...

// [truncated — 117644 bytes total]

Read Contract

claimableRewards 0xdc01f60d → uint256
daoTreasury 0x79022a9f → address
getCurrentRecord 0x19ad0eba → tuple
getDelegations 0x31cc13ba → tuple[]
getRawVotingPower 0x9f1acf08 → uint256
getRawVotingPower 0xde1ec403 → uint256
getTotalRawVotingPower 0x344ff1d0 → uint256
getVaultType 0x75baf37f → string
listPendingWithdrawals 0xc24ab3bb → tuple[]
owner 0x8da5cb5b → address
rewardToken 0xf7c618c1 → address
rewardsEmissionEndTime 0x4a62c9fb → uint256
rewardsEmissionRate 0x97a04d5a → uint256
stakedBalanceOf 0x16765391 → uint256
totalStaked 0x817b1cd2 → uint256
totalSupply 0x18160ddd → uint256
underlying 0x6f307dc3 → address

Write Contract 14 functions

These functions modify contract state and require a wallet transaction to execute.

changeDelegate 0xcead0481
address _oldDelegate
address _newDelegate
uint256 _amount
claimRewards 0x372500ab
No parameters
returns: uint256
delegateVote 0x926f7327
address _delegate
uint256 _amount
deposit 0x6e553f65
uint256 _tokenAmount
address _delegate
deposit 0xb6b55f25
uint256 _amount
globalCheckpoint 0x1ac40e66
No parameters
initialize 0xfe4b84df
uint256 _withdrawalWaitDuration
initiateWithdrawal 0x54438127
uint256 _vaultTokenAmount
address _delegate
returns: uint256
setWithdrawalWaitDuration 0xe9314c73
uint256 _duration
startMining 0x4ba9699e
address rewardsFrom
uint256 amount
uint256 endTime
stopMining 0xda408679
No parameters
undelegateVote 0xe2fcf550
address _delegate
uint256 _amount
userCheckpoint 0xb07b709b
address account
withdraw 0x2e1a7d4d
uint256 withdrawalId

Recent Transactions

No transactions found for this address