Address Contract Partially Verified
Address
0xD69F306549e9d96f183B1AecA30B8f4353c2ECC3
Balance
0 ETH
Nonce
1
Code Size
9326 bytes
Creator
0xe7aF1137...8f4a at tx 0x3a55f236...abb347
Indexed Transactions
0
Contract Bytecode
9326 bytes
0x608060405234801561001057600080fd5b50600436106102065760003560e01c806379cc67901161011a578063c2bf17b0116100ad578063dd62ed3e1161007c578063dd62ed3e146106c3578063e7a324dc146106f1578063f1127ed8146106f9578063f5743c4c14610753578063f9613ab21461077957610206565b8063c2bf17b0146105f1578063c3cda52014610623578063d505accf1461066a578063dccf4532146106bb57610206565b8063983b2d56116100e9578063983b2d5614610553578063a9059cbb14610579578063aa271e1a146105a5578063b4b5ea57146105cb57610206565b806379cc6790146104f15780637ecebe001461051d57806380d621131461054357806395d89b411461054b57610206565b8063355274ea1161019d578063587cde1e1161016c578063587cde1e146103dc5780635c19a95c1461041e5780636fcfff451461044457806370a0823114610483578063782d6fe1146104a957610206565b8063355274ea146103835780633644e5151461038b57806342966c6814610393578063449a52f8146103b057610206565b80632a7fbf91116101d95780632a7fbf91146103185780633092afd51461033757806330adf81f1461035d578063313ce5671461036557610206565b806306fdde031461020b578063095ea7b31461028857806318160ddd146102c857806323b872dd146102e2575b600080fd5b610213610796565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561024d578181015183820152602001610235565b50505050905090810190601f16801561027a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102b46004803603604081101561029e57600080fd5b506001600160a01b03813516906020013561082d565b604080519115158252519081900360200190f35b6102d0610844565b60408051918252519081900360200190f35b6102b4600480360360608110156102f857600080fd5b506001600160a01b03813581169160208101359091169060400135610866565b6103356004803603602081101561032e57600080fd5b5035610941565b005b6103356004803603602081101561034d57600080fd5b50356001600160a01b0316610993565b6102d0610a22565b61036d610a46565b6040805160ff9092168252519081900360200190f35b6102d0610a4f565b6102d0610a65565b6102b4600480360360208110156103a957600080fd5b5035610a6b565b6102b4600480360360408110156103c657600080fd5b506001600160a01b038135169060200135610a7f565b610402600480360360208110156103f257600080fd5b50356001600160a01b0316610ad8565b604080516001600160a01b039092168252519081900360200190f35b6103356004803603602081101561043457600080fd5b50356001600160a01b0316610af3565b61046a6004803603602081101561045a57600080fd5b50356001600160a01b0316610b00565b6040805163ffffffff9092168252519081900360200190f35b6102d06004803603602081101561049957600080fd5b50356001600160a01b0316610b18565b6104d5600480360360408110156104bf57600080fd5b506001600160a01b038135169060200135610b3c565b604080516001600160601b039092168252519081900360200190f35b6102b46004803603604081101561050757600080fd5b506001600160a01b038135169060200135610d69565b6102d06004803603602081101561053357600080fd5b50356001600160a01b0316610eb4565b6102d0610ecf565b610213610ed5565b6103356004803603602081101561056957600080fd5b50356001600160a01b0316610f36565b6102b46004803603604081101561058f57600080fd5b506001600160a01b038135169060200135610fc5565b6102b4600480360360208110156105bb57600080fd5b50356001600160a01b0316610fd2565b6104d5600480360360208110156105e157600080fd5b50356001600160a01b0316610fdf565b6104026004803603608081101561060757600080fd5b5080359060ff6020820135169060408101359060600135611050565b610335600480360360c081101561063957600080fd5b506001600160a01b038135169060208101359060408101359060ff6060820135169060808101359060a0013561111e565b610335600480360360e081101561068057600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c0013561124e565b6102d06113c1565b6102d0600480360360408110156106d957600080fd5b506001600160a01b03813581169160200135166113cb565b6102d06113ff565b61072b6004803603604081101561070f57600080fd5b5080356001600160a01b0316906020013563ffffffff16611423565b6040805163ffffffff90931683526001600160601b0390911660208301528051918290030190f35b6102d06004803603602081101561076957600080fd5b50356001600160a01b0316611458565b6102d06004803603602081101561078f57600080fd5b503561147c565b60058054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156108225780601f106107f757610100808354040283529160200191610822565b820191906000526020600020905b81548152906001019060200180831161080557829003601f168201915b505050505090505b90565b600061083a33848461153b565b5060015b92915050565b6000600c546000146108595750600c5461082a565b6108616116c1565b905090565b60006108738484846116d0565b610937843361092973fdcf2339a651e0198f901ed23e2d22f7c2837fa963738198b4876040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156108ca57600080fd5b505af41580156108de573d6000803e3d6000fd5b505050506040513d60208110156108f457600080fd5b50516001600160a01b03891660009081526003602090815260408083203384529091529020546001600160601b0316906118cf565b6001600160601b031661153b565b5060019392505050565b61094c600b33611935565b61098e576040805162461bcd60e51b815260206004820152600e60248201526d26bab9ba1031329036b4b73a32b960911b604482015290519081900360640190fd5b600c55565b61099e600b33611935565b6109e0576040805162461bcd60e51b815260206004820152600e60248201526d26bab9ba1031329036b4b73a32b960911b604482015290519081900360640190fd5b6109eb600b82611954565b6040516001600160a01b038216907fe94479a9f7e1952cc78f2d6baab678adc1b772d936c6583def489e524cb6669290600090a250565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60075460ff1690565b600454600160601b90046001600160601b031690565b60005481565b6000610a7733836119d1565b506001919050565b6000610a8c600b33611935565b610ace576040805162461bcd60e51b815260206004820152600e60248201526d26bab9ba1031329036b4b73a32b960911b604482015290519081900360640190fd5b61083a8383611b67565b6008602052600090815260409020546001600160a01b031681565b610afd3382611d7c565b50565b600a6020526000908152604090205463ffffffff1681565b6001600160a01b03166000908152600260205260409020546001600160601b031690565b6000438210610b7c5760405162461bcd60e51b81526004018080602001828103825260278152602001806123596027913960400191505060405180910390fd5b6001600160a01b0383166000908152600a602052604090205463ffffffff1680610baa57600091505061083e565b6001600160a01b038416600090815260096020908152604080832063ffffffff600019860181168552925290912054168310610c26576001600160a01b03841660009081526009602090815260408083206000199490940163ffffffff1683529290522054600160201b90046001600160601b0316905061083e565b6001600160a01b038416600090815260096020908152604080832083805290915290205463ffffffff16831015610c6157600091505061083e565b600060001982015b8163ffffffff168163ffffffff161115610d2457600282820363ffffffff16048103610c936122fc565b506001600160a01b038716600090815260096020908152604080832063ffffffff858116855290835292819020815180830190925254928316808252600160201b9093046001600160601b03169181019190915290871415610cff5760200151945061083e9350505050565b805163ffffffff16871115610d1657819350610d1d565b6001820392505b5050610c69565b506001600160a01b038516600090815260096020908152604080832063ffffffff909416835292905220546001600160601b03600160201b9091041691505092915050565b60008073fdcf2339a651e0198f901ed23e2d22f7c2837fa963738198b4610d9086336113cb565b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610dc457600080fd5b505af4158015610dd8573d6000803e3d6000fd5b505050506040513d6020811015610dee57600080fd5b505160408051631ce0662d60e21b8152600481018690529051919250600091610e899173fdcf2339a651e0198f901ed23e2d22f7c2837fa99163738198b491602480820192602092909190829003018186803b158015610e4d57600080fd5b505af4158015610e61573d6000803e3d6000fd5b505050506040513d6020811015610e7757600080fd5b50516001600160601b038416906118cf565b6001600160601b03169050610e9f85338361153b565b610ea985856119d1565b506001949350505050565b6001600160a01b031660009081526001602052604090205490565b600c5481565b60068054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156108225780601f106107f757610100808354040283529160200191610822565b610f41600b33611935565b610f83576040805162461bcd60e51b815260206004820152600e60248201526d26bab9ba1031329036b4b73a32b960911b604482015290519081900360640190fd5b610f8e600b826114ba565b6040516001600160a01b038216907f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f690600090a250565b600061083a3384846116d0565b600061083e600b83611935565b6001600160a01b0381166000908152600a602052604081205463ffffffff168061100a576000611049565b6001600160a01b0383166000908152600960209081526040808320600019850163ffffffff168452909152902054600160201b90046001600160601b03165b9392505050565b60008060018686868660405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156110ad573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116611115576040805162461bcd60e51b815260206004820152601960248201527f4552433731323a20696e76616c6964207369676e617475726500000000000000604482015290519081900360640190fd5b95945050505050565b8342111561115d5760405162461bcd60e51b81526004018080602001828103825260228152602001806123ad6022913960400191505060405180910390fd5b604080517fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf6020808301919091526001600160a01b038916828401526060820188905260808083018890528351808403909101815260a0909201909252805191012060006111ca8261147c565b905060006111da82878787611050565b90506111e589611458565b8814611238576040805162461bcd60e51b815260206004820152601e60248201527f4552433230476f7665726e616e63653a20696e76616c6964206e6f6e63650000604482015290519081900360640190fd5b611242818a611d7c565b5050505b505050505050565b4284101561129a576040805162461bcd60e51b8152602060048201526014602482015273115490cc8c14195c9b5a5d0e881156141254915160621b604482015290519081900360640190fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886112c98c611458565b8960405160200180878152602001866001600160a01b03168152602001856001600160a01b03168152602001848152602001838152602001828152602001965050505050505060405160208183030381529060405280519060200120905060006113328261147c565b9050600061134282878787611050565b9050896001600160a01b0316816001600160a01b0316146113aa576040805162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20494e56414c49445f5349474e41545552450000604482015290519081900360640190fd5b6113b58a8a8a61153b565b50505050505050505050565b60006108616116c1565b6001600160a01b0391821660009081526003602090815260408083209390941682529190915220546001600160601b031690565b7fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf81565b600960209081526000928352604080842090915290825290205463ffffffff811690600160201b90046001600160601b031682565b6001600160a01b031660009081526001602081905260409091208054918201905590565b6000546040805161190160f01b6020808301919091526022820193909352604280820194909452815180820390940184526062019052815191012090565b6114c48282611935565b15611516576040805162461bcd60e51b815260206004820152601c60248201527f726f6c6520616c72656164792068617320746865206163636f756e7400000000604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b6001600160a01b0383166115805760405162461bcd60e51b81526004018080602001828103825260248152602001806124156024913960400191505060405180910390fd5b6001600160a01b0382166115c55760405162461bcd60e51b81526004018080602001828103825260228152602001806123376022913960400191505060405180910390fd5b600073fdcf2339a651e0198f901ed23e2d22f7c2837fa963738198b4836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561161657600080fd5b505af415801561162a573d6000803e3d6000fd5b505050506040513d602081101561164057600080fd5b50516001600160a01b0385811660008181526003602090815260408083209489168084529482529182902080546001600160601b0319166001600160601b03871617905581518781529151949550929391927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92592918290030190a350505050565b6004546001600160601b031690565b6001600160a01b0383166117155760405162461bcd60e51b81526004018080602001828103825260258152602001806123f06025913960400191505060405180910390fd5b6001600160a01b03821661175a5760405162461bcd60e51b81526004018080602001828103825260238152602001806123146023913960400191505060405180910390fd5b611765838383611e11565b600073fdcf2339a651e0198f901ed23e2d22f7c2837fa963738198b4836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156117b657600080fd5b505af41580156117ca573d6000803e3d6000fd5b505050506040513d60208110156117e057600080fd5b50516001600160a01b038516600090815260026020526040902054909150611811906001600160601b0316826118cf565b6001600160a01b0385811660009081526002602052604080822080546001600160601b0319166001600160601b0395861617905591861681522054611857911682611ece565b6001600160a01b0384811660008181526002602090815260409182902080546001600160601b0319166001600160601b039690961695909517909455805186815290519193928816927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a350505050565b6000816001600160601b0316836001600160601b0316101561192f576040805162461bcd60e51b81526020600482015260146024820152737375627472616374696f6e206f766572666c6f7760601b604482015290519081900360640190fd5b50900390565b6001600160a01b03166000908152602091909152604090205460ff1690565b61195e8282611935565b6119af576040805162461bcd60e51b815260206004820152601d60248201527f726f6c6520646f73656e2774206861766520746865206163636f756e74000000604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff19169055565b6001600160a01b038216611a165760405162461bcd60e51b81526004018080602001828103825260218152602001806123cf6021913960400191505060405180910390fd5b611a2282600083611e11565b600073fdcf2339a651e0198f901ed23e2d22f7c2837fa963738198b4836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611a7357600080fd5b505af4158015611a87573d6000803e3d6000fd5b505050506040513d6020811015611a9d57600080fd5b5051600454909150611ab8906001600160601b0316826118cf565b600480546001600160601b0319166001600160601b039283161790556001600160a01b038416600090815260026020526040902054611af89116826118cf565b6001600160a01b038416600081815260026020908152604080832080546001600160601b0319166001600160601b03968716179055805194861685525191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a3505050565b6001600160a01b038216611bc2576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b611bce60008383611e11565b600073fdcf2339a651e0198f901ed23e2d22f7c2837fa963738198b4836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611c1f57600080fd5b505af4158015611c33573d6000803e3d6000fd5b505050506040513d6020811015611c4957600080fd5b5051600454909150611c64906001600160601b031682611ece565b600480546001600160601b0319166001600160601b039283161790819055600160601b8104821691161115611ce0576040805162461bcd60e51b815260206004820152601960248201527f45524332304361707065643a2063617020657863656564656400000000000000604482015290519081900360640190fd5b6001600160a01b038316600090815260026020526040902054611d0c906001600160601b031682611ece565b6001600160a01b038416600081815260026020908152604080832080546001600160601b0319166001600160601b039687161790558051948616855251929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a3505050565b6001600160a01b0380831660009081526008602052604081205490911690611da384611f28565b6001600160a01b0385811660008181526008602052604080822080546001600160a01b031916898616908117909155905194955093928616927f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a4611e0b828483611fb3565b50505050565b6001600160a01b03808416600090815260086020908152604080832054868516845292819020548151631ce0662d60e21b8152600481018790529151611ec29594851694919091169273fdcf2339a651e0198f901ed23e2d22f7c2837fa99263738198b49260248083019392829003018186803b158015611e9157600080fd5b505af4158015611ea5573d6000803e3d6000fd5b505050506040513d6020811015611ebb57600080fd5b5051611fb3565b611ec98383835b505050565b60008282016001600160601b038085169082161015611049576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b600073fdcf2339a651e0198f901ed23e2d22f7c2837fa963738198b4611f4d84610b18565b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611f8157600080fd5b505af4158015611f95573d6000803e3d6000fd5b505050506040513d6020811015611fab57600080fd5b505192915050565b816001600160a01b0316836001600160a01b031614158015611fde57506000816001600160601b0316115b15611ec9576001600160a01b03831615612086576001600160a01b0383166000908152600a602052604081205463ffffffff16908161201e57600061205d565b6001600160a01b0385166000908152600960209081526040808320600019860163ffffffff168452909152902054600160201b90046001600160601b03165b905060006120746001600160601b038316856118cf565b905061208286848484612121565b5050505b6001600160a01b03821615611ec9576001600160a01b0382166000908152600a602052604081205463ffffffff1690816120c1576000612100565b6001600160a01b0384166000908152600960209081526040808320600019860163ffffffff168452909152902054600160201b90046001600160601b03165b905060006121176001600160601b03831685611ece565b9050611246858484845b600160201b43106121635760405162461bcd60e51b815260040180806020018281038252602d815260200180612380602d913960400191505060405180910390fd5b4363ffffffff8416158015906121aa57506001600160a01b038516600090815260096020908152604080832063ffffffff6000198901811685529252909120548282169116145b15612209576001600160a01b0385166000908152600960209081526040808320600019880163ffffffff168452909152902080546fffffffffffffffffffffffff000000001916600160201b6001600160601b038516021790556122a8565b60408051808201825263ffffffff80841682526001600160601b0380861660208085019182526001600160a01b038b166000818152600983528781208c871682528352878120965187549451909516600160201b026fffffffffffffffffffffffff000000001995871663ffffffff19958616179590951694909417909555938252600a90935292909220805460018801909316929091169190911790555b604080516001600160601b0380861682528416602082015281516001600160a01b038816927fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724928290030190a25050505050565b60408051808201909152600080825260208201529056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f2061646472657373436f6d703a3a6765745072696f72566f7465733a206e6f74207965742064657465726d696e65644552433230476f7665726e616e63653a20626c6f636b206e756d626572206578636565647320333220626974734552433230476f7665726e616e63653a207369676e6174757265206578706972656445524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f2061646472657373a26469706673582212208acb9c0466222515b6f902e09d1d315baf885ae7a07e873fb43061d6190fc8c964736f6c63430007040033
Verified Source Code Partial Match
Compiler: v0.7.4+commit.3f05b770
EVM: istanbul
Optimization: Yes (200 runs)
MCHCoin.sol 505 lines
// Copyright (c) 2018-2020 double jump.tokyo inc.
pragma solidity 0.7.4;
interface IERC20Permit {
function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
}
interface IERC20WithPermit {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, 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);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
}
interface ICompGovernance {
function delegate(address delegatee) external;
function delegateBySig(address delegatee, uint nonce, uint expiry, uint8 v, bytes32 r, bytes32 s) external;
function getCurrentVotes(address account) external view returns (uint96);
function getPriorVotes(address account, uint blockNumber) external view returns (uint96);
event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);
event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance);
}
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, 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);
}
interface IERC20Optionals {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
library Uint96 {
function cast(uint256 a) public pure returns (uint96) {
require(a < 2**96);
return uint96(a);
}
function add(uint96 a, uint96 b) internal pure returns (uint96) {
uint96 c = a + b;
require(c >= a, "addition overflow");
return c;
}
function sub(uint96 a, uint96 b) internal pure returns (uint96) {
require(a >= b, "subtraction overflow");
return a - b;
}
function mul(uint96 a, uint96 b) internal pure returns (uint96) {
if (a == 0) {
return 0;
}
uint96 c = a * b;
require(c / a == b, "multiplication overflow");
return c;
}
function div(uint96 a, uint96 b) internal pure returns (uint96) {
require(b != 0, "division by 0");
return a / b;
}
function mod(uint96 a, uint96 b) internal pure returns (uint96) {
require(b != 0, "modulo by 0");
return a % b;
}
function toString(uint96 a) internal pure returns (string memory) {
bytes32 retBytes32;
uint96 len = 0;
if (a == 0) {
retBytes32 = "0";
len++;
} else {
uint96 value = a;
while (value > 0) {
retBytes32 = bytes32(uint256(retBytes32) / (2 ** 8));
retBytes32 |= bytes32(((value % 10) + 48) * 2 ** (8 * 31));
value /= 10;
len++;
}
}
bytes memory ret = new bytes(len);
uint96 i;
for (i = 0; i < len; i++) {
ret[i] = retBytes32[i];
}
return string(ret);
}
}
contract EIP712 {
bytes32 private constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)");
bytes32 public DOMAIN_SEPARATOR;
mapping (address => uint) private _nonces;
constructor(string memory name, string memory version) {
uint chainId = getChainId();
DOMAIN_SEPARATOR = keccak256(
abi.encode(
DOMAIN_TYPEHASH,
keccak256(bytes(name)),
keccak256(bytes(version)),
chainId,
address(this)
)
);
}
function getChainId() private pure returns (uint) {
uint chainId;
assembly {
chainId := chainid()
}
return chainId;
}
function nonces(address account) public view returns (uint) {
return _nonces[account];
}
function incrementNonce(address account) public returns (uint) {
return _nonces[account]++;
}
function getDigest(bytes32 structHash) public view returns (bytes32) {
return keccak256(
abi.encodePacked(
'\x19\x01',
DOMAIN_SEPARATOR,
structHash
)
);
}
function recover(bytes32 digest, uint8 v, bytes32 r, bytes32 s) public pure returns (address) {
address recoveredAddress = ecrecover(digest, v, r, s);
require(recoveredAddress != address(0), "ERC712: invalid signature");
return recoveredAddress;
}
}
library Roles {
struct Role {
mapping (address => bool) bearer;
}
function add(Role storage role, address account) internal {
require(!has(role, account), "role already has the account");
role.bearer[account] = true;
}
function remove(Role storage role, address account) internal {
require(has(role, account), "role dosen't have the account");
role.bearer[account] = false;
}
function has(Role storage role, address account) internal view returns (bool) {
return role.bearer[account];
}
}
contract Mintable {
using Roles for Roles.Role;
event MinterAdded(address indexed account);
event MinterRemoved(address indexed account);
Roles.Role private _minters;
constructor() {
_minters.add(msg.sender);
}
modifier onlyMinter() {
require(_minters.has(msg.sender), "Must be minter");
_;
}
function isMinter(address account) public view returns (bool) {
return _minters.has(account);
}
function addMinter(address account) public onlyMinter() {
_minters.add(account);
emit MinterAdded(account);
}
function removeMinter(address account) public onlyMinter() {
_minters.remove(account);
emit MinterRemoved(account);
}
}
abstract contract ERC20Uint96 is IERC20, IERC20Optionals {
using Uint96 for uint96;
mapping (address => uint96) private _balances;
mapping (address => mapping (address => uint96)) private _allowances;
uint96 private _totalSupply;
uint96 private _cap = 2**96-1;
string private _name;
string private _symbol;
uint8 private _decimals;
constructor (string memory tokenName, string memory tokenSymbol, uint96 tokenCap) {
require(tokenCap > 0, "ERC20Capped: cap is 0");
_name = tokenName;
_symbol = tokenSymbol;
_decimals = 18;
_cap = tokenCap;
}
function cap() public view returns (uint256) {
return _cap;
}
function totalSupply() public view override virtual returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view override returns (uint256) {
return _balances[account];
}
function transfer(address recipient, uint256 amount) external override returns (bool) {
_transfer(msg.sender, recipient, amount);
return true;
}
function allowance(address owner, address spender) public view override returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 amount) external override returns (bool) {
_approve(msg.sender, spender, amount);
return true;
}
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
uint96 _amount = Uint96.cast(amount);
_allowances[owner][spender] = _amount;
emit Approval(owner, spender, amount);
}
function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) {
_transfer(sender, recipient, amount);
_approve(sender, msg.sender, _allowances[sender][msg.sender].sub(Uint96.cast(amount)));
return true;
}
function _transfer(address sender, address recipient, uint amount) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
uint96 _amount = Uint96.cast(amount);
_balances[sender] = _balances[sender].sub(_amount);
_balances[recipient] = _balances[recipient].add(_amount);
emit Transfer(sender, recipient, amount);
}
function _beforeTokenTransfer(address sender, address recipient, uint256 amount) internal virtual {}
function _mint(address account, uint amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
uint96 _amount = Uint96.cast(amount);
_totalSupply = _totalSupply.add(_amount);
require(_totalSupply <= _cap, "ERC20Capped: cap exceeded");
_balances[account] = _balances[account].add(_amount);
emit Transfer(address(0), account, _amount);
}
function _burn(address account, uint amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint96 _amount = Uint96.cast(amount);
_totalSupply = _totalSupply.sub(_amount);
_balances[account] = _balances[account].sub(_amount);
emit Transfer(account, address(0), _amount);
}
function name() public view override returns (string memory) {
return _name;
}
function symbol() external view override returns (string memory) {
return _symbol;
}
function decimals() external view override returns (uint8) {
return _decimals;
}
}
abstract contract ERC20Uint96Governance is EIP712, ERC20Uint96, ICompGovernance {
using Uint96 for uint96;
struct Checkpoint {
uint32 fromBlock;
uint96 votes;
}
/// @notice The EIP-712 typehash for the delegation struct used by the contract
bytes32 public constant DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");
mapping (address => address) public delegates;
mapping (address => mapping (uint32 => Checkpoint)) public checkpoints;
mapping (address => uint32) public numCheckpoints;
constructor() {
}
function _beforeTokenTransfer(address sender, address recipient, uint256 amount) internal override {
_moveDelegates(delegates[sender], delegates[recipient], Uint96.cast(amount));
super._beforeTokenTransfer(sender, recipient, amount);
}
function delegate(address delegatee) public override {
return _delegate(msg.sender, delegatee);
}
function delegateBySig(address delegatee, uint nonce, uint deadline, uint8 v, bytes32 r, bytes32 s) public override {
require(block.timestamp <= deadline, "ERC20Governance: signature expired");
bytes32 structHash = keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, deadline));
bytes32 digest = getDigest(structHash);
address signatory = recover(digest, v, r, s);
require(nonce == incrementNonce(delegatee), "ERC20Governance: invalid nonce");
return _delegate(signatory, delegatee);
}
function getCurrentVotes(address account) external view override returns (uint96) {
uint32 nCheckpoints = numCheckpoints[account];
return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;
}
function getPriorVotes(address account, uint blockNumber) public view override returns (uint96) {
require(blockNumber < block.number, "Comp::getPriorVotes: not yet determined");
uint32 nCheckpoints = numCheckpoints[account];
if (nCheckpoints == 0) {
return 0;
}
// First check most recent balance
if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) {
return checkpoints[account][nCheckpoints - 1].votes;
}
// Next check implicit zero balance
if (checkpoints[account][0].fromBlock > blockNumber) {
return 0;
}
uint32 lower = 0;
uint32 upper = nCheckpoints - 1;
while (upper > lower) {
uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow
Checkpoint memory cp = checkpoints[account][center];
if (cp.fromBlock == blockNumber) {
return cp.votes;
} else if (cp.fromBlock < blockNumber) {
lower = center;
} else {
upper = center - 1;
}
}
return checkpoints[account][lower].votes;
}
function _delegate(address delegator, address delegatee) private {
address currentDelegate = delegates[delegator];
uint96 delegatorBalance = _balanceOf(delegator);
delegates[delegator] = delegatee;
emit DelegateChanged(delegator, currentDelegate, delegatee);
_moveDelegates(currentDelegate, delegatee, delegatorBalance);
}
function _moveDelegates(address srcRep, address dstRep, uint96 amount) private {
if (srcRep != dstRep && amount > 0) {
if (srcRep != address(0)) {
uint32 srcRepNum = numCheckpoints[srcRep];
uint96 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0;
uint96 srcRepNew = srcRepOld.sub(amount);
_writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);
}
if (dstRep != address(0)) {
uint32 dstRepNum = numCheckpoints[dstRep];
uint96 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0;
uint96 dstRepNew = dstRepOld.add(amount);
_writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);
}
}
}
function _writeCheckpoint(address delegatee, uint32 nCheckpoints, uint96 oldVotes, uint96 newVotes) private {
require(block.number < 2**32, "ERC20Governance: block number exceeds 32 bits");
uint32 blockNumber = uint32(block.number);
if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) {
checkpoints[delegatee][nCheckpoints - 1].votes = newVotes;
} else {
checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes);
numCheckpoints[delegatee] = nCheckpoints + 1;
}
emit DelegateVotesChanged(delegatee, oldVotes, newVotes);
}
function _balanceOf(address account) private view returns (uint96) {
return Uint96.cast(super.balanceOf(account));
}
}
contract MCHCoin is ERC20Uint96Governance, IERC20Permit, Mintable {
using Uint96 for uint96;
// 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
bytes32 public constant PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
constructor()
ERC20Uint96("MCHCoin","MCHC", 50000000 * 10**18)
EIP712("MCHCoin","1") {
}
uint256 public offchainIssued;
function setOffchainIssued(uint256 _new) external onlyMinter {
offchainIssued = _new;
}
function onchainIssued() external view returns (uint256) {
return super.totalSupply();
}
function totalSupply() public override view returns (uint256) {
if (offchainIssued != 0) {
return offchainIssued;
}
return super.totalSupply();
}
function mintTo(address account, uint amount) external onlyMinter returns (bool) {
_mint(account, amount);
return true;
}
function burn(uint amount) external returns (bool) {
_burn(msg.sender, amount);
return true;
}
function burnFrom(address account, uint amount) external returns (bool) {
uint96 allowance = Uint96.cast(allowance(account, msg.sender));
uint256 decreasedAllowance = allowance.sub(Uint96.cast(amount));
_approve(account, msg.sender, decreasedAllowance);
_burn(account, amount);
return true;
}
function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external override {
require(deadline >= block.timestamp, 'ERC20Permit: EXPIRED');
bytes32 structHash = keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, incrementNonce(owner), deadline));
bytes32 digest = getDigest(structHash);
address recoveredAddress = recover(digest, v, r, s);
require(recoveredAddress == owner, 'ERC20Permit: INVALID_SIGNATURE');
_approve(owner, spender, value);
}
}
Read Contract
DELEGATION_TYPEHASH 0xe7a324dc → bytes32
DOMAIN_SEPARATOR 0x3644e515 → bytes32
PERMIT_TYPEHASH 0x30adf81f → bytes32
allowance 0xdd62ed3e → uint256
balanceOf 0x70a08231 → uint256
cap 0x355274ea → uint256
checkpoints 0xf1127ed8 → uint32, uint96
decimals 0x313ce567 → uint8
delegates 0x587cde1e → address
getCurrentVotes 0xb4b5ea57 → uint96
getDigest 0xf9613ab2 → bytes32
getPriorVotes 0x782d6fe1 → uint96
isMinter 0xaa271e1a → bool
name 0x06fdde03 → string
nonces 0x7ecebe00 → uint256
numCheckpoints 0x6fcfff45 → uint32
offchainIssued 0x80d62113 → uint256
onchainIssued 0xdccf4532 → uint256
recover 0xc2bf17b0 → address
symbol 0x95d89b41 → string
totalSupply 0x18160ddd → uint256
Write Contract 13 functions
These functions modify contract state and require a wallet transaction to execute.
addMinter 0x983b2d56
address account
approve 0x095ea7b3
address spender
uint256 amount
returns: bool
burn 0x42966c68
uint256 amount
returns: bool
burnFrom 0x79cc6790
address account
uint256 amount
returns: bool
delegate 0x5c19a95c
address delegatee
delegateBySig 0xc3cda520
address delegatee
uint256 nonce
uint256 deadline
uint8 v
bytes32 r
bytes32 s
incrementNonce 0xf5743c4c
address account
returns: uint256
mintTo 0x449a52f8
address account
uint256 amount
returns: bool
permit 0xd505accf
address owner
address spender
uint256 value
uint256 deadline
uint8 v
bytes32 r
bytes32 s
removeMinter 0x3092afd5
address account
setOffchainIssued 0x2a7fbf91
uint256 _new
transfer 0xa9059cbb
address recipient
uint256 amount
returns: bool
transferFrom 0x23b872dd
address sender
address recipient
uint256 amount
returns: bool
Recent Transactions
No transactions found for this address