Address Contract Partially Verified
Address
0xe9Fbe23161eFC299F8a5eCeA2c75579acA21b88e
Balance
0 ETH
Nonce
50
Code Size
20945 bytes
Creator
0x6Ba17342...4D56 at tx 0x0baddbb7...8decf7
Indexed Transactions
0
Contract Bytecode
20945 bytes
0x60806040523480156200001157600080fd5b5060043610620001095760003560e01c806388a8d60211620000a3578063d4a22bde116200006e578063d4a22bde146200027d578063db90b1e01462000294578063ed27f7c914620002c3578063f987e55d14620002d757600080fd5b806388a8d602146200022757806397256094146200023b578063a22d7f631462000252578063aced1661146200026957600080fd5b80636a5f1aa211620000e45780636a5f1aa214620001a757806370905dce14620001c0578063748747e614620001e85780637dc0d1d014620001ff57600080fd5b80630d004424146200010e578063180cb47f146200013a5780634a3e6544146200017b575b600080fd5b620001256200011f36600462000c68565b620002ee565b60405190151581526020015b60405180910390f35b620001627f000000000000000000000000feb4acf3df3cdea7399794d0869ef76a6efaff5281565b6040516001600160a01b03909116815260200162000131565b620001626200018c36600462000c68565b6003602052600090815260409020546001600160a01b031681565b620001be620001b836600462000c68565b6200037e565b005b620001627f00000000000000000000000016388463d60ffe0661cf7f1f31a7d658ac790ff781565b620001be620001f936600462000c68565b6200041d565b620001627f0000000000000000000000009a9fa8338dd5e5b2188006f1cd2ef26d921650c281565b60005462000162906001600160a01b031681565b620001be6200024c36600462000c8f565b6200046c565b620001626200026336600462000dab565b620004c7565b60025462000162906001600160a01b031681565b620001be6200028e36600462000c68565b620008e9565b62000162620002a536600462000c68565b6001600160a01b039081166000908152600360205260409020541690565b60015462000162906001600160a01b031681565b62000162620002e836600462000e89565b6200097f565b600080826001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000330573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000356919062000ef3565b6001600160a01b03908116600090815260036020526040902054811693169290921492915050565b6000546001600160a01b03163314620003b45760405162461bcd60e51b8152600401620003ab9062000f13565b60405180910390fd5b6001600160a01b038116620003fb5760405162461bcd60e51b815260206004820152600c60248201526b5a45524f5f4144445245535360a01b6044820152606401620003ab565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146200044a5760405162461bcd60e51b8152600401620003ab9062000f13565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b03163314620004995760405162461bcd60e51b8152600401620003ab9062000f13565b6001600160a01b03918216600090815260036020526040902080546001600160a01b03191691909216179055565b600080546001600160a01b03163314620004f55760405162461bcd60e51b8152600401620003ab9062000f13565b60008a8a7f0000000000000000000000009a9fa8338dd5e5b2188006f1cd2ef26d921650c27f000000000000000000000000feb4acf3df3cdea7399794d0869ef76a6efaff52866040516200054a9062000c41565b6200055a95949392919062000f38565b604051809103906000f08015801562000577573d6000803e3d6000fd5b5060015460405163352f8d5160e11b81526001600160a01b039182166004820152919250821690636a5f1aa290602401600060405180830381600087803b158015620005c257600080fd5b505af1158015620005d7573d6000803e3d6000fd5b5050600254604051633a43a3f360e11b81526001600160a01b039182166004820152908416925063748747e69150602401600060405180830381600087803b1580156200062357600080fd5b505af115801562000638573d6000803e3d6000fd5b5050600054604051630f629b7960e41b81526001600160a01b039182166004820152908416925063f629b7909150602401600060405180830381600087803b1580156200068457600080fd5b505af115801562000699573d6000803e3d6000fd5b5050604051630d768ce560e21b81526001600160a01b037f00000000000000000000000016388463d60ffe0661cf7f1f31a7d658ac790ff781166004830152841692506335da33949150602401600060405180830381600087803b1580156200070157600080fd5b505af115801562000716573d6000803e3d6000fd5b5050604051633ba24f8160e01b81526001600160801b038916600482015265ffffffffffff8816602482015264ffffffffff871660448201526001600160a01b0384169250633ba24f819150606401600060405180830381600087803b1580156200078057600080fd5b505af115801562000795573d6000803e3d6000fd5b505060405163f462bbff60e01b81526001600160801b03808d1660048301528b1660248201526001600160a01b038416925063f462bbff9150604401600060405180830381600087803b158015620007ec57600080fd5b505af115801562000801573d6000803e3d6000fd5b5050505060001987146200086c5760405163bdc8144b60e01b8152600481018890526001600160a01b0382169063bdc8144b90602401600060405180830381600087803b1580156200085257600080fd5b505af115801562000867573d6000803e3d6000fd5b505050505b8a6001600160a01b0316816001600160a01b03167f4e26313b1dea133965fe2d5a105476115b8bbaf3300e207b839d078fb334266060405160405180910390a36001600160a01b039a8b16600090815260036020526040902080546001600160a01b0319169b82169b909b17909a55509798975050505050505050565b6000546001600160a01b03163314620009165760405162461bcd60e51b8152600401620003ab9062000f13565b6001600160a01b0381166200095d5760405162461bcd60e51b815260206004820152600c60248201526b5a45524f5f4144445245535360a01b6044820152606401620003ab565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b600080546001600160a01b03163314620009ad5760405162461bcd60e51b8152600401620003ab9062000f13565b600084847f0000000000000000000000009a9fa8338dd5e5b2188006f1cd2ef26d921650c27f000000000000000000000000feb4acf3df3cdea7399794d0869ef76a6efaff528660405162000a029062000c41565b62000a1295949392919062000f38565b604051809103906000f08015801562000a2f573d6000803e3d6000fd5b5060015460405163352f8d5160e11b81526001600160a01b039182166004820152919250821690636a5f1aa290602401600060405180830381600087803b15801562000a7a57600080fd5b505af115801562000a8f573d6000803e3d6000fd5b5050600254604051633a43a3f360e11b81526001600160a01b039182166004820152908416925063748747e69150602401600060405180830381600087803b15801562000adb57600080fd5b505af115801562000af0573d6000803e3d6000fd5b5050600054604051630f629b7960e41b81526001600160a01b039182166004820152908416925063f629b7909150602401600060405180830381600087803b15801562000b3c57600080fd5b505af115801562000b51573d6000803e3d6000fd5b5050604051630d768ce560e21b81526001600160a01b037f00000000000000000000000016388463d60ffe0661cf7f1f31a7d658ac790ff781166004830152841692506335da33949150602401600060405180830381600087803b15801562000bb957600080fd5b505af115801562000bce573d6000803e3d6000fd5b50506040516001600160a01b038089169350841691507f4e26313b1dea133965fe2d5a105476115b8bbaf3300e207b839d078fb334266090600090a36001600160a01b03948516600090815260036020526040902080546001600160a01b03191695821695909517909455509192915050565b6141e58062000fb783390190565b6001600160a01b038116811462000c6557600080fd5b50565b60006020828403121562000c7b57600080fd5b813562000c888162000c4f565b9392505050565b6000806040838503121562000ca357600080fd5b823562000cb08162000c4f565b9150602083013562000cc28162000c4f565b809150509250929050565b80356001600160801b038116811462000ce557600080fd5b919050565b803564ffffffffff8116811462000ce557600080fd5b634e487b7160e01b600052604160045260246000fd5b600082601f83011262000d2857600080fd5b813567ffffffffffffffff8082111562000d465762000d4662000d00565b604051601f8301601f19908116603f0116810190828211818310171562000d715762000d7162000d00565b8160405283815286602085880101111562000d8b57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060008060008060008060006101208a8c03121562000dcb57600080fd5b893562000dd88162000c4f565b985060208a013562000dea8162000c4f565b975062000dfa60408b0162000ccd565b965062000e0a60608b0162000ccd565b955060808a0135945062000e2160a08b0162000ccd565b935060c08a013565ffffffffffff8116811462000e3d57600080fd5b925062000e4d60e08b0162000cea565b91506101008a013567ffffffffffffffff81111562000e6b57600080fd5b62000e798c828d0162000d16565b9150509295985092959850929598565b60008060006060848603121562000e9f57600080fd5b833562000eac8162000c4f565b9250602084013562000ebe8162000c4f565b9150604084013567ffffffffffffffff81111562000edb57600080fd5b62000ee98682870162000d16565b9150509250925092565b60006020828403121562000f0657600080fd5b815162000c888162000c4f565b6020808252600b908201526a085b585b9859d95b595b9d60aa1b604082015260600190565b600060018060a01b0380881683526020818816818501528187166040850152818616606085015260a06080850152845191508160a085015260005b8281101562000f915785810182015185820160c00152810162000f73565b5050600060c0828501015260c0601f19601f830116840101915050969550505050505056fe6101206040526000805462ffffff60ff60e81b01191662271001600160e81b011790556000196003553480156200003557600080fd5b50604051620041e5380380620041e5833981016040819052620000589162000af4565b6001600160a01b0385166080523060a0526040518590829082908290620000c59062000091908490849033908190819060240162000c28565b60408051601f198184030181529190526020810180516001600160e01b03908116634b839d7360e11b17909152620004c116565b505073bb51273d6c746910c7c06fe718f30c936170fed07f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55505060008054600160281b600160c81b031916650100000000006001600160a01b03881602179055506200013162000555565b156200016e5760405162461bcd60e51b8152602060048201526007602482015266195e1c1a5c995960ca1b60448201526064015b60405180910390fd5b6001600160a01b0383811660c0526000805463ffffffff60c81b191660e160cc1b179055600280546001600160801b031665340aad21b3b760921b17905560408051630b2339af60e21b8152905191861691632c8ce6bc916004808201926060929091908290030181865afa158015620001ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000212919062000c6b565b600a80546001600160a01b03199081166001600160a01b0393841617909155600980549091169282169290921790915590811660e0819052604051633c21b3eb60e11b815291871660048301529063784367d690602401602060405180830381865afa15801562000287573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002ad919062000cb5565b620002e85760405162461bcd60e51b815260206004820152600a602482015269085d985b1a59081bdd5d60b21b604482015260640162000165565b60e051604051637d2d278360e11b81526001600160a01b0387811660048301529091169063fa5a4f0690602401602060405180830381865afa15801562000333573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000359919062000cb5565b620003935760405162461bcd60e51b815260206004820152600960248201526810bb30b634b21034b760b91b604482015260640162000165565b6032600b819055600c5560001960055561010060075566038d7ea4c680006008556040805160808101825260006060820152674563918244f4000081526404a817c800602082015261a8c09181019190915277a8c00004a817c80000000000000000004563918244f40000600d556200040e61c350620005d5565b6001600160a01b038381166101005260e0516200043d9188169060001962000674602090811b620018ee17901c565b6200047a73888888888889758f76e7103c6cbf23abbf58f94660001960e0516001600160a01b03166200067460201b620018ee179092919060201c565b600954620004b5906001600160a01b031673888888888889758f76e7103c6cbf23abbf58f94660001962000674602090811b620018ee17901c565b50505050505062000d0c565b606060008073bb51273d6c746910c7c06fe718f30c936170fed06001600160a01b031684604051620004f4919062000cd9565b600060405180830381855af49150503d806000811462000531576040519150601f19603f3d011682016040523d82523d6000602084013e62000536565b606091505b5091509150816200054e576040513d806000833e8082fd5b9392505050565b60008060059054906101000a90046001600160a01b03166001600160a01b0316632f13b60c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620005aa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620005d0919062000cb5565b905090565b60008111620006165760405162461bcd60e51b815260206004820152600c60248201526b085e995c9bc81c1c9bd99a5d60a21b604482015260640162000165565b61ffff811115620006565760405162461bcd60e51b8152602060048201526009602482015268042e8dede40d0d2ced60bb1b604482015260640162000165565b6000805461ffff9092166101000262ffff0019909216919091179055565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b17909152620006ce90859083906200074a16565b62000744576040516001600160a01b0384166024820152600060448201526200073890859063095ea7b360e01b9060640160408051808303601f190181529190526020810180516001600160e01b0319939093166001600160e01b03938416179052906200080216565b62000744848262000802565b50505050565b6000806000846001600160a01b03168460405162000769919062000cd9565b6000604051808303816000865af19150503d8060008114620007a8576040519150601f19603f3d011682016040523d82523d6000602084013e620007ad565b606091505b5091509150818015620007db575080511580620007db575080806020019051810190620007db919062000cb5565b8015620007f95750620007f985620008e860201b620019b01760201c565b95945050505050565b60006200085e826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316620008f760201b620019bf179092919060201c565b90508051600014806200088257508080602001905181019062000882919062000cb5565b620008e35760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000165565b505050565b6001600160a01b03163b151590565b606062000908848460008562000910565b949350505050565b606082471015620009735760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000165565b600080866001600160a01b0316858760405162000991919062000cd9565b60006040518083038185875af1925050503d8060008114620009d0576040519150601f19603f3d011682016040523d82523d6000602084013e620009d5565b606091505b509092509050620009e987838387620009f4565b979650505050505050565b6060831562000a6857825160000362000a60576001600160a01b0385163b62000a605760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000165565b508162000908565b62000908838381511562000a7f5781518083602001fd5b8060405162461bcd60e51b815260040162000165919062000cf7565b80516001600160a01b038116811462000ab357600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000aeb57818101518382015260200162000ad1565b50506000910152565b600080600080600060a0868803121562000b0d57600080fd5b62000b188662000a9b565b945062000b286020870162000a9b565b935062000b386040870162000a9b565b925062000b486060870162000a9b565b60808701519092506001600160401b038082111562000b6657600080fd5b818801915088601f83011262000b7b57600080fd5b81518181111562000b905762000b9062000ab8565b604051601f8201601f19908116603f0116810190838211818310171562000bbb5762000bbb62000ab8565b816040528281528b602084870101111562000bd557600080fd5b62000be883602083016020880162000ace565b80955050505050509295509295909350565b6000815180845262000c1481602086016020860162000ace565b601f01601f19169290920160200192915050565b600060018060a01b03808816835260a0602084015262000c4c60a084018862000bfa565b9581166040840152938416606083015250911660809091015292915050565b60008060006060848603121562000c8157600080fd5b62000c8c8462000a9b565b925062000c9c6020850162000a9b565b915062000cac6040850162000a9b565b90509250925092565b60006020828403121562000cc857600080fd5b815180151581146200054e57600080fd5b6000825162000ced81846020870162000ace565b9190910192915050565b6020815260006200054e602083018462000bfa565b60805160a05160c05160e051610100516133ad62000e386000396000818161032b015281816106f1015281816108170152610f330152600081816105a5015281816111ef0152818161131b015281816122bf0152818161279f0152818161285401526129c401526000818161236101528181612b1a0152612bea0152600081816108ce01528181610a9001528181610b1b01528181610be101528181610d1301528181610db301528181610e44015281816113a701528181611432015281816114bd0152818161153c01528181611641015281816116cc0152818161174c01528181611b2e01528181611c0c01528181611d5a0152611f52015260008181610752015281816112e50152818161200701528181612289015281816127ce01526129f301526133ad6000f3fe608060405234801561001057600080fd5b50600436106102695760003560e01c80637d96993211610151578063c05bd92d116100c3578063d696860111610087578063d69686011461067d578063d94073d414610690578063ecf70858146106a3578063f462bbff146106ac578063fcfff16f146106bf578063fde813a8146106d357610269565b8063c05bd92d146105ed578063cefba47414610600578063cf683c701461062c578063d19a3bb81461063f578063d63a8e111461065a57610269565b8063a4a7799511610115578063a4a77995146104ff578063ab1c99941461057a578063ac00ff261461058d578063afd27bf5146105a0578063bc06b529146105c7578063bdc8144b146105da57610269565b80637d9699321461049957806380f55605146104ac578063950b3d73146104c65780639d7fb70c146104d9578063a0ef795b146104ec57610269565b80633d6cb575116101ea5780634a5d0943116101ae5780634a5d094314610437578063503160d9146104485780635d265d3f1461045b5780636718835f146104715780636fdca5e01461047e578063797bf3431461049157610269565b80633d6cb575146103e357806345b1993f146103f65780634697f05d1461040957806346aa2f121461041c57806349317f1d1461042f57610269565b80631eab62a9116102315780631eab62a914610365578063256d8a231461036e5780632b24a878146103b05780632f13b60c146103b85780633ba24f81146103d057610269565b806301681a62146102a457806304bd4629146102b757806309b2c8a8146102df5780631809bca51461031d578063180cb47f14610326575b73bb51273d6c746910c7c06fe718f30c936170fed03660008037600080366000845af43d6000803e80801561029d573d6000f35b3d6000fd5b005b6102a26102b2366004612cd6565b6106e6565b6102cc6102c5366004612cd6565b5060001990565b6040519081526020015b60405180910390f35b6002546102fd906001600160801b0380821691600160801b90041682565b604080516001600160801b039384168152929091166020830152016102d6565b6102cc600c5481565b61034d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016102d6565b6102cc600b5481565b600454600554600654600754600854610388949392919085565b604080519586526020860194909452928401919091526060830152608082015260a0016102d6565b6102cc6108a0565b6103c06108af565b60405190151581526020016102d6565b6102a26103de366004612d0a565b6108b9565b6102a26103f1366004612d68565b610a6a565b6102a2610404366004612d81565b610a7b565b6102a2610417366004612dc1565b610b06565b6102cc61042a366004612cd6565b610ba8565b6102cc610c98565b600054610100900461ffff166102cc565b6102a2610456366004612d68565b610cb8565b610463610cc0565b6040516102d6929190612e4a565b6000546103c09060ff1681565b6102a261048c366004612e65565b610cfe565b6102cc610d94565b6000546301000000900461ffff166102cc565b60005461034d90600160281b90046001600160a01b031681565b6102a26104d4366004612d68565b610d9e565b6102a26104e7366004612d68565b610e1e565b6102a26104fa366004612e82565b610e2f565b600d5461053c906001600160801b0381169065ffffffffffff600160801b8204169064ffffffffff600160b01b8204811691600160d81b90041684565b604080516001600160801b03909516855265ffffffffffff909316602085015264ffffffffff918216928401929092521660608201526080016102d6565b6102a2610588366004612ea4565b610f28565b6102a261059b366004612e65565b611392565b61034d7f000000000000000000000000000000000000000000000000000000000000000081565b6102a26105d5366004612d68565b61141d565b6102a26105e8366004612d68565b6114a8565b6102a26105fb366004612ed0565b611527565b60005461061790600160c81b900463ffffffff1681565b60405163ffffffff90911681526020016102d6565b6102a261063a366004612d68565b61162c565b61034d73bb51273d6c746910c7c06fe718f30c936170fed081565b6103c0610668366004612cd6565b60016020526000908152604090205460ff1681565b6102a261068b366004612d68565b6116b7565b60095461034d906001600160a01b031681565b6102cc60035481565b6102a26106ba366004612ef6565b611737565b6000546103c090600160e81b900460ff1681565b6102a26106e1366004612d68565b6118dd565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146107505760405162461bcd60e51b81526004016107479060208082526004908201526310b3b7bb60e11b604082015260600190565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b0316036107ba5760405162461bcd60e51b815260206004820152600660248201526508585cdcd95d60d21b6044820152606401610747565b6009546001600160a01b03908116908216036107fe5760405162461bcd60e51b815260206004820152600360248201526208541560ea1b6044820152606401610747565b6040516370a0823160e01b815230600482015261089d907f0000000000000000000000000000000000000000000000000000000000000000906001600160a01b038416906370a0823190602401602060405180830381865afa158015610868573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088c9190612f29565b6001600160a01b03841691906119d6565b50565b60006108aa611a0b565b905090565b60006108aa611a79565b6040516348e4a64960e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906348e4a6499060240160006040518083038186803b15801561091857600080fd5b505afa15801561092c573d6000803e3d6000fd5b5050505060008164ffffffffff161161097a5760405162461bcd60e51b815260206004820152601060248201526f696e74657276616c20746f6f206c6f7760801b6044820152606401610747565b6001600160801b0383811611156109bf5760405162461bcd60e51b8152602060048201526009602482015268746f6f206c6172676560b81b6044820152606401610747565b6002546001600160801b039081169084161015610a125760405162461bcd60e51b81526020600482015260116024820152701d1c9a59d9d95c881d1bdbc81cdb585b1b607a1b6044820152606401610747565b600d805464ffffffffff909216600160b01b0264ffffffffff60b01b1965ffffffffffff909416600160801b026001600160b01b03199093166001600160801b03909516949094179190911791909116919091179055565b610a72611af1565b61089d81611b2a565b6040516348e4a64960e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906348e4a6499060240160006040518083038186803b158015610ada57600080fd5b505afa158015610aee573d6000803e3d6000fd5b50505060049490945560059290925560075560085550565b6040516348e4a64960e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906348e4a6499060240160006040518083038186803b158015610b6557600080fd5b505afa158015610b79573d6000803e3d6000fd5b505050506001600160a01b03919091166000908152600160205260409020805460ff1916911515919091179055565b6001600160a01b03811660009081526001602052604081205460ff1680610bd85750600054600160e81b900460ff165b15610c8b5760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166301e1d1146040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c619190612f29565b9050806003541115610c825780600354610c7b9190612f58565b9392505050565b50600092915050565b506000919050565b919050565b6000610ca2611af1565b610caa611bf8565b9050610cb581611d3c565b90565b61089d611af1565b60006060610ccc611e86565b6040805160048152602481019091526020810180516001600160e01b031663440368a360e01b17905290939092509050565b6040516348e4a64960e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906348e4a6499060240160006040518083038186803b158015610d5d57600080fd5b505afa158015610d71573d6000803e3d6000fd5b505060008054931515600160e81b0260ff60e81b19909416939093179092555050565b60006108aa611fef565b6040516348e4a64960e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906348e4a6499060240160006040518083038186803b158015610dfd57600080fd5b505afa158015610e11573d6000803e3d6000fd5b5050505061089d8161203e565b610e26611af1565b61089d816120d9565b6040516320b8029160e21b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906382e00a449060240160006040518083038186803b158015610e8e57600080fd5b505afa158015610ea2573d6000803e3d6000fd5b5050600280546001600160801b031690555060009050610ec0611a0b565b905080831115610ece578092505b6000610ed9846120ff565b905082811015610f225760405162461bcd60e51b81526020600482015260146024820152731d1bdbc81b1a5d1d1b1948185b5bdd5b9d13dd5d60621b6044820152606401610747565b50505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610f895760405162461bcd60e51b81526004016107479060208082526004908201526310b3b7bb60e11b604082015260600190565b610f91611a79565b610fcb5760405162461bcd60e51b815260206004820152600b60248201526a1b9bdd08195e1c1a5c995960aa1b6044820152606401610747565b6001600160a01b03821661100b5760405162461bcd60e51b8152602060048201526007602482015266085b585c9ad95d60ca1b6044820152606401610747565b6000546001600160a01b03808416600160281b909204160361105d5760405162461bcd60e51b815260206004820152600b60248201526a1cd85b59481b585c9ad95d60aa1b6044820152606401610747565b600054611078908390600160c81b900463ffffffff16612332565b6000611082611a0b565b9050801561111b57600a5460405163339748cb60e01b815273888888888889758f76e7103c6cbf23abbf58f9469163339748cb916110d59130916001600160a01b03909116908690600090600401612f6b565b6020604051808303816000875af11580156110f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111189190612f29565b90505b6000805465010000000000600160c81b031916600160281b6001600160a01b03861602179055611149611a79565b156111805760405162461bcd60e51b8152602060048201526007602482015266195e1c1a5c995960ca1b6044820152606401610747565b6000806000856001600160a01b0316632c8ce6bc6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156111c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e79190612f94565b9250925092507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316146112595760405162461bcd60e51b815260206004820152600860248201526777726f6e6720535960c01b6044820152606401610747565b600980546001600160a01b038085166001600160a01b03199283168117909355600a8054918516919092161790556112a89073888888888889758f76e7103c6cbf23abbf58f9466000196118ee565b831580156112b4575084155b156112c157505050505050565b60405163769f8e5d60e01b8152306004820152602481018590526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116604483015260648201879052600060848301527f0000000000000000000000000000000000000000000000000000000000000000169063769f8e5d9060a4016020604051808303816000875af1158015611364573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113889190612f29565b50505050505b5050565b6040516348e4a64960e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906348e4a6499060240160006040518083038186803b1580156113f157600080fd5b505afa158015611405573d6000803e3d6000fd5b50506000805460ff1916931515939093179092555050565b6040516348e4a64960e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906348e4a6499060240160006040518083038186803b15801561147c57600080fd5b505afa158015611490573d6000803e3d6000fd5b505050506127108111156114a357600080fd5b600c55565b6040516348e4a64960e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906348e4a6499060240160006040518083038186803b15801561150757600080fd5b505afa15801561151b573d6000803e3d6000fd5b50505060039190915550565b6040516320b8029160e21b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906382e00a449060240160006040518083038186803b15801561158657600080fd5b505afa15801561159a573d6000803e3d6000fd5b505050506103848163ffffffff1610156115e95760405162461bcd60e51b815260206004820152601060248201526f6475726174696f6e20746f6f206c6f7760801b6044820152606401610747565b60005461160690600160281b90046001600160a01b031682612332565b6000805463ffffffff909216600160c81b0263ffffffff60c81b19909216919091179055565b6040516348e4a64960e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906348e4a6499060240160006040518083038186803b15801561168b57600080fd5b505afa15801561169f573d6000803e3d6000fd5b505050506127108111156116b257600080fd5b600b55565b6040516348e4a64960e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906348e4a6499060240160006040518083038186803b15801561171657600080fd5b505afa15801561172a573d6000803e3d6000fd5b5050505061089d8161241b565b6040516348e4a64960e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906348e4a6499060240160006040518083038186803b15801561179657600080fd5b505afa1580156117aa573d6000803e3d6000fd5b5050506001600160801b0382811611801591506117d057506001600160801b0382811611155b6118085760405162461bcd60e51b8152602060048201526009602482015268746f6f206c6172676560b81b6044820152606401610747565b816001600160801b0316816001600160801b031610156118585760405162461bcd60e51b815260206004820152600b60248201526a3bb937b7339037b93232b960a91b6044820152606401610747565b600d546001600160801b03808416911610156118ab5760405162461bcd60e51b81526020600482015260126024820152716d696e417373657420746f6f206c6172676560701b6044820152606401610747565b604080518082019091526001600160801b03928316808252919092166020909201829052600160801b90910217600255565b6118e5611af1565b61089d8161247c565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b17905261193f848261251b565b610f22576040516001600160a01b0384166024820152600060448201526119a690859063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526125c2565b610f2284826125c2565b6001600160a01b03163b151590565b60606119ce8484600085612697565b949350505050565b6040516001600160a01b038316602482015260448101829052611a0690849063a9059cbb60e01b9060640161196f565b505050565b6009546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a08231906024015b602060405180830381865afa158015611a55573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108aa9190612f29565b60008060059054906101000a90046001600160a01b03166001600160a01b0316632f13b60c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611acd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108aa9190612fd6565b333014611b285760405162461bcd60e51b815260206004820152600560248201526410b9b2b63360d91b6044820152606401610747565b565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166301e1d1146040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bae9190612f29565b90506000611bba611fef565b611bc49083612f58565b905060008184611bd2611a0b565b611bdc9190612ff3565b611be6919061300a565b9050611bf1816120ff565b5050505050565b6000611c02611a79565b158015611c8e57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663bf86d6906040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c8c9190612fd6565b155b15611cf3576000611c9d611fef565b604080518082019091526002546001600160801b03808216808452600160801b90920416602083015291925090821115611cf057611cf0611ceb8383602001516001600160801b0316612772565b612788565b50505b612710600c54612710611d069190612f58565b611d16611d11611a0b565b6129c0565b611d209190612ff3565b611d2a919061300a565b611d32611fef565b6108aa919061302c565b60005460ff16611d5657506000805460ff19166001179055565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166301e1d1146040518163ffffffff1660e01b8152600401602060405180830381865afa158015611db6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dda9190612f29565b905080821115611e4e5760005461271090611dfe90610100900461ffff1683612ff3565b611e08919061300a565b611e128284612f58565b111561138e5760405162461bcd60e51b815260206004820152600b60248201526a6865616c7468436865636b60a81b6044820152606401610747565b8181111561138e5760005461271090611e72906301000000900461ffff1683612ff3565b611e7c919061300a565b611e128383612f58565b60408051608081018252600d546001600160801b038116825265ffffffffffff600160801b820416602083015264ffffffffff600160b01b8204811693830193909352600160d81b90049091166060820152600090611ee3611a79565b158015611f105750806040015164ffffffffff16816060015164ffffffffff1642611f0e9190612f58565b115b8015611f2c575080516001600160801b0316611f2a611fef565b115b8015611f495750600254600160801b90046001600160801b031615155b8015611fd457507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663bf86d6906040518163ffffffff1660e01b8152600401602060405180830381865afa158015611fae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd29190612fd6565b155b15611feb57806020015165ffffffffffff16481091505b5090565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401611a38565b6000811161207d5760405162461bcd60e51b815260206004820152600c60248201526b085e995c9bc81c1c9bd99a5d60a21b6044820152606401610747565b61ffff8111156120bb5760405162461bcd60e51b8152602060048201526009602482015268042e8dede40d0d2ced60bb1b6044820152606401610747565b6000805461ffff9092166101000262ffff0019909216919091179055565b61089d611ceb6120e7611fef565b600254600160801b90046001600160801b0316612772565b60008160000361211157506000919050565b612119611a79565b156121b357600a5460405163339748cb60e01b815273888888888889758f76e7103c6cbf23abbf58f9469163339748cb916121699130916001600160a01b03909116908790600090600401612f6b565b6020604051808303816000875af1158015612188573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ac9190612f29565b9150612265565b6121bb612c89565b60008054604051633346d3a360e01b815273888888888889758f76e7103c6cbf23abbf58f94692633346d3a39261220c923092600160281b9092046001600160a01b03169189918890600401613228565b60408051808303816000875af115801561222a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061224e9190613262565b50925060008390036122635750600092915050565b505b60405163769f8e5d60e01b8152306004820152602481018390526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116604483015260006064830181905260848301527f0000000000000000000000000000000000000000000000000000000000000000169063769f8e5d9060a4016020604051808303816000875af1158015612308573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061232c9190612f29565b92915050565b60405162439f4b60e91b81526001600160a01b03838116600483015263ffffffff8316602483015260009182917f0000000000000000000000000000000000000000000000000000000000000000169063873e960090604401606060405180830381865afa1580156123a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123cc9190613286565b925050915081806123db575080155b15610f225760405162461bcd60e51b815260206004820152601060248201526f6f7261636c65206e6f7420726561647960801b6044820152606401610747565b612710811061245a5760405162461bcd60e51b815260206004820152600b60248201526a085b1bdcdcc81b1a5b5a5d60aa1b6044820152606401610747565b6000805461ffff90921663010000000264ffff00000019909216919091179055565b6000612486611a0b565b905080821115612494578091505b600061249f836129c0565b905060006124ac846120ff565b9050612710600b546127106124c19190612f58565b6124cb9084612ff3565b6124d5919061300a565b811015610f225760405162461bcd60e51b81526020600482015260146024820152731d1bdbc81b1a5d1d1b1948185b5bdd5b9d13dd5d60621b6044820152606401610747565b6000806000846001600160a01b03168460405161253891906132cf565b6000604051808303816000865af19150503d8060008114612575576040519150601f19603f3d011682016040523d82523d6000602084013e61257a565b606091505b50915091508180156125a45750805115806125a45750808060200190518101906125a49190612fd6565b80156125b957506001600160a01b0385163b15155b95945050505050565b6000612617826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166119bf9092919063ffffffff16565b90508051600014806126385750808060200190518101906126389190612fd6565b611a065760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610747565b6060824710156126f85760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610747565b600080866001600160a01b0316858760405161271491906132cf565b60006040518083038185875af1925050503d8060008114612751576040519150601f19603f3d011682016040523d82523d6000602084013e612756565b606091505b509150915061276787838387612a64565b979650505050505050565b60008183106127815781610c7b565b5090919050565b6040516320e8c56560e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906320e8c565906127fb9030907f0000000000000000000000000000000000000000000000000000000000000000908690600090600401612f6b565b6020604051808303816000875af115801561281a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061283e9190612f29565b506040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156128a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128c79190612f29565b90506128d1612c89565b6000612710600b546127106128e69190612f58565b6128ef85612add565b6128f99190612ff3565b612903919061300a565b600054604051630a94245f60e21b815291925073888888888889758f76e7103c6cbf23abbf58f94691632a50917c91612959913091600160281b90046001600160a01b031690889087906004908a9082016132eb565b60408051808303816000875af1158015612977573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061299b9190613262565b5050600d80546001600160d81b0316600160d81b4264ffffffffff1602179055505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663cbe52ae37f0000000000000000000000000000000000000000000000000000000000000000612a1b85612ba3565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa158015612308573d6000803e3d6000fd5b60608315612ad3578251600003612acc576001600160a01b0385163b612acc5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610747565b50816119ce565b6119ce8383612c5f565b6000805460405163a31426d160e01b8152600160281b82046001600160a01b039081166004830152600160c81b90920463ffffffff1660248201527f00000000000000000000000000000000000000000000000000000000000000009091169063a31426d190604401602060405180830381865afa158015612b63573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b879190612f29565b612b99670de0b6b3a764000084612ff3565b61232c919061300a565b6000805460405163a31426d160e01b8152600160281b82046001600160a01b039081166004830152600160c81b90920463ffffffff166024820152670de0b6b3a7640000917f0000000000000000000000000000000000000000000000000000000000000000169063a31426d190604401602060405180830381865afa158015612c31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c559190612f29565b612b999084612ff3565b815115612c6f5781518083602001fd5b8060405162461bcd60e51b81526004016107479190613364565b6040518060a0016040528060006001600160a01b03168152602001600081526020016060815260200160608152602001606081525090565b6001600160a01b038116811461089d57600080fd5b600060208284031215612ce857600080fd5b8135610c7b81612cc1565b80356001600160801b0381168114610c9357600080fd5b600080600060608486031215612d1f57600080fd5b612d2884612cf3565b9250602084013565ffffffffffff81168114612d4357600080fd5b9150604084013564ffffffffff81168114612d5d57600080fd5b809150509250925092565b600060208284031215612d7a57600080fd5b5035919050565b60008060008060808587031215612d9757600080fd5b5050823594602084013594506040840135936060013592509050565b801515811461089d57600080fd5b60008060408385031215612dd457600080fd5b8235612ddf81612cc1565b91506020830135612def81612db3565b809150509250929050565b60005b83811015612e15578181015183820152602001612dfd565b50506000910152565b60008151808452612e36816020860160208601612dfa565b601f01601f19169290920160200192915050565b82151581526040602082015260006119ce6040830184612e1e565b600060208284031215612e7757600080fd5b8135610c7b81612db3565b60008060408385031215612e9557600080fd5b50508035926020909101359150565b60008060408385031215612eb757600080fd5b8235612ec281612cc1565b946020939093013593505050565b600060208284031215612ee257600080fd5b813563ffffffff81168114610c7b57600080fd5b60008060408385031215612f0957600080fd5b612f1283612cf3565b9150612f2060208401612cf3565b90509250929050565b600060208284031215612f3b57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561232c5761232c612f42565b6001600160a01b0394851681529290931660208301526040820152606081019190915260800190565b600080600060608486031215612fa957600080fd5b8351612fb481612cc1565b6020850151909350612fc581612cc1565b6040850151909250612d5d81612cc1565b600060208284031215612fe857600080fd5b8151610c7b81612db3565b808202811582820484141761232c5761232c612f42565b60008261302757634e487b7160e01b600052601260045260246000fd5b500490565b8082018082111561232c5761232c612f42565b6004811061305d57634e487b7160e01b600052602160045260246000fd5b9052565b600081518084526020808501808196508360051b8101915082860160005b858110156131b757828403895281516060815181875280518288015287810151608081818a0152604091508183015160a081818c015285850151955060c091506130cb828c018761303f565b91840151945060e0916130e88b8401876001600160a01b03169052565b84015194506101006131048b8201876001600160a01b03169052565b908401519450610120906131228b8301876001600160a01b03169052565b918401519450610140916131408b8401876001600160a01b03169052565b8401516101608b81019190915290840151610180808c0191909152918401516101a08b01528301516101c08a019190915292506131816101e0890184612e1e565b92508884015191508783038989015261319a8383612e1e565b93810151970196909652509885019893509084019060010161307f565b5091979650505050505050565b60018060a01b038151168252602081015160208301526000604082015160a060408501526131f560a0850182613061565b90506060830151848203606086015261320e8282613061565b915050608083015184820360808601526125b98282612e1e565b6001600160a01b03868116825285166020820152604081018490526060810183905260a060808201819052600090612767908301846131c4565b6000806040838503121561327557600080fd5b505080516020909101519092909150565b60008060006060848603121561329b57600080fd5b83516132a681612db3565b602085015190935061ffff811681146132be57600080fd5b6040850151909250612d5d81612db3565b600082516132e1818460208701612dfa565b9190910192915050565b6001600160a01b03878116825286166020820152604081018590526060810184905282546080820152600183015460a0820152600283015460c0820152600383015460e082015260048301546101008201526101406101208201819052600090613357838201856131c4565b9998505050505050505050565b602081526000610c7b6020830184612e1e56fea264697066735822122080aa6f66d3610913017e3c5a184bde24093d96e2dfe9bd5e62ab7b7ce4dbbc9664736f6c63430008120033a2646970667358221220b51a462e32e4cfad9298aff78f080ace9af6f1ba5ed9397c6648bb8a1eabfb4a64736f6c63430008120033
Verified Source Code Partial Match
Compiler: v0.8.18+commit.87f61d96
EVM: paris
Optimization: Yes (200 runs)
SingleSidedPTcoreFactory.sol 2891 lines
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.18;
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
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 amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}
// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)
/**
* @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;
}
}
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* The default value of {decimals} is 18. To change this, you should override
* this function so it returns a different value.
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC20
* applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the default value returned by this function, unless
* it's overridden.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual override returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
* - the caller must have allowance for ``from``'s tokens of at least
* `amount`.
*/
function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
/**
* @dev Moves `amount` of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
*/
function _transfer(address from, address to, uint256 amount) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
// Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
// decrementing then incrementing.
_balances[to] += amount;
}
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
unchecked {
// Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
_balances[account] += amount;
}
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
// Overflow not possible: amount <= accountBalance <= totalSupply.
_totalSupply -= amount;
}
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Updates `owner` s allowance for `spender` based on spent `amount`.
*
* Does not update the allowance amount in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Might emit an {Approval} event.
*/
function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* has been transferred to `to`.
* - when `from` is zero, `amount` tokens have been minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens have been burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}
}
// TokenizedStrategy interface used for internal view delegateCalls.
// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC4626.sol)
/**
* @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in
* https://eips.ethereum.org/EIPS/eip-4626[ERC-4626].
*
* _Available since v4.7._
*/
interface IERC4626 is IERC20, IERC20Metadata {
event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares);
event Withdraw(
address indexed sender,
address indexed receiver,
address indexed owner,
uint256 assets,
uint256 shares
);
/**
* @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing.
*
* - MUST be an ERC-20 token contract.
* - MUST NOT revert.
*/
function asset() external view returns (address assetTokenAddress);
/**
* @dev Returns the total amount of the underlying asset that is “managed” by Vault.
*
* - SHOULD include any compounding that occurs from yield.
* - MUST be inclusive of any fees that are charged against assets in the Vault.
* - MUST NOT revert.
*/
function totalAssets() external view returns (uint256 totalManagedAssets);
/**
* @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal
* scenario where all the conditions are met.
*
* - MUST NOT be inclusive of any fees that are charged against assets in the Vault.
* - MUST NOT show any variations depending on the caller.
* - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.
* - MUST NOT revert.
*
* NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the
* “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and
* from.
*/
function convertToShares(uint256 assets) external view returns (uint256 shares);
/**
* @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal
* scenario where all the conditions are met.
*
* - MUST NOT be inclusive of any fees that are charged against assets in the Vault.
* - MUST NOT show any variations depending on the caller.
* - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.
* - MUST NOT revert.
*
* NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the
* “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and
* from.
*/
function convertToAssets(uint256 shares) external view returns (uint256 assets);
/**
* @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver,
* through a deposit call.
*
* - MUST return a limited value if receiver is subject to some deposit limit.
* - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited.
* - MUST NOT revert.
*/
function maxDeposit(address receiver) external view returns (uint256 maxAssets);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given
* current on-chain conditions.
*
* - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit
* call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called
* in the same transaction.
* - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the
* deposit would be accepted, regardless if the user has enough tokens approved, etc.
* - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by depositing.
*/
function previewDeposit(uint256 assets) external view returns (uint256 shares);
/**
* @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens.
*
* - MUST emit the Deposit event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
* deposit execution, and are accounted for during deposit.
* - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not
* approving enough underlying tokens to the Vault contract, etc).
*
* NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.
*/
function deposit(uint256 assets, address receiver) external returns (uint256 shares);
/**
* @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call.
* - MUST return a limited value if receiver is subject to some mint limit.
* - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted.
* - MUST NOT revert.
*/
function maxMint(address receiver) external view returns (uint256 maxShares);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given
* current on-chain conditions.
*
* - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call
* in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the
* same transaction.
* - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint
* would be accepted, regardless if the user has enough tokens approved, etc.
* - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by minting.
*/
function previewMint(uint256 shares) external view returns (uint256 assets);
/**
* @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens.
*
* - MUST emit the Deposit event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint
* execution, and are accounted for during mint.
* - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not
* approving enough underlying tokens to the Vault contract, etc).
*
* NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.
*/
function mint(uint256 shares, address receiver) external returns (uint256 assets);
/**
* @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the
* Vault, through a withdraw call.
*
* - MUST return a limited value if owner is subject to some withdrawal limit or timelock.
* - MUST NOT revert.
*/
function maxWithdraw(address owner) external view returns (uint256 maxAssets);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block,
* given current on-chain conditions.
*
* - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw
* call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if
* called
* in the same transaction.
* - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though
* the withdrawal would be accepted, regardless if the user has enough shares, etc.
* - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by depositing.
*/
function previewWithdraw(uint256 assets) external view returns (uint256 shares);
/**
* @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver.
*
* - MUST emit the Withdraw event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
* withdraw execution, and are accounted for during withdraw.
* - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner
* not having enough shares, etc).
*
* Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed.
* Those methods should be performed separately.
*/
function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares);
/**
* @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault,
* through a redeem call.
*
* - MUST return a limited value if owner is subject to some withdrawal limit or timelock.
* - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock.
* - MUST NOT revert.
*/
function maxRedeem(address owner) external view returns (uint256 maxShares);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block,
* given current on-chain conditions.
*
* - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call
* in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the
* same transaction.
* - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the
* redemption would be accepted, regardless if the user has enough shares, etc.
* - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by redeeming.
*/
function previewRedeem(uint256 shares) external view returns (uint256 assets);
/**
* @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver.
*
* - MUST emit the Withdraw event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
* redeem execution, and are accounted for during redeem.
* - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner
* not having enough shares, etc).
*
* NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed.
* Those methods should be performed separately.
*/
function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets);
}
// OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol)
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*
* ==== Security Considerations
*
* There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
* expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
* considered as an intention to spend the allowance in any specific way. The second is that because permits have
* built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
* take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
* generally recommended is:
*
* ```solidity
* function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
* try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
* doThing(..., value);
* }
*
* function doThing(..., uint256 value) public {
* token.safeTransferFrom(msg.sender, address(this), value);
* ...
* }
* ```
*
* Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
* `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
* {SafeERC20-safeTransferFrom}).
*
* Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
* contracts should have entry points that don't rely on permit.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*
* CAUTION: See Security Considerations above.
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
// Interface that implements the 4626 standard and the implementation functions
interface ITokenizedStrategy is IERC4626, IERC20Permit {
/*//////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event StrategyShutdown();
event NewTokenizedStrategy(
address indexed strategy,
address indexed asset,
string apiVersion
);
event Reported(
uint256 profit,
uint256 loss,
uint256 protocolFees,
uint256 performanceFees
);
event UpdatePerformanceFeeRecipient(
address indexed newPerformanceFeeRecipient
);
event UpdateKeeper(address indexed newKeeper);
event UpdatePerformanceFee(uint16 newPerformanceFee);
event UpdateManagement(address indexed newManagement);
event UpdateEmergencyAdmin(address indexed newEmergencyAdmin);
event UpdateProfitMaxUnlockTime(uint256 newProfitMaxUnlockTime);
event UpdatePendingManagement(address indexed newPendingManagement);
/*//////////////////////////////////////////////////////////////
INITIALIZATION
//////////////////////////////////////////////////////////////*/
function initialize(
address _asset,
string memory _name,
address _management,
address _performanceFeeRecipient,
address _keeper
) external;
/*//////////////////////////////////////////////////////////////
NON-STANDARD 4626 OPTIONS
//////////////////////////////////////////////////////////////*/
function withdraw(
uint256 assets,
address receiver,
address owner,
uint256 maxLoss
) external returns (uint256);
function redeem(
uint256 shares,
address receiver,
address owner,
uint256 maxLoss
) external returns (uint256);
/*//////////////////////////////////////////////////////////////
MODIFIER HELPERS
//////////////////////////////////////////////////////////////*/
function requireManagement(address _sender) external view;
function requireKeeperOrManagement(address _sender) external view;
function requireEmergencyAuthorized(address _sender) external view;
/*//////////////////////////////////////////////////////////////
KEEPERS FUNCTIONS
//////////////////////////////////////////////////////////////*/
function tend() external;
function report() external returns (uint256 _profit, uint256 _loss);
/*//////////////////////////////////////////////////////////////
CONSTANTS
//////////////////////////////////////////////////////////////*/
function MAX_FEE() external view returns (uint16);
function FACTORY() external view returns (address);
/*//////////////////////////////////////////////////////////////
GETTERS
//////////////////////////////////////////////////////////////*/
function apiVersion() external view returns (string memory);
function pricePerShare() external view returns (uint256);
function management() external view returns (address);
function pendingManagement() external view returns (address);
function keeper() external view returns (address);
function emergencyAdmin() external view returns (address);
function performanceFee() external view returns (uint16);
function performanceFeeRecipient() external view returns (address);
function fullProfitUnlockDate() external view returns (uint256);
function profitUnlockingRate() external view returns (uint256);
function profitMaxUnlockTime() external view returns (uint256);
function lastReport() external view returns (uint256);
function isShutdown() external view returns (bool);
function unlockedShares() external view returns (uint256);
/*//////////////////////////////////////////////////////////////
SETTERS
//////////////////////////////////////////////////////////////*/
function setPendingManagement(address) external;
function acceptManagement() external;
function setKeeper(address _keeper) external;
function setEmergencyAdmin(address _emergencyAdmin) external;
function setPerformanceFee(uint16 _performanceFee) external;
function setPerformanceFeeRecipient(
address _performanceFeeRecipient
) external;
function setProfitMaxUnlockTime(uint256 _profitMaxUnlockTime) external;
function shutdownStrategy() external;
function emergencyWithdraw(uint256 _amount) external;
}
/**
* @title YearnV3 Base Strategy
* @author yearn.finance
* @notice
* BaseStrategy implements all of the required functionality to
* seamlessly integrate with the `TokenizedStrategy` implementation contract
* allowing anyone to easily build a fully permissionless ERC-4626 compliant
* Vault by inheriting this contract and overriding three simple functions.
* It utilizes an immutable proxy pattern that allows the BaseStrategy
* to remain simple and small. All standard logic is held within the
* `TokenizedStrategy` and is reused over any n strategies all using the
* `fallback` function to delegatecall the implementation so that strategists
* can only be concerned with writing their strategy specific code.
*
* This contract should be inherited and the three main abstract methods
* `_deployFunds`, `_freeFunds` and `_harvestAndReport` implemented to adapt
* the Strategy to the particular needs it has to generate yield. There are
* other optional methods that can be implemented to further customize
* the strategy if desired.
*
* All default storage for the strategy is controlled and updated by the
* `TokenizedStrategy`. The implementation holds a storage struct that
* contains all needed global variables in a manual storage slot. This
* means strategists can feel free to implement their own custom storage
* variables as they need with no concern of collisions. All global variables
* can be viewed within the Strategy by a simple call using the
* `TokenizedStrategy` variable. IE: TokenizedStrategy.globalVariable();.
*/
abstract contract BaseStrategy {
/*//////////////////////////////////////////////////////////////
MODIFIERS
//////////////////////////////////////////////////////////////*/
/**
* @dev Used on TokenizedStrategy callback functions to make sure it is post
* a delegateCall from this address to the TokenizedStrategy.
*/
modifier onlySelf() {
_onlySelf();
_;
}
/**
* @dev Use to assure that the call is coming from the strategies management.
*/
modifier onlyManagement() {
TokenizedStrategy.requireManagement(msg.sender);
_;
}
/**
* @dev Use to assure that the call is coming from either the strategies
* management or the keeper.
*/
modifier onlyKeepers() {
TokenizedStrategy.requireKeeperOrManagement(msg.sender);
_;
}
/**
* @dev Use to assure that the call is coming from either the strategies
* management or the emergency admin.
*/
modifier onlyEmergencyAuthorized() {
TokenizedStrategy.requireEmergencyAuthorized(msg.sender);
_;
}
/**
* @dev Require that the msg.sender is this address.
*/
function _onlySelf() internal view {
require(msg.sender == address(this), "!self");
}
/*//////////////////////////////////////////////////////////////
CONSTANTS
//////////////////////////////////////////////////////////////*/
/**
* @dev This is the address of the TokenizedStrategy implementation
* contract that will be used by all strategies to handle the
* accounting, logic, storage etc.
*
* Any external calls to the that don't hit one of the functions
* defined in this base or the strategy will end up being forwarded
* through the fallback function, which will delegateCall this address.
*
* This address should be the same for every strategy, never be adjusted
* and always be checked before any integration with the Strategy.
*/
address public constant tokenizedStrategyAddress =
0xBB51273D6c746910C7C06fe718f30c936170feD0;
/*//////////////////////////////////////////////////////////////
IMMUTABLES
//////////////////////////////////////////////////////////////*/
/**
* @dev Underlying asset the Strategy is earning yield on.
* Stored here for cheap retrievals within the strategy.
*/
ERC20 internal immutable asset;
/**
* @dev This variable is set to address(this) during initialization of each strategy.
*
* This can be used to retrieve storage data within the strategy
* contract as if it were a linked library.
*
* i.e. uint256 totalAssets = TokenizedStrategy.totalAssets()
*
* Using address(this) will mean any calls using this variable will lead
* to a call to itself. Which will hit the fallback function and
* delegateCall that to the actual TokenizedStrategy.
*/
ITokenizedStrategy internal immutable TokenizedStrategy;
/**
* @notice Used to initialize the strategy on deployment.
*
* This will set the `TokenizedStrategy` variable for easy
* internal view calls to the implementation. As well as
* initializing the default storage variables based on the
* parameters and using the deployer for the permissioned roles.
*
* @param _asset Address of the underlying asset.
* @param _name Name the strategy will use.
*/
constructor(address _asset, string memory _name) {
asset = ERC20(_asset);
// Set instance of the implementation for internal use.
TokenizedStrategy = ITokenizedStrategy(address(this));
// Initialize the strategy's storage variables.
_delegateCall(
abi.encodeCall(
ITokenizedStrategy.initialize,
(_asset, _name, msg.sender, msg.sender, msg.sender)
)
);
// Store the tokenizedStrategyAddress at the standard implementation
// address storage slot so etherscan picks up the interface. This gets
// stored on initialization and never updated.
assembly {
sstore(
// keccak256('eip1967.proxy.implementation' - 1)
0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,
tokenizedStrategyAddress
)
}
}
/*//////////////////////////////////////////////////////////////
NEEDED TO BE OVERRIDDEN BY STRATEGIST
//////////////////////////////////////////////////////////////*/
/**
* @dev Can deploy up to '_amount' of 'asset' in the yield source.
*
* This function is called at the end of a {deposit} or {mint}
* call. Meaning that unless a whitelist is implemented it will
* be entirely permissionless and thus can be sandwiched or otherwise
* manipulated.
*
* @param _amount The amount of 'asset' that the strategy can attempt
* to deposit in the yield source.
*/
function _deployFunds(uint256 _amount) internal virtual;
/**
* @dev Should attempt to free the '_amount' of 'asset'.
*
* NOTE: The amount of 'asset' that is already loose has already
* been accounted for.
*
* This function is called during {withdraw} and {redeem} calls.
* Meaning that unless a whitelist is implemented it will be
* entirely permissionless and thus can be sandwiched or otherwise
* manipulated.
*
* Should not rely on asset.balanceOf(address(this)) calls other than
* for diff accounting purposes.
*
* Any difference between `_amount` and what is actually freed will be
* counted as a loss and passed on to the withdrawer. This means
* care should be taken in times of illiquidity. It may be better to revert
* if withdraws are simply illiquid so not to realize incorrect losses.
*
* @param _amount, The amount of 'asset' to be freed.
*/
function _freeFunds(uint256 _amount) internal virtual;
/**
* @dev Internal function to harvest all rewards, redeploy any idle
* funds and return an accurate accounting of all funds currently
* held by the Strategy.
*
* This should do any needed harvesting, rewards selling, accrual,
* redepositing etc. to get the most accurate view of current assets.
*
* NOTE: All applicable assets including loose assets should be
* accounted for in this function.
*
* Care should be taken when relying on oracles or swap values rather
* than actual amounts as all Strategy profit/loss accounting will
* be done based on this returned value.
*
* This can still be called post a shutdown, a strategist can check
* `TokenizedStrategy.isShutdown()` to decide if funds should be
* redeployed or simply realize any profits/losses.
*
* @return _totalAssets A trusted and accurate account for the total
* amount of 'asset' the strategy currently holds including idle funds.
*/
function _harvestAndReport()
internal
virtual
returns (uint256 _totalAssets);
/*//////////////////////////////////////////////////////////////
OPTIONAL TO OVERRIDE BY STRATEGIST
//////////////////////////////////////////////////////////////*/
/**
* @dev Optional function for strategist to override that can
* be called in between reports.
*
* If '_tend' is used tendTrigger() will also need to be overridden.
*
* This call can only be called by a permissioned role so may be
* through protected relays.
*
* This can be used to harvest and compound rewards, deposit idle funds,
* perform needed position maintenance or anything else that doesn't need
* a full report for.
*
* EX: A strategy that can not deposit funds without getting
* sandwiched can use the tend when a certain threshold
* of idle to totalAssets has been reached.
*
* This will have no effect on PPS of the strategy till report() is called.
*
* @param _totalIdle The current amount of idle funds that are available to deploy.
*/
function _tend(uint256 _totalIdle) internal virtual {}
/**
* @dev Optional trigger to override if tend() will be used by the strategy.
* This must be implemented if the strategy hopes to invoke _tend().
*
* @return . Should return true if tend() should be called by keeper or false if not.
*/
function _tendTrigger() internal view virtual returns (bool) {
return false;
}
/**
* @notice Returns if tend() should be called by a keeper.
*
* @return . Should return true if tend() should be called by keeper or false if not.
* @return . Calldata for the tend call.
*/
function tendTrigger() external view virtual returns (bool, bytes memory) {
return (
// Return the status of the tend trigger.
_tendTrigger(),
// And the needed calldata either way.
abi.encodeWithSelector(ITokenizedStrategy.tend.selector)
);
}
/**
* @notice Gets the max amount of `asset` that an address can deposit.
* @dev Defaults to an unlimited amount for any address. But can
* be overridden by strategists.
*
* This function will be called before any deposit or mints to enforce
* any limits desired by the strategist. This can be used for either a
* tradition...
// [truncated — 112393 bytes total]
Read Contract
GOV 0x180cb47f → address
assetToStrategy 0x4a3e6544 → address
emergencyAdmin 0x70905dce → address
getStrategyByAsset 0xdb90b1e0 → address
isDeployedStrategy 0x0d004424 → bool
keeper 0xaced1661 → address
management 0x88a8d602 → address
oracle 0x7dc0d1d0 → address
performanceFeeRecipient 0xed27f7c9 → address
Write Contract 6 functions
These functions modify contract state and require a wallet transaction to execute.
newSingleSidedPTcore 0xa22d7f63
address _asset
address _market
uint128 _minAssetAmountToPT
uint128 _maxSingleTrade
uint256 _depositLimit
uint128 _depositTrigger
uint48 _maxTendBaseFee
uint40 _minDepositInterval
string _name
returns: address
newSingleSidedPTcore 0xf987e55d
address _asset
address _market
string _name
returns: address
setKeeper 0x748747e6
address _keeper
setManagement 0xd4a22bde
address _management
setPerformanceFeeRecipient 0x6a5f1aa2
address _performanceFeeRecipient
setStrategyByAsset 0x97256094
address _asset
address _strategy
Recent Transactions
No transactions found for this address