Address Contract Verified
Address
0xcEd33DF91AC49415c74BF1b5c218B83a2B8C2f3C
Balance
0 ETH
Nonce
1
Code Size
13617 bytes
Creator
0x392f0Fdf...3E7C at tx 0x75b6751c...3463bf
Indexed Transactions
0
Contract Bytecode
13617 bytes
0x6080604052600436106101b75760003560e01c8063747442d3116100ec578063c9c4bfca1161008a578063e097b3ff11610064578063e097b3ff14610535578063f794062e14610575578063fbd56e4114610595578063fe0d94c1146105b557600080fd5b8063c9c4bfca146104cc578063cc63604a14610500578063da35c6641461052057600080fd5b8063a84eb999116100c6578063a84eb99914610420578063b1bb8d2614610440578063bc20830214610460578063c7f758a81461049b57600080fd5b8063747442d3146103c057806383985259146103e0578063a230c5241461040057600080fd5b80633659cfe6116101595780634f1ef286116101335780634f1ef2861461036357806352d1902d146103765780635c60da1b1461038b5780636a6b2d86146103a057600080fd5b80633659cfe6146102f55780634162169f1461031557806341de68301461034757600080fd5b806329245f561161019557806329245f561461025f5780632caf024b1461027f578063303f4336146102b35780633628731c146102d557600080fd5b806301ffc9a7146101bc5780632358d5a8146101f157806327f1608d1461023c575b600080fd5b3480156101c857600080fd5b506101dc6101d73660046128f8565b6105d5565b60405190151581526020015b60405180910390f35b3480156101fd57600080fd5b506101dc61020c366004612937565b6000828152610191602090815260408083206001600160a01b038516845260020190915290205460ff1692915050565b34801561024857600080fd5b506102516106b5565b6040519081526020016101e8565b34801561026b57600080fd5b506101dc61027a366004612937565b6106d0565b34801561028b57600080fd5b506102517fb1750e46d35a0069c8465b8643e7838d2149a842a2db8ee233d9835590040cad81565b3480156102bf57600080fd5b506102d36102ce36600461297f565b6106e3565b005b3480156102e157600080fd5b506102d36102f03660046129e0565b61072e565b34801561030157600080fd5b506102d3610310366004612a22565b610813565b34801561032157600080fd5b5060c9546001600160a01b03165b6040516001600160a01b0390911681526020016101e8565b34801561035357600080fd5b5060006040516101e89190612a3f565b6102d3610371366004612ad6565b6109b0565b34801561038257600080fd5b50610251610b3a565b34801561039757600080fd5b5061032f610c00565b3480156103ac57600080fd5b506102516103bb366004612b69565b610c38565b3480156103cc57600080fd5b506102d36103db366004612ba0565b610c46565b3480156103ec57600080fd5b506102d36103fb366004612bc5565b610d59565b34801561040c57600080fd5b506101dc61041b366004612a22565b610f11565b34801561042c57600080fd5b506102d361043b3660046129e0565b610f1c565b34801561044c57600080fd5b506101dc61045b366004612c2d565b61100b565b34801561046c57600080fd5b50610193546104829067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016101e8565b3480156104a757600080fd5b506104bb6104b6366004612b69565b611038565b6040516101e8959493929190612d27565b3480156104d857600080fd5b506102517f821b6e3a557148015a918c89e5d092e878a69854a2d1a410635f771bd5a8a3f581565b34801561050c57600080fd5b506101dc61051b366004612b69565b6111ef565b34801561052c57600080fd5b506102516111fa565b34801561054157600080fd5b506101925461055b9060ff811690610100900461ffff1682565b60408051921515835261ffff9091166020830152016101e8565b34801561058157600080fd5b506101dc610590366004612a22565b611206565b3480156105a157600080fd5b506102516105b0366004612db3565b61123b565b3480156105c157600080fd5b506102d36105d0366004612b69565b611585565b60006001600160e01b031982167f8f85278600000000000000000000000000000000000000000000000000000000148061063857506001600160e01b031982167fd200f62300000000000000000000000000000000000000000000000000000000145b8061066c57506001600160e01b031982167f0bb5c60300000000000000000000000000000000000000000000000000000000145b806106a057506001600160e01b031982167fa230c52400000000000000000000000000000000000000000000000000000000145b806106af57506106af826115d0565b92915050565b60006106c261016061160e565b6001600160e01b0316905090565b60006106dc8383611656565b9392505050565b60c9547fb1750e46d35a0069c8465b8643e7838d2149a842a2db8ee233d9835590040cad90610721906001600160a01b031630335b846000366116e1565b61072a826117cf565b5050565b60c9547fb1750e46d35a0069c8465b8643e7838d2149a842a2db8ee233d9835590040cad90610767906001600160a01b03163033610718565b6000826107726106b5565b61077c9190612eae565b905061ffff8111156107ca576040517f125ae34000000000000000000000000000000000000000000000000000000000815261ffff6004820152602481018290526044015b60405180910390fd5b6107d48484611926565b7f11ba20e083ffba533caf1d501ce171aa2acdc05a5601e4e473e449460b0718d88484604051610805929190612ec1565b60405180910390a150505050565b6001600160a01b037f000000000000000000000000ced33df91ac49415c74bf1b5c218b83a2b8c2f3c1630036108b15760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c000000000000000000000000000000000000000060648201526084016107c1565b7f000000000000000000000000ced33df91ac49415c74bf1b5c218b83a2b8c2f3c6001600160a01b031661090c7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b0316146109885760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f7879000000000000000000000000000000000000000060648201526084016107c1565b61099181611a2f565b604080516000808252602082019092526109ad91839190611a68565b50565b6001600160a01b037f000000000000000000000000ced33df91ac49415c74bf1b5c218b83a2b8c2f3c163003610a4e5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c000000000000000000000000000000000000000060648201526084016107c1565b7f000000000000000000000000ced33df91ac49415c74bf1b5c218b83a2b8c2f3c6001600160a01b0316610aa97f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b031614610b255760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f7879000000000000000000000000000000000000000060648201526084016107c1565b610b2e82611a2f565b61072a82826001611a68565b6000306001600160a01b037f000000000000000000000000ced33df91ac49415c74bf1b5c218b83a2b8c2f3c1614610bda5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016107c1565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5b90565b6000610c337f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b905090565b60006106af61016083611c0d565b33610c518382611656565b610c99576040517f37eda872000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b03821660248201526044016107c1565b60008381526101916020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff811660016101009283900461ffff9081168201169092021782556001600160a01b03861680865260028301909452828520805460ff191690911790559051909286917f7b39c92a7e1a86e846edaeff6eba715a046352c596794c2a374269c126a997689190a3828015610d455750610d4584611cc0565b15610d5357610d5384611d03565b50505050565b600054610100900460ff1615808015610d795750600054600160ff909116105b80610d935750303b158015610d93575060005460ff166001145b610e055760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107c1565b6000805460ff191660011790558015610e28576000805461ff0019166101001790555b610e3185611e6b565b61ffff831115610e78576040517f125ae34000000000000000000000000000000000000000000000000000000000815261ffff6004820152602481018490526044016107c1565b610e828484611926565b7f11ba20e083ffba533caf1d501ce171aa2acdc05a5601e4e473e449460b0718d88484604051610eb3929190612ec1565b60405180910390a1610ec4826117cf565b8015610f0a576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b60006106af82611206565b60c9547fb1750e46d35a0069c8465b8643e7838d2149a842a2db8ee233d9835590040cad90610f55906001600160a01b03163033610718565b600082610f606106b5565b610f6a9190612f0f565b6101925490915061ffff61010090910481169082161015610fd057610192546040517f2f621d5a00000000000000000000000000000000000000000000000000000000815261ffff808416600483015261010090920490911660248201526044016107c1565b610fda8484611ef1565b7f0ba413f7646035cae0a4ee999d676078fc8a763d1a36a8ef25e4c10f67d8615d8484604051610805929190612ec1565b6001600160a01b038216600090815261015f6020526040812061102e9083611c0d565b6001149392505050565b60408051608080820183526000808352602080840182905283850182905260609384018290528582526101918152848220805486519485018752600182015461ffff808216875267ffffffffffffffff6201000083048116888701526a010000000000000000000083048116888b0152720100000000000000000000000000000000000090920490911686880152600383018054895181870281018701909a52808a5260ff841699610100909404909216979594909190859084015b828210156111d8576000848152602090819020604080516060810182526003860290920180546001600160a01b031683526001810154938301939093526002830180549293929184019161114790612f22565b80601f016020809104026020016040519081016040528092919081815260200182805461117390612f22565b80156111c05780601f10611195576101008083540402835291602001916111c0565b820191906000526020600020905b8154815290600101906020018083116111a357829003601f168201915b505050505081525050815260200190600101906110f4565b505050509250806004015491505091939590929450565b60006106af82611cc0565b6000610c3361012d5490565b6001600160a01b038116600090815261015f602052604081206112289061160e565b6001600160e01b03166001149050919050565b6101925460009060ff168015611257575061125533611206565b155b1561129c57335b6040517feab993440000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024016107c1565b600060016112a943611f5d565b61019354919003915067ffffffffffffffff808316911611156112cc573361125e565b8367ffffffffffffffff166000036112ee576112e742611f5d565b9350611362565b6112f742611f5d565b67ffffffffffffffff168467ffffffffffffffff1610156113625761131b42611f5d565b6040517f4cc9c0f400000000000000000000000000000000000000000000000000000000815267ffffffffffffffff918216600482015290851660248201526044016107c1565b8367ffffffffffffffff168367ffffffffffffffff1610156113c4576040517f4cc9c0f400000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8086166004830152841660248201526044016107c1565b6113d4338c8c87878e8e8e611fe1565b6000818152610191602052604090206001810180547fffffffffffffffffffffffffffff00000000000000000000000000000000ffff166201000067ffffffffffffffff868116919091027fffffffffffffffffffffffffffff0000000000000000ffffffffffffffffffff16919091176a010000000000000000000089831602177fffffffffffff0000000000000000ffffffffffffffffffffffffffffffffffff8116720100000000000000000000000000000000000092891692909202918217835561019254610100900461ffff167fffffffffffff0000000000000000ffffffffffffffffffffffffffffffff00009091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090921691909117179055909250871561150657600481018890555b60005b8981101561156557816003018b8b8381811061152757611527612f56565b90506020028101906115399190612f6c565b81546001810183556000928352602090922090916003020161155b8282612fd2565b5050600101611509565b508615611576576115768387610c46565b50509998505050505050505050565b61158e81611cc0565b6115c7576040517f9fefd0f1000000000000000000000000000000000000000000000000000000008152600481018290526024016107c1565b6109ad81611d03565b60006001600160e01b031982167fda35c6640000000000000000000000000000000000000000000000000000000014806106af57506106af82612047565b8054600090801561164d5761163683611628600184612f0f565b600091825260209091200190565b5464010000000090046001600160e01b03166106dc565b60009392505050565b60008281526101916020526040812061166e816120e2565b61167c5760009150506106af565b600181015461169c90849062010000900467ffffffffffffffff1661100b565b6116aa5760009150506106af565b6001600160a01b038316600090815260028201602052604090205460ff16156116d75760009150506106af565b5060019392505050565b6040517ffdef91060000000000000000000000000000000000000000000000000000000081526001600160a01b0387169063fdef91069061172e908890889088908890889060040161312e565b602060405180830381865afa15801561174b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176f919061316c565b6117c7576040517f32dbe3b40000000000000000000000000000000000000000000000000000000081526001600160a01b038088166004830152808716602483015285166044820152606481018490526084016107c1565b505050505050565b60006117d96106b5565b905061ffff81166117f06040840160208501613199565b61ffff16111561184b578061180b6040840160208501613199565b6040517f2f621d5a00000000000000000000000000000000000000000000000000000000815261ffff9283166004820152911660248201526044016107c1565b600161185d6040840160208501613199565b61ffff16101561187957600161180b6040840160208501613199565b8161019261188782826131b6565b90505061189343611f5d565b61019380547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790556118dd6040830160208401613199565b61ffff167f7d8a9a57630acbcfb28eb55b1ce0ff7b3d0dc9edea594075a8a6af35278a4cf961190f6020850185613219565b604051901515815260200160405180910390a25050565b60005b81811015611a1f5761195b83838381811061194657611946612f56565b90506020020160208101906105909190612a22565b156119c55782828281811061197257611972612f56565b90506020020160208101906119879190612a22565b6040517fc0b7477d0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024016107c1565b611a15600161015f60008686868181106119e1576119e1612f56565b90506020020160208101906119f69190612a22565b6001600160a01b0316815260208101919091526040016000209061215b565b5050600101611929565b50610d5361016061219183612195565b60c9547f821b6e3a557148015a918c89e5d092e878a69854a2d1a410635f771bd5a8a3f59061072a906001600160a01b03163033610718565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615611aa057611a9b836121cd565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611afa575060408051601f3d908101601f19168201909252611af791810190613236565b60015b611b6c5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f74205555505300000000000000000000000000000000000060648201526084016107c1565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8114611c015760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f7860448201527f6961626c6555554944000000000000000000000000000000000000000000000060648201526084016107c1565b50611a9b838383612298565b6000438210611c5e5760405162461bcd60e51b815260206004820181905260248201527f436865636b706f696e74733a20626c6f636b206e6f7420796574206d696e656460448201526064016107c1565b6000611c69836122bd565b84549091506000611c7c86848385612339565b90508015611caa57611c9386611628600184612f0f565b5464010000000090046001600160e01b0316611cad565b60005b6001600160e01b03169695505050505050565b600081815261019160205260408120611cd8816120e2565b611ce55750600092915050565b6001810154905461ffff918216610100909104909116101592915050565b600081815261019160205260409020805460ff19166001178155610d53611d3260c9546001600160a01b031690565b836101916000868152602001908152602001600020600301805480602002602001604051908101604052809291908181526020016000905b82821015611e4e576000848152602090819020604080516060810182526003860290920180546001600160a01b0316835260018101549383019390935260028301805492939291840191611dbd90612f22565b80601f0160208091040260200160405190810160405280929190818152602001828054611de990612f22565b8015611e365780601f10611e0b57610100808354040283529160200191611e36565b820191906000526020600020905b815481529060010190602001808311611e1957829003601f168201915b50505050508152505081526020019060010190611d6a565b505050600087815261019160205260409020600401549050612397565b600054610100900460ff16611ee85760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107c1565b6109ad81612466565b60005b81811015611f4d57611f1183838381811061194657611946612f56565b611f275782828281811061197257611972612f56565b611f43600061015f60008686868181106119e1576119e1612f56565b5050600101611ef4565b50610d5361016061251283612195565b600067ffffffffffffffff821115611fdd5760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203660448201527f342062697473000000000000000000000000000000000000000000000000000060648201526084016107c1565b5090565b6000611feb612517565b9050886001600160a01b0316817fa6c1f8f4276dc3f243459e13b557c84e8f4e90b2e09070bad5f6909cee687c9288888c8c8a8a8a604051612033979695949392919061324f565b60405180910390a398975050505050505050565b60006001600160e01b031982167f41de68300000000000000000000000000000000000000000000000000000000014806120aa57506001600160e01b031982167f52d1902d00000000000000000000000000000000000000000000000000000000145b806106af57507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b03198316146106af565b6000806120ee42611f5d565b835490915060ff161580156121225750600183015467ffffffffffffffff8083166a01000000000000000000009092041611155b80156106dc5750600183015467ffffffffffffffff80831672010000000000000000000000000000000000009092041610159392505050565b6000806121798461216b436122bd565b61217486612532565b6125b1565b6001600160e01b0391821693501690505b9250929050565b0190565b6000806121c0856121bb6121a88861160e565b6001600160e01b0316868863ffffffff16565b61215b565b915091505b935093915050565b6001600160a01b0381163b61224a5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016107c1565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6122a183612754565b6000825111806122ae5750805b15611a9b57610d538383612794565b600063ffffffff821115611fdd5760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201527f322062697473000000000000000000000000000000000000000000000000000060648201526084016107c1565b60005b8183101561238f576000612350848461289f565b60008781526020902090915063ffffffff86169082015463ffffffff16111561237b57809250612389565b612386816001612eae565b93505b5061233c565b509392505050565b6040517fc71bf3240000000000000000000000000000000000000000000000000000000081526060906000906001600160a01b0387169063c71bf324906123e69088908890889060040161335e565b6000604051808303816000875af1158015612405573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261242d9190810190613387565b604051919350915085907f712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f90600090a294509492505050565b600054610100900460ff166124e35760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107c1565b60c9805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b900390565b60006125216111fa565b9050610bfd61012d80546001019055565b60006001600160e01b03821115611fdd5760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203260448201527f323420626974730000000000000000000000000000000000000000000000000060648201526084016107c1565b8254600090819080156126fa5760006125cf87611628600185612f0f565b60408051808201909152905463ffffffff8082168084526401000000009092046001600160e01b0316602084015291925090871610156126515760405162461bcd60e51b815260206004820152601760248201527f436865636b706f696e743a20696e76616c6964206b657900000000000000000060448201526064016107c1565b805163ffffffff80881691160361269a578461267288611628600186612f0f565b80546001600160e01b03929092166401000000000263ffffffff9092169190911790556126ea565b6040805180820190915263ffffffff80881682526001600160e01b0380881660208085019182528b54600181018d5560008d81529190912094519151909216640100000000029216919091179101555b6020015192508391506121c59050565b50506040805180820190915263ffffffff80851682526001600160e01b0380851660208085019182528854600181018a5560008a8152918220955192519093166401000000000291909316179201919091559050816121c5565b61275d816121cd565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6128135760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016107c1565b600080846001600160a01b03168460405161282e919061348d565b600060405180830381855af49150503d8060008114612869576040519150601f19603f3d011682016040523d82523d6000602084013e61286e565b606091505b509150915061289682826040518060600160405280602781526020016134d5602791396128ba565b95945050505050565b60006128ae600284841861349f565b6106dc90848416612eae565b606083156128c95750816106dc565b6106dc83838151156128de5781518083602001fd5b8060405162461bcd60e51b81526004016107c191906134c1565b60006020828403121561290a57600080fd5b81356001600160e01b0319811681146106dc57600080fd5b6001600160a01b03811681146109ad57600080fd5b6000806040838503121561294a57600080fd5b82359150602083013561295c81612922565b809150509250929050565b60006040828403121561297957600080fd5b50919050565b60006040828403121561299157600080fd5b6106dc8383612967565b60008083601f8401126129ad57600080fd5b50813567ffffffffffffffff8111156129c557600080fd5b6020830191508360208260051b850101111561218a57600080fd5b600080602083850312156129f357600080fd5b823567ffffffffffffffff811115612a0a57600080fd5b612a168582860161299b565b90969095509350505050565b600060208284031215612a3457600080fd5b81356106dc81612922565b6020810160038310612a6157634e487b7160e01b600052602160045260246000fd5b91905290565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612aa657612aa6612a67565b604052919050565b600067ffffffffffffffff821115612ac857612ac8612a67565b50601f01601f191660200190565b60008060408385031215612ae957600080fd5b8235612af481612922565b9150602083013567ffffffffffffffff811115612b1057600080fd5b8301601f81018513612b2157600080fd5b8035612b34612b2f82612aae565b612a7d565b818152866020838501011115612b4957600080fd5b816020840160208301376000602083830101528093505050509250929050565b600060208284031215612b7b57600080fd5b5035919050565b80151581146109ad57600080fd5b8035612b9b81612b82565b919050565b60008060408385031215612bb357600080fd5b82359150602083013561295c81612b82565b60008060008060808587031215612bdb57600080fd5b8435612be681612922565b9350602085013567ffffffffffffffff811115612c0257600080fd5b612c0e8782880161299b565b9094509250612c2290508660408701612967565b905092959194509250565b60008060408385031215612c4057600080fd5b8235612c4b81612922565b946020939093013593505050565b60005b83811015612c74578181015183820152602001612c5c565b50506000910152565b60008151808452612c95816020860160208601612c59565b601f01601f19169290920160200192915050565b600081518084526020808501808196508360051b8101915082860160005b85811015612d1a578284038952815180516001600160a01b031685528581015186860152604090810151606091860182905290612d0681870183612c7d565b9a87019a9550505090840190600101612cc7565b5091979650505050505050565b6000610100871515835261ffff808816602085015280875116604085015250602086015167ffffffffffffffff80821660608601528060408901511660808601528060608901511660a086015250508060c0840152612d8881840186612ca9565b9150508260e08301529695505050505050565b803567ffffffffffffffff81168114612b9b57600080fd5b600080600080600080600080600060e08a8c031215612dd157600080fd5b893567ffffffffffffffff80821115612de957600080fd5b818c0191508c601f830112612dfd57600080fd5b813581811115612e0c57600080fd5b8d6020828501011115612e1e57600080fd5b60209283019b509950908b01359080821115612e3957600080fd5b50612e468c828d0161299b565b90985096505060408a01359450612e5f60608b01612b90565b9350612e6d60808b01612b90565b9250612e7b60a08b01612d9b565b9150612e8960c08b01612d9b565b90509295985092959850929598565b634e487b7160e01b600052601160045260246000fd5b808201808211156106af576106af612e98565b60208082528181018390526000908460408401835b86811015612f04578235612ee981612922565b6001600160a01b031682529183019190830190600101612ed6565b509695505050505050565b818103818111156106af576106af612e98565b600181811c90821680612f3657607f821691505b60208210810361297957634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60008235605e19833603018112612f8257600080fd5b9190910192915050565b601f821115611a9b57600081815260208120601f850160051c81016020861015612fb35750805b601f850160051c820191505b818110156117c757828155600101612fbf565b8135612fdd81612922565b6001600160a01b03811673ffffffffffffffffffffffffffffffffffffffff1983541617825550600160208084013582840155600283016040850135601e1986360301811261302b57600080fd5b8501803567ffffffffffffffff81111561304457600080fd5b803603848301131561305557600080fd5b613069816130638554612f22565b85612f8c565b6000601f82116001811461309f576000831561308757508382018601355b600019600385901b1c1916600184901b1785556130f8565b600085815260209020601f19841690835b828110156130cf578685018901358255938801939089019088016130b0565b50848210156130ee5760001960f88660031b161c198885880101351681555b50508683881b0185555b505050505050505050565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b60006001600160a01b03808816835280871660208401525084604083015260806060830152613161608083018486613103565b979650505050505050565b60006020828403121561317e57600080fd5b81516106dc81612b82565b61ffff811681146109ad57600080fd5b6000602082840312156131ab57600080fd5b81356106dc81613189565b81356131c181612b82565b815460ff19811691151560ff16918217835560208401356131e181613189565b62ffff008160081b16837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008416171784555050505050565b60006020828403121561322b57600080fd5b81356106dc81612b82565b60006020828403121561324857600080fd5b5051919050565b600067ffffffffffffffff808a1683526020818a1681850152604060a08186015261327e60a086018a8c613103565b606086820381880152818983528483019050848a60051b8401018b60005b8c81101561334057601f198684030184528135605e198f36030181126132c157600080fd5b8e0180356132ce81612922565b6001600160a01b0316845280890135898501528781013536829003601e190181126132f857600080fd5b0188810190358a81111561330b57600080fd5b80360382131561331a57600080fd5b868986015261332c8786018284613103565b958a0195945050509087019060010161329c565b50508097505050505050505082608083015298975050505050505050565b8381526060602082015260006133776060830185612ca9565b9050826040830152949350505050565b600080604080848603121561339b57600080fd5b835167ffffffffffffffff808211156133b357600080fd5b818601915086601f8301126133c757600080fd5b81516020828211156133db576133db612a67565b8160051b6133ea828201612a7d565b928352848101820192828101908b85111561340457600080fd5b83870192505b84831015613479578251868111156134225760008081fd5b8701603f81018d136134345760008081fd5b84810151613444612b2f82612aae565b8181528e8b8385010111156134595760008081fd5b613468828883018d8601612c59565b84525050918301919083019061340a565b9990920151989a9899505050505050505050565b60008251612f82818460208701612c59565b6000826134bc57634e487b7160e01b600052601260045260246000fd5b500490565b6020815260006106dc6020830184612c7d56fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220693ee201596a74b33acaa6f6f3a77dddf80efcc496a1cbe5be33b6273801141a64736f6c63430008110033
Verified Source Code Full Match
Compiler: v0.8.17+commit.8df45f5f
EVM: london
Optimization: Yes (2000 runs)
IDAO.sol 138 lines
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.8;
/// @title IDAO
/// @author Aragon Association - 2022-2023
/// @notice The interface required for DAOs within the Aragon App DAO framework.
interface IDAO {
/// @notice The action struct to be consumed by the DAO's `execute` function resulting in an external call.
/// @param to The address to call.
/// @param value The native token value to be sent with the call.
/// @param data The bytes-encoded function selector and calldata for the call.
struct Action {
address to;
uint256 value;
bytes data;
}
/// @notice Checks if an address has permission on a contract via a permission identifier and considers if `ANY_ADDRESS` was used in the granting process.
/// @param _where The address of the contract.
/// @param _who The address of a EOA or contract to give the permissions.
/// @param _permissionId The permission identifier.
/// @param _data The optional data passed to the `PermissionCondition` registered.
/// @return Returns true if the address has permission, false if not.
function hasPermission(
address _where,
address _who,
bytes32 _permissionId,
bytes memory _data
) external view returns (bool);
/// @notice Updates the DAO metadata (e.g., an IPFS hash).
/// @param _metadata The IPFS hash of the new metadata object.
function setMetadata(bytes calldata _metadata) external;
/// @notice Emitted when the DAO metadata is updated.
/// @param metadata The IPFS hash of the new metadata object.
event MetadataSet(bytes metadata);
/// @notice Executes a list of actions. If a zero allow-failure map is provided, a failing action reverts the entire execution. If a non-zero allow-failure map is provided, allowed actions can fail without the entire call being reverted.
/// @param _callId The ID of the call. The definition of the value of `callId` is up to the calling contract and can be used, e.g., as a nonce.
/// @param _actions The array of actions.
/// @param _allowFailureMap A bitmap allowing execution to succeed, even if individual actions might revert. If the bit at index `i` is 1, the execution succeeds even if the `i`th action reverts. A failure map value of 0 requires every action to not revert.
/// @return The array of results obtained from the executed actions in `bytes`.
/// @return The resulting failure map containing the actions have actually failed.
function execute(
bytes32 _callId,
Action[] memory _actions,
uint256 _allowFailureMap
) external returns (bytes[] memory, uint256);
/// @notice Emitted when a proposal is executed.
/// @param actor The address of the caller.
/// @param callId The ID of the call.
/// @param actions The array of actions executed.
/// @param allowFailureMap The allow failure map encoding which actions are allowed to fail.
/// @param failureMap The failure map encoding which actions have failed.
/// @param execResults The array with the results of the executed actions.
/// @dev The value of `callId` is defined by the component/contract calling the execute function. A `Plugin` implementation can use it, for example, as a nonce.
event Executed(
address indexed actor,
bytes32 callId,
Action[] actions,
uint256 allowFailureMap,
uint256 failureMap,
bytes[] execResults
);
/// @notice Emitted when a standard callback is registered.
/// @param interfaceId The ID of the interface.
/// @param callbackSelector The selector of the callback function.
/// @param magicNumber The magic number to be registered for the callback function selector.
event StandardCallbackRegistered(
bytes4 interfaceId,
bytes4 callbackSelector,
bytes4 magicNumber
);
/// @notice Deposits (native) tokens to the DAO contract with a reference string.
/// @param _token The address of the token or address(0) in case of the native token.
/// @param _amount The amount of tokens to deposit.
/// @param _reference The reference describing the deposit reason.
function deposit(address _token, uint256 _amount, string calldata _reference) external payable;
/// @notice Emitted when a token deposit has been made to the DAO.
/// @param sender The address of the sender.
/// @param token The address of the deposited token.
/// @param amount The amount of tokens deposited.
/// @param _reference The reference describing the deposit reason.
event Deposited(
address indexed sender,
address indexed token,
uint256 amount,
string _reference
);
/// @notice Emitted when a native token deposit has been made to the DAO.
/// @dev This event is intended to be emitted in the `receive` function and is therefore bound by the gas limitations for `send`/`transfer` calls introduced by [ERC-2929](https://eips.ethereum.org/EIPS/eip-2929).
/// @param sender The address of the sender.
/// @param amount The amount of native tokens deposited.
event NativeTokenDeposited(address sender, uint256 amount);
/// @notice Setter for the trusted forwarder verifying the meta transaction.
/// @param _trustedForwarder The trusted forwarder address.
function setTrustedForwarder(address _trustedForwarder) external;
/// @notice Getter for the trusted forwarder verifying the meta transaction.
/// @return The trusted forwarder address.
function getTrustedForwarder() external view returns (address);
/// @notice Emitted when a new TrustedForwarder is set on the DAO.
/// @param forwarder the new forwarder address.
event TrustedForwarderSet(address forwarder);
/// @notice Setter for the [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract.
/// @param _signatureValidator The address of the signature validator.
function setSignatureValidator(address _signatureValidator) external;
/// @notice Emitted when the signature validator address is updated.
/// @param signatureValidator The address of the signature validator.
event SignatureValidatorSet(address signatureValidator);
/// @notice Checks whether a signature is valid for the provided hash by forwarding the call to the set [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract.
/// @param _hash The hash of the data to be signed.
/// @param _signature The signature byte array associated with `_hash`.
/// @return Returns the `bytes4` magic value `0x1626ba7e` if the signature is valid.
function isValidSignature(bytes32 _hash, bytes memory _signature) external returns (bytes4);
/// @notice Registers an ERC standard having a callback by registering its [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID and callback function signature.
/// @param _interfaceId The ID of the interface.
/// @param _callbackSelector The selector of the callback function.
/// @param _magicNumber The magic number to be registered for the function signature.
function registerStandardCallback(
bytes4 _interfaceId,
bytes4 _callbackSelector,
bytes4 _magicNumber
) external;
}
auth.sol 33 lines
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.8;
import {IDAO} from "../dao/IDAO.sol";
/// @notice Thrown if a call is unauthorized in the associated DAO.
/// @param dao The associated DAO.
/// @param where The context in which the authorization reverted.
/// @param who The address (EOA or contract) missing the permission.
/// @param permissionId The permission identifier.
error DaoUnauthorized(address dao, address where, address who, bytes32 permissionId);
/// @notice A free function checking if a caller is granted permissions on a target contract via a permission identifier that redirects the approval to a `PermissionCondition` if this was specified in the setup.
/// @param _where The address of the target contract for which `who` receives permission.
/// @param _who The address (EOA or contract) owning the permission.
/// @param _permissionId The permission identifier.
/// @param _data The optional data passed to the `PermissionCondition` registered.
function _auth(
IDAO _dao,
address _where,
address _who,
bytes32 _permissionId,
bytes calldata _data
) view {
if (!_dao.hasPermission(_where, _who, _permissionId, _data))
revert DaoUnauthorized({
dao: address(_dao),
where: _where,
who: _who,
permissionId: _permissionId
});
}
IPlugin.sol 17 lines
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.8;
/// @title IPlugin
/// @author Aragon Association - 2022-2023
/// @notice An interface defining the traits of a plugin.
interface IPlugin {
enum PluginType {
UUPS,
Cloneable,
Constructable
}
/// @notice Returns the plugin's type
function pluginType() external view returns (PluginType);
}
UncheckedMath.sol 33 lines
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.8;
/// @notice Increments an unsigned integer by one without checking the result for overflow errors (using safe math).
/// @param i The number to be incremented.
/// @return The number incremented by one.
function _uncheckedIncrement(uint256 i) pure returns (uint256) {
unchecked {
++i;
}
return i;
}
/// @notice Adds two unsigned integers without checking the result for overflow errors (using safe math).
/// @param a The first summand.
/// @param b The second summand.
/// @return The sum.
function _uncheckedAdd(uint256 a, uint256 b) pure returns (uint256) {
unchecked {
return a + b;
}
}
/// @notice Subtracts two unsigned integers without checking the result for overflow errors (using safe math).
/// @param a The minuend.
/// @param b The subtrahend.
/// @return The difference.
function _uncheckedSub(uint256 a, uint256 b) pure returns (uint256) {
unchecked {
return a - b;
}
}
Addresslist.sol 97 lines
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.8;
import {CheckpointsUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/CheckpointsUpgradeable.sol";
import {_uncheckedAdd, _uncheckedSub} from "../../utils/UncheckedMath.sol";
/// @title Addresslist
/// @author Aragon Association - 2021-2023
/// @notice The majority voting implementation using a list of member addresses.
/// @dev This contract inherits from `MajorityVotingBase` and implements the `IMajorityVoting` interface.
abstract contract Addresslist {
using CheckpointsUpgradeable for CheckpointsUpgradeable.History;
/// @notice The mapping containing the checkpointed history of the address list.
mapping(address => CheckpointsUpgradeable.History) private _addresslistCheckpoints;
/// @notice The checkpointed history of the length of the address list.
CheckpointsUpgradeable.History private _addresslistLengthCheckpoints;
/// @notice Thrown when the address list update is invalid, which can be caused by the addition of an existing member or removal of a non-existing member.
/// @param member The array of member addresses to be added or removed.
error InvalidAddresslistUpdate(address member);
/// @notice Checks if an account is on the address list at a specific block number.
/// @param _account The account address being checked.
/// @param _blockNumber The block number.
/// @return Whether the account is listed at the specified block number.
function isListedAtBlock(
address _account,
uint256 _blockNumber
) public view virtual returns (bool) {
return _addresslistCheckpoints[_account].getAtBlock(_blockNumber) == 1;
}
/// @notice Checks if an account is currently on the address list.
/// @param _account The account address being checked.
/// @return Whether the account is currently listed.
function isListed(address _account) public view virtual returns (bool) {
return _addresslistCheckpoints[_account].latest() == 1;
}
/// @notice Returns the length of the address list at a specific block number.
/// @param _blockNumber The specific block to get the count from. If `0`, then the latest checkpoint value is returned.
/// @return The address list length at the specified block number.
function addresslistLengthAtBlock(uint256 _blockNumber) public view virtual returns (uint256) {
return _addresslistLengthCheckpoints.getAtBlock(_blockNumber);
}
/// @notice Returns the current length of the address list.
/// @return The current address list length.
function addresslistLength() public view virtual returns (uint256) {
return _addresslistLengthCheckpoints.latest();
}
/// @notice Internal function to add new addresses to the address list.
/// @param _newAddresses The new addresses to be added.
function _addAddresses(address[] calldata _newAddresses) internal virtual {
for (uint256 i; i < _newAddresses.length; ) {
if (isListed(_newAddresses[i])) {
revert InvalidAddresslistUpdate(_newAddresses[i]);
}
// Mark the address as listed
_addresslistCheckpoints[_newAddresses[i]].push(1);
unchecked {
++i;
}
}
_addresslistLengthCheckpoints.push(_uncheckedAdd, _newAddresses.length);
}
/// @notice Internal function to remove existing addresses from the address list.
/// @param _exitingAddresses The existing addresses to be removed.
function _removeAddresses(address[] calldata _exitingAddresses) internal virtual {
for (uint256 i; i < _exitingAddresses.length; ) {
if (!isListed(_exitingAddresses[i])) {
revert InvalidAddresslistUpdate(_exitingAddresses[i]);
}
// Mark the address as not listed
_addresslistCheckpoints[_exitingAddresses[i]].push(0);
unchecked {
++i;
}
}
_addresslistLengthCheckpoints.push(_uncheckedSub, _exitingAddresses.length);
}
/// @dev This empty reserved space is put in place to allow future versions to add new
/// variables without shifting down storage in the inheritance chain.
/// https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
uint256[48] private __gap;
}
IProposal.sol 36 lines
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.8;
import {IDAO} from "../../dao/IDAO.sol";
/// @title IProposal
/// @author Aragon Association - 2022-2023
/// @notice An interface to be implemented by DAO plugins that create and execute proposals.
interface IProposal {
/// @notice Emitted when a proposal is created.
/// @param proposalId The ID of the proposal.
/// @param creator The creator of the proposal.
/// @param startDate The start date of the proposal in seconds.
/// @param endDate The end date of the proposal in seconds.
/// @param metadata The metadata of the proposal.
/// @param actions The actions that will be executed if the proposal passes.
/// @param allowFailureMap A bitmap allowing the proposal to succeed, even if individual actions might revert. If the bit at index `i` is 1, the proposal succeeds even if the `i`th action reverts. A failure map value of 0 requires every action to not revert.
event ProposalCreated(
uint256 indexed proposalId,
address indexed creator,
uint64 startDate,
uint64 endDate,
bytes metadata,
IDAO.Action[] actions,
uint256 allowFailureMap
);
/// @notice Emitted when a proposal is executed.
/// @param proposalId The ID of the proposal.
event ProposalExecuted(uint256 indexed proposalId);
/// @notice Returns the proposal count determining the next proposal ID.
/// @return The proposal count.
function proposalCount() external view returns (uint256);
}
PluginUUPSUpgradeable.sol 67 lines
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.8;
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import {IERC1822ProxiableUpgradeable} from "@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol";
import {ERC165Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol";
import {IDAO} from "../dao/IDAO.sol";
import {DaoAuthorizableUpgradeable} from "./dao-authorizable/DaoAuthorizableUpgradeable.sol";
import {IPlugin} from "./IPlugin.sol";
/// @title PluginUUPSUpgradeable
/// @author Aragon Association - 2022-2023
/// @notice An abstract, upgradeable contract to inherit from when creating a plugin being deployed via the UUPS pattern (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)).
abstract contract PluginUUPSUpgradeable is
IPlugin,
ERC165Upgradeable,
UUPSUpgradeable,
DaoAuthorizableUpgradeable
{
// NOTE: When adding new state variables to the contract, the size of `_gap` has to be adapted below as well.
/// @notice Disables the initializers on the implementation contract to prevent it from being left uninitialized.
constructor() {
_disableInitializers();
}
/// @inheritdoc IPlugin
function pluginType() public pure override returns (PluginType) {
return PluginType.UUPS;
}
/// @notice The ID of the permission required to call the `_authorizeUpgrade` function.
bytes32 public constant UPGRADE_PLUGIN_PERMISSION_ID = keccak256("UPGRADE_PLUGIN_PERMISSION");
/// @notice Initializes the plugin by storing the associated DAO.
/// @param _dao The DAO contract.
function __PluginUUPSUpgradeable_init(IDAO _dao) internal virtual onlyInitializing {
__DaoAuthorizableUpgradeable_init(_dao);
}
/// @notice Checks if an interface is supported by this or its parent contract.
/// @param _interfaceId The ID of the interface.
/// @return Returns `true` if the interface is supported.
function supportsInterface(bytes4 _interfaceId) public view virtual override returns (bool) {
return
_interfaceId == type(IPlugin).interfaceId ||
_interfaceId == type(IERC1822ProxiableUpgradeable).interfaceId ||
super.supportsInterface(_interfaceId);
}
/// @notice Returns the address of the implementation contract in the [proxy storage slot](https://eips.ethereum.org/EIPS/eip-1967) slot the [UUPS proxy](https://eips.ethereum.org/EIPS/eip-1822) is pointing to.
/// @return The address of the implementation contract.
function implementation() public view returns (address) {
return _getImplementation();
}
/// @notice Internal method authorizing the upgrade of the contract via the [upgradeability mechanism for UUPS proxies](https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable) (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)).
/// @dev The caller must have the `UPGRADE_PLUGIN_PERMISSION_ID` permission.
function _authorizeUpgrade(
address
) internal virtual override auth(UPGRADE_PLUGIN_PERMISSION_ID) {}
/// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZeppelin's guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)).
uint256[50] private __gap;
}
IMembership.sol 26 lines
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.8;
/// @title IMembership
/// @author Aragon Association - 2022-2023
/// @notice An interface to be implemented by DAO plugins that define membership.
interface IMembership {
/// @notice Emitted when members are added to the DAO plugin.
/// @param members The list of new members being added.
event MembersAdded(address[] members);
/// @notice Emitted when members are removed from the DAO plugin.
/// @param members The list of existing members being removed.
event MembersRemoved(address[] members);
/// @notice Emitted to announce the membership being defined by a contract.
/// @param definingContract The contract defining the membership.
event MembershipContractAnnounced(address indexed definingContract);
/// @notice Checks if an account is a member of the DAO.
/// @param _account The address of the account to be checked.
/// @return Whether the account is a member or not.
/// @dev This function must be implemented in the plugin contract that introduces the members to the DAO.
function isMember(address _account) external view returns (bool);
}
Multisig.sol 460 lines
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity 0.8.17;
import {SafeCastUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol";
import {IDAO} from "../../../core/dao/IDAO.sol";
import {IMembership} from "../../../core/plugin/membership/IMembership.sol";
import {PluginUUPSUpgradeable} from "../../../core/plugin/PluginUUPSUpgradeable.sol";
import {ProposalUpgradeable} from "../../../core/plugin/proposal/ProposalUpgradeable.sol";
import {Addresslist} from "../../utils/Addresslist.sol";
import {IMultisig} from "./IMultisig.sol";
/// @title Multisig - Release 1, Build 2
/// @author Aragon Association - 2022-2023
/// @notice The on-chain multisig governance plugin in which a proposal passes if X out of Y approvals are met.
contract Multisig is
IMultisig,
IMembership,
PluginUUPSUpgradeable,
ProposalUpgradeable,
Addresslist
{
using SafeCastUpgradeable for uint256;
/// @notice A container for proposal-related information.
/// @param executed Whether the proposal is executed or not.
/// @param approvals The number of approvals casted.
/// @param parameters The proposal-specific approve settings at the time of the proposal creation.
/// @param approvers The approves casted by the approvers.
/// @param actions The actions to be executed when the proposal passes.
/// @param _allowFailureMap A bitmap allowing the proposal to succeed, even if individual actions might revert. If the bit at index `i` is 1, the proposal succeeds even if the `i`th action reverts. A failure map value of 0 requires every action to not revert.
struct Proposal {
bool executed;
uint16 approvals;
ProposalParameters parameters;
mapping(address => bool) approvers;
IDAO.Action[] actions;
uint256 allowFailureMap;
}
/// @notice A container for the proposal parameters.
/// @param minApprovals The number of approvals required.
/// @param snapshotBlock The number of the block prior to the proposal creation.
/// @param startDate The timestamp when the proposal starts.
/// @param endDate The timestamp when the proposal expires.
struct ProposalParameters {
uint16 minApprovals;
uint64 snapshotBlock;
uint64 startDate;
uint64 endDate;
}
/// @notice A container for the plugin settings.
/// @param onlyListed Whether only listed addresses can create a proposal or not.
/// @param minApprovals The minimal number of approvals required for a proposal to pass.
struct MultisigSettings {
bool onlyListed;
uint16 minApprovals;
}
/// @notice The [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID of the contract.
bytes4 internal constant MULTISIG_INTERFACE_ID =
this.initialize.selector ^
this.updateMultisigSettings.selector ^
this.createProposal.selector ^
this.getProposal.selector;
/// @notice The ID of the permission required to call the `addAddresses` and `removeAddresses` functions.
bytes32 public constant UPDATE_MULTISIG_SETTINGS_PERMISSION_ID =
keccak256("UPDATE_MULTISIG_SETTINGS_PERMISSION");
/// @notice A mapping between proposal IDs and proposal information.
mapping(uint256 => Proposal) internal proposals;
/// @notice The current plugin settings.
MultisigSettings public multisigSettings;
/// @notice Keeps track at which block number the multisig settings have been changed the last time.
/// @dev This variable prevents a proposal from being created in the same block in which the multisig settings change.
uint64 public lastMultisigSettingsChange;
/// @notice Thrown when a sender is not allowed to create a proposal.
/// @param sender The sender address.
error ProposalCreationForbidden(address sender);
/// @notice Thrown if an approver is not allowed to cast an approve. This can be because the proposal
/// - is not open,
/// - was executed, or
/// - the approver is not on the address list
/// @param proposalId The ID of the proposal.
/// @param sender The address of the sender.
error ApprovalCastForbidden(uint256 proposalId, address sender);
/// @notice Thrown if the proposal execution is forbidden.
/// @param proposalId The ID of the proposal.
error ProposalExecutionForbidden(uint256 proposalId);
/// @notice Thrown if the minimal approvals value is out of bounds (less than 1 or greater than the number of members in the address list).
/// @param limit The maximal value.
/// @param actual The actual value.
error MinApprovalsOutOfBounds(uint16 limit, uint16 actual);
/// @notice Thrown if the address list length is out of bounds.
/// @param limit The limit value.
/// @param actual The actual value.
error AddresslistLengthOutOfBounds(uint16 limit, uint256 actual);
/// @notice Thrown if a date is out of bounds.
/// @param limit The limit value.
/// @param actual The actual value.
error DateOutOfBounds(uint64 limit, uint64 actual);
/// @notice Emitted when a proposal is approve by an approver.
/// @param proposalId The ID of the proposal.
/// @param approver The approver casting the approve.
event Approved(uint256 indexed proposalId, address indexed approver);
/// @notice Emitted when the plugin settings are set.
/// @param onlyListed Whether only listed addresses can create a proposal.
/// @param minApprovals The minimum amount of approvals needed to pass a proposal.
event MultisigSettingsUpdated(bool onlyListed, uint16 indexed minApprovals);
/// @notice Initializes Release 1, Build 2.
/// @dev This method is required to support [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822).
/// @param _dao The IDAO interface of the associated DAO.
/// @param _members The addresses of the initial members to be added.
/// @param _multisigSettings The multisig settings.
function initialize(
IDAO _dao,
address[] calldata _members,
MultisigSettings calldata _multisigSettings
) external initializer {
__PluginUUPSUpgradeable_init(_dao);
if (_members.length > type(uint16).max) {
revert AddresslistLengthOutOfBounds({limit: type(uint16).max, actual: _members.length});
}
_addAddresses(_members);
emit MembersAdded({members: _members});
_updateMultisigSettings(_multisigSettings);
}
/// @notice Checks if this or the parent contract supports an interface by its ID.
/// @param _interfaceId The ID of the interface.
/// @return Returns `true` if the interface is supported.
function supportsInterface(
bytes4 _interfaceId
) public view virtual override(PluginUUPSUpgradeable, ProposalUpgradeable) returns (bool) {
return
_interfaceId == MULTISIG_INTERFACE_ID ||
_interfaceId == type(IMultisig).interfaceId ||
_interfaceId == type(Addresslist).interfaceId ||
_interfaceId == type(IMembership).interfaceId ||
super.supportsInterface(_interfaceId);
}
/// @inheritdoc IMultisig
function addAddresses(
address[] calldata _members
) external auth(UPDATE_MULTISIG_SETTINGS_PERMISSION_ID) {
uint256 newAddresslistLength = addresslistLength() + _members.length;
// Check if the new address list length would be greater than `type(uint16).max`, the maximal number of approvals.
if (newAddresslistLength > type(uint16).max) {
revert AddresslistLengthOutOfBounds({
limit: type(uint16).max,
actual: newAddresslistLength
});
}
_addAddresses(_members);
emit MembersAdded({members: _members});
}
/// @inheritdoc IMultisig
function removeAddresses(
address[] calldata _members
) external auth(UPDATE_MULTISIG_SETTINGS_PERMISSION_ID) {
uint16 newAddresslistLength = uint16(addresslistLength() - _members.length);
// Check if the new address list length would become less than the current minimum number of approvals required.
if (newAddresslistLength < multisigSettings.minApprovals) {
revert MinApprovalsOutOfBounds({
limit: newAddresslistLength,
actual: multisigSettings.minApprovals
});
}
_removeAddresses(_members);
emit MembersRemoved({members: _members});
}
/// @notice Updates the plugin settings.
/// @param _multisigSettings The new settings.
function updateMultisigSettings(
MultisigSettings calldata _multisigSettings
) external auth(UPDATE_MULTISIG_SETTINGS_PERMISSION_ID) {
_updateMultisigSettings(_multisigSettings);
}
/// @notice Creates a new multisig proposal.
/// @param _metadata The metadata of the proposal.
/// @param _actions The actions that will be executed after the proposal passes.
/// @param _allowFailureMap A bitmap allowing the proposal to succeed, even if individual actions might revert. If the bit at index `i` is 1, the proposal succeeds even if the `i`th action reverts. A failure map value of 0 requires every action to not revert.
/// @param _approveProposal If `true`, the sender will approve the proposal.
/// @param _tryExecution If `true`, execution is tried after the vote cast. The call does not revert if early execution is not possible.
/// @param _startDate The start date of the proposal.
/// @param _endDate The end date of the proposal.
/// @return proposalId The ID of the proposal.
function createProposal(
bytes calldata _metadata,
IDAO.Action[] calldata _actions,
uint256 _allowFailureMap,
bool _approveProposal,
bool _tryExecution,
uint64 _startDate,
uint64 _endDate
) external returns (uint256 proposalId) {
if (multisigSettings.onlyListed && !isListed(_msgSender())) {
revert ProposalCreationForbidden(_msgSender());
}
uint64 snapshotBlock;
unchecked {
snapshotBlock = block.number.toUint64() - 1; // The snapshot block must be mined already to protect the transaction against backrunning transactions causing census changes.
}
// Revert if the settings have been changed in the same block as this proposal should be created in.
// This prevents a malicious party from voting with previous addresses and the new settings.
if (lastMultisigSettingsChange > snapshotBlock) {
revert ProposalCreationForbidden(_msgSender());
}
if (_startDate == 0) {
_startDate = block.timestamp.toUint64();
} else if (_startDate < block.timestamp.toUint64()) {
revert DateOutOfBounds({limit: block.timestamp.toUint64(), actual: _startDate});
}
if (_endDate < _startDate) {
revert DateOutOfBounds({limit: _startDate, actual: _endDate});
}
proposalId = _createProposal({
_creator: _msgSender(),
_metadata: _metadata,
_startDate: _startDate,
_endDate: _endDate,
_actions: _actions,
_allowFailureMap: _allowFailureMap
});
// Create the proposal
Proposal storage proposal_ = proposals[proposalId];
proposal_.parameters.snapshotBlock = snapshotBlock;
proposal_.parameters.startDate = _startDate;
proposal_.parameters.endDate = _endDate;
proposal_.parameters.minApprovals = multisigSettings.minApprovals;
// Reduce costs
if (_allowFailureMap != 0) {
proposal_.allowFailureMap = _allowFailureMap;
}
for (uint256 i; i < _actions.length; ) {
proposal_.actions.push(_actions[i]);
unchecked {
++i;
}
}
if (_approveProposal) {
approve(proposalId, _tryExecution);
}
}
/// @inheritdoc IMultisig
function approve(uint256 _proposalId, bool _tryExecution) public {
address approver = _msgSender();
if (!_canApprove(_proposalId, approver)) {
revert ApprovalCastForbidden(_proposalId, approver);
}
Proposal storage proposal_ = proposals[_proposalId];
// As the list can never become more than type(uint16).max(due to addAddresses check)
// It's safe to use unchecked as it would never overflow.
unchecked {
proposal_.approvals += 1;
}
proposal_.approvers[approver] = true;
emit Approved({proposalId: _proposalId, approver: approver});
if (_tryExecution && _canExecute(_proposalId)) {
_execute(_proposalId);
}
}
/// @inheritdoc IMultisig
function canApprove(uint256 _proposalId, address _account) external view returns (bool) {
return _canApprove(_proposalId, _account);
}
/// @inheritdoc IMultisig
function canExecute(uint256 _proposalId) external view returns (bool) {
return _canExecute(_proposalId);
}
/// @notice Returns all information for a proposal vote by its ID.
/// @param _proposalId The ID of the proposal.
/// @return executed Whether the proposal is executed or not.
/// @return approvals The number of approvals casted.
/// @return parameters The parameters of the proposal vote.
/// @return actions The actions to be executed in the associated DAO after the proposal has passed.
/// @param allowFailureMap A bitmap allowing the proposal to succeed, even if individual actions might revert. If the bit at index `i` is 1, the proposal succeeds even if the `i`th action reverts. A failure map value of 0 requires every action to not revert.
function getProposal(
uint256 _proposalId
)
public
view
returns (
bool executed,
uint16 approvals,
ProposalParameters memory parameters,
IDAO.Action[] memory actions,
uint256 allowFailureMap
)
{
Proposal storage proposal_ = proposals[_proposalId];
executed = proposal_.executed;
approvals = proposal_.approvals;
parameters = proposal_.parameters;
actions = proposal_.actions;
allowFailureMap = proposal_.allowFailureMap;
}
/// @inheritdoc IMultisig
function hasApproved(uint256 _proposalId, address _account) public view returns (bool) {
return proposals[_proposalId].approvers[_account];
}
/// @inheritdoc IMultisig
function execute(uint256 _proposalId) public {
if (!_canExecute(_proposalId)) {
revert ProposalExecutionForbidden(_proposalId);
}
_execute(_proposalId);
}
/// @inheritdoc IMembership
function isMember(address _account) external view returns (bool) {
return isListed(_account);
}
/// @notice Internal function to execute a vote. It assumes the queried proposal exists.
/// @param _proposalId The ID of the proposal.
function _execute(uint256 _proposalId) internal {
Proposal storage proposal_ = proposals[_proposalId];
proposal_.executed = true;
_executeProposal(
dao(),
_proposalId,
proposals[_proposalId].actions,
proposals[_proposalId].allowFailureMap
);
}
/// @notice Internal function to check if an account can approve. It assumes the queried proposal exists.
/// @param _proposalId The ID of the proposal.
/// @param _account The account to check.
/// @return Returns `true` if the given account can approve on a certain proposal and `false` otherwise.
function _canApprove(uint256 _proposalId, address _account) internal view returns (bool) {
Proposal storage proposal_ = proposals[_proposalId];
if (!_isProposalOpen(proposal_)) {
// The proposal was executed already
return false;
}
if (!isListedAtBlock(_account, proposal_.parameters.snapshotBlock)) {
// The approver has no voting power.
return false;
}
if (proposal_.approvers[_account]) {
// The approver has already approved
return false;
}
return true;
}
/// @notice Internal function to check if a proposal can be executed. It assumes the queried proposal exists.
/// @param _proposalId The ID of the proposal.
/// @return Returns `true` if the proposal can be executed and `false` otherwise.
function _canExecute(uint256 _proposalId) internal view returns (bool) {
Proposal storage proposal_ = proposals[_proposalId];
// Verify that the proposal has not been executed or expired.
if (!_isProposalOpen(proposal_)) {
return false;
}
return proposal_.approvals >= proposal_.parameters.minApprovals;
}
/// @notice Internal function to check if a proposal vote is still open.
/// @param proposal_ The proposal struct.
/// @return True if the proposal vote is open, false otherwise.
function _isProposalOpen(Proposal storage proposal_) internal view returns (bool) {
uint64 currentTimestamp64 = block.timestamp.toUint64();
return
!proposal_.executed &&
proposal_.parameters.startDate <= currentTimestamp64 &&
proposal_.parameters.endDate >= currentTimestamp64;
}
/// @notice Internal function to update the plugin settings.
/// @param _multisigSettings The new settings.
function _updateMultisigSettings(MultisigSettings calldata _multisigSettings) internal {
uint16 addresslistLength_ = uint16(addresslistLength());
if (_multisigSettings.minApprovals > addresslistLength_) {
revert MinApprovalsOutOfBounds({
limit: addresslistLength_,
actual: _multisigSettings.minApprovals
});
}
if (_multisigSettings.minApprovals < 1) {
revert MinApprovalsOutOfBounds({limit: 1, actual: _multisigSettings.minApprovals});
}
multisigSettings = _multisigSettings;
lastMultisigSettingsChange = block.number.toUint64();
emit MultisigSettingsUpdated({
onlyListed: _multisigSettings.onlyListed,
minApprovals: _multisigSettings.minApprovals
});
}
/// @dev This empty reserved space is put in place to allow future versions to add new
/// variables without shifting down storage in the inheritance chain.
/// https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
uint256[47] private __gap;
}
IMultisig.sol 47 lines
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity 0.8.17;
import {IDAO} from "../../../core/dao/IDAO.sol";
/// @title IMultisig
/// @author Aragon Association - 2023
/// @notice An interface for an on-chain multisig governance plugin in which a proposal passes if X out of Y approvals are met.
interface IMultisig {
/// @notice Adds new members to the address list. Previously, it checks if the new address list length would be greater than `type(uint16).max`, the maximal number of approvals.
/// @param _members The addresses of the members to be added.
function addAddresses(address[] calldata _members) external;
/// @notice Removes existing members from the address list. Previously, it checks if the new address list length is at least as long as the minimum approvals parameter requires. Note that `minApprovals` is must be at least 1 so the address list cannot become empty.
/// @param _members The addresses of the members to be removed.
function removeAddresses(address[] calldata _members) external;
/// @notice Approves and, optionally, executes the proposal.
/// @param _proposalId The ID of the proposal.
/// @param _tryExecution If `true`, execution is tried after the approval cast. The call does not revert if execution is not possible.
function approve(uint256 _proposalId, bool _tryExecution) external;
/// @notice Checks if an account can participate on a proposal vote. This can be because the vote
/// - was executed, or
/// - the voter is not listed.
/// @param _proposalId The proposal Id.
/// @param _account The address of the user to check.
/// @return Returns true if the account is allowed to vote.
/// @dev The function assumes the queried proposal exists.
function canApprove(uint256 _proposalId, address _account) external view returns (bool);
/// @notice Checks if a proposal can be executed.
/// @param _proposalId The ID of the proposal to be checked.
/// @return True if the proposal can be executed, false otherwise.
function canExecute(uint256 _proposalId) external view returns (bool);
/// @notice Returns whether the account has approved the proposal. Note, that this does not check if the account is listed.
/// @param _proposalId The ID of the proposal.
/// @param _account The account address to be checked.
/// @return The vote option cast by a voter for a certain proposal.
function hasApproved(uint256 _proposalId, address _account) external view returns (bool);
/// @notice Executes a proposal.
/// @param _proposalId The ID of the proposal to be executed.
function execute(uint256 _proposalId) external;
}
ProposalUpgradeable.sol 84 lines
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.8;
import {CountersUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol";
import {ERC165Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol";
import "./IProposal.sol";
/// @title ProposalUpgradeable
/// @author Aragon Association - 2022-2023
/// @notice An abstract contract containing the traits and internal functionality to create and execute proposals that can be inherited by upgradeable DAO plugins.
abstract contract ProposalUpgradeable is IProposal, ERC165Upgradeable {
using CountersUpgradeable for CountersUpgradeable.Counter;
/// @notice The incremental ID for proposals and executions.
CountersUpgradeable.Counter private proposalCounter;
/// @inheritdoc IProposal
function proposalCount() public view override returns (uint256) {
return proposalCounter.current();
}
/// @notice Checks if this or the parent contract supports an interface by its ID.
/// @param _interfaceId The ID of the interface.
/// @return Returns `true` if the interface is supported.
function supportsInterface(bytes4 _interfaceId) public view virtual override returns (bool) {
return _interfaceId == type(IProposal).interfaceId || super.supportsInterface(_interfaceId);
}
/// @notice Creates a proposal ID.
/// @return proposalId The proposal ID.
function _createProposalId() internal returns (uint256 proposalId) {
proposalId = proposalCount();
proposalCounter.increment();
}
/// @notice Internal function to create a proposal.
/// @param _metadata The proposal metadata.
/// @param _startDate The start date of the proposal in seconds.
/// @param _endDate The end date of the proposal in seconds.
/// @param _allowFailureMap A bitmap allowing the proposal to succeed, even if individual actions might revert. If the bit at index `i` is 1, the proposal succeeds even if the `i`th action reverts. A failure map value of 0 requires every action to not revert.
/// @param _actions The actions that will be executed after the proposal passes.
/// @return proposalId The ID of the proposal.
function _createProposal(
address _creator,
bytes calldata _metadata,
uint64 _startDate,
uint64 _endDate,
IDAO.Action[] calldata _actions,
uint256 _allowFailureMap
) internal virtual returns (uint256 proposalId) {
proposalId = _createProposalId();
emit ProposalCreated({
proposalId: proposalId,
creator: _creator,
metadata: _metadata,
startDate: _startDate,
endDate: _endDate,
actions: _actions,
allowFailureMap: _allowFailureMap
});
}
/// @notice Internal function to execute a proposal.
/// @param _proposalId The ID of the proposal to be executed.
/// @param _actions The array of actions to be executed.
/// @param _allowFailureMap A bitmap allowing the proposal to succeed, even if individual actions might revert. If the bit at index `i` is 1, the proposal succeeds even if the `i`th action reverts. A failure map value of 0 requires every action to not revert.
/// @return execResults The array with the results of the executed actions.
/// @return failureMap The failure map encoding which actions have failed.
function _executeProposal(
IDAO _dao,
uint256 _proposalId,
IDAO.Action[] memory _actions,
uint256 _allowFailureMap
) internal virtual returns (bytes[] memory execResults, uint256 failureMap) {
(execResults, failureMap) = _dao.execute(bytes32(_proposalId), _actions, _allowFailureMap);
emit ProposalExecuted({proposalId: _proposalId});
}
/// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZeppelin's guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)).
uint256[49] private __gap;
}
DaoAuthorizableUpgradeable.sol 39 lines
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.8;
import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
import {IDAO} from "../../dao/IDAO.sol";
import {_auth} from "../../utils/auth.sol";
/// @title DaoAuthorizableUpgradeable
/// @author Aragon Association - 2022-2023
/// @notice An abstract contract providing a meta-transaction compatible modifier for upgradeable or cloneable contracts to authorize function calls through an associated DAO.
/// @dev Make sure to call `__DaoAuthorizableUpgradeable_init` during initialization of the inheriting contract.
abstract contract DaoAuthorizableUpgradeable is ContextUpgradeable {
/// @notice The associated DAO managing the permissions of inheriting contracts.
IDAO private dao_;
/// @notice Initializes the contract by setting the associated DAO.
/// @param _dao The associated DAO address.
function __DaoAuthorizableUpgradeable_init(IDAO _dao) internal onlyInitializing {
dao_ = _dao;
}
/// @notice Returns the DAO contract.
/// @return The DAO contract.
function dao() public view returns (IDAO) {
return dao_;
}
/// @notice A modifier to make functions on inheriting contracts authorized. Permissions to call the function are checked through the associated DAO's permission manager.
/// @param _permissionId The permission identifier required to call the method this modifier is applied to.
modifier auth(bytes32 _permissionId) {
_auth(dao_, address(this), _msgSender(), _permissionId, _msgData());
_;
}
/// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZeppelin's guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)).
uint256[49] private __gap;
}
AddressUpgradeable.sol 219 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library AddressUpgradeable {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
ContextUpgradeable.sol 37 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.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 ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {
}
function __Context_init_unchained() internal onlyInitializing {
}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}
Initializable.sol 165 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.1) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.2;
import "../../utils/AddressUpgradeable.sol";
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
* @custom:oz-retyped-from bool
*/
uint8 private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint8 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts.
*
* Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a
* constructor.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
bool isTopLevelCall = !_initializing;
require(
(isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),
"Initializable: contract is already initialized"
);
_initialized = 1;
if (isTopLevelCall) {
_initializing = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* A reinitializer may be used after the original initialization step. This is essential to configure modules that
* are added through upgrades and that require initialization.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*
* WARNING: setting the version to 255 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint8 version) {
require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
_initialized = version;
_initializing = true;
_;
_initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
require(_initializing, "Initializable: contract is not initializing");
_;
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
require(!_initializing, "Initializable: contract is initializing");
if (_initialized < type(uint8).max) {
_initialized = type(uint8).max;
emit Initialized(type(uint8).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint8) {
return _initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _initializing;
}
}
CountersUpgradeable.sol 43 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)
pragma solidity ^0.8.0;
/**
* @title Counters
* @author Matt Condon (@shrugs)
* @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
* of elements in a mapping, issuing ERC721 ids, or counting request ids.
*
* Include with `using Counters for Counters.Counter;`
*/
library CountersUpgradeable {
struct Counter {
// This variable should never be directly accessed by users of the library: interactions must be restricted to
// the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
// this feature: see https://github.com/ethereum/solidity/issues/4637
uint256 _value; // default: 0
}
function current(Counter storage counter) internal view returns (uint256) {
return counter._value;
}
function increment(Counter storage counter) internal {
unchecked {
counter._value += 1;
}
}
function decrement(Counter storage counter) internal {
uint256 value = counter._value;
require(value > 0, "Counter: decrement overflow");
unchecked {
counter._value = value - 1;
}
}
function reset(Counter storage counter) internal {
counter._value = 0;
}
}
MathUpgradeable.sol 345 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library MathUpgradeable {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
* with further edits by Uniswap Labs also under MIT license.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1);
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator,
Rounding rounding
) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10**64) {
value /= 10**64;
result += 64;
}
if (value >= 10**32) {
value /= 10**32;
result += 32;
}
if (value >= 10**16) {
value /= 10**16;
result += 16;
}
if (value >= 10**8) {
value /= 10**8;
result += 8;
}
if (value >= 10**4) {
value /= 10**4;
result += 4;
}
if (value >= 10**2) {
value /= 10**2;
result += 2;
}
if (value >= 10**1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256, rounded down, of a positive value.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
}
}
}
UUPSUpgradeable.sol 108 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/UUPSUpgradeable.sol)
pragma solidity ^0.8.0;
import "../../interfaces/draft-IERC1822Upgradeable.sol";
import "../ERC1967/ERC1967UpgradeUpgradeable.sol";
import "./Initializable.sol";
/**
* @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an
* {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.
*
* A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is
* reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing
* `UUPSUpgradeable` with a custom implementation of upgrades.
*
* The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.
*
* _Available since v4.1._
*/
abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {
function __UUPSUpgradeable_init() internal onlyInitializing {
}
function __UUPSUpgradeable_init_unchained() internal onlyInitializing {
}
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
address private immutable __self = address(this);
/**
* @dev Check that the execution is being performed through a delegatecall call and that the execution context is
* a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case
* for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a
* function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to
* fail.
*/
modifier onlyProxy() {
require(address(this) != __self, "Function must be called through delegatecall");
require(_getImplementation() == __self, "Function must be called through active proxy");
_;
}
/**
* @dev Check that the execution is not being performed through a delegate call. This allows a function to be
* callable on the implementing contract but not through proxies.
*/
modifier notDelegated() {
require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall");
_;
}
/**
* @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the
* implementation. It is used to validate the implementation's compatibility when performing an upgrade.
*
* IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
* function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.
*/
function proxiableUUID() external view virtual override notDelegated returns (bytes32) {
return _IMPLEMENTATION_SLOT;
}
/**
* @dev Upgrade the implementation of the proxy to `newImplementation`.
*
* Calls {_authorizeUpgrade}.
*
* Emits an {Upgraded} event.
*/
function upgradeTo(address newImplementation) external virtual onlyProxy {
_authorizeUpgrade(newImplementation);
_upgradeToAndCallUUPS(newImplementation, new bytes(0), false);
}
/**
* @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call
* encoded in `data`.
*
* Calls {_authorizeUpgrade}.
*
* Emits an {Upgraded} event.
*/
function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy {
_authorizeUpgrade(newImplementation);
_upgradeToAndCallUUPS(newImplementation, data, true);
}
/**
* @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by
* {upgradeTo} and {upgradeToAndCall}.
*
* Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.
*
* ```solidity
* function _authorizeUpgrade(address) internal override onlyOwner {}
* ```
*/
function _authorizeUpgrade(address newImplementation) internal virtual;
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}
CheckpointsUpgradeable.sol 554 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.1) (utils/Checkpoints.sol)
// This file was procedurally generated from scripts/generate/templates/Checkpoints.js.
pragma solidity ^0.8.0;
import "./math/MathUpgradeable.sol";
import "./math/SafeCastUpgradeable.sol";
/**
* @dev This library defines the `History` struct, for checkpointing values as they change at different points in
* time, and later looking up past values by block number. See {Votes} as an example.
*
* To create a history of checkpoints define a variable type `Checkpoints.History` in your contract, and store a new
* checkpoint for the current transaction block using the {push} function.
*
* _Available since v4.5._
*/
library CheckpointsUpgradeable {
struct History {
Checkpoint[] _checkpoints;
}
struct Checkpoint {
uint32 _blockNumber;
uint224 _value;
}
/**
* @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one
* before it is returned, or zero otherwise. Because the number returned corresponds to that at the end of the
* block, the requested block number must be in the past, excluding the current block.
*/
function getAtBlock(History storage self, uint256 blockNumber) internal view returns (uint256) {
require(blockNumber < block.number, "Checkpoints: block not yet mined");
uint32 key = SafeCastUpgradeable.toUint32(blockNumber);
uint256 len = self._checkpoints.length;
uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);
return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
}
/**
* @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one
* before it is returned, or zero otherwise. Similar to {upperLookup} but optimized for the case when the searched
* checkpoint is probably "recent", defined as being among the last sqrt(N) checkpoints where N is the number of
* checkpoints.
*/
function getAtProbablyRecentBlock(History storage self, uint256 blockNumber) internal view returns (uint256) {
require(blockNumber < block.number, "Checkpoints: block not yet mined");
uint32 key = SafeCastUpgradeable.toUint32(blockNumber);
uint256 len = self._checkpoints.length;
uint256 low = 0;
uint256 high = len;
if (len > 5) {
uint256 mid = len - MathUpgradeable.sqrt(len);
if (key < _unsafeAccess(self._checkpoints, mid)._blockNumber) {
high = mid;
} else {
low = mid + 1;
}
}
uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);
return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
}
/**
* @dev Pushes a value onto a History so that it is stored as the checkpoint for the current block.
*
* Returns previous value and new value.
*/
function push(History storage self, uint256 value) internal returns (uint256, uint256) {
return _insert(self._checkpoints, SafeCastUpgradeable.toUint32(block.number), SafeCastUpgradeable.toUint224(value));
}
/**
* @dev Pushes a value onto a History, by updating the latest value using binary operation `op`. The new value will
* be set to `op(latest, delta)`.
*
* Returns previous value and new value.
*/
function push(
History storage self,
function(uint256, uint256) view returns (uint256) op,
uint256 delta
) internal returns (uint256, uint256) {
return push(self, op(latest(self), delta));
}
/**
* @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.
*/
function latest(History storage self) internal view returns (uint224) {
uint256 pos = self._checkpoints.length;
return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
}
/**
* @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value
* in the most recent checkpoint.
*/
function latestCheckpoint(History storage self)
internal
view
returns (
bool exists,
uint32 _blockNumber,
uint224 _value
)
{
uint256 pos = self._checkpoints.length;
if (pos == 0) {
return (false, 0, 0);
} else {
Checkpoint memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);
return (true, ckpt._blockNumber, ckpt._value);
}
}
/**
* @dev Returns the number of checkpoint.
*/
function length(History storage self) internal view returns (uint256) {
return self._checkpoints.length;
}
/**
* @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,
* or by updating the last one.
*/
function _insert(
Checkpoint[] storage self,
uint32 key,
uint224 value
) private returns (uint224, uint224) {
uint256 pos = self.length;
if (pos > 0) {
// Copying to memory is important here.
Checkpoint memory last = _unsafeAccess(self, pos - 1);
// Checkpoints keys must be increasing.
require(last._blockNumber <= key, "Checkpoint: invalid key");
// Update or push new checkpoint
if (last._blockNumber == key) {
_unsafeAccess(self, pos - 1)._value = value;
} else {
self.push(Checkpoint({_blockNumber: key, _value: value}));
}
return (last._value, value);
} else {
self.push(Checkpoint({_blockNumber: key, _value: value}));
return (0, value);
}
}
/**
* @dev Return the index of the oldest checkpoint whose key is greater than the search key, or `high` if there is none.
* `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
*
* WARNING: `high` should not be greater than the array's length.
*/
function _upperBinaryLookup(
Checkpoint[] storage self,
uint32 key,
uint256 low,
uint256 high
) private view returns (uint256) {
while (low < high) {
uint256 mid = MathUpgradeable.average(low, high);
if (_unsafeAccess(self, mid)._blockNumber > key) {
high = mid;
} else {
low = mid + 1;
}
}
return high;
}
/**
* @dev Return the index of the oldest checkpoint whose key is greater or equal than the search key, or `high` if there is none.
* `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
*
* WARNING: `high` should not be greater than the array's length.
*/
function _lowerBinaryLookup(
Checkpoint[] storage self,
uint32 key,
uint256 low,
uint256 high
) private view returns (uint256) {
while (low < high) {
uint256 mid = MathUpgradeable.average(low, high);
if (_unsafeAccess(self, mid)._blockNumber < key) {
low = mid + 1;
} else {
high = mid;
}
}
return high;
}
/**
* @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
*/
function _unsafeAccess(Checkpoint[] storage self, uint256 pos) private pure returns (Checkpoint storage result) {
assembly {
mstore(0, self.slot)
result.slot := add(keccak256(0, 0x20), pos)
}
}
struct Trace224 {
Checkpoint224[] _checkpoints;
}
struct Checkpoint224 {
uint32 _key;
uint224 _value;
}
/**
* @dev Pushes a (`key`, `value`) pair into a Trace224 so that it is stored as the checkpoint.
*
* Returns previous value and new value.
*/
function push(
Trace224 storage self,
uint32 key,
uint224 value
) internal returns (uint224, uint224) {
return _insert(self._checkpoints, key, value);
}
/**
* @dev Returns the value in the oldest checkpoint with key greater or equal than the search key, or zero if there is none.
*/
function lowerLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {
uint256 len = self._checkpoints.length;
uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);
return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;
}
/**
* @dev Returns the value in the most recent checkpoint with key lower or equal than the search key.
*/
function upperLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {
uint256 len = self._checkpoints.length;
uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);
return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
}
/**
* @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.
*/
function latest(Trace224 storage self) internal view returns (uint224) {
uint256 pos = self._checkpoints.length;
return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
}
/**
* @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value
* in the most recent checkpoint.
*/
function latestCheckpoint(Trace224 storage self)
internal
view
returns (
bool exists,
uint32 _key,
uint224 _value
)
{
uint256 pos = self._checkpoints.length;
if (pos == 0) {
return (false, 0, 0);
} else {
Checkpoint224 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);
return (true, ckpt._key, ckpt._value);
}
}
/**
* @dev Returns the number of checkpoint.
*/
function length(Trace224 storage self) internal view returns (uint256) {
return self._checkpoints.length;
}
/**
* @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,
* or by updating the last one.
*/
function _insert(
Checkpoint224[] storage self,
uint32 key,
uint224 value
) private returns (uint224, uint224) {
uint256 pos = self.length;
if (pos > 0) {
// Copying to memory is important here.
Checkpoint224 memory last = _unsafeAccess(self, pos - 1);
// Checkpoints keys must be increasing.
require(last._key <= key, "Checkpoint: invalid key");
// Update or push new checkpoint
if (last._key == key) {
_unsafeAccess(self, pos - 1)._value = value;
} else {
self.push(Checkpoint224({_key: key, _value: value}));
}
return (last._value, value);
} else {
self.push(Checkpoint224({_key: key, _value: value}));
return (0, value);
}
}
/**
* @dev Return the index of the oldest checkpoint whose key is greater than the search key, or `high` if there is none.
* `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
*
* WARNING: `high` should not be greater than the array's length.
*/
function _upperBinaryLookup(
Checkpoint224[] storage self,
uint32 key,
uint256 low,
uint256 high
) private view returns (uint256) {
while (low < high) {
uint256 mid = MathUpgradeable.average(low, high);
if (_unsafeAccess(self, mid)._key > key) {
high = mid;
} else {
low = mid + 1;
}
}
return high;
}
/**
* @dev Return the index of the oldest checkpoint whose key is greater or equal than the search key, or `high` if there is none.
* `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
*
* WARNING: `high` should not be greater than the array's length.
*/
function _lowerBinaryLookup(
Checkpoint224[] storage self,
uint32 key,
uint256 low,
uint256 high
) private view returns (uint256) {
while (low < high) {
uint256 mid = MathUpgradeable.average(low, high);
if (_unsafeAccess(self, mid)._key < key) {
low = mid + 1;
} else {
high = mid;
}
}
return high;
}
/**
* @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
*/
function _unsafeAccess(Checkpoint224[] storage self, uint256 pos)
private
pure
returns (Checkpoint224 storage result)
{
assembly {
mstore(0, self.slot)
result.slot := add(keccak256(0, 0x20), pos)
}
}
struct Trace160 {
Checkpoint160[] _checkpoints;
}
struct Checkpoint160 {
uint96 _key;
uint160 _value;
}
/**
* @dev Pushes a (`key`, `value`) pair into a Trace160 so that it is stored as the checkpoint.
*
* Returns previous value and new value.
*/
function push(
Trace160 storage self,
uint96 key,
uint160 value
) internal returns (uint160, uint160) {
return _insert(self._checkpoints, key, value);
}
/**
* @dev Returns the value in the oldest checkpoint with key greater or equal than the search key, or zero if there is none.
*/
function lowerLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {
uint256 len = self._checkpoints.length;
uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);
return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;
}
/**
* @dev Returns the value in the most recent checkpoint with key lower or equal than the search key.
*/
function upperLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {
uint256 len = self._checkpoints.length;
uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);
return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
}
/**
* @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.
*/
function latest(Trace160 storage self) internal view returns (uint160) {
uint256 pos = self._checkpoints.length;
return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
}
/**
* @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value
* in the most recent checkpoint.
*/
function latestCheckpoint(Trace160 storage self)
internal
view
returns (
bool exists,
uint96 _key,
uint160 _value
)
{
uint256 pos = self._checkpoints.length;
if (pos == 0) {
return (false, 0, 0);
} else {
Checkpoint160 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);
return (true, ckpt._key, ckpt._value);
}
}
/**
* @dev Returns the number of checkpoint.
*/
function length(Trace160 storage self) internal view returns (uint256) {
return self._checkpoints.length;
}
/**
* @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,
* or by updating the last one.
*/
function _insert(
Checkpoint160[] storage self,
uint96 key,
uint160 value
) private returns (uint160, uint160) {
uint256 pos = self.length;
if (pos > 0) {
// Copying to memory is important here.
Checkpoint160 memory last = _unsafeAccess(self, pos - 1);
// Checkpoints keys must be increasing.
require(last._key <= key, "Checkpoint: invalid key");
// Update or push new checkpoint
if (last._key == key) {
_unsafeAccess(self, pos - 1)._value = value;
} else {
self.push(Checkpoint160({_key: key, _value: value}));
}
return (last._value, value);
} else {
self.push(Checkpoint160({_key: key, _value: value}));
return (0, value);
}
}
/**
* @dev Return the index of the oldest checkpoint whose key is greater than the search key, or `high` if there is none.
* `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
*
* WARNING: `high` should not be greater than the array's length.
*/
function _upperBinaryLookup(
Checkpoint160[] storage self,
uint96 key,
uint256 low,
uint256 high
) private view returns (uint256) {
while (low < high) {
uint256 mid = MathUpgradeable.average(low, high);
if (_unsafeAccess(self, mid)._key > key) {
high = mid;
} else {
low = mid + 1;
}
}
return high;
}
/**
* @dev Return the index of the oldest checkpoint whose key is greater or equal than the search key, or `high` if there is none.
* `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
*
* WARNING: `high` should not be greater than the array's length.
*/
function _lowerBinaryLookup(
Checkpoint160[] storage self,
uint96 key,
uint256 low,
uint256 high
) private view returns (uint256) {
while (low < high) {
uint256 mid = MathUpgradeable.average(low, high);
if (_unsafeAccess(self, mid)._key < key) {
low = mid + 1;
} else {
high = mid;
}
}
return high;
}
/**
* @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
*/
function _unsafeAccess(Checkpoint160[] storage self, uint256 pos)
private
pure
returns (Checkpoint160 storage result)
{
assembly {
mstore(0, self.slot)
result.slot := add(keccak256(0, 0x20), pos)
}
}
}
StorageSlotUpgradeable.sol 88 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)
pragma solidity ^0.8.0;
/**
* @dev Library for reading and writing primitive types to specific storage slots.
*
* Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
* This library helps with reading and writing to such slots without the need for inline assembly.
*
* The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
*
* Example usage to set ERC1967 implementation slot:
* ```
* contract ERC1967 {
* bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
*
* function _getImplementation() internal view returns (address) {
* return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
* }
*
* function _setImplementation(address newImplementation) internal {
* require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
* StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
* }
* }
* ```
*
* _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._
*/
library StorageSlotUpgradeable {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 value;
}
/**
* @dev Returns an `AddressSlot` with member `value` located at `slot`.
*/
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `BooleanSlot` with member `value` located at `slot`.
*/
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
*/
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Uint256Slot` with member `value` located at `slot`.
*/
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
}
SafeCastUpgradeable.sol 1136 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.
pragma solidity ^0.8.0;
/**
* @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
* checks.
*
* Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
* easily result in undesired exploitation or bugs, since developers usually
* assume that overflows raise errors. `SafeCast` restores this intuition by
* reverting the transaction when such an operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*
* Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
* all math on `uint256` and `int256` and then downcasting.
*/
library SafeCastUpgradeable {
/**
* @dev Returns the downcasted uint248 from uint256, reverting on
* overflow (when the input is greater than largest uint248).
*
* Counterpart to Solidity's `uint248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*
* _Available since v4.7._
*/
function toUint248(uint256 value) internal pure returns (uint248) {
require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits");
return uint248(value);
}
/**
* @dev Returns the downcasted uint240 from uint256, reverting on
* overflow (when the input is greater than largest uint240).
*
* Counterpart to Solidity's `uint240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*
* _Available since v4.7._
*/
function toUint240(uint256 value) internal pure returns (uint240) {
require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits");
return uint240(value);
}
/**
* @dev Returns the downcasted uint232 from uint256, reverting on
* overflow (when the input is greater than largest uint232).
*
* Counterpart to Solidity's `uint232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*
* _Available since v4.7._
*/
function toUint232(uint256 value) internal pure returns (uint232) {
require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits");
return uint232(value);
}
/**
* @dev Returns the downcasted uint224 from uint256, reverting on
* overflow (when the input is greater than largest uint224).
*
* Counterpart to Solidity's `uint224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*
* _Available since v4.2._
*/
function toUint224(uint256 value) internal pure returns (uint224) {
require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
return uint224(value);
}
/**
* @dev Returns the downcasted uint216 from uint256, reverting on
* overflow (when the input is greater than largest uint216).
*
* Counterpart to Solidity's `uint216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*
* _Available since v4.7._
*/
function toUint216(uint256 value) internal pure returns (uint216) {
require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits");
return uint216(value);
}
/**
* @dev Returns the downcasted uint208 from uint256, reverting on
* overflow (when the input is greater than largest uint208).
*
* Counterpart to Solidity's `uint208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*
* _Available since v4.7._
*/
function toUint208(uint256 value) internal pure returns (uint208) {
require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits");
return uint208(value);
}
/**
* @dev Returns the downcasted uint200 from uint256, reverting on
* overflow (when the input is greater than largest uint200).
*
* Counterpart to Solidity's `uint200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*
* _Available since v4.7._
*/
function toUint200(uint256 value) internal pure returns (uint200) {
require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits");
return uint200(value);
}
/**
* @dev Returns the downcasted uint192 from uint256, reverting on
* overflow (when the input is greater than largest uint192).
*
* Counterpart to Solidity's `uint192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*
* _Available since v4.7._
*/
function toUint192(uint256 value) internal pure returns (uint192) {
require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits");
return uint192(value);
}
/**
* @dev Returns the downcasted uint184 from uint256, reverting on
* overflow (when the input is greater than largest uint184).
*
* Counterpart to Solidity's `uint184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*
* _Available since v4.7._
*/
function toUint184(uint256 value) internal pure returns (uint184) {
require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits");
return uint184(value);
}
/**
* @dev Returns the downcasted uint176 from uint256, reverting on
* overflow (when the input is greater than largest uint176).
*
* Counterpart to Solidity's `uint176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*
* _Available since v4.7._
*/
function toUint176(uint256 value) internal pure returns (uint176) {
require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits");
return uint176(value);
}
/**
* @dev Returns the downcasted uint168 from uint256, reverting on
* overflow (when the input is greater than largest uint168).
*
* Counterpart to Solidity's `uint168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*
* _Available since v4.7._
*/
function toUint168(uint256 value) internal pure returns (uint168) {
require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits");
return uint168(value);
}
/**
* @dev Returns the downcasted uint160 from uint256, reverting on
* overflow (when the input is greater than largest uint160).
*
* Counterpart to Solidity's `uint160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*
* _Available since v4.7._
*/
function toUint160(uint256 value) internal pure returns (uint160) {
require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits");
return uint160(value);
}
/**
* @dev Returns the downcasted uint152 from uint256, reverting on
* overflow (when the input is greater than largest uint152).
*
* Counterpart to Solidity's `uint152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*
* _Available since v4.7._
*/
function toUint152(uint256 value) internal pure returns (uint152) {
require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits");
return uint152(value);
}
/**
* @dev Returns the downcasted uint144 from uint256, reverting on
* overflow (when the input is greater than largest uint144).
*
* Counterpart to Solidity's `uint144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*
* _Available since v4.7._
*/
function toUint144(uint256 value) internal pure returns (uint144) {
require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits");
return uint144(value);
}
/**
* @dev Returns the downcasted uint136 from uint256, reverting on
* overflow (when the input is greater than largest uint136).
*
* Counterpart to Solidity's `uint136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*
* _Available since v4.7._
*/
function toUint136(uint256 value) internal pure returns (uint136) {
require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits");
return uint136(value);
}
/**
* @dev Returns the downcasted uint128 from uint256, reverting on
* overflow (when the input is greater than largest uint128).
*
* Counterpart to Solidity's `uint128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v2.5._
*/
function toUint128(uint256 value) internal pure returns (uint128) {
require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
return uint128(value);
}
/**
* @dev Returns the downcasted uint120 from uint256, reverting on
* overflow (when the input is greater than largest uint120).
*
* Counterpart to Solidity's `uint120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*
* _Available since v4.7._
*/
function toUint120(uint256 value) internal pure returns (uint120) {
require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits");
return uint120(value);
}
/**
* @dev Returns the downcasted uint112 from uint256, reverting on
* overflow (when the input is greater than largest uint112).
*
* Counterpart to Solidity's `uint112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*
* _Available since v4.7._
*/
function toUint112(uint256 value) internal pure returns (uint112) {
require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits");
return uint112(value);
}
/**
* @dev Returns the downcasted uint104 from uint256, reverting on
* overflow (when the input is greater than largest uint104).
*
* Counterpart to Solidity's `uint104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*
* _Available since v4.7._
*/
function toUint104(uint256 value) internal pure returns (uint104) {
require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits");
return uint104(value);
}
/**
* @dev Returns the downcasted uint96 from uint256, reverting on
* overflow (when the input is greater than largest uint96).
*
* Counterpart to Solidity's `uint96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*
* _Available since v4.2._
*/
function toUint96(uint256 value) internal pure returns (uint96) {
require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
return uint96(value);
}
/**
* @dev Returns the downcasted uint88 from uint256, reverting on
* overflow (when the input is greater than largest uint88).
*
* Counterpart to Solidity's `uint88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*
* _Available since v4.7._
*/
function toUint88(uint256 value) internal pure returns (uint88) {
require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits");
return uint88(value);
}
/**
* @dev Returns the downcasted uint80 from uint256, reverting on
* overflow (when the input is greater than largest uint80).
*
* Counterpart to Solidity's `uint80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*
* _Available since v4.7._
*/
function toUint80(uint256 value) internal pure returns (uint80) {
require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits");
return uint80(value);
}
/**
* @dev Returns the downcasted uint72 from uint256, reverting on
* overflow (when the input is greater than largest uint72).
*
* Counterpart to Solidity's `uint72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*
* _Available since v4.7._
*/
function toUint72(uint256 value) internal pure returns (uint72) {
require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits");
return uint72(value);
}
/**
* @dev Returns the downcasted uint64 from uint256, reverting on
* overflow (when the input is greater than largest uint64).
*
* Counterpart to Solidity's `uint64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v2.5._
*/
function toUint64(uint256 value) internal pure returns (uint64) {
require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
return uint64(value);
}
/**
* @dev Returns the downcasted uint56 from uint256, reverting on
* overflow (when the input is greater than largest uint56).
*
* Counterpart to Solidity's `uint56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*
* _Available since v4.7._
*/
function toUint56(uint256 value) internal pure returns (uint56) {
require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits");
return uint56(value);
}
/**
* @dev Returns the downcasted uint48 from uint256, reverting on
* overflow (when the input is greater than largest uint48).
*
* Counterpart to Solidity's `uint48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*
* _Available since v4.7._
*/
function toUint48(uint256 value) internal pure returns (uint48) {
require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits");
return uint48(value);
}
/**
* @dev Returns the downcasted uint40 from uint256, reverting on
* overflow (when the input is greater than largest uint40).
*
* Counterpart to Solidity's `uint40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*
* _Available since v4.7._
*/
function toUint40(uint256 value) internal pure returns (uint40) {
require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits");
return uint40(value);
}
/**
* @dev Returns the downcasted uint32 from uint256, reverting on
* overflow (when the input is greater than largest uint32).
*
* Counterpart to Solidity's `uint32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v2.5._
*/
function toUint32(uint256 value) internal pure returns (uint32) {
require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
return uint32(value);
}
/**
* @dev Returns the downcasted uint24 from uint256, reverting on
* overflow (when the input is greater than largest uint24).
*
* Counterpart to Solidity's `uint24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*
* _Available since v4.7._
*/
function toUint24(uint256 value) internal pure returns (uint24) {
require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits");
return uint24(value);
}
/**
* @dev Returns the downcasted uint16 from uint256, reverting on
* overflow (when the input is greater than largest uint16).
*
* Counterpart to Solidity's `uint16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v2.5._
*/
function toUint16(uint256 value) internal pure returns (uint16) {
require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
return uint16(value);
}
/**
* @dev Returns the downcasted uint8 from uint256, reverting on
* overflow (when the input is greater than largest uint8).
*
* Counterpart to Solidity's `uint8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*
* _Available since v2.5._
*/
function toUint8(uint256 value) internal pure returns (uint8) {
require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
return uint8(value);
}
/**
* @dev Converts a signed int256 into an unsigned uint256.
*
* Requirements:
*
* - input must be greater than or equal to 0.
*
* _Available since v3.0._
*/
function toUint256(int256 value) internal pure returns (uint256) {
require(value >= 0, "SafeCast: value must be positive");
return uint256(value);
}
/**
* @dev Returns the downcasted int248 from int256, reverting on
* overflow (when the input is less than smallest int248 or
* greater than largest int248).
*
* Counterpart to Solidity's `int248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*
* _Available since v4.7._
*/
function toInt248(int256 value) internal pure returns (int248 downcasted) {
downcasted = int248(value);
require(downcasted == value, "SafeCast: value doesn't fit in 248 bits");
}
/**
* @dev Returns the downcasted int240 from int256, reverting on
* overflow (when the input is less than smallest int240 or
* greater than largest int240).
*
* Counterpart to Solidity's `int240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*
* _Available since v4.7._
*/
function toInt240(int256 value) internal pure returns (int240 downcasted) {
downcasted = int240(value);
require(downcasted == value, "SafeCast: value doesn't fit in 240 bits");
}
/**
* @dev Returns the downcasted int232 from int256, reverting on
* overflow (when the input is less than smallest int232 or
* greater than largest int232).
*
* Counterpart to Solidity's `int232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*
* _Available since v4.7._
*/
function toInt232(int256 value) internal pure returns (int232 downcasted) {
downcasted = int232(value);
require(downcasted == value, "SafeCast: value doesn't fit in 232 bits");
}
/**
* @dev Returns the downcasted int224 from int256, reverting on
* overflow (when the input is less than smallest int224 or
* greater than largest int224).
*
* Counterpart to Solidity's `int224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*
* _Available since v4.7._
*/
function toInt224(int256 value) internal pure returns (int224 downcasted) {
downcasted = int224(value);
require(downcasted == value, "SafeCast: value doesn't fit in 224 bits");
}
/**
* @dev Returns the downcasted int216 from int256, reverting on
* overflow (when the input is less than smallest int216 or
* greater than largest int216).
*
* Counterpart to Solidity's `int216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*
* _Available since v4.7._
*/
function toInt216(int256 value) internal pure returns (int216 downcasted) {
downcasted = int216(value);
require(downcasted == value, "SafeCast: value doesn't fit in 216 bits");
}
/**
* @dev Returns the downcasted int208 from int256, reverting on
* overflow (when the input is less than smallest int208 or
* greater than largest int208).
*
* Counterpart to Solidity's `int208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*
* _Available since v4.7._
*/
function toInt208(int256 value) internal pure returns (int208 downcasted) {
downcasted = int208(value);
require(downcasted == value, "SafeCast: value doesn't fit in 208 bits");
}
/**
* @dev Returns the downcasted int200 from int256, reverting on
* overflow (when the input is less than smallest int200 or
* greater than largest int200).
*
* Counterpart to Solidity's `int200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*
* _Available since v4.7._
*/
function toInt200(int256 value) internal pure returns (int200 downcasted) {
downcasted = int200(value);
require(downcasted == value, "SafeCast: value doesn't fit in 200 bits");
}
/**
* @dev Returns the downcasted int192 from int256, reverting on
* overflow (when the input is less than smallest int192 or
* greater than largest int192).
*
* Counterpart to Solidity's `int192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*
* _Available since v4.7._
*/
function toInt192(int256 value) internal pure returns (int192 downcasted) {
downcasted = int192(value);
require(downcasted == value, "SafeCast: value doesn't fit in 192 bits");
}
/**
* @dev Returns the downcasted int184 from int256, reverting on
* overflow (when the input is less than smallest int184 or
* greater than largest int184).
*
* Counterpart to Solidity's `int184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*
* _Available since v4.7._
*/
function toInt184(int256 value) internal pure returns (int184 downcasted) {
downcasted = int184(value);
require(downcasted == value, "SafeCast: value doesn't fit in 184 bits");
}
/**
* @dev Returns the downcasted int176 from int256, reverting on
* overflow (when the input is less than smallest int176 or
* greater than largest int176).
*
* Counterpart to Solidity's `int176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*
* _Available since v4.7._
*/
function toInt176(int256 value) internal pure returns (int176 downcasted) {
downcasted = int176(value);
require(downcasted == value, "SafeCast: value doesn't fit in 176 bits");
}
/**
* @dev Returns the downcasted int168 from int256, reverting on
* overflow (when the input is less than smallest int168 or
* greater than largest int168).
*
* Counterpart to Solidity's `int168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*
* _Available since v4.7._
*/
function toInt168(int256 value) internal pure returns (int168 downcasted) {
downcasted = int168(value);
require(downcasted == value, "SafeCast: value doesn't fit in 168 bits");
}
/**
* @dev Returns the downcasted int160 from int256, reverting on
* overflow (when the input is less than smallest int160 or
* greater than largest int160).
*
* Counterpart to Solidity's `int160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*
* _Available since v4.7._
*/
function toInt160(int256 value) internal pure returns (int160 downcasted) {
downcasted = int160(value);
require(downcasted == value, "SafeCast: value doesn't fit in 160 bits");
}
/**
* @dev Returns the downcasted int152 from int256, reverting on
* overflow (when the input is less than smallest int152 or
* greater than largest int152).
*
* Counterpart to Solidity's `int152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*
* _Available since v4.7._
*/
function toInt152(int256 value) internal pure returns (int152 downcasted) {
downcasted = int152(value);
require(downcasted == value, "SafeCast: value doesn't fit in 152 bits");
}
/**
* @dev Returns the downcasted int144 from int256, reverting on
* overflow (when the input is less than smallest int144 or
* greater than largest int144).
*
* Counterpart to Solidity's `int144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*
* _Available since v4.7._
*/
function toInt144(int256 value) internal pure returns (int144 downcasted) {
downcasted = int144(value);
require(downcasted == value, "SafeCast: value doesn't fit in 144 bits");
}
/**
* @dev Returns the downcasted int136 from int256, reverting on
* overflow (when the input is less than smallest int136 or
* greater than largest int136).
*
* Counterpart to Solidity's `int136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*
* _Available since v4.7._
*/
function toInt136(int256 value) internal pure returns (int136 downcasted) {
downcasted = int136(value);
require(downcasted == value, "SafeCast: value doesn't fit in 136 bits");
}
/**
* @dev Returns the downcasted int128 from int256, reverting on
* overflow (when the input is less than smallest int128 or
* greater than largest int128).
*
* Counterpart to Solidity's `int128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v3.1._
*/
function toInt128(int256 value) internal pure returns (int128 downcasted) {
downcasted = int128(value);
require(downcasted == value, "SafeCast: value doesn't fit in 128 bits");
}
/**
* @dev Returns the downcasted int120 from int256, reverting on
* overflow (when the input is less than smallest int120 or
* greater than largest int120).
*
* Counterpart to Solidity's `int120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*
* _Available since v4.7._
*/
function toInt120(int256 value) internal pure returns (int120 downcasted) {
downcasted = int120(value);
require(downcasted == value, "SafeCast: value doesn't fit in 120 bits");
}
/**
* @dev Returns the downcasted int112 from int256, reverting on
* overflow (when the input is less than smallest int112 or
* greater than largest int112).
*
* Counterpart to Solidity's `int112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*
* _Available since v4.7._
*/
function toInt112(int256 value) internal pure returns (int112 downcasted) {
downcasted = int112(value);
require(downcasted == value, "SafeCast: value doesn't fit in 112 bits");
}
/**
* @dev Returns the downcasted int104 from int256, reverting on
* overflow (when the input is less than smallest int104 or
* greater than largest int104).
*
* Counterpart to Solidity's `int104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*
* _Available since v4.7._
*/
function toInt104(int256 value) internal pure returns (int104 downcasted) {
downcasted = int104(value);
require(downcasted == value, "SafeCast: value doesn't fit in 104 bits");
}
/**
* @dev Returns the downcasted int96 from int256, reverting on
* overflow (when the input is less than smallest int96 or
* greater than largest int96).
*
* Counterpart to Solidity's `int96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*
* _Available since v4.7._
*/
function toInt96(int256 value) internal pure returns (int96 downcasted) {
downcasted = int96(value);
require(downcasted == value, "SafeCast: value doesn't fit in 96 bits");
}
/**
* @dev Returns the downcasted int88 from int256, reverting on
* overflow (when the input is less than smallest int88 or
* greater than largest int88).
*
* Counterpart to Solidity's `int88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*
* _Available since v4.7._
*/
function toInt88(int256 value) internal pure returns (int88 downcasted) {
downcasted = int88(value);
require(downcasted == value, "SafeCast: value doesn't fit in 88 bits");
}
/**
* @dev Returns the downcasted int80 from int256, reverting on
* overflow (when the input is less than smallest int80 or
* greater than largest int80).
*
* Counterpart to Solidity's `int80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*
* _Available since v4.7._
*/
function toInt80(int256 value) internal pure returns (int80 downcasted) {
downcasted = int80(value);
require(downcasted == value, "SafeCast: value doesn't fit in 80 bits");
}
/**
* @dev Returns the downcasted int72 from int256, reverting on
* overflow (when the input is less than smallest int72 or
* greater than largest int72).
*
* Counterpart to Solidity's `int72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*
* _Available since v4.7._
*/
function toInt72(int256 value) internal pure returns (int72 downcasted) {
downcasted = int72(value);
require(downcasted == value, "SafeCast: value doesn't fit in 72 bits");
}
/**
* @dev Returns the downcasted int64 from int256, reverting on
* overflow (when the input is less than smallest int64 or
* greater than largest int64).
*
* Counterpart to Solidity's `int64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v3.1._
*/
function toInt64(int256 value) internal pure returns (int64 downcasted) {
downcasted = int64(value);
require(downcasted == value, "SafeCast: value doesn't fit in 64 bits");
}
/**
* @dev Returns the downcasted int56 from int256, reverting on
* overflow (when the input is less than smallest int56 or
* greater than largest int56).
*
* Counterpart to Solidity's `int56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*
* _Available since v4.7._
*/
function toInt56(int256 value) internal pure returns (int56 downcasted) {
downcasted = int56(value);
require(downcasted == value, "SafeCast: value doesn't fit in 56 bits");
}
/**
* @dev Returns the downcasted int48 from int256, reverting on
* overflow (when the input is less than smallest int48 or
* greater than largest int48).
*
* Counterpart to Solidity's `int48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*
* _Available since v4.7._
*/
function toInt48(int256 value) internal pure returns (int48 downcasted) {
downcasted = int48(value);
require(downcasted == value, "SafeCast: value doesn't fit in 48 bits");
}
/**
* @dev Returns the downcasted int40 from int256, reverting on
* overflow (when the input is less than smallest int40 or
* greater than largest int40).
*
* Counterpart to Solidity's `int40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*
* _Available since v4.7._
*/
function toInt40(int256 value) internal pure returns (int40 downcasted) {
downcasted = int40(value);
require(downcasted == value, "SafeCast: value doesn't fit in 40 bits");
}
/**
* @dev Returns the downcasted int32 from int256, reverting on
* overflow (when the input is less than smallest int32 or
* greater than largest int32).
*
* Counterpart to Solidity's `int32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v3.1._
*/
function toInt32(int256 value) internal pure returns (int32 downcasted) {
downcasted = int32(value);
require(downcasted == value, "SafeCast: value doesn't fit in 32 bits");
}
/**
* @dev Returns the downcasted int24 from int256, reverting on
* overflow (when the input is less than smallest int24 or
* greater than largest int24).
*
* Counterpart to Solidity's `int24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*
* _Available since v4.7._
*/
function toInt24(int256 value) internal pure returns (int24 downcasted) {
downcasted = int24(value);
require(downcasted == value, "SafeCast: value doesn't fit in 24 bits");
}
/**
* @dev Returns the downcasted int16 from int256, reverting on
* overflow (when the input is less than smallest int16 or
* greater than largest int16).
*
* Counterpart to Solidity's `int16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v3.1._
*/
function toInt16(int256 value) internal pure returns (int16 downcasted) {
downcasted = int16(value);
require(downcasted == value, "SafeCast: value doesn't fit in 16 bits");
}
/**
* @dev Returns the downcasted int8 from int256, reverting on
* overflow (when the input is less than smallest int8 or
* greater than largest int8).
*
* Counterpart to Solidity's `int8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*
* _Available since v3.1._
*/
function toInt8(int256 value) internal pure returns (int8 downcasted) {
downcasted = int8(value);
require(downcasted == value, "SafeCast: value doesn't fit in 8 bits");
}
/**
* @dev Converts an unsigned uint256 into a signed int256.
*
* Requirements:
*
* - input must be less than or equal to maxInt256.
*
* _Available since v3.0._
*/
function toInt256(uint256 value) internal pure returns (int256) {
// Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
return int256(value);
}
}
IBeaconUpgradeable.sol 16 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)
pragma solidity ^0.8.0;
/**
* @dev This is the interface that {BeaconProxy} expects of its beacon.
*/
interface IBeaconUpgradeable {
/**
* @dev Must return an address that can be used as a delegate call target.
*
* {BeaconProxy} will check that this address is a contract.
*/
function implementation() external view returns (address);
}
draft-IERC1822Upgradeable.sol 20 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)
pragma solidity ^0.8.0;
/**
* @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified
* proxy whose upgrades are fully controlled by the current implementation.
*/
interface IERC1822ProxiableUpgradeable {
/**
* @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation
* address.
*
* IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
* function revert if invoked through a proxy.
*/
function proxiableUUID() external view returns (bytes32);
}
ERC165Upgradeable.sol 42 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./IERC165Upgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {
function __ERC165_init() internal onlyInitializing {
}
function __ERC165_init_unchained() internal onlyInitializing {
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165Upgradeable).interfaceId;
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}
IERC165Upgradeable.sol 25 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165Upgradeable {
/**
* @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[EIP 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);
}
ERC1967UpgradeUpgradeable.sol 212 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)
pragma solidity ^0.8.2;
import "../beacon/IBeaconUpgradeable.sol";
import "../../interfaces/draft-IERC1822Upgradeable.sol";
import "../../utils/AddressUpgradeable.sol";
import "../../utils/StorageSlotUpgradeable.sol";
import "../utils/Initializable.sol";
/**
* @dev This abstract contract provides getters and event emitting update functions for
* https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
*
* _Available since v4.1._
*
* @custom:oz-upgrades-unsafe-allow delegatecall
*/
abstract contract ERC1967UpgradeUpgradeable is Initializable {
function __ERC1967Upgrade_init() internal onlyInitializing {
}
function __ERC1967Upgrade_init_unchained() internal onlyInitializing {
}
// This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1
bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;
/**
* @dev Storage slot with the address of the current implementation.
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/**
* @dev Emitted when the implementation is upgraded.
*/
event Upgraded(address indexed implementation);
/**
* @dev Returns the current implementation address.
*/
function _getImplementation() internal view returns (address) {
return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 implementation slot.
*/
function _setImplementation(address newImplementation) private {
require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract");
StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
}
/**
* @dev Perform implementation upgrade
*
* Emits an {Upgraded} event.
*/
function _upgradeTo(address newImplementation) internal {
_setImplementation(newImplementation);
emit Upgraded(newImplementation);
}
/**
* @dev Perform implementation upgrade with additional setup call.
*
* Emits an {Upgraded} event.
*/
function _upgradeToAndCall(
address newImplementation,
bytes memory data,
bool forceCall
) internal {
_upgradeTo(newImplementation);
if (data.length > 0 || forceCall) {
_functionDelegateCall(newImplementation, data);
}
}
/**
* @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.
*
* Emits an {Upgraded} event.
*/
function _upgradeToAndCallUUPS(
address newImplementation,
bytes memory data,
bool forceCall
) internal {
// Upgrades from old implementations will perform a rollback test. This test requires the new
// implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing
// this special case will break upgrade paths from old UUPS implementation to new ones.
if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) {
_setImplementation(newImplementation);
} else {
try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) {
require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID");
} catch {
revert("ERC1967Upgrade: new implementation is not UUPS");
}
_upgradeToAndCall(newImplementation, data, forceCall);
}
}
/**
* @dev Storage slot with the admin of the contract.
* This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
/**
* @dev Emitted when the admin account has changed.
*/
event AdminChanged(address previousAdmin, address newAdmin);
/**
* @dev Returns the current admin.
*/
function _getAdmin() internal view returns (address) {
return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 admin slot.
*/
function _setAdmin(address newAdmin) private {
require(newAdmin != address(0), "ERC1967: new admin is the zero address");
StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;
}
/**
* @dev Changes the admin of the proxy.
*
* Emits an {AdminChanged} event.
*/
function _changeAdmin(address newAdmin) internal {
emit AdminChanged(_getAdmin(), newAdmin);
_setAdmin(newAdmin);
}
/**
* @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
* This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.
*/
bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;
/**
* @dev Emitted when the beacon is upgraded.
*/
event BeaconUpgraded(address indexed beacon);
/**
* @dev Returns the current beacon.
*/
function _getBeacon() internal view returns (address) {
return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;
}
/**
* @dev Stores a new beacon in the EIP1967 beacon slot.
*/
function _setBeacon(address newBeacon) private {
require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract");
require(
AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),
"ERC1967: beacon implementation is not a contract"
);
StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;
}
/**
* @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does
* not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).
*
* Emits a {BeaconUpgraded} event.
*/
function _upgradeBeaconToAndCall(
address newBeacon,
bytes memory data,
bool forceCall
) internal {
_setBeacon(newBeacon);
emit BeaconUpgraded(newBeacon);
if (data.length > 0 || forceCall) {
_functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);
}
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) {
require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.delegatecall(data);
return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed");
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}
Read Contract
UPDATE_MULTISIG_SETTINGS_PERMISSION_ID 0x2caf024b → bytes32
UPGRADE_PLUGIN_PERMISSION_ID 0xc9c4bfca → bytes32
addresslistLength 0x27f1608d → uint256
addresslistLengthAtBlock 0x6a6b2d86 → uint256
canApprove 0x29245f56 → bool
canExecute 0xcc63604a → bool
dao 0x4162169f → address
getProposal 0xc7f758a8 → bool, uint16, tuple, tuple[], uint256
hasApproved 0x2358d5a8 → bool
implementation 0x5c60da1b → address
isListed 0xf794062e → bool
isListedAtBlock 0xb1bb8d26 → bool
isMember 0xa230c524 → bool
lastMultisigSettingsChange 0xbc208302 → uint64
multisigSettings 0xe097b3ff → bool, uint16
pluginType 0x41de6830 → uint8
proposalCount 0xda35c664 → uint256
proxiableUUID 0x52d1902d → bytes32
supportsInterface 0x01ffc9a7 → bool
Write Contract 9 functions
These functions modify contract state and require a wallet transaction to execute.
addAddresses 0x3628731c
address[] _members
approve 0x747442d3
uint256 _proposalId
bool _tryExecution
createProposal 0xe230f6e3
bytes _metadata
tuple[] _actions
uint256 _allowFailureMap
bool _approveProposal
bool _tryExecution
uint64 _startDate
uint64 _endDate
returns: uint256
execute 0xfe0d94c1
uint256 _proposalId
initialize 0x50b8c89d
address _dao
address[] _members
tuple _multisigSettings
removeAddresses 0xa84eb999
address[] _members
updateMultisigSettings 0x5a756b59
tuple _multisigSettings
upgradeTo 0x3659cfe6
address newImplementation
upgradeToAndCall 0x4f1ef286
address newImplementation
bytes data
Recent Transactions
No transactions found for this address