Address Contract Partially Verified
Address
0x2e343AD2e670A2139b05Ea4cf90312612D7a42Ae
Balance
0 ETH
Nonce
1
Code Size
10922 bytes
Creator
0x6F586AC8...3882 at tx 0x4b7fe918...2360e8
Indexed Transactions
0 (1 on-chain, 1.5% indexed)
Contract Bytecode
10922 bytes
0x60806040526004361061021e5760003560e01c80639169d83311610123578063e2bbb158116100ab578063f3fef3a31161006f578063f3fef3a314610694578063f65baefa146106b4578063f7888aec146106c9578063fa09e630146106e9578063ffa1ad741461070957600080fd5b8063e2bbb158146105cf578063e30c3978146105ef578063e6a6e7a21461060d578063ec21145a1461062d578063f2fde38b1461067457600080fd5b8063b61d27f6116100f2578063b61d27f61461053c578063b6703fcd1461054f578063c4e2c1e61461056f578063da3e33971461058f578063e1b97139146105af57600080fd5b80639169d833146104885780639ac2a011146104a8578063a3c01c42146104e8578063b381cf401461050857600080fd5b806362b88f54116101a657806379ba50971161017557806379ba5097146104005780637cbc2373146104155780638c53b747146104355780638da5cb5b1461045557806390adc83c1461047357600080fd5b806362b88f541461037d57806368c4af7f146103ab5780636ed625ab146103cb578063715018a6146103eb57600080fd5b806324788429116101ed57806324788429146102b757806332c8fa46146102d75780633419ba231461030f57806334b10a6d1461032f57806354621b421461034f57600080fd5b8063077d97d71461022a578063087ed8371461023f5780631ea68c001461026a5780631f5a0bbe1461029757600080fd5b3661022557005b600080fd5b61023d610238366004612170565b61073d565b005b34801561024b57600080fd5b506102546108b3565b604051610261919061224e565b60405180910390f35b34801561027657600080fd5b5061028a610285366004612312565b610916565b6040516102619190612389565b3480156102a357600080fd5b5061023d6102b23660046123b1565b610a00565b3480156102c357600080fd5b5061023d6102d23660046123b1565b610a6b565b3480156102e357600080fd5b506005546102f7906001600160a01b031681565b6040516001600160a01b039091168152602001610261565b34801561031b57600080fd5b5061023d61032a3660046123ce565b610ad3565b34801561033b57600080fd5b5061023d61034a366004612407565b610aeb565b34801561035b57600080fd5b5061036f61036a366004612407565b610bbb565b604051908152602001610261565b34801561038957600080fd5b5061039d610398366004612420565b610c4a565b60405161026192919061245b565b3480156103b757600080fd5b5061023d6103c6366004612497565b610e20565b3480156103d757600080fd5b5061036f6103e63660046124fb565b611052565b3480156103f757600080fd5b5061023d61116e565b34801561040c57600080fd5b5061023d611182565b34801561042157600080fd5b5061036f6104303660046124fb565b6111c6565b34801561044157600080fd5b5061023d6104503660046123b1565b611376565b34801561046157600080fd5b506000546001600160a01b03166102f7565b34801561047f57600080fd5b5061036f6113d4565b34801561049457600080fd5b5061023d6104a3366004612407565b6113f1565b3480156104b457600080fd5b506104d86104c33660046123b1565b60026020526000908152604090205460ff1681565b6040519015158152602001610261565b3480156104f457600080fd5b5061023d6105033660046123ce565b6114bb565b34801561051457600080fd5b506102f77f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b61023d61054a36600461251d565b6115c1565b34801561055b57600080fd5b5061023d61056a3660046123ce565b61164e565b34801561057b57600080fd5b5061023d61058a3660046125a6565b611673565b34801561059b57600080fd5b5061023d6105aa3660046125dd565b611686565b3480156105bb57600080fd5b5061023d6105ca3660046123b1565b611699565b3480156105db57600080fd5b5061036f6105ea3660046124fb565b6116f7565b3480156105fb57600080fd5b506001546001600160a01b03166102f7565b34801561061957600080fd5b5061036f610628366004612407565b611895565b34801561063957600080fd5b50600354600454610654916001600160a01b03908116911682565b604080516001600160a01b03938416815292909116602083015201610261565b34801561068057600080fd5b5061023d61068f3660046123b1565b611983565b3480156106a057600080fd5b5061023d6106af36600461261e565b6119f4565b3480156106c057600080fd5b5061039d611a07565b3480156106d557600080fd5b5061036f6106e43660046123ce565b611afe565b3480156106f557600080fd5b5061023d6107043660046123b1565b611b73565b34801561071557600080fd5b5060408051808201825260058152640312e302e360dc1b60208201529051610261919061264a565b610745611b93565b848314801561075357508481145b6107a45760405162461bcd60e51b815260206004820152601960248201527f417267756d656e7473206c656e677468206d69736d617463680000000000000060448201526064015b60405180910390fd5b60005b858110156108aa576000808888848181106107c4576107c4612698565b90506020020160208101906107d991906123b1565b6001600160a01b03168787858181106107f4576107f4612698565b9050602002013586868681811061080d5761080d612698565b905060200281019061081f91906126ae565b60405161082d9291906126f5565b60006040518083038185875af1925050503d806000811461086a576040519150601f19603f3d011682016040523d82523d6000602084013e61086f565b606091505b50915091508181906108945760405162461bcd60e51b815260040161079b919061264a565b50505080806108a29061271b565b9150506107a7565b50505050505050565b6040805160018082528183019092526060916000919060208083019080368337505060035482519293506001600160a01b0316918391506000906108f9576108f9612698565b6001600160a01b0390921660209283029190910190910152919050565b60603361092b6000546001600160a01b031690565b6001600160a01b0316148061094f57503360009081526002602052604090205460ff165b61096b5760405162461bcd60e51b815260040161079b90612734565b6004546001600160a01b03166109935760405162461bcd60e51b815260040161079b9061277a565b604080516001808252818301909252600091602080830190803683370190505090506109d984846000815181106109cc576109cc612698565b6020026020010151611052565b816000815181106109ec576109ec612698565b602090810291909101015290505b92915050565b610a08611b93565b604051600181526001600160a01b038216907f9fdbc2d48b8a0db2f62663bf9312ad02f5b1f6414ad600b55a247d09aeec3ea29060200160405180910390a26001600160a01b03166000908152600260205260409020805460ff19166001179055565b610a73611b93565b604051600081526001600160a01b038216907f9fdbc2d48b8a0db2f62663bf9312ad02f5b1f6414ad600b55a247d09aeec3ea29060200160405180910390a26001600160a01b03166000908152600260205260409020805460ff19169055565b610adb611b93565b610ae782826000611bc0565b5050565b33610afe6000546001600160a01b031690565b6001600160a01b03161480610b2257503360009081526002602052604090205460ff165b610b3e5760405162461bcd60e51b815260040161079b90612734565b604051632e1a7d4d60e01b8152600481018290527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031690632e1a7d4d90602401600060405180830381600087803b158015610ba057600080fd5b505af1158015610bb4573d6000803e3d6000fd5b5050505050565b600033610bd06000546001600160a01b031690565b6001600160a01b03161480610bf457503360009081526002602052604090205460ff165b610c105760405162461bcd60e51b815260040161079b90612734565b6004546001600160a01b0316610c385760405162461bcd60e51b815260040161079b9061277a565b6109fa670de0b6b3a764000083611052565b60608033610c606000546001600160a01b031690565b6001600160a01b03161480610c8457503360009081526002602052604090205460ff165b610ca05760405162461bcd60e51b815260040161079b90612734565b6005546001600160a01b03166371ee95c0610cbb8580612796565b610cc86020880188612796565b610cd560408a018a612796565b610ce260608c018c612796565b6040518963ffffffff1660e01b8152600401610d05989796959493929190612850565b600060405180830381600087803b158015610d1f57600080fd5b505af1158015610d33573d6000803e3d6000fd5b503392507feb52dffbee1e79ccc1299cb412e00457926f40b2106ff16cd712172213b06bb69150610d6990506020860186612796565b610d766040880188612796565b604051610d869493929190612931565b60405180910390a2610d9b6020840184612796565b610da86040860186612796565b83838080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808702828101820190935286825294985095965093949386938693508392508501908490808284376000920191909152509597509195505050505050915091565b33610e336000546001600160a01b031690565b6001600160a01b03161480610e5757503360009081526002602052604090205460ff165b610e735760405162461bcd60e51b815260040161079b90612734565b6000825167ffffffffffffffff811115610e8f57610e8f612261565b604051908082528060200260200182016040528015610eb8578160200160208202803683370190505b50905060005b8351811015610f9257846001600160a01b031663e186935230868481518110610ee957610ee9612698565b60200260200101516040518363ffffffff1660e01b8152600401610f229291906001600160a01b03929092168252602082015260400190565b6040805180830381865afa158015610f3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f629190612958565b50828281518110610f7557610f75612698565b602090810291909101015280610f8a8161271b565b915050610ebe565b5060405163120f2e9360e31b81526001600160a01b03851690639079749890610fc39030908790879060040161297c565b6020604051808303816000875af1158015610fe2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061100691906129b2565b50336001600160a01b03167f71eedba2a5f5a9128d4136dcaea39b92caabee151f08a303767bb4b97ecf7d20858584604051611044939291906129cf565b60405180910390a250505050565b6000336110676000546001600160a01b031690565b6001600160a01b0316148061108b57503360009081526002602052604090205460ff165b6110a75760405162461bcd60e51b815260040161079b90612734565b6004546001600160a01b03166110cf5760405162461bcd60e51b815260040161079b9061277a565b670de0b6b3a764000083111561110c5760405162461bcd60e51b8152602060048201526002602482015261503160f01b604482015260640161079b565b8260000361111c575060006109fa565b600061112f6111296113d4565b85611c9f565b905061113b81846111c6565b6040519092507fcb98953bd1dbc99409d236f79303561f0568a868c3a01b79116dd95a8374f29990600090a15092915050565b611176611b93565b6111806000611cbe565b565b60015433906001600160a01b031681146111ba5760405163118cdaa760e01b81526001600160a01b038216600482015260240161079b565b6111c381611cbe565b50565b6000336111db6000546001600160a01b031690565b6001600160a01b031614806111ff57503360009081526002602052604090205460ff165b61121b5760405162461bcd60e51b815260040161079b90612734565b6004546001600160a01b03166112435760405162461bcd60e51b815260040161079b9061277a565b6040805180820182526003546001600160a01b03908116825260048054909116602083018190529251635d043b2960e11b81529081018690523060248201819052604482015290919063ba087652906064016020604051808303816000875af11580156112b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d89190612a05565b91508282101561130f5760405162461bcd60e51b8152602060048201526002602482015261523160f01b604482015260640161079b565b8051602080830151604080516001600160a01b039485168152939091169183019190915281018390526060810185905233907faee47cdf925cf525fdae94f9777ee5a06cac37e1c41220d0a8a89ed154f62d1c906080015b60405180910390a25092915050565b61137e611b93565b600580546001600160a01b0319166001600160a01b03831690811790915560405190815233907f896f95e2f70e072cc713066c108b45f737eaffbe450cdf479ba0b6249b2000749060200160405180910390a250565b6004546000906113ec906001600160a01b0316611cd7565b905090565b336114046000546001600160a01b031690565b6001600160a01b0316148061142857503360009081526002602052604090205460ff165b6114445760405162461bcd60e51b815260040161079b90612734565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561149f57600080fd5b505af11580156114b3573d6000803e3d6000fd5b505050505050565b6114c3611b93565b816001600160a01b0316816001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561150b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061152f9190612a1e565b6001600160a01b03161461154257600080fd5b6040805180820182526001600160a01b038481168083529084166020928301819052600380546001600160a01b03199081168417909155600480549091168217905583519182529181019190915233917f6483954a781fd2a588f0f6fe46f8e799cfe4c6a31dceaa6b6b0145fdbd0f1146910160405180910390a25050565b6115c9611b93565b600080856001600160a01b03168585856040516115e79291906126f5565b60006040518083038185875af1925050503d8060008114611624576040519150601f19603f3d011682016040523d82523d6000602084013e611629565b606091505b50915091508181906108aa5760405162461bcd60e51b815260040161079b919061264a565b611656611b93565b600061166183611d42565b905061166e838284611d67565b505050565b61167b611b93565b61166e838383611d67565b61168e611b93565b61166e838383611bc0565b6116a1611b93565b6001600160a01b0381166111ba5760405162461bcd60e51b815260206004820152601860248201527f4954424f776e61626c653a207a65726f20616464726573730000000000000000604482015260640161079b565b60003361170c6000546001600160a01b031690565b6001600160a01b0316148061173057503360009081526002602052604090205460ff165b61174c5760405162461bcd60e51b815260040161079b90612734565b6004546001600160a01b03166117745760405162461bcd60e51b815260040161079b9061277a565b6040805180820182526003546001600160a01b03908116825260048054909116602083018190529251636e553f6560e01b8152908101869052306024820152909190636e553f65906044016020604051808303816000875af11580156117de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118029190612a05565b9150828210156118395760405162461bcd60e51b8152602060048201526002602482015261443160f01b604482015260640161079b565b8051602080830151604080516001600160a01b039485168152939091169183019190915281018590526060810183905233907f5fe47ed6d4225326d3303476197d782ded5a4e9c14f479dc9ec4992af4e85d5990608001611367565b6000336118aa6000546001600160a01b031690565b6001600160a01b031614806118ce57503360009081526002602052604090205460ff165b6118ea5760405162461bcd60e51b815260040161079b90612734565b6004546001600160a01b03166119125760405162461bcd60e51b815260040161079b9061277a565b604080518082019091526003546001600160a01b03908116808352600454909116602083015260009061194490611cd7565b905061195081856116f7565b6040519093507fb36627d41b80e3867adc36deaed5334f9ea56f559579be82ffe726ad28f21f9b90600090a15050919050565b61198b611b93565b600180546001600160a01b0383166001600160a01b031990911681179091556119bc6000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6119fc611b93565b610ae7828233611d67565b6060806000611a146108b3565b90506000815167ffffffffffffffff811115611a3257611a32612261565b604051908082528060200260200182016040528015611a5b578160200160208202803683370190505b506004549091506001600160a01b03166307a2d13a611a786113d4565b6040518263ffffffff1660e01b8152600401611a9691815260200190565b602060405180830381865afa158015611ab3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ad79190612a05565b81600081518110611aea57611aea612698565b602090810291909101015290939092509050565b6040516370a0823160e01b81526001600160a01b038281166004830152600091908416906370a0823190602401602060405180830381865afa158015611b48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b6c9190612a05565b9392505050565b611b7b611b93565b6000611b8682611d42565b9050610ae7828233611d67565b6000546001600160a01b031633146111805760405163118cdaa760e01b815233600482015260240161079b565b8015611bdf57611bda6001600160a01b0384168383611f1f565b611c54565b60405163095ea7b360e01b81526001600160a01b0383811660048301526024820183905284169063095ea7b3906044016020604051808303816000875af1158015611c2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c5291906129b2565b505b604080516001600160a01b038481168252602082018490528516917feded619173dbb378903f97d44ecec898a1c4876f445ae551e063113aef58b471910160405180910390a2505050565b6000670de0b6b3a7640000611cb48385612a3b565b611b6c9190612a52565b600180546001600160a01b03191690556111c381611fe3565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa158015611d1e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109fa9190612a05565b60006001600160a01b03821615611d6157611d5c82611cd7565b6109fa565b476109fa565b6001600160a01b038116611daf5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015260640161079b565b6000611dba84611d42565b905082811015611e015760405162461bcd60e51b8152602060048201526012602482015271496e73756666696369656e742066756e647360701b604482015260640161079b565b6001600160a01b038416611eb8576000826001600160a01b03168460405160006040518083038185875af1925050503d8060008114611e5c576040519150601f19603f3d011682016040523d82523d6000602084013e611e61565b606091505b5050905080611eb25760405162461bcd60e51b815260206004820152601760248201527f4e6174697665207472616e73666572206661696c65642e000000000000000000604482015260640161079b565b50611ecc565b611ecc6001600160a01b0385168385612033565b836001600160a01b0316826001600160a01b03167f9207361cc2a04b9c7a06691df1eb87c6a63957ae88bf01d0d18c81e3d127209985604051611f1191815260200190565b60405180910390a350505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052611f708482612064565b611fdd576040516001600160a01b03848116602483015260006044830152611fd391869182169063095ea7b3906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506120b3565b611fdd84826120b3565b50505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6040516001600160a01b0383811660248301526044820183905261166e91859182169063a9059cbb90606401611fa1565b6000806000806020600086516020880160008a5af192503d915060005190508280156120a95750811561209a57806001146120a9565b6000866001600160a01b03163b115b9695505050505050565b600080602060008451602086016000885af1806120d6576040513d6000823e3d81fd5b50506000513d915081156120ee5780600114156120fb565b6001600160a01b0384163b155b15611fdd57604051635274afe760e01b81526001600160a01b038516600482015260240161079b565b60008083601f84011261213657600080fd5b50813567ffffffffffffffff81111561214e57600080fd5b6020830191508360208260051b850101111561216957600080fd5b9250929050565b6000806000806000806060878903121561218957600080fd5b863567ffffffffffffffff808211156121a157600080fd5b6121ad8a838b01612124565b909850965060208901359150808211156121c657600080fd5b6121d28a838b01612124565b909650945060408901359150808211156121eb57600080fd5b506121f889828a01612124565b979a9699509497509295939492505050565b600081518084526020808501945080840160005b838110156122435781516001600160a01b03168752958201959082019060010161221e565b509495945050505050565b602081526000611b6c602083018461220a565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261228857600080fd5b8135602067ffffffffffffffff808311156122a5576122a5612261565b8260051b604051601f19603f830116810181811084821117156122ca576122ca612261565b6040529384528581018301938381019250878511156122e857600080fd5b83870191505b84821015612307578135835291830191908301906122ee565b979650505050505050565b6000806040838503121561232557600080fd5b82359150602083013567ffffffffffffffff81111561234357600080fd5b61234f85828601612277565b9150509250929050565b600081518084526020808501945080840160005b838110156122435781518752958201959082019060010161236d565b602081526000611b6c6020830184612359565b6001600160a01b03811681146111c357600080fd5b6000602082840312156123c357600080fd5b8135611b6c8161239c565b600080604083850312156123e157600080fd5b82356123ec8161239c565b915060208301356123fc8161239c565b809150509250929050565b60006020828403121561241957600080fd5b5035919050565b60006020828403121561243257600080fd5b813567ffffffffffffffff81111561244957600080fd5b820160808185031215611b6c57600080fd5b60408152600061246e604083018561220a565b82810360208401526124808185612359565b95945050505050565b80151581146111c357600080fd5b6000806000606084860312156124ac57600080fd5b83356124b78161239c565b9250602084013567ffffffffffffffff8111156124d357600080fd5b6124df86828701612277565b92505060408401356124f081612489565b809150509250925092565b6000806040838503121561250e57600080fd5b50508035926020909101359150565b6000806000806060858703121561253357600080fd5b843561253e8161239c565b935060208501359250604085013567ffffffffffffffff8082111561256257600080fd5b818701915087601f83011261257657600080fd5b81358181111561258557600080fd5b88602082850101111561259757600080fd5b95989497505060200194505050565b6000806000606084860312156125bb57600080fd5b83356125c68161239c565b92506020840135915060408401356124f08161239c565b6000806000606084860312156125f257600080fd5b83356125fd8161239c565b9250602084013561260d8161239c565b929592945050506040919091013590565b6000806040838503121561263157600080fd5b823561263c8161239c565b946020939093013593505050565b600060208083528351808285015260005b818110156126775785810183015185820160400152820161265b565b506000604082860101526040601f19601f8301168501019250505092915050565b634e487b7160e01b600052603260045260246000fd5b6000808335601e198436030181126126c557600080fd5b83018035915067ffffffffffffffff8211156126e057600080fd5b60200191503681900382131561216957600080fd5b8183823760009101908152919050565b634e487b7160e01b600052601160045260246000fd5b60006001820161272d5761272d612705565b5060010190565b60208082526026908201527f45786563757461626c653a2063616c6c6572206973206e6f742074686520657860408201526532b1baba37b960d11b606082015260800190565b602080825260029082015261413360f01b604082015260600190565b6000808335601e198436030181126127ad57600080fd5b83018035915067ffffffffffffffff8211156127c857600080fd5b6020019150600581901b360382131561216957600080fd5b8183526000602080850194508260005b858110156122435781356128038161239c565b6001600160a01b0316875295820195908201906001016127f0565b81835260006001600160fb1b0383111561283757600080fd5b8260051b80836020870137939093016020019392505050565b608081526000612864608083018a8c6127e0565b602083820381850152612878828a8c6127e0565b9150838203604085015261288d82888a61281e565b84810360608601528581529150808201600586811b840183018860005b8981101561291c57868303601f190185528135368c9003601e190181126128d057600080fd5b8b01868101903567ffffffffffffffff8111156128ec57600080fd5b80861b36038213156128fd57600080fd5b61290885828461281e565b9688019694505050908501906001016128aa565b50909f9e505050505050505050505050505050565b6040815260006129456040830186886127e0565b828103602084015261230781858761281e565b6000806040838503121561296b57600080fd5b505080516020909101519092909150565b6001600160a01b03841681526060602082018190526000906129a090830185612359565b90508215156040830152949350505050565b6000602082840312156129c457600080fd5b8151611b6c81612489565b6001600160a01b03841681526060602082018190526000906129f390830185612359565b82810360408401526120a98185612359565b600060208284031215612a1757600080fd5b5051919050565b600060208284031215612a3057600080fd5b8151611b6c8161239c565b80820281158282048414176109fa576109fa612705565b600082612a6f57634e487b7160e01b600052601260045260246000fd5b50049056fea2646970667358221220fe839a737b6feb9b2da5b22a08ca8ad1204187f9ca2bb38a45eca78d6390336d64736f6c63430008150033
Verified Source Code Partial Match
Compiler: v0.8.21+commit.d9974bed
EVM: paris
Optimization: Yes (200 runs)
IERC20WrapperLocked.sol 10 lines
/* SPDX-License-Identifier: UNLICENSED */
pragma solidity ^0.8.15;
interface IERC20WrapperLocked {
function withdrawToByLockTimestamps(address account, uint[] memory lockTimestamps, bool allowRemainderLoss) external returns (bool);
function getLockedAmounts(address account) external view returns (uint[] memory lock_timestamps, uint[] memory amounts);
function getWithdrawAmountsByLockTimestamp(address account, uint lockTimestamp) external view returns (uint unlocked, uint locked);
}
IEVault.sol 32 lines
/* SPDX-License-Identifier: UNLICENSED */
pragma solidity ^0.8.15;
interface IEVault {
function deposit(uint amount, address receiver) external returns (uint);
function redeem(uint amount, address receiver, address owner) external returns (uint);
function maxWithdraw(address owner) external view returns (uint);
function maxRedeem(address owner) external view returns (uint);
function maxDeposit(address account) external view returns (uint);
function convertToAssets(uint shares) external view returns (uint);
function convertToShares(uint assets) external view returns (uint);
function asset() external view returns (address);
function totalAssets() external view returns (uint);
function totalSupply() external view returns (uint);
function interestRate() external view returns (uint);
function cash() external view returns (uint);
function totalBorrows() external view returns (uint);
function interestFee() external view returns (uint);
}
IMerkleDistributor.sol 8 lines
/* SPDX-License-Identifier: UNLICENSED */
pragma solidity ^0.8.15;
interface IMerkleDistributor {
function claim(address[] calldata users, address[] calldata tokens, uint256[] calldata amounts, bytes32[][] calldata proofs) external;
function claimed(address user, address token) external view returns (uint208 amount, uint48 timestamp, bytes32 merkleRoot);
}
PositionManager.sol 115 lines
/* SPDX-License-Identifier: UNLICENSED */
pragma solidity ^0.8.15;
import './PositionManagerHolder.sol';
/// @title PositionManager for EulerV2
/// @author IntoTheBlock Corp
contract PositionManager is PositionManagerHolder {
event Deposit(address indexed caller, address token, address vault, uint amount, uint lpt_change);
event Redeem(address indexed caller, address token, address vault, uint amount, uint lpt_change);
event Assemble();
event Disassemble();
event ClaimLockedRewards(address indexed caller, address reward_token, uint[] lock_timestamps, uint[] amounts);
/// @param _executors Executor addresses
/// @param _wnative Wrapped native token address
/// @param _vault vault address
/// @param _merkle_distributor reward distributor address
constructor(address[] memory _executors, address payable _wnative, address _underlying, address _vault, address _merkle_distributor) PositionManagerHolder(_executors, _wnative, _underlying, _vault, _merkle_distributor) {}
modifier hasConfig() {
require(position_config.vault != address(0), 'A3'); // position_config is missing
_;
}
/// @param _underlying underlying address
/// @param _vault vault address
function updatePositionConfig(address _underlying, address _vault) public override onlyOwner {
require(IEVault(_vault).asset() == _underlying);
position_config = PositionConfig(_underlying, _vault);
emit UpdatePositionConfig(msg.sender, _underlying, _vault);
}
/* Primitives */
/// @notice Deposits the underlying token into the vault and returns the equivalent lpt_out
/// @param _amount underlying token amount
/// @param _min_lpt_out min lpt out
/// @return lpt_out lpt out
function deposit(uint _amount, uint _min_lpt_out) public onlyExecutor hasConfig returns (uint lpt_out) {
PositionConfig memory c = position_config;
lpt_out = IEVault(c.vault).deposit(_amount, address(this));
require(lpt_out >= _min_lpt_out, 'D1'); // Insufficient lpt_out
emit Deposit(msg.sender, c.underlying, c.vault, _amount, lpt_out);
}
/// @notice Deposits the entire balance of the underlying token into the vault and returns the equivalent lpt_out
/// @param _min_lpt_out min lpt out
/// @return lpt_out lpt out
function assemble(uint _min_lpt_out) public virtual onlyExecutor hasConfig returns (uint lpt_out) {
PositionConfig memory c = position_config;
uint underlying_amount = _erc20Balance(c.underlying);
lpt_out = deposit(underlying_amount, _min_lpt_out);
emit Assemble();
}
/// @notice Redeems the specified lpt amount for the underlying token in the vault.
/// @param _lpt_amount amount to redeem
/// @param _min_out minimum amount of underlying token to receive
/// @return amount_out amount of underlying token to receive
function redeem(uint _lpt_amount, uint _min_out) public onlyExecutor hasConfig returns (uint amount_out) {
PositionConfig memory c = position_config;
amount_out = IEVault(c.vault).redeem(_lpt_amount, address(this), address(this));
require(amount_out >= _min_out, 'R1'); // Insufficient amount_out
emit Redeem(msg.sender, c.underlying, c.vault, amount_out, _lpt_amount);
}
/// @notice Redeems a percentage-based amount of lpt for the underlying token in the vault
/// @param _percentage Percentage of the total position to redeem
/// @param _min_out minimum amount of underlying token to receive
/// @return amount_out amount of underlying token to receive
function disassemble(uint _percentage, uint _min_out) public onlyExecutor hasConfig returns (uint amount_out) {
require(_percentage <= ONE, 'P1');
if (_percentage == 0)
return 0;
uint lpt_change = _percentageAmount(getLPTBalance(), _percentage);
amount_out = redeem(lpt_change, _min_out);
emit Disassemble();
}
/// @notice Redeems the entire position of lpt for the underlying token in the vault.
/// @param _min_out minimum amount of underlying token to receive
/// @return amount_out amount of underlying token to receive
function fullDisassemble(uint _min_out) public onlyExecutor hasConfig returns (uint amount_out) {
return disassemble(ONE, _min_out);
}
function claimLockedReward(address _reward_token, uint[] memory _lock_timestamps, bool _allow_remainder_loss) external onlyExecutor {
uint[] memory reward_amounts = new uint[](_lock_timestamps.length);
for (uint i = 0; i < _lock_timestamps.length; i++)
(reward_amounts[i], ) = IERC20WrapperLocked(_reward_token).getWithdrawAmountsByLockTimestamp(address(this), _lock_timestamps[i]);
IERC20WrapperLocked(_reward_token).withdrawToByLockTimestamps(address(this), _lock_timestamps, _allow_remainder_loss);
emit ClaimLockedRewards(msg.sender, _reward_token, _lock_timestamps, reward_amounts);
}
/* View */
function getPositionAssets() public view returns (address[] memory) {
address[] memory assets = new address[](1);
assets[0] = position_config.underlying;
return assets;
}
function getLPTBalance() public view returns (uint) {
return _erc20Balance(position_config.vault);
}
function getUnderlyings() external view returns (address[] memory assets, uint[] memory amounts) {
address[] memory tokens = getPositionAssets();
uint[] memory balances = new uint[](tokens.length);
balances[0] = IEVault(position_config.vault).convertToAssets(getLPTBalance());
return (tokens, balances);
}
}
PositionManagerHolder.sol 70 lines
/* SPDX-License-Identifier: UNLICENSED */
pragma solidity ^0.8.15;
import '@itb/quant-common/contracts/solidity8/ITBContract.sol';
import './interfaces/IEVault.sol';
import './interfaces/IMerkleDistributor.sol';
import './interfaces/IERC20WrapperLocked.sol';
struct MerkleClaimData {
address[] users;
address[] tokens;
uint[] values;
bytes32[][] proof;
}
/// @title PositionManager for Holding rewards and underlying
/// @author IntoTheBlock Corp
contract PositionManagerHolder is ITBContract {
struct PositionConfig {
address underlying;
address vault;
}
PositionConfig public position_config;
IMerkleDistributor public merkle_distributor;
event UpdatePositionConfig(address indexed caller, address underlying, address vault);
event UpdateMerkleDistributor(address indexed caller, address merkle_distributor);
event ClaimMerkleRewards(address indexed caller, address[] tokens, uint[] values);
/// @param _executors Executor addresses
/// @param _wnative Wrapped native token address
/// @param _underlying underlying address
/// @param _vault vault address. Not used in Holder
/// @param _merkle_distributor reward distributor address
constructor(address[] memory _executors, address payable _wnative, address _underlying, address _vault, address _merkle_distributor) ITBContract(_executors, _wnative) {
updatePositionConfig(_underlying, _vault);
updateMerkleDistributor(_merkle_distributor);
}
/* Infra */
function VERSION() external pure returns (string memory) {
return '1.0.0';
}
/* Config */
/// @param _merkle_distributor reward distributor address
function updateMerkleDistributor(address _merkle_distributor) public onlyOwner {
merkle_distributor = IMerkleDistributor(_merkle_distributor);
emit UpdateMerkleDistributor(msg.sender, _merkle_distributor);
}
/// @param _underlying underlying address
/// @param _vault vault address
function updatePositionConfig(address _underlying, address _vault) public virtual onlyOwner {
position_config = PositionConfig(_underlying, _vault);
emit UpdatePositionConfig(msg.sender, _underlying, _vault);
}
/// @notice Claims the merkle rewards for the specified users
/// @param _merkle_claim_data merkle claim data
/// @return merkle_tokens_out tokens addresses claimed
/// @return merkle_amounts_out amounts of tokens claimed
function claimRewards(MerkleClaimData calldata _merkle_claim_data) external onlyExecutor returns (address[] memory merkle_tokens_out, uint[] memory merkle_amounts_out) {
merkle_distributor.claim(_merkle_claim_data.users, _merkle_claim_data.tokens, _merkle_claim_data.values, _merkle_claim_data.proof);
emit ClaimMerkleRewards(msg.sender, _merkle_claim_data.tokens, _merkle_claim_data.values);
return (_merkle_claim_data.tokens, _merkle_claim_data.values);
}
}
YieldPosition.sol 14 lines
/* SPDX-License-Identifier: UNLICENSED */
pragma solidity ^0.8.0;
import './PositionManager.sol';
contract YieldPosition is PositionManager {
constructor(address[] memory _executors, address payable _wnative, address _underlying, address _vault, address _merkle_distributor) PositionManager(_executors, _wnative, _underlying, _vault, _merkle_distributor) {}
function disassemble(uint _percentage, uint[] memory _min_outs) public onlyExecutor hasConfig returns (uint[] memory) {
uint[] memory amounts_out = new uint[](1);
amounts_out[0] = disassemble(_percentage, _min_outs[0]);
return amounts_out;
}
}
YieldPositionOwnable2StepWithShortcut.sol 9 lines
/* SPDX-License-Identifier: UNLICENSED */
pragma solidity ^0.8.0;
import './YieldPosition.sol';
import '@itb/quant-common/contracts/solidity8/utils/Ownable2StepWithShortcut.sol';
contract YieldPositionOwnable2StepWithShortcut is YieldPosition, Ownable2StepWithShortcut {
constructor(address[] memory _executors, address payable _wnative, address _underlying, address _vault, address _merkle_distributor) YieldPosition(_executors, _wnative, _underlying, _vault, _merkle_distributor) {}
}
ITBContract.sol 100 lines
/* SPDX-License-Identifier: UNLICENSED */
pragma solidity ^0.8.20;
import './utils/Withdrawable.sol';
import './utils/IWETH.sol';
/// @title ITBContract contract that implements common owner only functions accros all strategies
/// @author IntoTheBlock Corp
/// @dev Abstract
abstract contract ITBContract is Withdrawable {
using SafeERC20 for IERC20;
event ApproveToken(address indexed token, address guy, uint256 wad);
address payable immutable public WNATIVE;
uint constant ONE = 1e18;
/// @param _executors Executor addresses
constructor(address[] memory _executors, address payable _wnative) Executable(_executors) {
WNATIVE = _wnative;
}
function _percentageAmount(uint _amount, uint _percentage) internal pure returns (uint) {
return _amount * _percentage / ONE;
}
/// @notice Set allowance for a given token, amount and spender
/// @param _token Token to spend
/// @param _guy Spender
/// @param _wad Max amount to spend
function _approveToken(address _token, address _guy, uint256 _wad) internal {
if (_wad != 0)
IERC20(_token).forceApprove(_guy, _wad);
else
IERC20(_token).approve(_guy, _wad);
emit ApproveToken(_token, _guy, _wad);
}
/// @notice For a given token, amount and spender, check if contract can spend amount and, if necessary, set the allowance to amount
/// @param _token Token to spend
/// @param _guy Spender
/// @param _amount Amount to spend
function _checkAllowanceAndApprove(address _token, address _guy, uint256 _amount) internal {
_checkAllowanceAndApprove(_token, _guy, _amount, _amount);
}
/// @notice For a given token, amount and spender, check if contract can spend amount and, if necessary, set the allowance to approval amount
/// @param _token Token to spend
/// @param _guy Spender
/// @param _amount Amount to spend
/// @param _approval_amount Amount to approve
function _checkAllowanceAndApprove(address _token, address _guy, uint256 _amount, uint256 _approval_amount) internal {
if (IERC20(_token).allowance(address(this), _guy) < _amount)
_approveToken(_token, _guy, _approval_amount);
}
/// @notice Only owner. Set allowance for a given token, amount and spender
/// @param _token Token to spend
/// @param _guy Spender
/// @param _wad Max amount to spend
function approveToken(address _token, address _guy, uint256 _wad) external onlyOwner {
_approveToken(_token, _guy, _wad);
}
/// @notice Only owner. Revoke allowance for a given token and spender
/// @param _token Token to spend
/// @param _guy Spender
function revokeToken(address _token, address _guy) external onlyOwner {
_approveToken(_token, _guy, 0);
}
/// @notice Only owner. Execute an arbitrary call
/// @param _to Target address
/// @param _value Value (i. e. msg.value)
/// @param _data Invocation data
function execute(address _to, uint256 _value, bytes calldata _data) external payable onlyOwner {
(bool success, bytes memory returnData) = _to.call{ value: _value }(_data);
require(success, string(returnData));
}
/// @notice Only owner. Execute multiple arbitrary calls in order
/// @param _tos Target address for each call
/// @param _values Value for each call (i. e. msg.value)
/// @param _datas Invocation data for each call
function batchExecute(address[] calldata _tos, uint256[] calldata _values, bytes[] calldata _datas) external payable onlyOwner {
require(_tos.length == _values.length && _tos.length == _datas.length, "Arguments length mismatch");
for (uint256 i = 0; i < _tos.length; i++) {
(bool success, bytes memory returnData) = _tos[i].call{ value: _values[i] }(_datas[i]);
require(success, string(returnData));
}
}
function wrapNative(uint256 _amount) public onlyExecutor {
IWETH(WNATIVE).deposit{ value: _amount }();
}
function unwrapNative(uint256 _amount) public onlyExecutor {
IWETH(WNATIVE).withdraw(_amount);
}
}
Executable.sol 40 lines
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/access/Ownable2Step.sol";
/// @title Base contract that implements executor related functions
/// @author IntoTheBlock Corp
/// @dev Abstract
abstract contract Executable is Ownable2Step {
mapping(address => bool) public executors;
event ExecutorUpdated(address indexed executor, bool enabled);
/// @param _executors Initial whitelisted executor addresses
constructor(address[] memory _executors) Ownable(msg.sender) {
for (uint256 i = 0; i < _executors.length; i++) {
addExecutor(_executors[i]);
}
}
/// @notice Revert if call is not being made from the owner or an executor
modifier onlyExecutor() {
require(owner() == msg.sender || executors[msg.sender], "Executable: caller is not the executor");
_;
}
/// @notice Only owner. Add an executor
/// @param _executor New executor address
function addExecutor(address _executor) public onlyOwner {
emit ExecutorUpdated(_executor, true);
executors[_executor] = true;
}
/// @notice Only owner. Remove an executor
/// @param _executor Executor address to remove
function removeExecutor(address _executor) external onlyOwner {
emit ExecutorUpdated(_executor, false);
executors[_executor] = false;
}
}
IWETH.sol 25 lines
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;
interface IWETH {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
event Approval(address indexed src, address indexed guy, uint256 wad);
event Transfer(address indexed src, address indexed dst, uint256 wad);
event Deposit(address indexed dst, uint256 wad);
event Withdrawal(address indexed src, uint256 wad);
function balanceOf(address) external view returns (uint256);
function allowance(address, address) external view returns (uint256);
fallback() external payable;
receive() external payable;
function deposit() external payable;
function withdraw(uint256 wad) external;
function totalSupply() external view returns (uint256);
function approve(address guy, uint256 wad) external returns (bool);
function transfer(address dst, uint256 wad) external returns (bool);
function transferFrom(address src, address dst, uint256 wad) external returns (bool);
}
Ownable2StepWithShortcut.sol 11 lines
/* SPDX-License-Identifier: UNLICENSED */
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/access/Ownable2Step.sol";
abstract contract Ownable2StepWithShortcut is Ownable2Step {
function transferOwnership1Step(address newOwner) public onlyOwner {
require(newOwner != address(0), "ITBOwnable: zero address");
_transferOwnership(newOwner);
}
}
Withdrawable.sol 97 lines
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import './Executable.sol';
/**
Ensures that any contract that inherits from this contract is able to
withdraw funds that are accidentally received or stuck.
*/
/// @title Base contract that implements withdrawal related functions
/// @author IntoTheBlock Corp
/// @dev Abstract
abstract contract Withdrawable is Executable {
using SafeERC20 for IERC20;
address constant ETHER = address(0);
event LogWithdraw(
address indexed _to,
address indexed _asset_address,
uint256 amount
);
receive() external payable {}
/// @notice ERC20 or ETH balance of this contract given a token address
/// @param _asset_address Token address or address(0) for ETH
/// @return Balance
function _erc20OrNativeBalance(address _asset_address) internal view returns (uint256) {
return _asset_address == ETHER ? _nativeBalance() : _erc20Balance(_asset_address);
}
function _erc20Balance(address _asset_address) internal view returns (uint256) {
return IERC20(_asset_address).balanceOf(address(this));
}
function _nativeBalance() internal view returns (uint256) {
return address(this).balance;
}
/// @notice ERC20 balance of given account
/// @param _asset_address Token address
/// @param _account Account address
/// @return Balance
function balanceOf(address _asset_address, address _account) public view returns (uint256) {
return IERC20(_asset_address).balanceOf(_account);
}
/// @notice Send the given amount of the given token or ETH to the given receiver
/// @param _asset_address Token address or address(0) for ETH
/// @param _amount Amount to send
/// @param _to Receiver address
function _withdraw_to(address _asset_address, uint256 _amount, address payable _to) internal {
require(_to != address(0), 'Invalid address');
uint256 balance = _erc20OrNativeBalance(_asset_address);
require(balance >= _amount, 'Insufficient funds');
if (_asset_address == ETHER) {
(bool success, ) = _to.call{value: _amount}(''); /* carry gas over so it works with contracts with custom fallback, we dont care about reentrancy on onlyOwner */
require(success, 'Native transfer failed.');
} else
IERC20(_asset_address).safeTransfer(_to, _amount);
emit LogWithdraw(_to, _asset_address, _amount);
}
/// @notice Only owner. Send the given amount of the given token or ETH to the caller
/// @param _asset_address Token address or address(0) for ETH
/// @param _amount Amount to send
function withdraw(address _asset_address, uint256 _amount) external onlyOwner {
_withdraw_to(_asset_address, _amount, payable(msg.sender));
}
/// @notice Only owner. Send the given amount of the given token or ETH to the given receiver
/// @param _asset_address Token address or address(0) for ETH
/// @param _amount Amount to send
/// @param _to Receiver address
function withdrawTo(address _asset_address, uint256 _amount, address payable _to) external onlyOwner {
_withdraw_to(_asset_address, _amount, _to);
}
/// @notice Only owner. Send its entire balance of the given token or ETH to the caller
/// @param _asset_address Token address or address(0) for ETH
function withdrawAll(address _asset_address) external onlyOwner {
uint256 balance = _erc20OrNativeBalance(_asset_address);
_withdraw_to(_asset_address, balance, payable(msg.sender));
}
/// @notice Only owner. Send its entire balance of the given token or ETH to the given receiver
/// @param _asset_address Token address or address(0) for ETH
/// @param _to Receiver address
function withdrawAllTo(address _asset_address, address payable _to) external onlyOwner {
uint256 balance = _erc20OrNativeBalance(_asset_address);
_withdraw_to(_asset_address, balance, _to);
}
}
Ownable.sol 100 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
Ownable2Step.sol 67 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (access/Ownable2Step.sol)
pragma solidity ^0.8.20;
import {Ownable} from "./Ownable.sol";
/**
* @dev Contract module which provides access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* This extension of the {Ownable} contract includes a two-step mechanism to transfer
* ownership, where the new owner must call {acceptOwnership} in order to replace the
* old one. This can help prevent common mistakes, such as transfers of ownership to
* incorrect accounts, or to contracts that are unable to interact with the
* permission system.
*
* The initial owner is specified at deployment time in the constructor for `Ownable`. This
* can later be changed with {transferOwnership} and {acceptOwnership}.
*
* This module is used through inheritance. It will make available all functions
* from parent (Ownable).
*/
abstract contract Ownable2Step is Ownable {
address private _pendingOwner;
event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
/**
* @dev Returns the address of the pending owner.
*/
function pendingOwner() public view virtual returns (address) {
return _pendingOwner;
}
/**
* @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
* Can only be called by the current owner.
*
* Setting `newOwner` to the zero address is allowed; this can be used to cancel an initiated ownership transfer.
*/
function transferOwnership(address newOwner) public virtual override onlyOwner {
_pendingOwner = newOwner;
emit OwnershipTransferStarted(owner(), newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual override {
delete _pendingOwner;
super._transferOwnership(newOwner);
}
/**
* @dev The new owner accepts the ownership transfer.
*/
function acceptOwnership() public virtual {
address sender = _msgSender();
if (pendingOwner() != sender) {
revert OwnableUnauthorizedAccount(sender);
}
_transferOwnership(sender);
}
}
IERC1363.sol 86 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1363.sol)
pragma solidity >=0.6.2;
import {IERC20} from "./IERC20.sol";
import {IERC165} from "./IERC165.sol";
/**
* @title IERC1363
* @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].
*
* Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract
* after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.
*/
interface IERC1363 is IERC20, IERC165 {
/*
* Note: the ERC-165 identifier for this interface is 0xb0202a11.
* 0xb0202a11 ===
* bytes4(keccak256('transferAndCall(address,uint256)')) ^
* bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^
* bytes4(keccak256('approveAndCall(address,uint256)')) ^
* bytes4(keccak256('approveAndCall(address,uint256,bytes)'))
*/
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @param data Additional data with no specified format, sent in call to `spender`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);
}
IERC165.sol 6 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC165.sol)
pragma solidity >=0.4.16;
import {IERC165} from "../utils/introspection/IERC165.sol";
IERC20.sol 6 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20.sol)
pragma solidity >=0.4.16;
import {IERC20} from "../token/ERC20/IERC20.sol";
IERC20.sol 79 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev 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.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens 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.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
SafeERC20.sol 212 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC1363} from "../../../interfaces/IERC1363.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC-20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
/**
* @dev An operation with an ERC-20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {
return _callOptionalReturnBool(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {
return _callOptionalReturnBool(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*
* NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function
* only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being
* set here.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
safeTransfer(token, to, value);
} else if (!token.transferAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target
* has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferFromAndCallRelaxed(
IERC1363 token,
address from,
address to,
uint256 value,
bytes memory data
) internal {
if (to.code.length == 0) {
safeTransferFrom(token, from, to, value);
} else if (!token.transferFromAndCall(from, to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.
* Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}
* once without retrying, and relies on the returned value to be true.
*
* Reverts if the returned value is other than `true`.
*/
function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
forceApprove(token, to, value);
} else if (!token.approveAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements.
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
// bubble errors
if iszero(success) {
let ptr := mload(0x40)
returndatacopy(ptr, 0, returndatasize())
revert(ptr, returndatasize())
}
returnSize := returndatasize()
returnValue := mload(0)
}
if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
bool success;
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
returnSize := returndatasize()
returnValue := mload(0)
}
return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);
}
}
Context.sol 28 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
IERC165.sol 25 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
Read Contract
VERSION 0xffa1ad74 → string
WNATIVE 0xb381cf40 → address
balanceOf 0xf7888aec → uint256
executors 0x9ac2a011 → bool
getLPTBalance 0x90adc83c → uint256
getPositionAssets 0x087ed837 → address[]
getUnderlyings 0xf65baefa → address[], uint256[]
merkle_distributor 0x32c8fa46 → address
owner 0x8da5cb5b → address
pendingOwner 0xe30c3978 → address
position_config 0xec21145a → address, address
Write Contract 26 functions
These functions modify contract state and require a wallet transaction to execute.
acceptOwnership 0x79ba5097
No parameters
addExecutor 0x1f5a0bbe
address _executor
approveToken 0xda3e3397
address _token
address _guy
uint256 _wad
assemble 0xe6a6e7a2
uint256 _min_lpt_out
returns: uint256
batchExecute 0x077d97d7
address[] _tos
uint256[] _values
bytes[] _datas
claimLockedReward 0x68c4af7f
address _reward_token
uint256[] _lock_timestamps
bool _allow_remainder_loss
claimRewards 0x99da3c03
tuple _merkle_claim_data
returns: address[], uint256[]
deposit 0xe2bbb158
uint256 _amount
uint256 _min_lpt_out
returns: uint256
disassemble 0x1ea68c00
uint256 _percentage
uint256[] _min_outs
returns: uint256[]
disassemble 0x6ed625ab
uint256 _percentage
uint256 _min_out
returns: uint256
execute 0xb61d27f6
address _to
uint256 _value
bytes _data
fullDisassemble 0x54621b42
uint256 _min_out
returns: uint256
redeem 0x7cbc2373
uint256 _lpt_amount
uint256 _min_out
returns: uint256
removeExecutor 0x24788429
address _executor
renounceOwnership 0x715018a6
No parameters
revokeToken 0x3419ba23
address _token
address _guy
transferOwnership 0xf2fde38b
address newOwner
transferOwnership1Step 0xe1b97139
address newOwner
unwrapNative 0x34b10a6d
uint256 _amount
updateMerkleDistributor 0x8c53b747
address _merkle_distributor
updatePositionConfig 0xa3c01c42
address _underlying
address _vault
withdraw 0xf3fef3a3
address _asset_address
uint256 _amount
withdrawAll 0xfa09e630
address _asset_address
withdrawAllTo 0xb6703fcd
address _asset_address
address _to
withdrawTo 0xc4e2c1e6
address _asset_address
uint256 _amount
address _to
wrapNative 0x9169d833
uint256 _amount
Recent Transactions
This address has 1 on-chain transactions, but only 1.5% of the chain is indexed. Transactions will appear as indexing progresses. View on Etherscan →