Address Contract Verified
Address
0x52E4f244f380f8fA51816c8a10A63105dd4De084
Balance
0 ETH
Nonce
1
Code Size
12011 bytes
Creator
0x1b9dFC56...911c at tx 0xf3989f18...679fa0
Indexed Transactions
0
Contract Bytecode
12011 bytes
0x608060405234801561001057600080fd5b50600436106102d35760003560e01c806380f51c1211610186578063b5f2bc47116100e3578063e43581b811610097578063f832138311610071578063f8321383146106b3578063f8734302146106d3578063f9a8ea08146106e657600080fd5b8063e43581b814610661578063eecdac881461068d578063f2fde38b146106a057600080fd5b8063ccf2683b116100c8578063ccf2683b1461060f578063e026049c14610636578063e3eece261461063e57600080fd5b8063b5f2bc47146105dc578063bf4816f0146105fc57600080fd5b80639e422c331161013a578063adc0d57f1161011f578063adc0d57f14610553578063b1c94d94146105c0578063b4d8cedc146105c957600080fd5b80639e422c331461052d578063a00293011461054057600080fd5b80638456cb591161016b5780638456cb59146104ed5780638da5cb5b146104f55780639e25fc5c1461051a57600080fd5b806380f51c12146104b757806382dc1ec4146104da57600080fd5b806352532faa116102345780636b2c0f55116101e8578063715018a6116101cd578063715018a61461047c57806379fcd8ee146104845780637f8560131461049757600080fd5b80636b2c0f55146104615780636ef8d66d1461047457600080fd5b806357d775f81161021957806357d775f8146104265780635c975abb1461042f57806360216b001461044157600080fd5b806352532faa146103f357806354eea7961461041357600080fd5b80633d5721071161028b57806346fbf68e1161027057806346fbf68e1461039457806347b16c6c146103c0578063497bf3b2146103d357600080fd5b80633d572107146103795780633f4ba83a1461038c57600080fd5b806317bdbae5116102bc57806317bdbae514610325578063274cee31146103385780633c4a25d01461036657600080fd5b806301e64725146102d857806315d0975c14610310575b600080fd5b6102fb6102e6366004612911565b600a6020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b61032361031e366004612946565b6106f9565b005b6103236103333660046129bc565b6107c9565b610358610346366004612a28565b600b6020526000908152604090205481565b604051908152602001610307565b610323610374366004612a28565b610967565b610323610387366004612911565b6109bb565b610323610a4f565b6102fb6103a2366004612a28565b6001600160a01b031660009081526001602052604090205460ff1690565b6103236103ce3660046129bc565b610ab8565b6103586103e1366004612a28565b600d6020526000908152604090205481565b610358610401366004612a28565b60086020526000908152604090205481565b610323610421366004612911565b610c4f565b61035860035481565b600054600160a01b900460ff166102fb565b61035861044f366004612a28565b60046020526000908152604090205481565b61032361046f366004612a28565b610cdc565b610323610d2d565b610323610d36565b610323610492366004612946565b610d88565b6103586104a5366004612a28565b600c6020526000908152604090205481565b6102fb6104c5366004612a28565b60016020526000908152604090205460ff1681565b6103236104e8366004612a28565b610df8565b610323610e49565b6000546001600160a01b03165b6040516001600160a01b039091168152602001610307565b610323610528366004612911565b610eb0565b61035861053b366004612a62565b610f7d565b61035861054e366004612a62565b611049565b610595610561366004612911565b60076020526000908152604090208054600182015460028301546003909301546001600160a01b0392831693919092169184565b604080516001600160a01b039586168152949093166020850152918301526060820152608001610307565b61035860095481565b6103236105d7366004612946565b6110dc565b6103586105ea366004612a28565b60056020526000908152604090205481565b61032361060a3660046129bc565b611175565b6105027f0000000000000000000000005427fefa711eff984124bfbb1ab6fbf5e3da182081565b61032361130c565b6102fb61064c366004612a28565b60026020526000908152604090205460ff1681565b6102fb61066f366004612a28565b6001600160a01b031660009081526002602052604090205460ff1690565b61032361069b366004612a28565b611315565b6103236106ae366004612a28565b611366565b6103586106c1366004612a28565b60066020526000908152604090205481565b6103586106e1366004612ac0565b611433565b6103236106f43660046129bc565b61187e565b6000546001600160a01b031633146107465760405162461bcd60e51b81526020600482018190526024820152600080516020612e9683398151915260448201526064015b60405180910390fd5b6001600160a01b0382166000908152600b60205260408120805483929061076e908490612bc5565b90915550506001600160a01b0382166000818152600b6020908152604091829020548251938452908301527feb2f7272b55acd6dea98f5742868e8d2221ad82acb36b2d0cdd00150290e949991015b60405180910390a15050565b3360009081526002602052604090205460ff166108215760405162461bcd60e51b815260206004820152601660248201527521b0b63632b91034b9903737ba1033b7bb32b93737b960511b604482015260640161073d565b8281146108625760405162461bcd60e51b815260206004820152600f60248201526e0d8cadccee8d040dad2e6dac2e8c6d608b1b604482015260640161073d565b60005b838110156109605782828281811061087f5761087f612bdc565b905060200201356008600087878581811061089c5761089c612bdc565b90506020020160208101906108b19190612a28565b6001600160a01b031681526020810191909152604001600020557fceaad6533bfb481492fb3e08ef19297f46611b8fa9de5ef4cf8dc23a56ad09ce8585838181106108fe576108fe612bdc565b90506020020160208101906109139190612a28565b84848481811061092557610925612bdc565b604080516001600160a01b0390951685526020918202939093013590840152500160405180910390a18061095881612bf2565b915050610865565b5050505050565b6000546001600160a01b031633146109af5760405162461bcd60e51b81526020600482018190526024820152600080516020612e96833981519152604482015260640161073d565b6109b881611a15565b50565b3360009081526002602052604090205460ff16610a135760405162461bcd60e51b815260206004820152601660248201527521b0b63632b91034b9903737ba1033b7bb32b93737b960511b604482015260640161073d565b60098190556040518181527fc0a39f234199b125fb93713c4d067bdcebbf691087f87b79c0feb92b156ba8b6906020015b60405180910390a150565b3360009081526001602052604090205460ff16610aae5760405162461bcd60e51b815260206004820152601460248201527f43616c6c6572206973206e6f7420706175736572000000000000000000000000604482015260640161073d565b610ab6611ad2565b565b3360009081526002602052604090205460ff16610b105760405162461bcd60e51b815260206004820152601660248201527521b0b63632b91034b9903737ba1033b7bb32b93737b960511b604482015260640161073d565b828114610b515760405162461bcd60e51b815260206004820152600f60248201526e0d8cadccee8d040dad2e6dac2e8c6d608b1b604482015260640161073d565b60005b8381101561096057828282818110610b6e57610b6e612bdc565b9050602002013560056000878785818110610b8b57610b8b612bdc565b9050602002016020810190610ba09190612a28565b6001600160a01b031681526020810191909152604001600020557f608e49c22994f20b5d3496dca088b88dfd81b4a3e8cc3809ea1e10a320107e89858583818110610bed57610bed612bdc565b9050602002016020810190610c029190612a28565b848484818110610c1457610c14612bdc565b604080516001600160a01b0390951685526020918202939093013590840152500160405180910390a180610c4781612bf2565b915050610b54565b3360009081526002602052604090205460ff16610ca75760405162461bcd60e51b815260206004820152601660248201527521b0b63632b91034b9903737ba1033b7bb32b93737b960511b604482015260640161073d565b60038190556040518181527f2664fec2ff76486ac58ed087310855b648b15b9d19f3de8529e95f7c46b7d6b390602001610a44565b6000546001600160a01b03163314610d245760405162461bcd60e51b81526020600482018190526024820152600080516020612e96833981519152604482015260640161073d565b6109b881611b78565b610ab633611b78565b6000546001600160a01b03163314610d7e5760405162461bcd60e51b81526020600482018190526024820152600080516020612e96833981519152604482015260640161073d565b610ab66000611c31565b6000546001600160a01b03163314610dd05760405162461bcd60e51b81526020600482018190526024820152600080516020612e96833981519152604482015260640161073d565b6001600160a01b0382166000908152600b60205260408120805483929061076e908490612c0d565b6000546001600160a01b03163314610e405760405162461bcd60e51b81526020600482018190526024820152600080516020612e96833981519152604482015260640161073d565b6109b881611c8e565b3360009081526001602052604090205460ff16610ea85760405162461bcd60e51b815260206004820152601460248201527f43616c6c6572206973206e6f7420706175736572000000000000000000000000604482015260640161073d565b610ab6611d4c565b600054600160a01b900460ff1615610efd5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161073d565b6000610f0882611dd4565b6020810151815160408084015190516340c10f1960e01b81526001600160a01b039283166004820152602481019190915292935016906340c10f1990604401600060405180830381600087803b158015610f6157600080fd5b505af1158015610f75573d6000803e3d6000fd5b505050505050565b60008054600160a01b900460ff1615610fcb5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161073d565b6000610fda8787878787611fa6565b60405163079cc67960e41b8152336004820152602481018890529091506001600160a01b038816906379cc6790906044015b600060405180830381600087803b15801561102657600080fd5b505af115801561103a573d6000803e3d6000fd5b50929998505050505050505050565b60008054600160a01b900460ff16156110975760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161073d565b60006110a68787878787611fa6565b604051632770a7eb60e21b8152336004820152602481018890529091506001600160a01b03881690639dc29fac9060440161100c565b6000546001600160a01b031633146111245760405162461bcd60e51b81526020600482018190526024820152600080516020612e96833981519152604482015260640161073d565b6001600160a01b0382166000818152600b6020908152604091829020849055815192835282018390527feb2f7272b55acd6dea98f5742868e8d2221ad82acb36b2d0cdd00150290e949991016107bd565b3360009081526002602052604090205460ff166111cd5760405162461bcd60e51b815260206004820152601660248201527521b0b63632b91034b9903737ba1033b7bb32b93737b960511b604482015260640161073d565b82811461120e5760405162461bcd60e51b815260206004820152600f60248201526e0d8cadccee8d040dad2e6dac2e8c6d608b1b604482015260640161073d565b60005b838110156109605782828281811061122b5761122b612bdc565b90506020020135600c600087878581811061124857611248612bdc565b905060200201602081019061125d9190612a28565b6001600160a01b031681526020810191909152604001600020557f3796cd0b17a8734f8da819920625598e9a18be490f686725282e5383f1d066838585838181106112aa576112aa612bdc565b90506020020160208101906112bf9190612a28565b8484848181106112d1576112d1612bdc565b604080516001600160a01b0390951685526020918202939093013590840152500160405180910390a18061130481612bf2565b915050611211565b610ab633612246565b6000546001600160a01b0316331461135d5760405162461bcd60e51b81526020600482018190526024820152600080516020612e96833981519152604482015260640161073d565b6109b881612246565b6000546001600160a01b031633146113ae5760405162461bcd60e51b81526020600482018190526024820152600080516020612e96833981519152604482015260640161073d565b6001600160a01b03811661142a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161073d565b6109b881611c31565b60008054600160a01b900460ff16156114815760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161073d565b600046306040516020016114be92919091825260601b6bffffffffffffffffffffffff1916602082015263135a5b9d60e21b603482015260380190565b6040516020818303038152906040528051906020012090507f0000000000000000000000005427fefa711eff984124bfbb1ab6fbf5e3da18206001600160a01b031663682dbc22828c8c60405160200161151a93929190612c25565b6040516020818303038152906040528a8a8a8a8a8a6040518863ffffffff1660e01b81526004016115519796959493929190612d8c565b60006040518083038186803b15801561156957600080fd5b505afa15801561157d573d6000803e3d6000fd5b5050505060006115c28b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506122ff92505050565b6020818101518251604080850151606080870151608088015160a089015185516bffffffffffffffffffffffff1998851b8916818b015296841b88166034880152604887019490945290821b8616606886015277ffffffffffffffffffffffffffffffffffffffffffffffff1960c09190911b16607c850152608484019190915230901b90921660a48201528151808203609801815260b890910182528051908301206000818152600a9093529120549192509060ff16156116b65760405162461bcd60e51b815260206004820152600d60248201526c7265636f72642065786973747360981b604482015260640161073d565b6000818152600a602052604090819020805460ff191660011790558251908301516116e19190612461565b81516001600160a01b0316600090815260086020526040902054801580159061170d5750808360400151115b1561172f5761172a82846020015185600001518660400151612579565b61179f565b8251602084015160408086015190516340c10f1960e01b81526001600160a01b03928316600482015260248101919091529116906340c10f1990604401600060405180830381600087803b15801561178657600080fd5b505af115801561179a573d6000803e3d6000fd5b505050505b60408084015184516001600160a01b03166000908152600b6020529182208054919290916117ce908490612c0d565b925050819055507f5bc84ecccfced5bb04bfc7f3efcdbe7f5cd21949ef146811b4d1967fe41f777a8284600001518560200151866040015187608001518860a00151896060015160405161186697969594939291909687526001600160a01b0395861660208801529385166040870152606086019290925267ffffffffffffffff16608085015260a08401521660c082015260e00190565b60405180910390a1509b9a5050505050505050505050565b3360009081526002602052604090205460ff166118d65760405162461bcd60e51b815260206004820152601660248201527521b0b63632b91034b9903737ba1033b7bb32b93737b960511b604482015260640161073d565b8281146119175760405162461bcd60e51b815260206004820152600f60248201526e0d8cadccee8d040dad2e6dac2e8c6d608b1b604482015260640161073d565b60005b838110156109605782828281811061193457611934612bdc565b90506020020135600d600087878581811061195157611951612bdc565b90506020020160208101906119669190612a28565b6001600160a01b031681526020810191909152604001600020557fa3181379f6db47d9037efc6b6e8e3efe8c55ddb090b4f0512c152f97c4e47da58585838181106119b3576119b3612bdc565b90506020020160208101906119c89190612a28565b8484848181106119da576119da612bdc565b604080516001600160a01b0390951685526020918202939093013590840152500160405180910390a180611a0d81612bf2565b91505061191a565b6001600160a01b03811660009081526002602052604090205460ff1615611a7e5760405162461bcd60e51b815260206004820152601b60248201527f4163636f756e7420697320616c726561647920676f7665726e6f720000000000604482015260640161073d565b6001600160a01b038116600081815260026020908152604091829020805460ff1916600117905590519182527fdc5a48d79e2e147530ff63ecdbed5a5a66adb9d5cf339384d5d076da197c40b59101610a44565b600054600160a01b900460ff16611b2b5760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015260640161073d565b6000805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6001600160a01b03811660009081526001602052604090205460ff16611be05760405162461bcd60e51b815260206004820152601560248201527f4163636f756e74206973206e6f74207061757365720000000000000000000000604482015260640161073d565b6001600160a01b038116600081815260016020908152604091829020805460ff1916905590519182527fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e9101610a44565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811660009081526001602052604090205460ff1615611cf75760405162461bcd60e51b815260206004820152601960248201527f4163636f756e7420697320616c72656164792070617573657200000000000000604482015260640161073d565b6001600160a01b038116600081815260016020818152604092839020805460ff191690921790915590519182527f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f89101610a44565b600054600160a01b900460ff1615611d995760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161073d565b6000805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611b5b3390565b604080516080810182526000808252602082018190529181018290526060810191909152600082815260076020908152604091829020825160808101845281546001600160a01b0390811682526001830154169281019290925260028101549282019290925260039091015460608201819052611e935760405162461bcd60e51b815260206004820152601a60248201527f64656c61796564207472616e73666572206e6f74206578697374000000000000604482015260640161073d565b6009548160600151611ea59190612c0d565b4211611ef35760405162461bcd60e51b815260206004820152601d60248201527f64656c61796564207472616e73666572207374696c6c206c6f636b6564000000604482015260640161073d565b6000838152600760209081526040808320805473ffffffffffffffffffffffffffffffffffffffff199081168255600182018054909116905560028101849055600301929092558251908301518383015192517f3b40e5089937425d14cdd96947e5661868357e224af59bd8b24a4b8a330d442693611f9893889390929091909384526001600160a01b03928316602085015291166040830152606082015260800190565b60405180910390a192915050565b6001600160a01b0385166000908152600c6020526040812054851161200d5760405162461bcd60e51b815260206004820152601060248201527f616d6f756e7420746f6f20736d616c6c00000000000000000000000000000000604482015260640161073d565b6001600160a01b0386166000908152600d6020526040902054158061204a57506001600160a01b0386166000908152600d60205260409020548511155b6120965760405162461bcd60e51b815260206004820152601060248201527f616d6f756e7420746f6f206c6172676500000000000000000000000000000000604482015260640161073d565b6001600160a01b0386166000908152600b6020526040812080548792906120be908490612bc5565b90915550506040516bffffffffffffffffffffffff1933606090811b8216602084015288811b821660348401526048830188905277ffffffffffffffffffffffffffffffffffffffffffffffff1960c088811b8216606886015287831b8416607086015286811b8216608486015246901b16608c84015230901b16609482015260009060a80160408051601f1981840301815291815281516020928301206000818152600a90935291205490915060ff16156121ac5760405162461bcd60e51b815260206004820152600d60248201526c7265636f72642065786973747360981b604482015260640161073d565b6000818152600a6020908152604091829020805460ff1916600117905581518381526001600160a01b038a81169282019290925233928101929092526060820188905267ffffffffffffffff878116608084015290861660a0830152841660c08201527f6298d7b58f235730b3b399dc5c282f15dae8b022e5fbbf89cee21fd83c8810a39060e00160405180910390a19695505050505050565b6001600160a01b03811660009081526002602052604090205460ff166122ae5760405162461bcd60e51b815260206004820152601760248201527f4163636f756e74206973206e6f7420676f7665726e6f72000000000000000000604482015260640161073d565b6001600160a01b038116600081815260026020908152604091829020805460ff1916905590519182527f1ebe834e73d60a5fec822c1e1727d34bc79f2ad977ed504581cc1822fe20fb5b9101610a44565b6040805160c08101825260008082526020808301829052828401829052606083018290526080830182905260a0830182905283518085019094528184528301849052909190805b602083015151835110156124595761235d83612699565b9092509050816001141561238c5761237c612377846126d3565b612790565b6001600160a01b03168452612346565b81600214156123b4576123a1612377846126d3565b6001600160a01b03166020850152612346565b81600314156123d8576123ce6123c9846126d3565b6127a1565b6040850152612346565b8160041415612400576123ed612377846126d3565b6001600160a01b03166060850152612346565b816005141561242657612412836127d8565b67ffffffffffffffff166080850152612346565b816006141561244a5761244061243b846126d3565b61285a565b60a0850152612346565b6124548382612872565b612346565b505050919050565b60035461246c575050565b6001600160a01b0382166000908152600560205260409020548061248f57505050565b6001600160a01b038316600090815260046020526040812054600354909142916124b98184612e28565b6124c39190612e4a565b6001600160a01b0387166000908152600660205260409020549091508111156124ee578492506124fb565b6124f88584612c0d565b92505b8383111561254b5760405162461bcd60e51b815260206004820152601260248201527f766f6c756d652065786365656473206361700000000000000000000000000000604482015260640161073d565b506001600160a01b039094166000908152600460209081526040808320939093556006905220929092555050565b600084815260076020526040902060030154156125d85760405162461bcd60e51b815260206004820152601f60248201527f64656c61796564207472616e7366657220616c72656164792065786973747300604482015260640161073d565b604080516080810182526001600160a01b0380861682528481166020808401918252838501868152426060860190815260008b81526007909352918690209451855490851673ffffffffffffffffffffffffffffffffffffffff1991821617865592516001860180549190951693169290921790925551600283015551600390910155517fcbcfffe5102114216a85d3aceb14ad4b81a3935b1b5c468fadf3889eb9c5dce69061268b9086815260200190565b60405180910390a150505050565b60008060006126a7846127d8565b90506126b4600882612e28565b92508060071660058111156126cb576126cb612e69565b915050915091565b606060006126e0836127d8565b905060008184600001516126f49190612c0d565b905083602001515181111561270857600080fd5b8167ffffffffffffffff81111561272157612721612e7f565b6040519080825280601f01601f19166020018201604052801561274b576020820181803683370190505b50602080860151865192955091818601919083010160005b8581101561278557818101518382015261277e602082612c0d565b9050612763565b505050935250919050565b600061279b826128e9565b92915050565b60006020825111156127b257600080fd5b60208201519050815160206127c79190612bc5565b6127d2906008612e4a565b1c919050565b602080820151825181019091015160009182805b600a8110156128545783811a9150612805816007612e4a565b82607f16901b85179450816080166000141561284257612826816001612c0d565b86518790612835908390612c0d565b9052509395945050505050565b8061284c81612bf2565b9150506127ec565b50600080fd5b6000815160201461286a57600080fd5b506020015190565b600081600581111561288657612886612e69565b141561289a57612895826127d8565b505050565b60028160058111156128ae576128ae612e69565b14156102d35760006128bf836127d8565b905080836000018181516128d39190612c0d565b9052506020830151518351111561289557600080fd5b600081516014146128f957600080fd5b50602001516c01000000000000000000000000900490565b60006020828403121561292357600080fd5b5035919050565b80356001600160a01b038116811461294157600080fd5b919050565b6000806040838503121561295957600080fd5b6129628361292a565b946020939093013593505050565b60008083601f84011261298257600080fd5b50813567ffffffffffffffff81111561299a57600080fd5b6020830191508360208260051b85010111156129b557600080fd5b9250929050565b600080600080604085870312156129d257600080fd5b843567ffffffffffffffff808211156129ea57600080fd5b6129f688838901612970565b90965094506020870135915080821115612a0f57600080fd5b50612a1c87828801612970565b95989497509550505050565b600060208284031215612a3a57600080fd5b612a438261292a565b9392505050565b803567ffffffffffffffff8116811461294157600080fd5b600080600080600060a08688031215612a7a57600080fd5b612a838661292a565b945060208601359350612a9860408701612a4a565b9250612aa66060870161292a565b9150612ab460808701612a4a565b90509295509295909350565b6000806000806000806000806080898b031215612adc57600080fd5b883567ffffffffffffffff80821115612af457600080fd5b818b0191508b601f830112612b0857600080fd5b813581811115612b1757600080fd5b8c6020828501011115612b2957600080fd5b60209283019a509850908a01359080821115612b4457600080fd5b612b508c838d01612970565b909850965060408b0135915080821115612b6957600080fd5b612b758c838d01612970565b909650945060608b0135915080821115612b8e57600080fd5b50612b9b8b828c01612970565b999c989b5096995094979396929594505050565b634e487b7160e01b600052601160045260246000fd5b600082821015612bd757612bd7612baf565b500390565b634e487b7160e01b600052603260045260246000fd5b6000600019821415612c0657612c06612baf565b5060010190565b60008219821115612c2057612c20612baf565b500190565b838152818360208301376000910160200190815292915050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b818352600060208085019450848460051b86018460005b87811015612ce95783830389528135601e19883603018112612ca057600080fd5b8701803567ffffffffffffffff811115612cb957600080fd5b803603891315612cc857600080fd5b612cd58582898501612c3f565b9a87019a9450505090840190600101612c7f565b5090979650505050505050565b8183526000602080850194508260005b85811015612d32576001600160a01b03612d1f8361292a565b1687529582019590820190600101612d06565b509495945050505050565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115612d6f57600080fd5b8260051b8083602087013760009401602001938452509192915050565b608081526000885180608084015260005b81811015612dba576020818c0181015160a0868401015201612d9d565b81811115612dcc57600060a083860101525b50601f01601f1916820182810360a09081016020850152612df0908201898b612c68565b90508281036040840152612e05818789612cf6565b90508281036060840152612e1a818587612d3d565b9a9950505050505050505050565b600082612e4557634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615612e6457612e64612baf565b500290565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052604160045260246000fdfe4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a2646970667358221220a515a5f7eae8e711a8bed52104adb554e3185fd54e316a308a998fb457b70c5864736f6c63430008090033
Verified Source Code Full Match
Compiler: v0.8.9+commit.e5eed63a
EVM: london
Optimization: Yes (800 runs)
Pb.sol 192 lines
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.9;
// runtime proto sol library
library Pb {
enum WireType {
Varint,
Fixed64,
LengthDelim,
StartGroup,
EndGroup,
Fixed32
}
struct Buffer {
uint256 idx; // the start index of next read. when idx=b.length, we're done
bytes b; // hold serialized proto msg, readonly
}
// create a new in-memory Buffer object from raw msg bytes
function fromBytes(bytes memory raw) internal pure returns (Buffer memory buf) {
buf.b = raw;
buf.idx = 0;
}
// whether there are unread bytes
function hasMore(Buffer memory buf) internal pure returns (bool) {
return buf.idx < buf.b.length;
}
// decode current field number and wiretype
function decKey(Buffer memory buf) internal pure returns (uint256 tag, WireType wiretype) {
uint256 v = decVarint(buf);
tag = v / 8;
wiretype = WireType(v & 7);
}
// count tag occurrences, return an array due to no memory map support
// have to create array for (maxtag+1) size. cnts[tag] = occurrences
// should keep buf.idx unchanged because this is only a count function
function cntTags(Buffer memory buf, uint256 maxtag) internal pure returns (uint256[] memory cnts) {
uint256 originalIdx = buf.idx;
cnts = new uint256[](maxtag + 1); // protobuf's tags are from 1 rather than 0
uint256 tag;
WireType wire;
while (hasMore(buf)) {
(tag, wire) = decKey(buf);
cnts[tag] += 1;
skipValue(buf, wire);
}
buf.idx = originalIdx;
}
// read varint from current buf idx, move buf.idx to next read, return the int value
function decVarint(Buffer memory buf) internal pure returns (uint256 v) {
bytes10 tmp; // proto int is at most 10 bytes (7 bits can be used per byte)
bytes memory bb = buf.b; // get buf.b mem addr to use in assembly
v = buf.idx; // use v to save one additional uint variable
assembly {
tmp := mload(add(add(bb, 32), v)) // load 10 bytes from buf.b[buf.idx] to tmp
}
uint256 b; // store current byte content
v = 0; // reset to 0 for return value
for (uint256 i = 0; i < 10; i++) {
assembly {
b := byte(i, tmp) // don't use tmp[i] because it does bound check and costs extra
}
v |= (b & 0x7F) << (i * 7);
if (b & 0x80 == 0) {
buf.idx += i + 1;
return v;
}
}
revert(); // i=10, invalid varint stream
}
// read length delimited field and return bytes
function decBytes(Buffer memory buf) internal pure returns (bytes memory b) {
uint256 len = decVarint(buf);
uint256 end = buf.idx + len;
require(end <= buf.b.length); // avoid overflow
b = new bytes(len);
bytes memory bufB = buf.b; // get buf.b mem addr to use in assembly
uint256 bStart;
uint256 bufBStart = buf.idx;
assembly {
bStart := add(b, 32)
bufBStart := add(add(bufB, 32), bufBStart)
}
for (uint256 i = 0; i < len; i += 32) {
assembly {
mstore(add(bStart, i), mload(add(bufBStart, i)))
}
}
buf.idx = end;
}
// return packed ints
function decPacked(Buffer memory buf) internal pure returns (uint256[] memory t) {
uint256 len = decVarint(buf);
uint256 end = buf.idx + len;
require(end <= buf.b.length); // avoid overflow
// array in memory must be init w/ known length
// so we have to create a tmp array w/ max possible len first
uint256[] memory tmp = new uint256[](len);
uint256 i = 0; // count how many ints are there
while (buf.idx < end) {
tmp[i] = decVarint(buf);
i++;
}
t = new uint256[](i); // init t with correct length
for (uint256 j = 0; j < i; j++) {
t[j] = tmp[j];
}
return t;
}
// move idx pass current value field, to beginning of next tag or msg end
function skipValue(Buffer memory buf, WireType wire) internal pure {
if (wire == WireType.Varint) {
decVarint(buf);
} else if (wire == WireType.LengthDelim) {
uint256 len = decVarint(buf);
buf.idx += len; // skip len bytes value data
require(buf.idx <= buf.b.length); // avoid overflow
} else {
revert();
} // unsupported wiretype
}
// type conversion help utils
function _bool(uint256 x) internal pure returns (bool v) {
return x != 0;
}
function _uint256(bytes memory b) internal pure returns (uint256 v) {
require(b.length <= 32); // b's length must be smaller than or equal to 32
assembly {
v := mload(add(b, 32))
} // load all 32bytes to v
v = v >> (8 * (32 - b.length)); // only first b.length is valid
}
function _address(bytes memory b) internal pure returns (address v) {
v = _addressPayable(b);
}
function _addressPayable(bytes memory b) internal pure returns (address payable v) {
require(b.length == 20);
//load 32bytes then shift right 12 bytes
assembly {
v := div(mload(add(b, 32)), 0x1000000000000000000000000)
}
}
function _bytes32(bytes memory b) internal pure returns (bytes32 v) {
require(b.length == 32);
assembly {
v := mload(add(b, 32))
}
}
// uint[] to uint8[]
function uint8s(uint256[] memory arr) internal pure returns (uint8[] memory t) {
t = new uint8[](arr.length);
for (uint256 i = 0; i < t.length; i++) {
t[i] = uint8(arr[i]);
}
}
function uint32s(uint256[] memory arr) internal pure returns (uint32[] memory t) {
t = new uint32[](arr.length);
for (uint256 i = 0; i < t.length; i++) {
t[i] = uint32(arr[i]);
}
}
function uint64s(uint256[] memory arr) internal pure returns (uint64[] memory t) {
t = new uint64[](arr.length);
for (uint256 i = 0; i < t.length; i++) {
t[i] = uint64(arr[i]);
}
}
function bools(uint256[] memory arr) internal pure returns (bool[] memory t) {
t = new bool[](arr.length);
for (uint256 i = 0; i < t.length; i++) {
t[i] = arr[i] != 0;
}
}
}
Pauser.sol 58 lines
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.9;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
abstract contract Pauser is Ownable, Pausable {
mapping(address => bool) public pausers;
event PauserAdded(address account);
event PauserRemoved(address account);
constructor() {
_addPauser(msg.sender);
}
modifier onlyPauser() {
require(isPauser(msg.sender), "Caller is not pauser");
_;
}
function pause() public onlyPauser {
_pause();
}
function unpause() public onlyPauser {
_unpause();
}
function isPauser(address account) public view returns (bool) {
return pausers[account];
}
function addPauser(address account) public onlyOwner {
_addPauser(account);
}
function removePauser(address account) public onlyOwner {
_removePauser(account);
}
function renouncePauser() public {
_removePauser(msg.sender);
}
function _addPauser(address account) private {
require(!isPauser(account), "Account is already pauser");
pausers[account] = true;
emit PauserAdded(account);
}
function _removePauser(address account) private {
require(isPauser(account), "Account is not pauser");
pausers[account] = false;
emit PauserRemoved(account);
}
}
PbPegged.sol 82 lines
// SPDX-License-Identifier: GPL-3.0-only
// Code generated by protoc-gen-sol. DO NOT EDIT.
// source: contracts/libraries/proto/pegged.proto
pragma solidity 0.8.9;
import "./Pb.sol";
library PbPegged {
using Pb for Pb.Buffer; // so we can call Pb funcs on Buffer obj
struct Mint {
address token; // tag: 1
address account; // tag: 2
uint256 amount; // tag: 3
address depositor; // tag: 4
uint64 refChainId; // tag: 5
bytes32 refId; // tag: 6
} // end struct Mint
function decMint(bytes memory raw) internal pure returns (Mint memory m) {
Pb.Buffer memory buf = Pb.fromBytes(raw);
uint256 tag;
Pb.WireType wire;
while (buf.hasMore()) {
(tag, wire) = buf.decKey();
if (false) {}
// solidity has no switch/case
else if (tag == 1) {
m.token = Pb._address(buf.decBytes());
} else if (tag == 2) {
m.account = Pb._address(buf.decBytes());
} else if (tag == 3) {
m.amount = Pb._uint256(buf.decBytes());
} else if (tag == 4) {
m.depositor = Pb._address(buf.decBytes());
} else if (tag == 5) {
m.refChainId = uint64(buf.decVarint());
} else if (tag == 6) {
m.refId = Pb._bytes32(buf.decBytes());
} else {
buf.skipValue(wire);
} // skip value of unknown tag
}
} // end decoder Mint
struct Withdraw {
address token; // tag: 1
address receiver; // tag: 2
uint256 amount; // tag: 3
address burnAccount; // tag: 4
uint64 refChainId; // tag: 5
bytes32 refId; // tag: 6
} // end struct Withdraw
function decWithdraw(bytes memory raw) internal pure returns (Withdraw memory m) {
Pb.Buffer memory buf = Pb.fromBytes(raw);
uint256 tag;
Pb.WireType wire;
while (buf.hasMore()) {
(tag, wire) = buf.decKey();
if (false) {}
// solidity has no switch/case
else if (tag == 1) {
m.token = Pb._address(buf.decBytes());
} else if (tag == 2) {
m.receiver = Pb._address(buf.decBytes());
} else if (tag == 3) {
m.amount = Pb._uint256(buf.decBytes());
} else if (tag == 4) {
m.burnAccount = Pb._address(buf.decBytes());
} else if (tag == 5) {
m.refChainId = uint64(buf.decVarint());
} else if (tag == 6) {
m.refId = Pb._bytes32(buf.decBytes());
} else {
buf.skipValue(wire);
} // skip value of unknown tag
}
} // end decoder Withdraw
}
Governor.sol 49 lines
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.9;
import "@openzeppelin/contracts/access/Ownable.sol";
abstract contract Governor is Ownable {
mapping(address => bool) public governors;
event GovernorAdded(address account);
event GovernorRemoved(address account);
modifier onlyGovernor() {
require(isGovernor(msg.sender), "Caller is not governor");
_;
}
constructor() {
_addGovernor(msg.sender);
}
function isGovernor(address _account) public view returns (bool) {
return governors[_account];
}
function addGovernor(address _account) public onlyOwner {
_addGovernor(_account);
}
function removeGovernor(address _account) public onlyOwner {
_removeGovernor(_account);
}
function renounceGovernor() public {
_removeGovernor(msg.sender);
}
function _addGovernor(address _account) private {
require(!isGovernor(_account), "Account is already governor");
governors[_account] = true;
emit GovernorAdded(_account);
}
function _removeGovernor(address _account) private {
require(isGovernor(_account), "Account is not governor");
governors[_account] = false;
emit GovernorRemoved(_account);
}
}
IPeggedToken.sol 9 lines
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.8.0;
interface IPeggedToken {
function mint(address _to, uint256 _amount) external;
function burn(address _from, uint256 _amount) external;
}
VolumeControl.sol 49 lines
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.9;
import "./Governor.sol";
abstract contract VolumeControl is Governor {
uint256 public epochLength; // seconds
mapping(address => uint256) public epochVolumes; // key is token
mapping(address => uint256) public epochVolumeCaps; // key is token
mapping(address => uint256) public lastOpTimestamps; // key is token
event EpochLengthUpdated(uint256 length);
event EpochVolumeUpdated(address token, uint256 cap);
function setEpochLength(uint256 _length) external onlyGovernor {
epochLength = _length;
emit EpochLengthUpdated(_length);
}
function setEpochVolumeCaps(address[] calldata _tokens, uint256[] calldata _caps) external onlyGovernor {
require(_tokens.length == _caps.length, "length mismatch");
for (uint256 i = 0; i < _tokens.length; i++) {
epochVolumeCaps[_tokens[i]] = _caps[i];
emit EpochVolumeUpdated(_tokens[i], _caps[i]);
}
}
function _updateVolume(address _token, uint256 _amount) internal {
if (epochLength == 0) {
return;
}
uint256 cap = epochVolumeCaps[_token];
if (cap == 0) {
return;
}
uint256 volume = epochVolumes[_token];
uint256 timestamp = block.timestamp;
uint256 epochStartTime = (timestamp / epochLength) * epochLength;
if (lastOpTimestamps[_token] < epochStartTime) {
volume = _amount;
} else {
volume += _amount;
}
require(volume <= cap, "volume exceeds cap");
epochVolumes[_token] = volume;
lastOpTimestamps[_token] = timestamp;
}
}
ISigsVerifier.sol 19 lines
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.8.0;
interface ISigsVerifier {
/**
* @notice Verifies that a message is signed by a quorum among the signers.
* @param _msg signed message
* @param _sigs list of signatures sorted by signer addresses in ascending order
* @param _signers sorted list of current signers
* @param _powers powers of current signers
*/
function verifySigs(
bytes memory _msg,
bytes[] calldata _sigs,
address[] calldata _signers,
uint256[] calldata _powers
) external view;
}
DelayedTransfer.sol 62 lines
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.9;
import "./Governor.sol";
abstract contract DelayedTransfer is Governor {
struct delayedTransfer {
address receiver;
address token;
uint256 amount;
uint256 timestamp;
}
mapping(bytes32 => delayedTransfer) public delayedTransfers;
mapping(address => uint256) public delayThresholds;
uint256 public delayPeriod; // in seconds
event DelayedTransferAdded(bytes32 id);
event DelayedTransferExecuted(bytes32 id, address receiver, address token, uint256 amount);
event DelayPeriodUpdated(uint256 period);
event DelayThresholdUpdated(address token, uint256 threshold);
function setDelayThresholds(address[] calldata _tokens, uint256[] calldata _thresholds) external onlyGovernor {
require(_tokens.length == _thresholds.length, "length mismatch");
for (uint256 i = 0; i < _tokens.length; i++) {
delayThresholds[_tokens[i]] = _thresholds[i];
emit DelayThresholdUpdated(_tokens[i], _thresholds[i]);
}
}
function setDelayPeriod(uint256 _period) external onlyGovernor {
delayPeriod = _period;
emit DelayPeriodUpdated(_period);
}
function _addDelayedTransfer(
bytes32 id,
address receiver,
address token,
uint256 amount
) internal {
require(delayedTransfers[id].timestamp == 0, "delayed transfer already exists");
delayedTransfers[id] = delayedTransfer({
receiver: receiver,
token: token,
amount: amount,
timestamp: block.timestamp
});
emit DelayedTransferAdded(id);
}
// caller needs to do the actual token transfer
function _executeDelayedTransfer(bytes32 id) internal returns (delayedTransfer memory) {
delayedTransfer memory transfer = delayedTransfers[id];
require(transfer.timestamp > 0, "delayed transfer not exist");
require(block.timestamp > transfer.timestamp + delayPeriod, "delayed transfer still locked");
delete delayedTransfers[id];
emit DelayedTransferExecuted(id, transfer.receiver, transfer.token, transfer.amount);
return transfer;
}
}
Context.sol 24 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
Ownable.sol 76 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
Pausable.sol 91 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is Context {
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state.
*/
constructor() {
_paused = false;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
require(!paused(), "Pausable: paused");
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
require(paused(), "Pausable: not paused");
_;
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
IPeggedTokenBurnFrom.sol 11 lines
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.8.0;
// used for pegged token with openzeppelin ERC20Burnable interface
// only compatible with PeggedTokenBridgeV2
interface IPeggedTokenBurnFrom {
function mint(address _to, uint256 _amount) external;
function burnFrom(address _from, uint256 _amount) external;
}
PeggedTokenBridgeV2.sol 208 lines
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.9;
import "../interfaces/ISigsVerifier.sol";
import "../interfaces/IPeggedToken.sol";
import "../interfaces/IPeggedTokenBurnFrom.sol";
import "../libraries/PbPegged.sol";
import "../safeguard/Pauser.sol";
import "../safeguard/VolumeControl.sol";
import "../safeguard/DelayedTransfer.sol";
/**
* @title The bridge contract to mint and burn pegged tokens
* @dev Work together with OriginalTokenVault deployed at remote chains.
*/
contract PeggedTokenBridgeV2 is Pauser, VolumeControl, DelayedTransfer {
ISigsVerifier public immutable sigsVerifier;
mapping(bytes32 => bool) public records;
mapping(address => uint256) public supplies;
mapping(address => uint256) public minBurn;
mapping(address => uint256) public maxBurn;
event Mint(
bytes32 mintId,
address token,
address account,
uint256 amount,
// ref_chain_id defines the reference chain ID, taking values of:
// 1. The common case: the chain ID on which the remote corresponding deposit or burn happened;
// 2. Refund for wrong burn: this chain ID on which the burn happened
uint64 refChainId,
// ref_id defines a unique reference ID, taking values of:
// 1. The common case of deposit/burn-mint: the deposit or burn ID on the remote chain;
// 2. Refund for wrong burn: the burn ID on this chain
bytes32 refId,
address depositor
);
event Burn(
bytes32 burnId,
address token,
address account,
uint256 amount,
uint64 toChainId,
address toAccount,
uint64 nonce
);
event MinBurnUpdated(address token, uint256 amount);
event MaxBurnUpdated(address token, uint256 amount);
event SupplyUpdated(address token, uint256 supply);
constructor(ISigsVerifier _sigsVerifier) {
sigsVerifier = _sigsVerifier;
}
/**
* @notice Mint tokens triggered by deposit at a remote chain's OriginalTokenVault.
* @param _request The serialized Mint protobuf.
* @param _sigs The list of signatures sorted by signing addresses in ascending order. A relay must be signed-off by
* +2/3 of the sigsVerifier's current signing power to be delivered.
* @param _signers The sorted list of signers.
* @param _powers The signing powers of the signers.
*/
function mint(
bytes calldata _request,
bytes[] calldata _sigs,
address[] calldata _signers,
uint256[] calldata _powers
) external whenNotPaused returns (bytes32) {
bytes32 domain = keccak256(abi.encodePacked(block.chainid, address(this), "Mint"));
sigsVerifier.verifySigs(abi.encodePacked(domain, _request), _sigs, _signers, _powers);
PbPegged.Mint memory request = PbPegged.decMint(_request);
bytes32 mintId = keccak256(
// len = 20 + 20 + 32 + 20 + 8 + 32 + 20 = 152
abi.encodePacked(
request.account,
request.token,
request.amount,
request.depositor,
request.refChainId,
request.refId,
address(this)
)
);
require(records[mintId] == false, "record exists");
records[mintId] = true;
_updateVolume(request.token, request.amount);
uint256 delayThreshold = delayThresholds[request.token];
if (delayThreshold > 0 && request.amount > delayThreshold) {
_addDelayedTransfer(mintId, request.account, request.token, request.amount);
} else {
IPeggedToken(request.token).mint(request.account, request.amount);
}
supplies[request.token] += request.amount;
emit Mint(
mintId,
request.token,
request.account,
request.amount,
request.refChainId,
request.refId,
request.depositor
);
return mintId;
}
/**
* @notice Burn pegged tokens to trigger a cross-chain withdrawal of the original tokens at a remote chain's
* OriginalTokenVault, or mint at another remote chain
* NOTE: This function DOES NOT SUPPORT fee-on-transfer / rebasing tokens.
* @param _token The pegged token address.
* @param _amount The amount to burn.
* @param _toChainId If zero, withdraw from original vault; otherwise, the remote chain to mint tokens.
* @param _toAccount The account to receive tokens on the remote chain
* @param _nonce A number to guarantee unique depositId. Can be timestamp in practice.
*/
function burn(
address _token,
uint256 _amount,
uint64 _toChainId,
address _toAccount,
uint64 _nonce
) external whenNotPaused returns (bytes32) {
bytes32 burnId = _burn(_token, _amount, _toChainId, _toAccount, _nonce);
IPeggedToken(_token).burn(msg.sender, _amount);
return burnId;
}
// same with `burn` above, use openzeppelin ERC20Burnable interface
function burnFrom(
address _token,
uint256 _amount,
uint64 _toChainId,
address _toAccount,
uint64 _nonce
) external whenNotPaused returns (bytes32) {
bytes32 burnId = _burn(_token, _amount, _toChainId, _toAccount, _nonce);
IPeggedTokenBurnFrom(_token).burnFrom(msg.sender, _amount);
return burnId;
}
function _burn(
address _token,
uint256 _amount,
uint64 _toChainId,
address _toAccount,
uint64 _nonce
) private returns (bytes32) {
require(_amount > minBurn[_token], "amount too small");
require(maxBurn[_token] == 0 || _amount <= maxBurn[_token], "amount too large");
supplies[_token] -= _amount;
bytes32 burnId = keccak256(
// len = 20 + 20 + 32 + 8 + 20 + 8 + 8 + 20 = 136
abi.encodePacked(
msg.sender,
_token,
_amount,
_toChainId,
_toAccount,
_nonce,
uint64(block.chainid),
address(this)
)
);
require(records[burnId] == false, "record exists");
records[burnId] = true;
emit Burn(burnId, _token, msg.sender, _amount, _toChainId, _toAccount, _nonce);
return burnId;
}
function executeDelayedTransfer(bytes32 id) external whenNotPaused {
delayedTransfer memory transfer = _executeDelayedTransfer(id);
IPeggedToken(transfer.token).mint(transfer.receiver, transfer.amount);
}
function setMinBurn(address[] calldata _tokens, uint256[] calldata _amounts) external onlyGovernor {
require(_tokens.length == _amounts.length, "length mismatch");
for (uint256 i = 0; i < _tokens.length; i++) {
minBurn[_tokens[i]] = _amounts[i];
emit MinBurnUpdated(_tokens[i], _amounts[i]);
}
}
function setMaxBurn(address[] calldata _tokens, uint256[] calldata _amounts) external onlyGovernor {
require(_tokens.length == _amounts.length, "length mismatch");
for (uint256 i = 0; i < _tokens.length; i++) {
maxBurn[_tokens[i]] = _amounts[i];
emit MaxBurnUpdated(_tokens[i], _amounts[i]);
}
}
function setSupply(address _token, uint256 _supply) external onlyOwner {
supplies[_token] = _supply;
emit SupplyUpdated(_token, _supply);
}
function increaseSupply(address _token, uint256 _delta) external onlyOwner {
supplies[_token] += _delta;
emit SupplyUpdated(_token, supplies[_token]);
}
function decreaseSupply(address _token, uint256 _delta) external onlyOwner {
supplies[_token] -= _delta;
emit SupplyUpdated(_token, supplies[_token]);
}
}
Read Contract
delayPeriod 0xb1c94d94 → uint256
delayThresholds 0x52532faa → uint256
delayedTransfers 0xadc0d57f → address, address, uint256, uint256
epochLength 0x57d775f8 → uint256
epochVolumeCaps 0xb5f2bc47 → uint256
epochVolumes 0x60216b00 → uint256
governors 0xe3eece26 → bool
isGovernor 0xe43581b8 → bool
isPauser 0x46fbf68e → bool
lastOpTimestamps 0xf8321383 → uint256
maxBurn 0x497bf3b2 → uint256
minBurn 0x7f856013 → uint256
owner 0x8da5cb5b → address
paused 0x5c975abb → bool
pausers 0x80f51c12 → bool
records 0x01e64725 → bool
sigsVerifier 0xccf2683b → address
supplies 0x274cee31 → uint256
Write Contract 23 functions
These functions modify contract state and require a wallet transaction to execute.
addGovernor 0x3c4a25d0
address _account
addPauser 0x82dc1ec4
address account
burn 0xa0029301
address _token
uint256 _amount
uint64 _toChainId
address _toAccount
uint64 _nonce
returns: bytes32
burnFrom 0x9e422c33
address _token
uint256 _amount
uint64 _toChainId
address _toAccount
uint64 _nonce
returns: bytes32
decreaseSupply 0x15d0975c
address _token
uint256 _delta
executeDelayedTransfer 0x9e25fc5c
bytes32 id
increaseSupply 0x79fcd8ee
address _token
uint256 _delta
mint 0xf8734302
bytes _request
bytes[] _sigs
address[] _signers
uint256[] _powers
returns: bytes32
pause 0x8456cb59
No parameters
removeGovernor 0xeecdac88
address _account
removePauser 0x6b2c0f55
address account
renounceGovernor 0xe026049c
No parameters
renounceOwnership 0x715018a6
No parameters
renouncePauser 0x6ef8d66d
No parameters
setDelayPeriod 0x3d572107
uint256 _period
setDelayThresholds 0x17bdbae5
address[] _tokens
uint256[] _thresholds
setEpochLength 0x54eea796
uint256 _length
setEpochVolumeCaps 0x47b16c6c
address[] _tokens
uint256[] _caps
setMaxBurn 0xf9a8ea08
address[] _tokens
uint256[] _amounts
setMinBurn 0xbf4816f0
address[] _tokens
uint256[] _amounts
setSupply 0xb4d8cedc
address _token
uint256 _supply
transferOwnership 0xf2fde38b
address newOwner
unpause 0x3f4ba83a
No parameters
Recent Transactions
No transactions found for this address