Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0x454BD9E2B29EB5963048cC1A8BD6fD44e89899Cb
Balance 0 ETH
Nonce 1
Code Size 16974 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

16974 bytes
0x6080604052600436106101cd5760003560e01c806395d89b41116100f7578063d505accf11610095578063ec60bcf311610064578063ec60bcf314610708578063f2b0653714610745578063f5ba1c8714610782578063fc0c546a146107bf576101cd565b8063d505accf1461063c578063d8bff5a514610665578063dd62ed3e146106a2578063e37c9fd5146106df576101cd565b8063a9059cbb116100d1578063a9059cbb14610580578063ac7e534e146105bd578063b3ab15fb146105e8578063c1a287e214610611576101cd565b806395d89b41146104da5780639dc29fac14610505578063a87430ba14610542576101cd565b80634881636d1161016f57806370a082311161013e57806370a08231146103e65780637ecebe001461042357806380b3b0991461046057806394bf804d1461049d576101cd565b80634881636d14610328578063570ca7351461035357806369b411701461037e5780636dd7d8ea146103a9576101cd565b806323b872dd116101ab57806323b872dd14610265578063313ce567146102a25780633644e515146102cd5780633f579f42146102f8576101cd565b806306fdde03146101d2578063095ea7b3146101fd57806318160ddd1461023a575b600080fd5b3480156101de57600080fd5b506101e76107ea565b6040516101f49190613cdd565b60405180910390f35b34801561020957600080fd5b50610224600480360381019061021f91906133c7565b610888565b6040516102319190613b8d565b60405180910390f35b34801561024657600080fd5b5061024f61097a565b60405161025c9190613f28565b60405180910390f35b34801561027157600080fd5b5061028c600480360381019061028791906132da565b610980565b6040516102999190613b8d565b60405180910390f35b3480156102ae57600080fd5b506102b76109a2565b6040516102c49190613fb1565b60405180910390f35b3480156102d957600080fd5b506102e26109a7565b6040516102ef9190613ba8565b60405180910390f35b610312600480360381019061030d9190613403565b6109b6565b60405161031f9190613ca0565b60405180910390f35b34801561033457600080fd5b5061033d610ceb565b60405161034a9190613f28565b60405180910390f35b34801561035f57600080fd5b50610368610cf1565b6040516103759190613ad4565b60405180910390f35b34801561038a57600080fd5b50610393610d17565b6040516103a09190613f28565b60405180910390f35b3480156103b557600080fd5b506103d060048036038101906103cb9190613275565b610d1e565b6040516103dd9190613b8d565b60405180910390f35b3480156103f257600080fd5b5061040d60048036038101906104089190613275565b61100e565b60405161041a9190613f28565b60405180910390f35b34801561042f57600080fd5b5061044a60048036038101906104459190613275565b611088565b6040516104579190613f28565b60405180910390f35b34801561046c57600080fd5b5061048760048036038101906104829190613403565b6110a0565b6040516104949190613ba8565b60405180910390f35b3480156104a957600080fd5b506104c460048036038101906104bf91906134e5565b61128a565b6040516104d19190613b8d565b60405180910390f35b3480156104e657600080fd5b506104ef611929565b6040516104fc9190613cdd565b60405180910390f35b34801561051157600080fd5b5061052c600480360381019061052791906133c7565b6119c7565b6040516105399190613b8d565b60405180910390f35b34801561054e57600080fd5b5061056960048036038101906105649190613275565b6119de565b604051610577929190613eff565b60405180910390f35b34801561058c57600080fd5b506105a760048036038101906105a291906133c7565b611a3a565b6040516105b49190613b8d565b60405180910390f35b3480156105c957600080fd5b506105d2611a51565b6040516105df9190613ad4565b60405180910390f35b3480156105f457600080fd5b5061060f600480360381019061060a9190613275565b611a77565b005b34801561061d57600080fd5b50610626611d9c565b6040516106339190613f28565b60405180910390f35b34801561064857600080fd5b50610663600480360381019061065e9190613329565b611da3565b005b34801561067157600080fd5b5061068c60048036038101906106879190613275565b6120a8565b6040516106999190613f28565b60405180910390f35b3480156106ae57600080fd5b506106c960048036038101906106c4919061329e565b6120c0565b6040516106d69190613f28565b60405180910390f35b3480156106eb57600080fd5b5061070660048036038101906107019190613403565b6120e5565b005b34801561071457600080fd5b5061072f600480360381019061072a91906132da565b612214565b60405161073c9190613b8d565b60405180910390f35b34801561075157600080fd5b5061076c60048036038101906107679190613493565b612236565b6040516107799190613f28565b60405180910390f35b34801561078e57600080fd5b506107a960048036038101906107a49190613275565b61224e565b6040516107b69190613ad4565b60405180910390f35b3480156107cb57600080fd5b506107d4612281565b6040516107e19190613cc2565b60405180910390f35b60018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156108805780601f1061085557610100808354040283529160200191610880565b820191906000526020600020905b81548152906001019060200180831161086357829003601f168201915b505050505081565b600081600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516109689190613f28565b60405180910390a36001905092915050565b60025481565b600061098c84836122a5565b610997848484612453565b600190509392505050565b601281565b60006109b1612a60565b905090565b6060600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a3f90613e5f565b60405180910390fd5b600254600260056000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540211610af0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae790613d1f565b60405180910390fd5b6000848484604051602001610b0793929190613b4f565b6040516020818303038152906040528051906020012090506000600b600083815260200190815260200160002054905080421015610b7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b7190613e1f565b60405180910390fd5b621275008101421115610bc2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bb990613ddf565b60405180910390fd5b6000600b600084815260200190815260200160002081905550600060608773ffffffffffffffffffffffffffffffffffffffff168787604051610c059190613a84565b60006040518083038185875af1925050503d8060008114610c42576040519150601f19603f3d011682016040523d82523d6000602084013e610c47565b606091505b509150915081610c8c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c8390613e3f565b60405180910390fd5b8773ffffffffffffffffffffffffffffffffffffffff16847f71f2f703ef5605f99bb79556066217af28b9d991b829c9f4255e1abdf873fb4a8989604051610cd5929190613f43565b60405180910390a3809450505050509392505050565b600a5481565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6202a30081565b600080600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461100457610dbe613165565b600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16815250509050600081600001516fffffffffffffffffffffffffffffffff161115610f845780600001516fffffffffffffffffffffffffffffffff16600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555080600001516fffffffffffffffffffffffffffffffff16600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505b83600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505b6001915050919050565b6000600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff169050919050565b60086020528060005260406000206000915090505481565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611132576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161112990613e5f565b60405180910390fd5b600254600260056000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205402116111da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111d190613d1f565b60405180910390fd5b60008484846040516020016111f193929190613b4f565b60405160208183030381529060405280519060200120905060006202a3004201905080600b6000848152602001908152602001600020819055508573ffffffffffffffffffffffffffffffffffffffff16827f9ffdf0c63c8eec344b500e806ac1d1d37308fdf141a29d10cdd82c069aec6e4887878560405161127693929190613f73565b60405180910390a381925050509392505050565b60008073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156112fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112f290613dbf565b60405180910390fd5b611303613165565b600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060007f000000000000000000000000d084944d3c05cd115c09d072b9f44ba3e0e4592173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161143e9190613ad4565b60206040518083038186803b15801561145657600080fd5b505afa15801561146a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061148e91906134bc565b9050600080600254146114ae57816002548702816114a857fe5b046114b0565b855b90506000600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008290508673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461166b57600085600001516fffffffffffffffffffffffffffffffff1611156115ec5784600001516fffffffffffffffffffffffffffffffff16600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555084600001516fffffffffffffffffffffffffffffffff16810190505b86600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b80600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055506116c183612ac3565b85600001818151019150906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff1681525050611704620151804201612ac3565b85602001906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff168152505084600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050826002600082825401925050819055507f000000000000000000000000d084944d3c05cd115c09d072b9f44ba3e0e4592173ffffffffffffffffffffffffffffffffffffffff166323b872dd33308b6040518463ffffffff1660e01b815260040161186193929190613aef565b602060405180830381600087803b15801561187b57600080fd5b505af115801561188f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b3919061346a565b503373ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040516119129190613f28565b60405180910390a360019550505050505092915050565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156119bf5780601f10611994576101008083540402835291602001916119bf565b820191906000526020600020905b8154815290600101906020018083116119a257829003601f168201915b505050505081565b60006119d4338484612b42565b6001905092915050565b60066020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b6000611a47338484612453565b6001905092915050565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611ae7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ade90613d7f565b60405180910390fd5b6000600560008073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600254039050600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614611c5a57806002600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540211611c08576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bff90613d1f565b60405180910390fd5b81600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555062093a804201600a81905550611d98565b806002600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054021115611d4d57600a54421015611ce9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ce090613edf565b60405180910390fd5b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6000600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600a819055505b5050565b6212750081565b600073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff161415611e13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e0a90613e9f565b60405180910390fd5b834210611e55576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e4c90613ebf565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff166001611f177f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c960001b8a8a8a600860008f73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815480929190600101919050558b604051602001611efc96959493929190613bc3565b6040516020818303038152906040528051906020012061302d565b85858560405160008152602001604052604051611f379493929190613c5b565b6020604051602081039080840390855afa158015611f59573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff1614611fb9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fb090613e7f565b60405180910390fd5b84600760008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925876040516120979190613f28565b60405180910390a350505050505050565b60056020528060005260406000206000915090505481565b6007602052816000526040600020602052806000526040600020600091509150505481565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612175576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161216c90613e5f565b60405180910390fd5b600083838360405160200161218c93929190613b4f565b6040516020818303038152906040528051906020012090506000600b6000838152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff16817f7666fc3824e27fff7f62adc190adf39d59915b1634803f46f6002f5a071de7f78585604051612206929190613f43565b60405180910390a350505050565b600061222084836122a5565b61222b848484612b42565b600190509392505050565b600b6020528060005260406000206000915090505481565b60046020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7f000000000000000000000000d084944d3c05cd115c09d072b9f44ba3e0e4592181565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156122de5761244f565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461244d57818110156123c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123c090613d5f565b60405180910390fd5b818103600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b505b5050565b61245b613165565b600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905080602001516fffffffffffffffffffffffffffffffff16421015612594576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161258b90613d3f565b60405180910390fd5b600082146129f5578181600001516fffffffffffffffffffffffffffffffff1610156125f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125ec90613d9f565b60405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146129f457600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415612698576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161268f90613dbf565b60405180910390fd5b6126a0613165565b600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff168152505090506000600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000600460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905061285185612ac3565b846000015103600660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506128d885612ac3565b836000015101600660008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555084600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555084600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505050505b5b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612a529190613f28565b60405180910390a350505050565b6000804690507f00000000000000000000000000000000000000000000000000000000000000018114612a9b57612a968161309d565b612abd565b7fa6caa45134e22d4caefce58f5734f99602b09c3c94b7f1d03d0fab0131090c985b91505090565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6fffffffffffffffffffffffffffffffff16821115612b3a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b3190613dff565b60405180910390fd5b819050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612bb2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ba990613dbf565b60405180910390fd5b612bba613165565b600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905080602001516fffffffffffffffffffffffffffffffff16421015612cf3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cea90613d3f565b60405180910390fd5b60006002547f000000000000000000000000d084944d3c05cd115c09d072b9f44ba3e0e4592173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401612d519190613ad4565b60206040518083038186803b158015612d6957600080fd5b505afa158015612d7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612da191906134bc565b840281612daa57fe5b049050612dde612db984612ac3565b83600001516fffffffffffffffffffffffffffffffff166130f190919063ffffffff16565b600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550826002600082825403925050819055508260056000600460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055507f000000000000000000000000d084944d3c05cd115c09d072b9f44ba3e0e4592173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85836040518363ffffffff1660e01b8152600401612f6d929190613b26565b602060405180830381600087803b158015612f8757600080fd5b505af1158015612f9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fbf919061346a565b50600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161301e9190613f28565b60405180910390a35050505050565b60006040518060400160405280600281526020017f190100000000000000000000000000000000000000000000000000000000000081525061306d612a60565b8360405160200161308093929190613a9b565b604051602081830303815290604052805190602001209050919050565b60007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a7946921882306040516020016130d493929190613c24565b604051602081830303815290604052805190602001209050919050565b6000826fffffffffffffffffffffffffffffffff168284039150816fffffffffffffffffffffffffffffffff16111561315f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161315690613cff565b60405180910390fd5b92915050565b604051806040016040528060006fffffffffffffffffffffffffffffffff16815260200160006fffffffffffffffffffffffffffffffff1681525090565b6000813590506131b2816141a5565b92915050565b6000815190506131c7816141bc565b92915050565b6000813590506131dc816141d3565b92915050565b600082601f8301126131f357600080fd5b813561320661320182613ff9565b613fcc565b9150808252602083016020830185838301111561322257600080fd5b61322d838284614148565b50505092915050565b600081359050613245816141ea565b92915050565b60008151905061325a816141ea565b92915050565b60008135905061326f81614201565b92915050565b60006020828403121561328757600080fd5b6000613295848285016131a3565b91505092915050565b600080604083850312156132b157600080fd5b60006132bf858286016131a3565b92505060206132d0858286016131a3565b9150509250929050565b6000806000606084860312156132ef57600080fd5b60006132fd868287016131a3565b935050602061330e868287016131a3565b925050604061331f86828701613236565b9150509250925092565b600080600080600080600060e0888a03121561334457600080fd5b60006133528a828b016131a3565b97505060206133638a828b016131a3565b96505060406133748a828b01613236565b95505060606133858a828b01613236565b94505060806133968a828b01613260565b93505060a06133a78a828b016131cd565b92505060c06133b88a828b016131cd565b91505092959891949750929550565b600080604083850312156133da57600080fd5b60006133e8858286016131a3565b92505060206133f985828601613236565b9150509250929050565b60008060006060848603121561341857600080fd5b6000613426868287016131a3565b935050602061343786828701613236565b925050604084013567ffffffffffffffff81111561345457600080fd5b613460868287016131e2565b9150509250925092565b60006020828403121561347c57600080fd5b600061348a848285016131b8565b91505092915050565b6000602082840312156134a557600080fd5b60006134b3848285016131cd565b91505092915050565b6000602082840312156134ce57600080fd5b60006134dc8482850161324b565b91505092915050565b600080604083850312156134f857600080fd5b600061350685828601613236565b9250506020613517858286016131a3565b9150509250929050565b61352a816140ee565b82525050565b61353981614073565b82525050565b61354881614085565b82525050565b61355781614091565b82525050565b61356e61356982614091565b61418a565b82525050565b600061357f82614025565b613589818561403b565b9350613599818560208601614157565b6135a281614194565b840191505092915050565b60006135b882614025565b6135c2818561404c565b93506135d2818560208601614157565b80840191505092915050565b6135e781614100565b82525050565b60006135f882614030565b6136028185614057565b9350613612818560208601614157565b61361b81614194565b840191505092915050565b600061363182614030565b61363b8185614068565b935061364b818560208601614157565b80840191505092915050565b6000613664601583614057565b91507f426f72696e674d6174683a20556e646572666c6f7700000000000000000000006000830152602082019050919050565b60006136a4601083614057565b91507f4e6f7420656e6f75676820766f746573000000000000000000000000000000006000830152602082019050919050565b60006136e4600683614057565b91507f4c6f636b656400000000000000000000000000000000000000000000000000006000830152602082019050919050565b6000613724600d83614057565b91507f4c6f7720616c6c6f77616e6365000000000000000000000000000000000000006000830152602082019050919050565b6000613764600d83614057565b91507f5a65726f206f70657261746f72000000000000000000000000000000000000006000830152602082019050919050565b60006137a4600b83614057565b91507f4c6f772062616c616e63650000000000000000000000000000000000000000006000830152602082019050919050565b60006137e4600c83614057565b91507f5a65726f206164647265737300000000000000000000000000000000000000006000830152602082019050919050565b6000613824600883614057565b91507f5478207374616c650000000000000000000000000000000000000000000000006000830152602082019050919050565b6000613864601c83614057565b91507f426f72696e674d6174683a2075696e74313238204f766572666c6f77000000006000830152602082019050919050565b60006138a4600983614057565b91507f546f6f206561726c7900000000000000000000000000000000000000000000006000830152602082019050919050565b60006138e4600e83614057565b91507f5478207265766572746564203a280000000000000000000000000000000000006000830152602082019050919050565b6000613924600d83614057565b91507f4f70657261746f72206f6e6c79000000000000000000000000000000000000006000830152602082019050919050565b6000613964600b83614057565b91507f496e76616c6964205369670000000000000000000000000000000000000000006000830152602082019050919050565b60006139a4600a83614057565b91507f5a65726f206f776e6572000000000000000000000000000000000000000000006000830152602082019050919050565b60006139e4600783614057565b91507f45787069726564000000000000000000000000000000000000000000000000006000830152602082019050919050565b6000613a24600b83614057565b91507f57616974206c6f6e6765720000000000000000000000000000000000000000006000830152602082019050919050565b613a608161409b565b82525050565b613a6f816140d7565b82525050565b613a7e816140e1565b82525050565b6000613a9082846135ad565b915081905092915050565b6000613aa78286613626565b9150613ab3828561355d565b602082019150613ac3828461355d565b602082019150819050949350505050565b6000602082019050613ae96000830184613530565b92915050565b6000606082019050613b046000830186613521565b613b116020830185613530565b613b1e6040830184613a66565b949350505050565b6000604082019050613b3b6000830185613530565b613b486020830184613a66565b9392505050565b6000606082019050613b646000830186613530565b613b716020830185613a66565b8181036040830152613b838184613574565b9050949350505050565b6000602082019050613ba2600083018461353f565b92915050565b6000602082019050613bbd600083018461354e565b92915050565b600060c082019050613bd8600083018961354e565b613be56020830188613530565b613bf26040830187613530565b613bff6060830186613a66565b613c0c6080830185613a66565b613c1960a0830184613a66565b979650505050505050565b6000606082019050613c39600083018661354e565b613c466020830185613a66565b613c536040830184613530565b949350505050565b6000608082019050613c70600083018761354e565b613c7d6020830186613a75565b613c8a604083018561354e565b613c97606083018461354e565b95945050505050565b60006020820190508181036000830152613cba8184613574565b905092915050565b6000602082019050613cd760008301846135de565b92915050565b60006020820190508181036000830152613cf781846135ed565b905092915050565b60006020820190508181036000830152613d1881613657565b9050919050565b60006020820190508181036000830152613d3881613697565b9050919050565b60006020820190508181036000830152613d58816136d7565b9050919050565b60006020820190508181036000830152613d7881613717565b9050919050565b60006020820190508181036000830152613d9881613757565b9050919050565b60006020820190508181036000830152613db881613797565b9050919050565b60006020820190508181036000830152613dd8816137d7565b9050919050565b60006020820190508181036000830152613df881613817565b9050919050565b60006020820190508181036000830152613e1881613857565b9050919050565b60006020820190508181036000830152613e3881613897565b9050919050565b60006020820190508181036000830152613e58816138d7565b9050919050565b60006020820190508181036000830152613e7881613917565b9050919050565b60006020820190508181036000830152613e9881613957565b9050919050565b60006020820190508181036000830152613eb881613997565b9050919050565b60006020820190508181036000830152613ed8816139d7565b9050919050565b60006020820190508181036000830152613ef881613a17565b9050919050565b6000604082019050613f146000830185613a57565b613f216020830184613a57565b9392505050565b6000602082019050613f3d6000830184613a66565b92915050565b6000604082019050613f586000830185613a66565b8181036020830152613f6a8184613574565b90509392505050565b6000606082019050613f886000830186613a66565b8181036020830152613f9a8185613574565b9050613fa96040830184613a66565b949350505050565b6000602082019050613fc66000830184613a75565b92915050565b6000604051905081810181811067ffffffffffffffff82111715613fef57600080fd5b8060405250919050565b600067ffffffffffffffff82111561401057600080fd5b601f19601f8301169050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b600061407e826140b7565b9050919050565b60008115159050919050565b6000819050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60006140f982614124565b9050919050565b600061410b82614112565b9050919050565b600061411d826140b7565b9050919050565b600061412f82614136565b9050919050565b6000614141826140b7565b9050919050565b82818337600083830152505050565b60005b8381101561417557808201518184015260208101905061415a565b83811115614184576000848401525b50505050565b6000819050919050565b6000601f19601f8301169050919050565b6141ae81614073565b81146141b957600080fd5b50565b6141c581614085565b81146141d057600080fd5b50565b6141dc81614091565b81146141e757600080fd5b50565b6141f3816140d7565b81146141fe57600080fd5b50565b61420a816140e1565b811461421557600080fd5b5056fea26469706673582212209dc1f17058f9eb6fee2a9196d61acece9e534d01ee6408e38a8777ddd963656d64736f6c634300060c0033

Verified Source Code Full Match

Compiler: v0.6.12+commit.27d51765 EVM: istanbul Optimization: No
DAO.sol 547 lines
// SPDX-License-Identifier: MIXED

// File @boringcrypto/boring-solidity/contracts/libraries/[email protected]
// License-Identifier: MIT
pragma solidity 0.6.12;

/// @notice A library for performing overflow-/underflow-safe math,
/// updated with awesomeness from of DappHub (https://github.com/dapphub/ds-math).
library BoringMath {
    function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
        require((c = a + b) >= b, "BoringMath: Add Overflow");
    }

    function sub(uint256 a, uint256 b) internal pure returns (uint256 c) {
        require((c = a - b) <= a, "BoringMath: Underflow");
    }

    function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
        require(b == 0 || (c = a * b) / b == a, "BoringMath: Mul Overflow");
    }

    function to128(uint256 a) internal pure returns (uint128 c) {
        require(a <= uint128(-1), "BoringMath: uint128 Overflow");
        c = uint128(a);
    }

    function to64(uint256 a) internal pure returns (uint64 c) {
        require(a <= uint64(-1), "BoringMath: uint64 Overflow");
        c = uint64(a);
    }

    function to32(uint256 a) internal pure returns (uint32 c) {
        require(a <= uint32(-1), "BoringMath: uint32 Overflow");
        c = uint32(a);
    }
}

/// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint128.
library BoringMath128 {
    function add(uint128 a, uint128 b) internal pure returns (uint128 c) {
        require((c = a + b) >= b, "BoringMath: Add Overflow");
    }

    function sub(uint128 a, uint128 b) internal pure returns (uint128 c) {
        require((c = a - b) <= a, "BoringMath: Underflow");
    }
}

/// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint64.
library BoringMath64 {
    function add(uint64 a, uint64 b) internal pure returns (uint64 c) {
        require((c = a + b) >= b, "BoringMath: Add Overflow");
    }

    function sub(uint64 a, uint64 b) internal pure returns (uint64 c) {
        require((c = a - b) <= a, "BoringMath: Underflow");
    }
}

/// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint32.
library BoringMath32 {
    function add(uint32 a, uint32 b) internal pure returns (uint32 c) {
        require((c = a + b) >= b, "BoringMath: Add Overflow");
    }

    function sub(uint32 a, uint32 b) internal pure returns (uint32 c) {
        require((c = a - b) <= a, "BoringMath: Underflow");
    }
}

// File @boringcrypto/boring-solidity/contracts/[email protected]
// License-Identifier: MIT
// Based on code and smartness by Ross Campbell and Keno
// Uses immutable to store the domain separator to reduce gas usage
// If the chain id changes due to a fork, the forked chain will calculate on the fly.
pragma solidity 0.6.12;

// solhint-disable no-inline-assembly

contract Domain {
    bytes32 private constant DOMAIN_SEPARATOR_SIGNATURE_HASH = keccak256("EIP712Domain(uint256 chainId,address verifyingContract)");
    // See https://eips.ethereum.org/EIPS/eip-191
    string private constant EIP191_PREFIX_FOR_EIP712_STRUCTURED_DATA = "\x19\x01";

    // solhint-disable var-name-mixedcase
    bytes32 private immutable _DOMAIN_SEPARATOR;
    uint256 private immutable DOMAIN_SEPARATOR_CHAIN_ID;    

    /// @dev Calculate the DOMAIN_SEPARATOR
    function _calculateDomainSeparator(uint256 chainId) private view returns (bytes32) {
        return keccak256(
            abi.encode(
                DOMAIN_SEPARATOR_SIGNATURE_HASH,
                chainId,
                address(this)
            )
        );
    }

    constructor() public {
        uint256 chainId; assembly {chainId := chainid()}
        _DOMAIN_SEPARATOR = _calculateDomainSeparator(DOMAIN_SEPARATOR_CHAIN_ID = chainId);
    }

    /// @dev Return the DOMAIN_SEPARATOR
    // It's named internal to allow making it public from the contract that uses it by creating a simple view function
    // with the desired public name, such as DOMAIN_SEPARATOR or domainSeparator.
    // solhint-disable-next-line func-name-mixedcase
    function _domainSeparator() internal view returns (bytes32) {
        uint256 chainId; assembly {chainId := chainid()}
        return chainId == DOMAIN_SEPARATOR_CHAIN_ID ? _DOMAIN_SEPARATOR : _calculateDomainSeparator(chainId);
    }

    function _getDigest(bytes32 dataHash) internal view returns (bytes32 digest) {
        digest =
            keccak256(
                abi.encodePacked(
                    EIP191_PREFIX_FOR_EIP712_STRUCTURED_DATA,
                    _domainSeparator(),
                    dataHash
                )
            );
    }
}

// File contracts/interfaces/IERC20.sol
//License-Identifier: MIT
pragma solidity ^0.6.12;

interface IERC20 {
    function totalSupply() external view returns (uint256);

    function balanceOf(address account) external view returns (uint256);

    function allowance(address owner, address spender)
        external
        view
        returns (uint256);

    function approve(address spender, uint256 amount) external returns (bool);

    function transfer(address to, uint256 amount) external returns (bool);

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);

    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );

    /// @notice EIP 2612
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;
}

// File contracts/DictatorDAO.sol
//License-Identifier: MIT
pragma solidity ^0.6.12;
pragma experimental ABIEncoderV2;


// DAO code/operator management/dutch auction, etc by BoringCrypto
// Staking in DictatorDAO inspired by Chef Nomi's SushiBar (heavily modified) - MIT license (originally WTFPL)
// TimeLock functionality Copyright 2020 Compound Labs, Inc. - BSD 3-Clause "New" or "Revised" License
contract DictatorDAO is IERC20, Domain {
    using BoringMath for uint256;
    using BoringMath128 for uint128;

    string public symbol;
    string public name;
    uint8 public constant decimals = 18;
    uint256 public override totalSupply;

    IERC20 public immutable token;
    address public operator;

    mapping(address => address) public userVote;
    mapping(address => uint256) public votes;

    constructor(
        string memory sharesSymbol,
        string memory sharesName,
        IERC20 token_,
        address initialOperator
    ) public {
        symbol = sharesSymbol;
        name = sharesName;
        token = token_;
        operator = initialOperator;
    }

    struct User {
        uint128 balance;
        uint128 lockedUntil;
    }

    /// @notice owner > balance mapping.
    mapping(address => User) public users;
    /// @notice owner > spender > allowance mapping.
    mapping(address => mapping(address => uint256)) public override allowance;
    /// @notice owner > nonce mapping. Used in `permit`.
    mapping(address => uint256) public nonces;

    function balanceOf(address user)
        public
        view
        override
        returns (uint256 balance)
    {
        return users[user].balance;
    }

    function _transfer(
        address from,
        address to,
        uint256 shares
    ) internal {
        User memory fromUser = users[from];
        require(block.timestamp >= fromUser.lockedUntil, "Locked");
        if (shares != 0) {
            require(fromUser.balance >= shares, "Low balance");
            if (from != to) {
                require(to != address(0), "Zero address"); // Moved down so other failed calls save some gas
                User memory toUser = users[to];

                address userVoteTo = userVote[to];
                address userVoteFrom = userVote[from];

                users[from].balance = fromUser.balance - shares.to128(); // Underflow is checked
                users[to].balance = toUser.balance + shares.to128(); // Can't overflow because totalSupply would be greater than 2^256-1

                // The "from" user's nominee started with at least that user's
                // votes, and votes correspond to 1:1 to balances. By the
                // "Low balance" check above this will not underflow.
                votes[userVoteFrom] -= shares;

                // The "to" user's nominee started with at most `totalSupply`
                // votes. By the above, they have at least `shares` fewer now.
                // It follows that there can be no overflow.
                votes[userVoteTo] += shares;
            }
        }
        emit Transfer(from, to, shares);
    }

    function _useAllowance(address from, uint256 shares) internal {
        if (msg.sender == from) {
            return;
        }
        uint256 spenderAllowance = allowance[from][msg.sender];
        // If allowance is infinite, don't decrease it to save on gas (breaks with EIP-20).
        if (spenderAllowance != type(uint256).max) {
            require(spenderAllowance >= shares, "Low allowance");
            allowance[from][msg.sender] = spenderAllowance - shares; // Underflow is checked
        }
    }

    /// @notice Transfers `shares` tokens from `msg.sender` to `to`.
    /// @param to The address to move the tokens.
    /// @param shares of the tokens to move.
    /// @return (bool) Returns True if succeeded.
    function transfer(address to, uint256 shares)
        external
        override
        returns (bool)
    {
        _transfer(msg.sender, to, shares);
        return true;
    }

    /// @notice Transfers `shares` tokens from `from` to `to`. Caller needs approval for `from`.
    /// @param from Address to draw tokens from.
    /// @param to The address to move the tokens.
    /// @param shares The token shares to move.
    /// @return (bool) Returns True if succeeded.
    function transferFrom(
        address from,
        address to,
        uint256 shares
    ) external override returns (bool) {
        _useAllowance(from, shares);
        _transfer(from, to, shares);
        return true;
    }

    /// @notice Approves `amount` from sender to be spend by `spender`.
    /// @param spender Address of the party that can draw from msg.sender's account.
    /// @param amount The maximum collective amount that `spender` can draw.
    /// @return (bool) Returns True if approved.
    function approve(address spender, uint256 amount)
        external
        override
        returns (bool)
    {
        allowance[msg.sender][spender] = amount;
        emit Approval(msg.sender, spender, amount);
        return true;
    }

    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32) {
        return _domainSeparator();
    }

    // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
    bytes32 private constant PERMIT_SIGNATURE_HASH =
        0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;

    /// @notice Approves `value` from `owner_` to be spend by `spender`.
    /// @param owner_ Address of the owner.
    /// @param spender The address of the spender that gets approved to draw from `owner_`.
    /// @param value The maximum collective amount that `spender` can draw.
    /// @param deadline This permit must be redeemed before this deadline (UTC timestamp in seconds).
    function permit(
        address owner_,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external override {
        require(owner_ != address(0), "Zero owner");
        require(block.timestamp < deadline, "Expired");
        require(
            ecrecover(
                _getDigest(
                    keccak256(
                        abi.encode(
                            PERMIT_SIGNATURE_HASH,
                            owner_,
                            spender,
                            value,
                            nonces[owner_]++,
                            deadline
                        )
                    )
                ),
                v,
                r,
                s
            ) == owner_,
            "Invalid Sig"
        );
        allowance[owner_][spender] = value;
        emit Approval(owner_, spender, value);
    }

    // Operator Setting
    address public pendingOperator;
    uint256 public pendingOperatorTime;

    // Condition for safe math: totalSupply < 2^255, so that the doubling fits.
    // A sufficient condition is for this to hold for token.totalSupply.
    function setOperator(address newOperator) public {
        require(newOperator != address(0), "Zero operator");
        uint256 netVotes = totalSupply - votes[address(0)];
        if (newOperator != pendingOperator) {
            require(votes[newOperator] * 2 > netVotes, "Not enough votes");
            pendingOperator = newOperator;
            pendingOperatorTime = block.timestamp + 7 days;
        } else {
            if (votes[newOperator] * 2 > netVotes) {
                require(block.timestamp >= pendingOperatorTime, "Wait longer");
                operator = pendingOperator;
            }
            // If there aren't enough votes, then the pending operator failed
            // to maintain a majority. If there are, then they are now the
            // operator. In either situation:
            pendingOperator = address(0);
            pendingOperatorTime = 0;
        }
    }

    /// math is ok, because amount, totalSupply and shares is always 0 <= amount <= 100.000.000 * 10^18
    /// theoretically you can grow the amount/share ratio, but it's not practical and useless
    function mint(uint256 amount, address operatorVote) public returns (bool) {
        require(msg.sender != address(0), "Zero address");
        User memory user = users[msg.sender];

        uint256 totalTokens = token.balanceOf(address(this));
        uint256 shares =
            totalSupply == 0 ? amount : (amount * totalSupply) / totalTokens;

        // Did we change our vote? Do this while we know our previous total:
        address currentVote = userVote[msg.sender];
        uint256 extraVotes = shares;
        if (currentVote != operatorVote) {
            if (user.balance > 0) {
                // Safe, because the user must have added their balance before
                votes[currentVote] -= user.balance;
                extraVotes += user.balance;
            }
            userVote[msg.sender] = operatorVote;
        }
        votes[operatorVote] += extraVotes;

        user.balance += shares.to128();
        user.lockedUntil = (block.timestamp + 24 hours).to128();
        users[msg.sender] = user;
        totalSupply += shares;

        token.transferFrom(msg.sender, address(this), amount);

        emit Transfer(address(0), msg.sender, shares);
        return true;
    }

    // Change your vote. Does not lock tokens.
    function vote(address operatorVote) public returns (bool) {
        address currentVote = userVote[msg.sender];
        if (currentVote != operatorVote) {
            User memory user = users[msg.sender];
            if (user.balance > 0) {
                votes[currentVote] -= user.balance;
                votes[operatorVote] += user.balance;
            }
            userVote[msg.sender] = operatorVote;
        }
        return true;
    }

    function _burn(
        address from,
        address to,
        uint256 shares
    ) internal {
        require(to != address(0), "Zero address");
        User memory user = users[from];
        require(block.timestamp >= user.lockedUntil, "Locked");
        uint256 amount =
            (shares * token.balanceOf(address(this))) / totalSupply;
        users[from].balance = user.balance.sub(shares.to128()); // Must check underflow
        totalSupply -= shares;
        votes[userVote[from]] -= shares;

        token.transfer(to, amount);

        emit Transfer(from, address(0), shares);
    }

    function burn(address to, uint256 shares) public returns (bool) {
        _burn(msg.sender, to, shares);
        return true;
    }

    function burnFrom(
        address from,
        address to,
        uint256 shares
    ) public returns (bool) {
        _useAllowance(from, shares);
        _burn(from, to, shares);
        return true;
    }

    event QueueTransaction(
        bytes32 indexed txHash,
        address indexed target,
        uint256 value,
        bytes data,
        uint256 eta
    );
    event CancelTransaction(
        bytes32 indexed txHash,
        address indexed target,
        uint256 value,
        bytes data
    );
    event ExecuteTransaction(
        bytes32 indexed txHash,
        address indexed target,
        uint256 value,
        bytes data
    );

    uint256 public constant GRACE_PERIOD = 14 days;
    uint256 public constant DELAY = 2 days;
    mapping(bytes32 => uint256) public queuedTransactions;

    function queueTransaction(
        address target,
        uint256 value,
        bytes memory data
    ) public returns (bytes32) {
        require(msg.sender == operator, "Operator only");
        require(votes[operator] * 2 > totalSupply, "Not enough votes");

        bytes32 txHash = keccak256(abi.encode(target, value, data));
        uint256 eta = block.timestamp + DELAY;
        queuedTransactions[txHash] = eta;

        emit QueueTransaction(txHash, target, value, data, eta);
        return txHash;
    }

    function cancelTransaction(
        address target,
        uint256 value,
        bytes memory data
    ) public {
        require(msg.sender == operator, "Operator only");

        bytes32 txHash = keccak256(abi.encode(target, value, data));
        queuedTransactions[txHash] = 0;

        emit CancelTransaction(txHash, target, value, data);
    }

    function executeTransaction(
        address target,
        uint256 value,
        bytes memory data
    ) public payable returns (bytes memory) {
        require(msg.sender == operator, "Operator only");
        require(votes[operator] * 2 > totalSupply, "Not enough votes");

        bytes32 txHash = keccak256(abi.encode(target, value, data));
        uint256 eta = queuedTransactions[txHash];
        require(block.timestamp >= eta, "Too early");
        require(block.timestamp <= eta + GRACE_PERIOD, "Tx stale");

        queuedTransactions[txHash] = 0;

        // solium-disable-next-line security/no-call-value
        (bool success, bytes memory returnData) =
            target.call{value: value}(data);
        require(success, "Tx reverted :(");

        emit ExecuteTransaction(txHash, target, value, data);

        return returnData;
    }
}

Read Contract

DELAY 0x69b41170 → uint256
DOMAIN_SEPARATOR 0x3644e515 → bytes32
GRACE_PERIOD 0xc1a287e2 → uint256
allowance 0xdd62ed3e → uint256
balanceOf 0x70a08231 → uint256
decimals 0x313ce567 → uint8
name 0x06fdde03 → string
nonces 0x7ecebe00 → uint256
operator 0x570ca735 → address
pendingOperator 0xac7e534e → address
pendingOperatorTime 0x4881636d → uint256
queuedTransactions 0xf2b06537 → uint256
symbol 0x95d89b41 → string
token 0xfc0c546a → address
totalSupply 0x18160ddd → uint256
userVote 0xf5ba1c87 → address
users 0xa87430ba → uint128, uint128
votes 0xd8bff5a5 → uint256

Write Contract 12 functions

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

approve 0x095ea7b3
address spender
uint256 amount
returns: bool
burn 0x9dc29fac
address to
uint256 shares
returns: bool
burnFrom 0xec60bcf3
address from
address to
uint256 shares
returns: bool
cancelTransaction 0xe37c9fd5
address target
uint256 value
bytes data
executeTransaction 0x3f579f42
address target
uint256 value
bytes data
returns: bytes
mint 0x94bf804d
uint256 amount
address operatorVote
returns: bool
permit 0xd505accf
address owner_
address spender
uint256 value
uint256 deadline
uint8 v
bytes32 r
bytes32 s
queueTransaction 0x80b3b099
address target
uint256 value
bytes data
returns: bytes32
setOperator 0xb3ab15fb
address newOperator
transfer 0xa9059cbb
address to
uint256 shares
returns: bool
transferFrom 0x23b872dd
address from
address to
uint256 shares
returns: bool
vote 0x6dd7d8ea
address operatorVote
returns: bool

Recent Transactions

No transactions found for this address