{"matchId":"30785476","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-06-04T04:35:39Z","creationBytecode":{"onchainBytecode":"0x60a060405234801561001057600080fd5b50604051610e56380380610e5683398101604081905261002f916100a1565b61003833610051565b6001600160a01b039092166080526001556002556100e4565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000806000606084860312156100b657600080fd5b83516001600160a01b03811681146100cd57600080fd5b602085015160409095015190969495509392505050565b608051610d4961010d600039600081816101ba0152818161046d01526106a80152610d496000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063715018a61161008c5780638da5cb5b116100665780638da5cb5b1461023b578063a694fc3a1461024c578063bf9befb11461025f578063f2fde38b1461026857600080fd5b8063715018a6146101f457806372f0cb30146101fc5780637a7664601461020f57600080fd5b806330b75e04116100c857806330b75e04146101335780633222012f1461014657806343b0215f1461014f57806368bfce99146101b557600080fd5b80630288a39c146100ef5780632e17de781461010b5780632e1a7d4d14610120575b600080fd5b6100f860025481565b6040519081526020015b60405180910390f35b61011e610119366004610bef565b61027b565b005b61011e61012e366004610bef565b6103da565b61011e610141366004610bef565b6104c6565b6100f860015481565b61018d61015d366004610c08565b60046020819052600091825260409091208054600182015460028301546003840154939094015491939092909185565b604080519586526020860194909452928401919091526060830152608082015260a001610102565b6101dc7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610102565b61011e61055e565b61011e61020a366004610bef565b6105c4565b6100f861021d366004610c08565b6001600160a01b031660009081526004602052604090206002015490565b6000546001600160a01b03166101dc565b61011e61025a366004610bef565b610655565b6100f860035481565b61011e610276366004610c08565b610702565b33600090815260046020526040902060015481546102999190610c47565b4210156102ed5760405162461bcd60e51b815260206004820152601860248201527f756e7374616b652064656c6179206e6f7420706173736564000000000000000060448201526064015b60405180910390fd5b81816002015410156103415760405162461bcd60e51b815260206004820152601a60248201527f696e73756666696369656e74207374616b656420616d6f756e7400000000000060448201526064016102e4565b61034a816107e4565b428160010181905550818160020160008282546103679190610c5f565b92505081905550818160030160008282546103829190610c47565b92505081905550816003600082825461039b9190610c5f565b909155505060405182815233907f0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f75906020015b60405180910390a25050565b3360009081526004602052604090206103f2816107e4565b81816004015410156104465760405162461bcd60e51b815260206004820152601c60248201527f696e73756666696369656e7420756e6c6f636b656420616d6f756e740000000060448201526064016102e4565b8181600401600082825461045a9190610c5f565b9091555061049490506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163384610835565b60405182815233907f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5906020016103ce565b6000546001600160a01b031633146105205760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e4565b600181905560405181815233907f67aa75375fca757eaa536cc0b6855969ff77b119e0ddd3519c6f603dccc460df906020015b60405180910390a250565b6000546001600160a01b031633146105b85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e4565b6105c260006108ca565b565b6000546001600160a01b0316331461061e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e4565b600281905560405181815233907fa4cdbe995bf935cd31b353c9a555c4c7ceb0888e6ddc0f259d552368a319108b90602001610553565b3360009081526004602052604081204281556002810180549192849261067c908490610c47565b9250508190555081600360008282546106959190610c47565b909155506106d090506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333085610932565b60405182815233907f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d906020016103ce565b6000546001600160a01b0316331461075c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e4565b6001600160a01b0381166107d85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102e4565b6107e1816108ca565b50565b60008160030154118015610809575060025481600101546108059190610c47565b4210155b156107e15780600301548160040160008282546108269190610c47565b90915550506000600382015550565b6040516001600160a01b0383166024820152604481018290526108c590849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610970565b505050565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6040516001600160a01b038085166024830152831660448201526064810182905261096a9085906323b872dd60e01b90608401610861565b50505050565b60006109c5826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610a559092919063ffffffff16565b8051909150156108c557808060200190518101906109e39190610c76565b6108c55760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016102e4565b6060610a648484600085610a6e565b90505b9392505050565b606082471015610ae65760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016102e4565b6001600160a01b0385163b610b3d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016102e4565b600080866001600160a01b03168587604051610b599190610cc4565b60006040518083038185875af1925050503d8060008114610b96576040519150601f19603f3d011682016040523d82523d6000602084013e610b9b565b606091505b5091509150610bab828286610bb6565b979650505050505050565b60608315610bc5575081610a67565b825115610bd55782518084602001fd5b8160405162461bcd60e51b81526004016102e49190610ce0565b600060208284031215610c0157600080fd5b5035919050565b600060208284031215610c1a57600080fd5b81356001600160a01b0381168114610a6757600080fd5b634e487b7160e01b600052601160045260246000fd5b60008219821115610c5a57610c5a610c31565b500190565b600082821015610c7157610c71610c31565b500390565b600060208284031215610c8857600080fd5b81518015158114610a6757600080fd5b60005b83811015610cb3578181015183820152602001610c9b565b8381111561096a5750506000910152565b60008251610cd6818460208701610c98565b9190910192915050565b6020815260008251806020840152610cff816040850160208701610c98565b601f01601f1916919091016040019291505056fea264697066735822122029fa20caa730666231f3429f218849c1b4a81c13952dee43dd0e9e4066849c4d64736f6c634300080d0033000000000000000000000000e6df05ce8c8301223373cf5b969afcb1498c55280000000000000000000000000000000000000000000000000000000000093a800000000000000000000000000000000000000000000000000000000000093a80","recompiledBytecode":"0x60a060405234801561001057600080fd5b50604051610e56380380610e5683398101604081905261002f916100a1565b61003833610051565b6001600160a01b039092166080526001556002556100e4565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000806000606084860312156100b657600080fd5b83516001600160a01b03811681146100cd57600080fd5b602085015160409095015190969495509392505050565b608051610d4961010d600039600081816101ba0152818161046d01526106a80152610d496000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063715018a61161008c5780638da5cb5b116100665780638da5cb5b1461023b578063a694fc3a1461024c578063bf9befb11461025f578063f2fde38b1461026857600080fd5b8063715018a6146101f457806372f0cb30146101fc5780637a7664601461020f57600080fd5b806330b75e04116100c857806330b75e04146101335780633222012f1461014657806343b0215f1461014f57806368bfce99146101b557600080fd5b80630288a39c146100ef5780632e17de781461010b5780632e1a7d4d14610120575b600080fd5b6100f860025481565b6040519081526020015b60405180910390f35b61011e610119366004610bef565b61027b565b005b61011e61012e366004610bef565b6103da565b61011e610141366004610bef565b6104c6565b6100f860015481565b61018d61015d366004610c08565b60046020819052600091825260409091208054600182015460028301546003840154939094015491939092909185565b604080519586526020860194909452928401919091526060830152608082015260a001610102565b6101dc7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610102565b61011e61055e565b61011e61020a366004610bef565b6105c4565b6100f861021d366004610c08565b6001600160a01b031660009081526004602052604090206002015490565b6000546001600160a01b03166101dc565b61011e61025a366004610bef565b610655565b6100f860035481565b61011e610276366004610c08565b610702565b33600090815260046020526040902060015481546102999190610c47565b4210156102ed5760405162461bcd60e51b815260206004820152601860248201527f756e7374616b652064656c6179206e6f7420706173736564000000000000000060448201526064015b60405180910390fd5b81816002015410156103415760405162461bcd60e51b815260206004820152601a60248201527f696e73756666696369656e74207374616b656420616d6f756e7400000000000060448201526064016102e4565b61034a816107e4565b428160010181905550818160020160008282546103679190610c5f565b92505081905550818160030160008282546103829190610c47565b92505081905550816003600082825461039b9190610c5f565b909155505060405182815233907f0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f75906020015b60405180910390a25050565b3360009081526004602052604090206103f2816107e4565b81816004015410156104465760405162461bcd60e51b815260206004820152601c60248201527f696e73756666696369656e7420756e6c6f636b656420616d6f756e740000000060448201526064016102e4565b8181600401600082825461045a9190610c5f565b9091555061049490506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163384610835565b60405182815233907f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5906020016103ce565b6000546001600160a01b031633146105205760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e4565b600181905560405181815233907f67aa75375fca757eaa536cc0b6855969ff77b119e0ddd3519c6f603dccc460df906020015b60405180910390a250565b6000546001600160a01b031633146105b85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e4565b6105c260006108ca565b565b6000546001600160a01b0316331461061e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e4565b600281905560405181815233907fa4cdbe995bf935cd31b353c9a555c4c7ceb0888e6ddc0f259d552368a319108b90602001610553565b3360009081526004602052604081204281556002810180549192849261067c908490610c47565b9250508190555081600360008282546106959190610c47565b909155506106d090506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333085610932565b60405182815233907f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d906020016103ce565b6000546001600160a01b0316331461075c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e4565b6001600160a01b0381166107d85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102e4565b6107e1816108ca565b50565b60008160030154118015610809575060025481600101546108059190610c47565b4210155b156107e15780600301548160040160008282546108269190610c47565b90915550506000600382015550565b6040516001600160a01b0383166024820152604481018290526108c590849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610970565b505050565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6040516001600160a01b038085166024830152831660448201526064810182905261096a9085906323b872dd60e01b90608401610861565b50505050565b60006109c5826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610a559092919063ffffffff16565b8051909150156108c557808060200190518101906109e39190610c76565b6108c55760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016102e4565b6060610a648484600085610a6e565b90505b9392505050565b606082471015610ae65760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016102e4565b6001600160a01b0385163b610b3d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016102e4565b600080866001600160a01b03168587604051610b599190610cc4565b60006040518083038185875af1925050503d8060008114610b96576040519150601f19603f3d011682016040523d82523d6000602084013e610b9b565b606091505b5091509150610bab828286610bb6565b979650505050505050565b60608315610bc5575081610a67565b825115610bd55782518084602001fd5b8160405162461bcd60e51b81526004016102e49190610ce0565b600060208284031215610c0157600080fd5b5035919050565b600060208284031215610c1a57600080fd5b81356001600160a01b0381168114610a6757600080fd5b634e487b7160e01b600052601160045260246000fd5b60008219821115610c5a57610c5a610c31565b500190565b600082821015610c7157610c71610c31565b500390565b600060208284031215610c8857600080fd5b81518015158114610a6757600080fd5b60005b83811015610cb3578181015183820152602001610c9b565b8381111561096a5750506000910152565b60008251610cd6818460208701610c98565b9190910192915050565b6020815260008251806020840152610cff816040850160208701610c98565b601f01601f1916919091016040019291505056fea264697066735822122029fa20caa730666231f3429f218849c1b4a81c13952dee43dd0e9e4066849c4d64736f6c634300080d0033","sourceMap":"399:5328:5:-:0;;;2140:211;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;921:32:0;719:10:4;921:18:0;:32::i;:::-;-1:-1:-1;;;;;2254:12:5;;;;;2276;:28;2314:13;:30;399:5328;;2270:187:0;2343:16;2362:6;;-1:-1:-1;;;;;2378:17:0;;;-1:-1:-1;;;;;;2378:17:0;;;;;;2410:40;;2362:6;;;;;;;2410:40;;2343:16;2410:40;2333:124;2270:187;:::o;14:412:6:-;102:6;110;118;171:2;159:9;150:7;146:23;142:32;139:52;;;187:1;184;177:12;139:52;213:16;;-1:-1:-1;;;;;258:31:6;;248:42;;238:70;;304:1;301;294:12;238:70;372:2;357:18;;351:25;416:2;401:18;;;395:25;327:5;;351:25;;-1:-1:-1;395:25:6;14:412;-1:-1:-1;;;14:412:6:o;:::-;399:5328:5;;;;;;;;;;;;;;;;;;;;;;","linkReferences":{},"cborAuxdata":{"1":{"value":"0xa264697066735822122029fa20caa730666231f3429f218849c1b4a81c13952dee43dd0e9e4066849c4d64736f6c634300080d0033","offset":3617}},"transformations":[{"type":"insert","offset":3670,"reason":"constructorArguments"}],"transformationValues":{"constructorArguments":"0x000000000000000000000000e6df05ce8c8301223373cf5b969afcb1498c55280000000000000000000000000000000000000000000000000000000000093a800000000000000000000000000000000000000000000000000000000000093a80"}},"runtimeBytecode":{"onchainBytecode":"0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063715018a61161008c5780638da5cb5b116100665780638da5cb5b1461023b578063a694fc3a1461024c578063bf9befb11461025f578063f2fde38b1461026857600080fd5b8063715018a6146101f457806372f0cb30146101fc5780637a7664601461020f57600080fd5b806330b75e04116100c857806330b75e04146101335780633222012f1461014657806343b0215f1461014f57806368bfce99146101b557600080fd5b80630288a39c146100ef5780632e17de781461010b5780632e1a7d4d14610120575b600080fd5b6100f860025481565b6040519081526020015b60405180910390f35b61011e610119366004610bef565b61027b565b005b61011e61012e366004610bef565b6103da565b61011e610141366004610bef565b6104c6565b6100f860015481565b61018d61015d366004610c08565b60046020819052600091825260409091208054600182015460028301546003840154939094015491939092909185565b604080519586526020860194909452928401919091526060830152608082015260a001610102565b6101dc7f000000000000000000000000e6df05ce8c8301223373cf5b969afcb1498c552881565b6040516001600160a01b039091168152602001610102565b61011e61055e565b61011e61020a366004610bef565b6105c4565b6100f861021d366004610c08565b6001600160a01b031660009081526004602052604090206002015490565b6000546001600160a01b03166101dc565b61011e61025a366004610bef565b610655565b6100f860035481565b61011e610276366004610c08565b610702565b33600090815260046020526040902060015481546102999190610c47565b4210156102ed5760405162461bcd60e51b815260206004820152601860248201527f756e7374616b652064656c6179206e6f7420706173736564000000000000000060448201526064015b60405180910390fd5b81816002015410156103415760405162461bcd60e51b815260206004820152601a60248201527f696e73756666696369656e74207374616b656420616d6f756e7400000000000060448201526064016102e4565b61034a816107e4565b428160010181905550818160020160008282546103679190610c5f565b92505081905550818160030160008282546103829190610c47565b92505081905550816003600082825461039b9190610c5f565b909155505060405182815233907f0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f75906020015b60405180910390a25050565b3360009081526004602052604090206103f2816107e4565b81816004015410156104465760405162461bcd60e51b815260206004820152601c60248201527f696e73756666696369656e7420756e6c6f636b656420616d6f756e740000000060448201526064016102e4565b8181600401600082825461045a9190610c5f565b9091555061049490506001600160a01b037f000000000000000000000000e6df05ce8c8301223373cf5b969afcb1498c5528163384610835565b60405182815233907f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5906020016103ce565b6000546001600160a01b031633146105205760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e4565b600181905560405181815233907f67aa75375fca757eaa536cc0b6855969ff77b119e0ddd3519c6f603dccc460df906020015b60405180910390a250565b6000546001600160a01b031633146105b85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e4565b6105c260006108ca565b565b6000546001600160a01b0316331461061e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e4565b600281905560405181815233907fa4cdbe995bf935cd31b353c9a555c4c7ceb0888e6ddc0f259d552368a319108b90602001610553565b3360009081526004602052604081204281556002810180549192849261067c908490610c47565b9250508190555081600360008282546106959190610c47565b909155506106d090506001600160a01b037f000000000000000000000000e6df05ce8c8301223373cf5b969afcb1498c552816333085610932565b60405182815233907f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d906020016103ce565b6000546001600160a01b0316331461075c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e4565b6001600160a01b0381166107d85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102e4565b6107e1816108ca565b50565b60008160030154118015610809575060025481600101546108059190610c47565b4210155b156107e15780600301548160040160008282546108269190610c47565b90915550506000600382015550565b6040516001600160a01b0383166024820152604481018290526108c590849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610970565b505050565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6040516001600160a01b038085166024830152831660448201526064810182905261096a9085906323b872dd60e01b90608401610861565b50505050565b60006109c5826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610a559092919063ffffffff16565b8051909150156108c557808060200190518101906109e39190610c76565b6108c55760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016102e4565b6060610a648484600085610a6e565b90505b9392505050565b606082471015610ae65760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016102e4565b6001600160a01b0385163b610b3d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016102e4565b600080866001600160a01b03168587604051610b599190610cc4565b60006040518083038185875af1925050503d8060008114610b96576040519150601f19603f3d011682016040523d82523d6000602084013e610b9b565b606091505b5091509150610bab828286610bb6565b979650505050505050565b60608315610bc5575081610a67565b825115610bd55782518084602001fd5b8160405162461bcd60e51b81526004016102e49190610ce0565b600060208284031215610c0157600080fd5b5035919050565b600060208284031215610c1a57600080fd5b81356001600160a01b0381168114610a6757600080fd5b634e487b7160e01b600052601160045260246000fd5b60008219821115610c5a57610c5a610c31565b500190565b600082821015610c7157610c71610c31565b500390565b600060208284031215610c8857600080fd5b81518015158114610a6757600080fd5b60005b83811015610cb3578181015183820152602001610c9b565b8381111561096a5750506000910152565b60008251610cd6818460208701610c98565b9190910192915050565b6020815260008251806020840152610cff816040850160208701610c98565b601f01601f1916919091016040019291505056fea264697066735822122029fa20caa730666231f3429f218849c1b4a81c13952dee43dd0e9e4066849c4d64736f6c634300080d0033","recompiledBytecode":"0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063715018a61161008c5780638da5cb5b116100665780638da5cb5b1461023b578063a694fc3a1461024c578063bf9befb11461025f578063f2fde38b1461026857600080fd5b8063715018a6146101f457806372f0cb30146101fc5780637a7664601461020f57600080fd5b806330b75e04116100c857806330b75e04146101335780633222012f1461014657806343b0215f1461014f57806368bfce99146101b557600080fd5b80630288a39c146100ef5780632e17de781461010b5780632e1a7d4d14610120575b600080fd5b6100f860025481565b6040519081526020015b60405180910390f35b61011e610119366004610bef565b61027b565b005b61011e61012e366004610bef565b6103da565b61011e610141366004610bef565b6104c6565b6100f860015481565b61018d61015d366004610c08565b60046020819052600091825260409091208054600182015460028301546003840154939094015491939092909185565b604080519586526020860194909452928401919091526060830152608082015260a001610102565b6101dc7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610102565b61011e61055e565b61011e61020a366004610bef565b6105c4565b6100f861021d366004610c08565b6001600160a01b031660009081526004602052604090206002015490565b6000546001600160a01b03166101dc565b61011e61025a366004610bef565b610655565b6100f860035481565b61011e610276366004610c08565b610702565b33600090815260046020526040902060015481546102999190610c47565b4210156102ed5760405162461bcd60e51b815260206004820152601860248201527f756e7374616b652064656c6179206e6f7420706173736564000000000000000060448201526064015b60405180910390fd5b81816002015410156103415760405162461bcd60e51b815260206004820152601a60248201527f696e73756666696369656e74207374616b656420616d6f756e7400000000000060448201526064016102e4565b61034a816107e4565b428160010181905550818160020160008282546103679190610c5f565b92505081905550818160030160008282546103829190610c47565b92505081905550816003600082825461039b9190610c5f565b909155505060405182815233907f0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f75906020015b60405180910390a25050565b3360009081526004602052604090206103f2816107e4565b81816004015410156104465760405162461bcd60e51b815260206004820152601c60248201527f696e73756666696369656e7420756e6c6f636b656420616d6f756e740000000060448201526064016102e4565b8181600401600082825461045a9190610c5f565b9091555061049490506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163384610835565b60405182815233907f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5906020016103ce565b6000546001600160a01b031633146105205760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e4565b600181905560405181815233907f67aa75375fca757eaa536cc0b6855969ff77b119e0ddd3519c6f603dccc460df906020015b60405180910390a250565b6000546001600160a01b031633146105b85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e4565b6105c260006108ca565b565b6000546001600160a01b0316331461061e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e4565b600281905560405181815233907fa4cdbe995bf935cd31b353c9a555c4c7ceb0888e6ddc0f259d552368a319108b90602001610553565b3360009081526004602052604081204281556002810180549192849261067c908490610c47565b9250508190555081600360008282546106959190610c47565b909155506106d090506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333085610932565b60405182815233907f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d906020016103ce565b6000546001600160a01b0316331461075c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e4565b6001600160a01b0381166107d85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102e4565b6107e1816108ca565b50565b60008160030154118015610809575060025481600101546108059190610c47565b4210155b156107e15780600301548160040160008282546108269190610c47565b90915550506000600382015550565b6040516001600160a01b0383166024820152604481018290526108c590849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610970565b505050565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6040516001600160a01b038085166024830152831660448201526064810182905261096a9085906323b872dd60e01b90608401610861565b50505050565b60006109c5826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610a559092919063ffffffff16565b8051909150156108c557808060200190518101906109e39190610c76565b6108c55760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016102e4565b6060610a648484600085610a6e565b90505b9392505050565b606082471015610ae65760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016102e4565b6001600160a01b0385163b610b3d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016102e4565b600080866001600160a01b03168587604051610b599190610cc4565b60006040518083038185875af1925050503d8060008114610b96576040519150601f19603f3d011682016040523d82523d6000602084013e610b9b565b606091505b5091509150610bab828286610bb6565b979650505050505050565b60608315610bc5575081610a67565b825115610bd55782518084602001fd5b8160405162461bcd60e51b81526004016102e49190610ce0565b600060208284031215610c0157600080fd5b5035919050565b600060208284031215610c1a57600080fd5b81356001600160a01b0381168114610a6757600080fd5b634e487b7160e01b600052601160045260246000fd5b60008219821115610c5a57610c5a610c31565b500190565b600082821015610c7157610c71610c31565b500390565b600060208284031215610c8857600080fd5b81518015158114610a6757600080fd5b60005b83811015610cb3578181015183820152602001610c9b565b8381111561096a5750506000910152565b60008251610cd6818460208701610c98565b9190910192915050565b6020815260008251806020840152610cff816040850160208701610c98565b601f01601f1916919091016040019291505056fea264697066735822122029fa20caa730666231f3429f218849c1b4a81c13952dee43dd0e9e4066849c4d64736f6c634300080d0033","sourceMap":"399:5328:5:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1659:28;;;;;;;;;160:25:6;;;148:2;133:18;1659:28:5;;;;;;;;3414:514;;;;;;:::i;:::-;;:::i;:::-;;4091:384;;;;;;:::i;:::-;;:::i;5263:173::-;;;;;;:::i;:::-;;:::i;1552:27::-;;;;;;1798:45;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;954:25:6;;;1010:2;995:18;;988:34;;;;1038:18;;;1031:34;;;;1096:2;1081:18;;1074:34;1139:3;1124:19;;1117:35;941:3;926:19;1798:45:5;695:463:6;1447:29:5;;;;;;;;-1:-1:-1;;;;;1327:55:6;;;1309:74;;1297:2;1282:18;1447:29:5;1163:226:6;1668:101:0;;;:::i;5546:179:5:-;;;;;;:::i;:::-;;:::i;4989:111::-;;;;;;:::i;:::-;-1:-1:-1;;;;;5071:16:5;5045:7;5071:16;;;:9;:16;;;;;:22;;;;4989:111;1036:85:0;1082:7;1108:6;-1:-1:-1;;;;;1108:6:0;1036:85;;2494:330:5;;;;;;:::i;:::-;;:::i;1727:26::-;;;;;;1918:198:0;;;;;;:::i;:::-;;:::i;3414:514:5:-;3501:10;3467:21;3491;;;:9;:21;;;;;3570:12;;3549:18;;:33;;3570:12;3549:33;:::i;:::-;3530:15;:52;;3522:89;;;;-1:-1:-1;;;3522:89:5;;1861:2:6;3522:89:5;;;1843:21:6;1900:2;1880:18;;;1873:30;1939:26;1919:18;;;1912:54;1983:18;;3522:89:5;;;;;;;;;3643:7;3629:4;:10;;;:21;;3621:60;;;;-1:-1:-1;;;3621:60:5;;2214:2:6;3621:60:5;;;2196:21:6;2253:2;2233:18;;;2226:30;2292:28;2272:18;;;2265:56;2338:18;;3621:60:5;2012:350:6;3621:60:5;3692:27;3714:4;3692:21;:27::i;:::-;3752:15;3729:4;:20;;:38;;;;3791:7;3777:4;:10;;;:21;;;;;;;:::i;:::-;;;;;;;;3837:7;3808:4;:25;;;:36;;;;;;;:::i;:::-;;;;;;;;3869:7;3854:11;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;3892:29:5;;160:25:6;;;3901:10:5;;3892:29;;148:2:6;133:18;3892:29:5;;;;;;;;3457:471;3414:514;:::o;4091:384::-;4179:10;4145:21;4169;;;:9;:21;;;;;4200:27;4169:21;4200;:27::i;:::-;4277:7;4246:4;:27;;;:38;;4238:79;;;;-1:-1:-1;;;4238:79:5;;2699:2:6;4238:79:5;;;2681:21:6;2738:2;2718:18;;;2711:30;2777;2757:18;;;2750:58;2825:18;;4238:79:5;2497:352:6;4238:79:5;4359:7;4328:4;:27;;;:38;;;;;;;:::i;:::-;;;;-1:-1:-1;4377:46:5;;-1:-1:-1;;;;;;4384:4:5;4377:25;4403:10;4415:7;4377:25;:46::i;:::-;4438:30;;160:25:6;;;4448:10:5;;4438:30;;148:2:6;133:18;4438:30:5;14:177:6;5263:173:5;1082:7:0;1108:6;-1:-1:-1;;;;;1108:6:0;719:10:4;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;3056:2:6;1240:68:0;;;3038:21:6;;;3075:18;;;3068:30;3134:34;3114:18;;;3107:62;3186:18;;1240:68:0;2854:356:6;1240:68:0;5340:12:5::1;:28:::0;;;5383:46:::1;::::0;160:25:6;;;5403:10:5::1;::::0;5383:46:::1;::::0;148:2:6;133:18;5383:46:5::1;;;;;;;;5263:173:::0;:::o;1668:101:0:-;1082:7;1108:6;-1:-1:-1;;;;;1108:6:0;719:10:4;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;3056:2:6;1240:68:0;;;3038:21:6;;;3075:18;;;3068:30;3134:34;3114:18;;;3107:62;3186:18;;1240:68:0;2854:356:6;1240:68:0;1732:30:::1;1759:1;1732:18;:30::i;:::-;1668:101::o:0;5546:179:5:-;1082:7:0;1108:6;-1:-1:-1;;;;;1108:6:0;719:10:4;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;3056:2:6;1240:68:0;;;3038:21:6;;;3075:18;;;3068:30;3134:34;3114:18;;;3107:62;3186:18;;1240:68:0;2854:356:6;1240:68:0;5625:13:5::1;:30:::0;;;5670:48:::1;::::0;160:25:6;;;5691:10:5::1;::::0;5670:48:::1;::::0;148:2:6;133:18;5670:48:5::1;14:177:6::0;2494:330:5;2579:10;2545:21;2569;;;:9;:21;;;;;2621:15;2600:36;;2646:10;;;:21;;2569;;2660:7;;2646:21;;2660:7;;2646:21;:::i;:::-;;;;;;;;2692:7;2677:11;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;2710:65:5;;-1:-1:-1;;;;;;2717:4:5;2710:29;2740:10;2760:4;2767:7;2710:29;:65::i;:::-;2790:27;;160:25:6;;;2797:10:5;;2790:27;;148:2:6;133:18;2790:27:5;14:177:6;1918:198:0;1082:7;1108:6;-1:-1:-1;;;;;1108:6:0;719:10:4;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;3056:2:6;1240:68:0;;;3038:21:6;;;3075:18;;;3068:30;3134:34;3114:18;;;3107:62;3186:18;;1240:68:0;2854:356:6;1240:68:0;-1:-1:-1;;;;;2006:22:0;::::1;1998:73;;;::::0;-1:-1:-1;;;1998:73:0;;3417:2:6;1998:73:0::1;::::0;::::1;3399:21:6::0;3456:2;3436:18;;;3429:30;3495:34;3475:18;;;3468:62;3566:8;3546:18;;;3539:36;3592:19;;1998:73:0::1;3215:402:6::0;1998:73:0::1;2081:28;2100:8;2081:18;:28::i;:::-;1918:198:::0;:::o;4577:303:5:-;4684:1;4655:5;:26;;;:30;:90;;;;;4732:13;;4708:5;:21;;;:37;;;;:::i;:::-;4689:15;:56;;4655:90;4651:223;;;4793:5;:26;;;4761:5;:28;;;:58;;;;;;;:::i;:::-;;;;-1:-1:-1;;4862:1:5;4833:26;;;:30;4577:303;:::o;701:205:2:-;840:58;;-1:-1:-1;;;;;3814:55:6;;840:58:2;;;3796:74:6;3886:18;;;3879:34;;;813:86:2;;833:5;;-1:-1:-1;;;863:23:2;3769:18:6;;840:58:2;;;;-1:-1:-1;;840:58:2;;;;;;;;;;;;;;;;;;;;;;;;;;;813:19;:86::i;:::-;701:205;;;:::o;2270:187:0:-;2343:16;2362:6;;-1:-1:-1;;;;;2378:17:0;;;;;;;;;;2410:40;;2362:6;;;;;;;2410:40;;2343:16;2410:40;2333:124;2270:187;:::o;912:241:2:-;1077:68;;-1:-1:-1;;;;;4205:15:6;;;1077:68:2;;;4187:34:6;4257:15;;4237:18;;;4230:43;4289:18;;;4282:34;;;1050:96:2;;1070:5;;-1:-1:-1;;;1100:27:2;4099:18:6;;1077:68:2;3924:398:6;1050:96:2;912:241;;;;:::o;3207:706::-;3626:23;3652:69;3680:4;3652:69;;;;;;;;;;;;;;;;;3660:5;-1:-1:-1;;;;;3652:27:2;;;:69;;;;;:::i;:::-;3735:17;;3626:95;;-1:-1:-1;3735:21:2;3731:176;;3830:10;3819:30;;;;;;;;;;;;:::i;:::-;3811:85;;;;-1:-1:-1;;;3811:85:2;;4811:2:6;3811:85:2;;;4793:21:6;4850:2;4830:18;;;4823:30;4889:34;4869:18;;;4862:62;4960:12;4940:18;;;4933:40;4990:19;;3811:85:2;4609:406:6;3861:223:3;3994:12;4025:52;4047:6;4055:4;4061:1;4064:12;4025:21;:52::i;:::-;4018:59;;3861:223;;;;;;:::o;4948:499::-;5113:12;5170:5;5145:21;:30;;5137:81;;;;-1:-1:-1;;;5137:81:3;;5222:2:6;5137:81:3;;;5204:21:6;5261:2;5241:18;;;5234:30;5300:34;5280:18;;;5273:62;5371:8;5351:18;;;5344:36;5397:19;;5137:81:3;5020:402:6;5137:81:3;-1:-1:-1;;;;;1465:19:3;;;5228:60;;;;-1:-1:-1;;;5228:60:3;;5629:2:6;5228:60:3;;;5611:21:6;5668:2;5648:18;;;5641:30;5707:31;5687:18;;;5680:59;5756:18;;5228:60:3;5427:353:6;5228:60:3;5300:12;5314:23;5341:6;-1:-1:-1;;;;;5341:11:3;5360:5;5367:4;5341:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5299:73;;;;5389:51;5406:7;5415:10;5427:12;5389:16;:51::i;:::-;5382:58;4948:499;-1:-1:-1;;;;;;;4948:499:3:o;7561:692::-;7707:12;7735:7;7731:516;;;-1:-1:-1;7765:10:3;7758:17;;7731:516;7876:17;;:21;7872:365;;8070:10;8064:17;8130:15;8117:10;8113:2;8109:19;8102:44;7872:365;8209:12;8202:20;;-1:-1:-1;;;8202:20:3;;;;;;;;:::i;196:180:6:-;255:6;308:2;296:9;287:7;283:23;279:32;276:52;;;324:1;321;314:12;276:52;-1:-1:-1;347:23:6;;196:180;-1:-1:-1;196:180:6:o;381:309::-;440:6;493:2;481:9;472:7;468:23;464:32;461:52;;;509:1;506;499:12;461:52;548:9;535:23;-1:-1:-1;;;;;591:5:6;587:54;580:5;577:65;567:93;;656:1;653;646:12;1394:127;1455:10;1450:3;1446:20;1443:1;1436:31;1486:4;1483:1;1476:15;1510:4;1507:1;1500:15;1526:128;1566:3;1597:1;1593:6;1590:1;1587:13;1584:39;;;1603:18;;:::i;:::-;-1:-1:-1;1639:9:6;;1526:128::o;2367:125::-;2407:4;2435:1;2432;2429:8;2426:34;;;2440:18;;:::i;:::-;-1:-1:-1;2477:9:6;;2367:125::o;4327:277::-;4394:6;4447:2;4435:9;4426:7;4422:23;4418:32;4415:52;;;4463:1;4460;4453:12;4415:52;4495:9;4489:16;4548:5;4541:13;4534:21;4527:5;4524:32;4514:60;;4570:1;4567;4560:12;5785:258;5857:1;5867:113;5881:6;5878:1;5875:13;5867:113;;;5957:11;;;5951:18;5938:11;;;5931:39;5903:2;5896:10;5867:113;;;5998:6;5995:1;5992:13;5989:48;;;-1:-1:-1;;6033:1:6;6015:16;;6008:27;5785:258::o;6048:274::-;6177:3;6215:6;6209:13;6231:53;6277:6;6272:3;6265:4;6257:6;6253:17;6231:53;:::i;:::-;6300:16;;;;;6048:274;-1:-1:-1;;6048:274:6:o;6327:383::-;6476:2;6465:9;6458:21;6439:4;6508:6;6502:13;6551:6;6546:2;6535:9;6531:18;6524:34;6567:66;6626:6;6621:2;6610:9;6606:18;6601:2;6593:6;6589:15;6567:66;:::i;:::-;6694:2;6673:15;-1:-1:-1;;6669:29:6;6654:45;;;;6701:2;6650:54;;6327:383;-1:-1:-1;;6327:383:6:o","linkReferences":{},"cborAuxdata":{"1":{"value":"0xa264697066735822122029fa20caa730666231f3429f218849c1b4a81c13952dee43dd0e9e4066849c4d64736f6c634300080d0033","offset":3348}},"immutableReferences":{"778":[{"start":442,"length":32},{"start":1133,"length":32},{"start":1704,"length":32}]},"transformations":[{"id":"778","type":"replace","offset":442,"reason":"immutable"},{"id":"778","type":"replace","offset":1133,"reason":"immutable"},{"id":"778","type":"replace","offset":1704,"reason":"immutable"}],"transformationValues":{"immutables":{"778":"0x000000000000000000000000e6df05ce8c8301223373cf5b969afcb1498c5528"}}},"deployment":{"transactionHash":"0x5b5ab2183778718de40dad90afa110981e2c8d4e2808c34a57e157c0916145f4","blockNumber":"16396990","transactionIndex":"133","deployer":"0xa044D502c7E23840dcD5997Fb3Ba85a6DE5763E4"},"sources":{"@openzeppelin/contracts/access/Ownable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    constructor() {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n        _;\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby removing any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"},"@openzeppelin/contracts/token/ERC20/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(\n        address from,\n        address to,\n        uint256 amount\n    ) external returns (bool);\n\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"},"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    using Address for address;\n\n    function safeTransfer(\n        IERC20 token,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    function safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n    }\n\n    /**\n     * @dev Deprecated. This function has issues similar to the ones found in\n     * {IERC20-approve}, and its usage is discouraged.\n     *\n     * Whenever possible, use {safeIncreaseAllowance} and\n     * {safeDecreaseAllowance} instead.\n     */\n    function safeApprove(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        // safeApprove should only be called when setting an initial allowance,\n        // or when resetting it to zero. To increase and decrease it, use\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n        require(\n            (value == 0) || (token.allowance(address(this), spender) == 0),\n            \"SafeERC20: approve from non-zero to non-zero allowance\"\n        );\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n    }\n\n    function safeIncreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        uint256 newAllowance = token.allowance(address(this), spender) + value;\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n    }\n\n    function safeDecreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        unchecked {\n            uint256 oldAllowance = token.allowance(address(this), spender);\n            require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n            uint256 newAllowance = oldAllowance - value;\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n        if (returndata.length > 0) {\n            // Return data is optional\n            require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n        }\n    }\n}\n"},"@openzeppelin/contracts/utils/Address.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        require(isContract(target), \"Address: call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        require(isContract(target), \"Address: static call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(isContract(target), \"Address: delegate call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert(errorMessage);\n            }\n        }\n    }\n}\n"},"@openzeppelin/contracts/utils/Context.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n}\n"},"contracts/Staking.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.13;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/**\n * @title A simple staking contract with delays for unstake and withdraw operations.\n * Staking KOGE is required for participating in BNB48 DAO governance.\n */\ncontract Staking is Ownable {\n    using SafeERC20 for IERC20;\n\n    struct UserInfo {\n        // The last time the user called `stake`.\n        uint256 lastStakeTime;\n        // The last time the user called `unstake`.\n        uint256 lastUnstakeTime;\n        // The current stake of the user.\n        uint256 stake;\n        // The current amount of unstaked but locked tokens for the user. These are withdrawable\n        // after `withdrawDelay` has passed.\n        uint256 lockedUnstakedAmount;\n        // The current amount of unstaked and unlocked, but not-yet-withdrawn tokens for the user.\n        uint256 unlockedUnstakedAmount;\n    }\n\n    // Events\n    event Staked(address indexed user, uint256 amount);\n    event Unstaked(address indexed user, uint256 amount);\n    event Withdrawn(address indexed user, uint256 amount);\n    // Admin events\n    event UnstakeDelayUpdated(address indexed caller, uint256 unstakeDelay);\n    event WithdrawDelayUpdated(address indexed caller, uint256 withdrawDelay);\n\n    // The address of the KOGE token.\n    address public immutable koge;\n    // Required delay to unstake after a stake operation, in seconds.\n    uint256 public unstakeDelay;\n    // Required delay to withdraw after an unstake operation, in seconds.\n    uint256 public withdrawDelay;\n\n    // The current total stakes.\n    uint256 public totalStakes;\n    // The staking info for each user.\n    mapping(address => UserInfo) public userInfos;\n\n    /**\n     * @notice Staking constructor.\n     * @param _koge The address of the KOGE token.\n     * @param _unstakeDelay Required delay to unstake after a stake operation, in seconds.\n     * @param _withdrawDelay Required delay to withdraw after an unstake operation, in seconds.\n     */\n    constructor(\n        address _koge,\n        uint256 _unstakeDelay,\n        uint256 _withdrawDelay\n    ) {\n        koge = _koge;\n        unstakeDelay = _unstakeDelay;\n        withdrawDelay = _withdrawDelay;\n    }\n\n    /**\n     * @notice Stake into the contract. Resets `lastStakeTime`.\n     * @param _amount The amount of KOGE token to stake.\n     */\n    function stake(uint256 _amount) external {\n        UserInfo storage user = userInfos[msg.sender];\n        user.lastStakeTime = block.timestamp;\n        user.stake += _amount;\n        totalStakes += _amount;\n\n        IERC20(koge).safeTransferFrom(msg.sender, address(this), _amount);\n        emit Staked(msg.sender, _amount);\n    }\n\n    /**\n     * @notice Unstake from the contract after `unstakeDelay` has passed. This reduces the stake of the user\n     * immediately, but the tokens are not withdrawable until `withdrawDelay` has passed. Resets `lastUnstakeTime`.\n     * NOTE: This unlocks unstaked amount only after `withdrawDelay` has passed since `lastUnstakeTime`. Additional\n     * unstake operations before `withdrawDelay` has passed since `lastUnstakeTime` will effectively extend the lockup\n     * period of the previously unstaked amount.\n     * @param _amount The amount of KOGE token to unstake.\n     */\n    function unstake(uint256 _amount) external {\n        UserInfo storage user = userInfos[msg.sender];\n        require(block.timestamp >= user.lastStakeTime + unstakeDelay, \"unstake delay not passed\");\n        require(user.stake >= _amount, \"insufficient staked amount\");\n\n        _unlockUnstakedAmount(user);\n        user.lastUnstakeTime = block.timestamp;\n        user.stake -= _amount;\n        user.lockedUnstakedAmount += _amount;\n        totalStakes -= _amount;\n\n        emit Unstaked(msg.sender, _amount);\n    }\n\n    /**\n     * @notice Withdraw KOGE from the contract after `withdrawDelay` has passed.\n     * @param _amount The amount of KOGE token to withdraw.\n     */\n    function withdraw(uint256 _amount) external {\n        UserInfo storage user = userInfos[msg.sender];\n        _unlockUnstakedAmount(user);\n\n        require(user.unlockedUnstakedAmount >= _amount, \"insufficient unlocked amount\");\n\n        user.unlockedUnstakedAmount -= _amount;\n\n        IERC20(koge).safeTransfer(msg.sender, _amount);\n        emit Withdrawn(msg.sender, _amount);\n    }\n\n    /**\n     * @dev Updates the unlocked unstaked amount.\n     * @param _user The user.\n     */\n    function _unlockUnstakedAmount(UserInfo storage _user) internal {\n        if (_user.lockedUnstakedAmount > 0 && block.timestamp >= _user.lastUnstakeTime + withdrawDelay) {\n            _user.unlockedUnstakedAmount += _user.lockedUnstakedAmount;\n            _user.lockedUnstakedAmount = 0;\n        }\n    }\n\n    /**\n     * @notice Gets the current stake of a user.\n     * @param _user The user address.\n     */\n    function getStake(address _user) external view returns (uint256) {\n        return userInfos[_user].stake;\n    }\n\n    // -------------------- Admin --------------------\n\n    /**\n     * @dev Sets `unstakeDelay`.\n     * @param _unstakeDelay The new `unstakeDelay`.\n     */\n    function setUnstakeDelay(uint256 _unstakeDelay) external onlyOwner {\n        unstakeDelay = _unstakeDelay;\n        emit UnstakeDelayUpdated(msg.sender, _unstakeDelay);\n    }\n\n    /**\n     * @dev Sets `withdrawDelay`.\n     * @param _withdrawDelay The new `withdrawDelay`.\n     */\n    function setWithdrawDelay(uint256 _withdrawDelay) external onlyOwner {\n        withdrawDelay = _withdrawDelay;\n        emit WithdrawDelayUpdated(msg.sender, _withdrawDelay);\n    }\n}\n"}},"compilation":{"language":"Solidity","compiler":"solc","compilerVersion":"0.8.13+commit.abaa5c0e","compilerSettings":{"metadata":{"bytecodeHash":"ipfs","useLiteralContent":true},"libraries":{},"optimizer":{"runs":800,"enabled":true},"evmVersion":"london","remappings":[]},"name":"Staking","fullyQualifiedName":"contracts/Staking.sol:Staking"},"abi":[{"type":"constructor","inputs":[{"name":"_koge","type":"address","internalType":"address"},{"name":"_unstakeDelay","type":"uint256","internalType":"uint256"},{"name":"_withdrawDelay","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"name":"OwnershipTransferred","type":"event","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"Staked","type":"event","inputs":[{"name":"user","type":"address","indexed":true,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"UnstakeDelayUpdated","type":"event","inputs":[{"name":"caller","type":"address","indexed":true,"internalType":"address"},{"name":"unstakeDelay","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"Unstaked","type":"event","inputs":[{"name":"user","type":"address","indexed":true,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"WithdrawDelayUpdated","type":"event","inputs":[{"name":"caller","type":"address","indexed":true,"internalType":"address"},{"name":"withdrawDelay","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"Withdrawn","type":"event","inputs":[{"name":"user","type":"address","indexed":true,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"getStake","type":"function","inputs":[{"name":"_user","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"koge","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"owner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"renounceOwnership","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"setUnstakeDelay","type":"function","inputs":[{"name":"_unstakeDelay","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setWithdrawDelay","type":"function","inputs":[{"name":"_withdrawDelay","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"stake","type":"function","inputs":[{"name":"_amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"totalStakes","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"transferOwnership","type":"function","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"unstake","type":"function","inputs":[{"name":"_amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"unstakeDelay","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"userInfos","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"lastStakeTime","type":"uint256","internalType":"uint256"},{"name":"lastUnstakeTime","type":"uint256","internalType":"uint256"},{"name":"stake","type":"uint256","internalType":"uint256"},{"name":"lockedUnstakedAmount","type":"uint256","internalType":"uint256"},{"name":"unlockedUnstakedAmount","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"withdraw","type":"function","inputs":[{"name":"_amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"withdrawDelay","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"}],"metadata":{"compiler":{"version":"0.8.13+commit.abaa5c0e"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"_koge","type":"address"},{"internalType":"uint256","name":"_unstakeDelay","type":"uint256"},{"internalType":"uint256","name":"_withdrawDelay","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"unstakeDelay","type":"uint256"}],"name":"UnstakeDelayUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Unstaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"withdrawDelay","type":"uint256"}],"name":"WithdrawDelayUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"koge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_unstakeDelay","type":"uint256"}],"name":"setUnstakeDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_withdrawDelay","type":"uint256"}],"name":"setWithdrawDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalStakes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unstakeDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userInfos","outputs":[{"internalType":"uint256","name":"lastStakeTime","type":"uint256"},{"internalType":"uint256","name":"lastUnstakeTime","type":"uint256"},{"internalType":"uint256","name":"stake","type":"uint256"},{"internalType":"uint256","name":"lockedUnstakedAmount","type":"uint256"},{"internalType":"uint256","name":"unlockedUnstakedAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}],"devdoc":{"kind":"dev","methods":{"constructor":{"params":{"_koge":"The address of the KOGE token.","_unstakeDelay":"Required delay to unstake after a stake operation, in seconds.","_withdrawDelay":"Required delay to withdraw after an unstake operation, in seconds."}},"getStake(address)":{"params":{"_user":"The user address."}},"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"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."},"setUnstakeDelay(uint256)":{"details":"Sets `unstakeDelay`.","params":{"_unstakeDelay":"The new `unstakeDelay`."}},"setWithdrawDelay(uint256)":{"details":"Sets `withdrawDelay`.","params":{"_withdrawDelay":"The new `withdrawDelay`."}},"stake(uint256)":{"params":{"_amount":"The amount of KOGE token to stake."}},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."},"unstake(uint256)":{"params":{"_amount":"The amount of KOGE token to unstake."}},"withdraw(uint256)":{"params":{"_amount":"The amount of KOGE token to withdraw."}}},"title":"A simple staking contract with delays for unstake and withdraw operations. Staking KOGE is required for participating in BNB48 DAO governance.","version":1},"userdoc":{"kind":"user","methods":{"constructor":{"notice":"Staking constructor."},"getStake(address)":{"notice":"Gets the current stake of a user."},"stake(uint256)":{"notice":"Stake into the contract. Resets `lastStakeTime`."},"unstake(uint256)":{"notice":"Unstake from the contract after `unstakeDelay` has passed. This reduces the stake of the user immediately, but the tokens are not withdrawable until `withdrawDelay` has passed. Resets `lastUnstakeTime`. NOTE: This unlocks unstaked amount only after `withdrawDelay` has passed since `lastUnstakeTime`. Additional unstake operations before `withdrawDelay` has passed since `lastUnstakeTime` will effectively extend the lockup period of the previously unstaked amount."},"withdraw(uint256)":{"notice":"Withdraw KOGE from the contract after `withdrawDelay` has passed."}},"version":1}},"settings":{"compilationTarget":{"contracts/Staking.sol":"Staking"},"evmVersion":"london","libraries":{},"metadata":{"bytecodeHash":"ipfs","useLiteralContent":true},"optimizer":{"enabled":true,"runs":800},"remappings":[]},"sources":{"@openzeppelin/contracts/access/Ownable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    constructor() {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n        _;\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby removing any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n","keccak256":"0x24e0364e503a9bbde94c715d26573a76f14cd2a202d45f96f52134ab806b67b9","license":"MIT"},"@openzeppelin/contracts/token/ERC20/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(\n        address from,\n        address to,\n        uint256 amount\n    ) external returns (bool);\n\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n","keccak256":"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2","license":"MIT"},"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    using Address for address;\n\n    function safeTransfer(\n        IERC20 token,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    function safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n    }\n\n    /**\n     * @dev Deprecated. This function has issues similar to the ones found in\n     * {IERC20-approve}, and its usage is discouraged.\n     *\n     * Whenever possible, use {safeIncreaseAllowance} and\n     * {safeDecreaseAllowance} instead.\n     */\n    function safeApprove(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        // safeApprove should only be called when setting an initial allowance,\n        // or when resetting it to zero. To increase and decrease it, use\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n        require(\n            (value == 0) || (token.allowance(address(this), spender) == 0),\n            \"SafeERC20: approve from non-zero to non-zero allowance\"\n        );\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n    }\n\n    function safeIncreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        uint256 newAllowance = token.allowance(address(this), spender) + value;\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n    }\n\n    function safeDecreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        unchecked {\n            uint256 oldAllowance = token.allowance(address(this), spender);\n            require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n            uint256 newAllowance = oldAllowance - value;\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n        if (returndata.length > 0) {\n            // Return data is optional\n            require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n        }\n    }\n}\n","keccak256":"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5","license":"MIT"},"@openzeppelin/contracts/utils/Address.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        require(isContract(target), \"Address: call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        require(isContract(target), \"Address: static call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(isContract(target), \"Address: delegate call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert(errorMessage);\n            }\n        }\n    }\n}\n","keccak256":"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87","license":"MIT"},"@openzeppelin/contracts/utils/Context.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n}\n","keccak256":"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7","license":"MIT"},"contracts/Staking.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.13;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/**\n * @title A simple staking contract with delays for unstake and withdraw operations.\n * Staking KOGE is required for participating in BNB48 DAO governance.\n */\ncontract Staking is Ownable {\n    using SafeERC20 for IERC20;\n\n    struct UserInfo {\n        // The last time the user called `stake`.\n        uint256 lastStakeTime;\n        // The last time the user called `unstake`.\n        uint256 lastUnstakeTime;\n        // The current stake of the user.\n        uint256 stake;\n        // The current amount of unstaked but locked tokens for the user. These are withdrawable\n        // after `withdrawDelay` has passed.\n        uint256 lockedUnstakedAmount;\n        // The current amount of unstaked and unlocked, but not-yet-withdrawn tokens for the user.\n        uint256 unlockedUnstakedAmount;\n    }\n\n    // Events\n    event Staked(address indexed user, uint256 amount);\n    event Unstaked(address indexed user, uint256 amount);\n    event Withdrawn(address indexed user, uint256 amount);\n    // Admin events\n    event UnstakeDelayUpdated(address indexed caller, uint256 unstakeDelay);\n    event WithdrawDelayUpdated(address indexed caller, uint256 withdrawDelay);\n\n    // The address of the KOGE token.\n    address public immutable koge;\n    // Required delay to unstake after a stake operation, in seconds.\n    uint256 public unstakeDelay;\n    // Required delay to withdraw after an unstake operation, in seconds.\n    uint256 public withdrawDelay;\n\n    // The current total stakes.\n    uint256 public totalStakes;\n    // The staking info for each user.\n    mapping(address => UserInfo) public userInfos;\n\n    /**\n     * @notice Staking constructor.\n     * @param _koge The address of the KOGE token.\n     * @param _unstakeDelay Required delay to unstake after a stake operation, in seconds.\n     * @param _withdrawDelay Required delay to withdraw after an unstake operation, in seconds.\n     */\n    constructor(\n        address _koge,\n        uint256 _unstakeDelay,\n        uint256 _withdrawDelay\n    ) {\n        koge = _koge;\n        unstakeDelay = _unstakeDelay;\n        withdrawDelay = _withdrawDelay;\n    }\n\n    /**\n     * @notice Stake into the contract. Resets `lastStakeTime`.\n     * @param _amount The amount of KOGE token to stake.\n     */\n    function stake(uint256 _amount) external {\n        UserInfo storage user = userInfos[msg.sender];\n        user.lastStakeTime = block.timestamp;\n        user.stake += _amount;\n        totalStakes += _amount;\n\n        IERC20(koge).safeTransferFrom(msg.sender, address(this), _amount);\n        emit Staked(msg.sender, _amount);\n    }\n\n    /**\n     * @notice Unstake from the contract after `unstakeDelay` has passed. This reduces the stake of the user\n     * immediately, but the tokens are not withdrawable until `withdrawDelay` has passed. Resets `lastUnstakeTime`.\n     * NOTE: This unlocks unstaked amount only after `withdrawDelay` has passed since `lastUnstakeTime`. Additional\n     * unstake operations before `withdrawDelay` has passed since `lastUnstakeTime` will effectively extend the lockup\n     * period of the previously unstaked amount.\n     * @param _amount The amount of KOGE token to unstake.\n     */\n    function unstake(uint256 _amount) external {\n        UserInfo storage user = userInfos[msg.sender];\n        require(block.timestamp >= user.lastStakeTime + unstakeDelay, \"unstake delay not passed\");\n        require(user.stake >= _amount, \"insufficient staked amount\");\n\n        _unlockUnstakedAmount(user);\n        user.lastUnstakeTime = block.timestamp;\n        user.stake -= _amount;\n        user.lockedUnstakedAmount += _amount;\n        totalStakes -= _amount;\n\n        emit Unstaked(msg.sender, _amount);\n    }\n\n    /**\n     * @notice Withdraw KOGE from the contract after `withdrawDelay` has passed.\n     * @param _amount The amount of KOGE token to withdraw.\n     */\n    function withdraw(uint256 _amount) external {\n        UserInfo storage user = userInfos[msg.sender];\n        _unlockUnstakedAmount(user);\n\n        require(user.unlockedUnstakedAmount >= _amount, \"insufficient unlocked amount\");\n\n        user.unlockedUnstakedAmount -= _amount;\n\n        IERC20(koge).safeTransfer(msg.sender, _amount);\n        emit Withdrawn(msg.sender, _amount);\n    }\n\n    /**\n     * @dev Updates the unlocked unstaked amount.\n     * @param _user The user.\n     */\n    function _unlockUnstakedAmount(UserInfo storage _user) internal {\n        if (_user.lockedUnstakedAmount > 0 && block.timestamp >= _user.lastUnstakeTime + withdrawDelay) {\n            _user.unlockedUnstakedAmount += _user.lockedUnstakedAmount;\n            _user.lockedUnstakedAmount = 0;\n        }\n    }\n\n    /**\n     * @notice Gets the current stake of a user.\n     * @param _user The user address.\n     */\n    function getStake(address _user) external view returns (uint256) {\n        return userInfos[_user].stake;\n    }\n\n    // -------------------- Admin --------------------\n\n    /**\n     * @dev Sets `unstakeDelay`.\n     * @param _unstakeDelay The new `unstakeDelay`.\n     */\n    function setUnstakeDelay(uint256 _unstakeDelay) external onlyOwner {\n        unstakeDelay = _unstakeDelay;\n        emit UnstakeDelayUpdated(msg.sender, _unstakeDelay);\n    }\n\n    /**\n     * @dev Sets `withdrawDelay`.\n     * @param _withdrawDelay The new `withdrawDelay`.\n     */\n    function setWithdrawDelay(uint256 _withdrawDelay) external onlyOwner {\n        withdrawDelay = _withdrawDelay;\n        emit WithdrawDelayUpdated(msg.sender, _withdrawDelay);\n    }\n}\n","keccak256":"0x203ce7cde5d1d243f7167b07508fca6fcb68a16fa02db0c72b38026aeb49a726","license":"MIT"}},"version":1},"storageLayout":{"types":{"t_address":{"label":"address","encoding":"inplace","numberOfBytes":"20"},"t_uint256":{"label":"uint256","encoding":"inplace","numberOfBytes":"32"},"t_struct(UserInfo)746_storage":{"label":"struct Staking.UserInfo","members":[{"slot":"0","type":"t_uint256","astId":737,"label":"lastStakeTime","offset":0,"contract":"contracts/Staking.sol:Staking"},{"slot":"1","type":"t_uint256","astId":739,"label":"lastUnstakeTime","offset":0,"contract":"contracts/Staking.sol:Staking"},{"slot":"2","type":"t_uint256","astId":741,"label":"stake","offset":0,"contract":"contracts/Staking.sol:Staking"},{"slot":"3","type":"t_uint256","astId":743,"label":"lockedUnstakedAmount","offset":0,"contract":"contracts/Staking.sol:Staking"},{"slot":"4","type":"t_uint256","astId":745,"label":"unlockedUnstakedAmount","offset":0,"contract":"contracts/Staking.sol:Staking"}],"encoding":"inplace","numberOfBytes":"160"},"t_mapping(t_address,t_struct(UserInfo)746_storage)":{"key":"t_address","label":"mapping(address => struct Staking.UserInfo)","value":"t_struct(UserInfo)746_storage","encoding":"mapping","numberOfBytes":"32"}},"storage":[{"slot":"0","type":"t_address","astId":7,"label":"_owner","offset":0,"contract":"contracts/Staking.sol:Staking"},{"slot":"1","type":"t_uint256","astId":780,"label":"unstakeDelay","offset":0,"contract":"contracts/Staking.sol:Staking"},{"slot":"2","type":"t_uint256","astId":782,"label":"withdrawDelay","offset":0,"contract":"contracts/Staking.sol:Staking"},{"slot":"3","type":"t_uint256","astId":784,"label":"totalStakes","offset":0,"contract":"contracts/Staking.sol:Staking"},{"slot":"4","type":"t_mapping(t_address,t_struct(UserInfo)746_storage)","astId":789,"label":"userInfos","offset":0,"contract":"contracts/Staking.sol:Staking"}]},"transientStorageLayout":null,"userdoc":{"kind":"user","methods":{"constructor":{"notice":"Staking constructor."},"stake(uint256)":{"notice":"Stake into the contract. Resets `lastStakeTime`."},"unstake(uint256)":{"notice":"Unstake from the contract after `unstakeDelay` has passed. This reduces the stake of the user immediately, but the tokens are not withdrawable until `withdrawDelay` has passed. Resets `lastUnstakeTime`. NOTE: This unlocks unstaked amount only after `withdrawDelay` has passed since `lastUnstakeTime`. Additional unstake operations before `withdrawDelay` has passed since `lastUnstakeTime` will effectively extend the lockup period of the previously unstaked amount."},"getStake(address)":{"notice":"Gets the current stake of a user."},"withdraw(uint256)":{"notice":"Withdraw KOGE from the contract after `withdrawDelay` has passed."}},"version":1},"devdoc":{"kind":"dev","title":"A simple staking contract with delays for unstake and withdraw operations. Staking KOGE is required for participating in BNB48 DAO governance.","methods":{"owner()":{"details":"Returns the address of the current owner."},"constructor":{"params":{"_koge":"The address of the KOGE token.","_unstakeDelay":"Required delay to unstake after a stake operation, in seconds.","_withdrawDelay":"Required delay to withdraw after an unstake operation, in seconds."}},"stake(uint256)":{"params":{"_amount":"The amount of KOGE token to stake."}},"unstake(uint256)":{"params":{"_amount":"The amount of KOGE token to unstake."}},"getStake(address)":{"params":{"_user":"The user address."}},"withdraw(uint256)":{"params":{"_amount":"The amount of KOGE token to withdraw."}},"renounceOwnership()":{"details":"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."},"setUnstakeDelay(uint256)":{"params":{"_unstakeDelay":"The new `unstakeDelay`."},"details":"Sets `unstakeDelay`."},"setWithdrawDelay(uint256)":{"params":{"_withdrawDelay":"The new `withdrawDelay`."},"details":"Sets `withdrawDelay`."},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"version":1},"sourceIds":{"contracts/Staking.sol":{"id":5},"@openzeppelin/contracts/utils/Address.sol":{"id":3},"@openzeppelin/contracts/utils/Context.sol":{"id":4},"@openzeppelin/contracts/access/Ownable.sol":{"id":0},"@openzeppelin/contracts/token/ERC20/IERC20.sol":{"id":1},"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol":{"id":2}},"additionalInput":null,"stdJsonInput":{"sources":{"contracts/Staking.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.13;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/**\n * @title A simple staking contract with delays for unstake and withdraw operations.\n * Staking KOGE is required for participating in BNB48 DAO governance.\n */\ncontract Staking is Ownable {\n    using SafeERC20 for IERC20;\n\n    struct UserInfo {\n        // The last time the user called `stake`.\n        uint256 lastStakeTime;\n        // The last time the user called `unstake`.\n        uint256 lastUnstakeTime;\n        // The current stake of the user.\n        uint256 stake;\n        // The current amount of unstaked but locked tokens for the user. These are withdrawable\n        // after `withdrawDelay` has passed.\n        uint256 lockedUnstakedAmount;\n        // The current amount of unstaked and unlocked, but not-yet-withdrawn tokens for the user.\n        uint256 unlockedUnstakedAmount;\n    }\n\n    // Events\n    event Staked(address indexed user, uint256 amount);\n    event Unstaked(address indexed user, uint256 amount);\n    event Withdrawn(address indexed user, uint256 amount);\n    // Admin events\n    event UnstakeDelayUpdated(address indexed caller, uint256 unstakeDelay);\n    event WithdrawDelayUpdated(address indexed caller, uint256 withdrawDelay);\n\n    // The address of the KOGE token.\n    address public immutable koge;\n    // Required delay to unstake after a stake operation, in seconds.\n    uint256 public unstakeDelay;\n    // Required delay to withdraw after an unstake operation, in seconds.\n    uint256 public withdrawDelay;\n\n    // The current total stakes.\n    uint256 public totalStakes;\n    // The staking info for each user.\n    mapping(address => UserInfo) public userInfos;\n\n    /**\n     * @notice Staking constructor.\n     * @param _koge The address of the KOGE token.\n     * @param _unstakeDelay Required delay to unstake after a stake operation, in seconds.\n     * @param _withdrawDelay Required delay to withdraw after an unstake operation, in seconds.\n     */\n    constructor(\n        address _koge,\n        uint256 _unstakeDelay,\n        uint256 _withdrawDelay\n    ) {\n        koge = _koge;\n        unstakeDelay = _unstakeDelay;\n        withdrawDelay = _withdrawDelay;\n    }\n\n    /**\n     * @notice Stake into the contract. Resets `lastStakeTime`.\n     * @param _amount The amount of KOGE token to stake.\n     */\n    function stake(uint256 _amount) external {\n        UserInfo storage user = userInfos[msg.sender];\n        user.lastStakeTime = block.timestamp;\n        user.stake += _amount;\n        totalStakes += _amount;\n\n        IERC20(koge).safeTransferFrom(msg.sender, address(this), _amount);\n        emit Staked(msg.sender, _amount);\n    }\n\n    /**\n     * @notice Unstake from the contract after `unstakeDelay` has passed. This reduces the stake of the user\n     * immediately, but the tokens are not withdrawable until `withdrawDelay` has passed. Resets `lastUnstakeTime`.\n     * NOTE: This unlocks unstaked amount only after `withdrawDelay` has passed since `lastUnstakeTime`. Additional\n     * unstake operations before `withdrawDelay` has passed since `lastUnstakeTime` will effectively extend the lockup\n     * period of the previously unstaked amount.\n     * @param _amount The amount of KOGE token to unstake.\n     */\n    function unstake(uint256 _amount) external {\n        UserInfo storage user = userInfos[msg.sender];\n        require(block.timestamp >= user.lastStakeTime + unstakeDelay, \"unstake delay not passed\");\n        require(user.stake >= _amount, \"insufficient staked amount\");\n\n        _unlockUnstakedAmount(user);\n        user.lastUnstakeTime = block.timestamp;\n        user.stake -= _amount;\n        user.lockedUnstakedAmount += _amount;\n        totalStakes -= _amount;\n\n        emit Unstaked(msg.sender, _amount);\n    }\n\n    /**\n     * @notice Withdraw KOGE from the contract after `withdrawDelay` has passed.\n     * @param _amount The amount of KOGE token to withdraw.\n     */\n    function withdraw(uint256 _amount) external {\n        UserInfo storage user = userInfos[msg.sender];\n        _unlockUnstakedAmount(user);\n\n        require(user.unlockedUnstakedAmount >= _amount, \"insufficient unlocked amount\");\n\n        user.unlockedUnstakedAmount -= _amount;\n\n        IERC20(koge).safeTransfer(msg.sender, _amount);\n        emit Withdrawn(msg.sender, _amount);\n    }\n\n    /**\n     * @dev Updates the unlocked unstaked amount.\n     * @param _user The user.\n     */\n    function _unlockUnstakedAmount(UserInfo storage _user) internal {\n        if (_user.lockedUnstakedAmount > 0 && block.timestamp >= _user.lastUnstakeTime + withdrawDelay) {\n            _user.unlockedUnstakedAmount += _user.lockedUnstakedAmount;\n            _user.lockedUnstakedAmount = 0;\n        }\n    }\n\n    /**\n     * @notice Gets the current stake of a user.\n     * @param _user The user address.\n     */\n    function getStake(address _user) external view returns (uint256) {\n        return userInfos[_user].stake;\n    }\n\n    // -------------------- Admin --------------------\n\n    /**\n     * @dev Sets `unstakeDelay`.\n     * @param _unstakeDelay The new `unstakeDelay`.\n     */\n    function setUnstakeDelay(uint256 _unstakeDelay) external onlyOwner {\n        unstakeDelay = _unstakeDelay;\n        emit UnstakeDelayUpdated(msg.sender, _unstakeDelay);\n    }\n\n    /**\n     * @dev Sets `withdrawDelay`.\n     * @param _withdrawDelay The new `withdrawDelay`.\n     */\n    function setWithdrawDelay(uint256 _withdrawDelay) external onlyOwner {\n        withdrawDelay = _withdrawDelay;\n        emit WithdrawDelayUpdated(msg.sender, _withdrawDelay);\n    }\n}\n"},"@openzeppelin/contracts/utils/Address.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        require(isContract(target), \"Address: call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        require(isContract(target), \"Address: static call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(isContract(target), \"Address: delegate call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert(errorMessage);\n            }\n        }\n    }\n}\n"},"@openzeppelin/contracts/utils/Context.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n}\n"},"@openzeppelin/contracts/access/Ownable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    constructor() {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n        _;\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby removing any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"},"@openzeppelin/contracts/token/ERC20/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(\n        address from,\n        address to,\n        uint256 amount\n    ) external returns (bool);\n\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"},"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    using Address for address;\n\n    function safeTransfer(\n        IERC20 token,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    function safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n    }\n\n    /**\n     * @dev Deprecated. This function has issues similar to the ones found in\n     * {IERC20-approve}, and its usage is discouraged.\n     *\n     * Whenever possible, use {safeIncreaseAllowance} and\n     * {safeDecreaseAllowance} instead.\n     */\n    function safeApprove(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        // safeApprove should only be called when setting an initial allowance,\n        // or when resetting it to zero. To increase and decrease it, use\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n        require(\n            (value == 0) || (token.allowance(address(this), spender) == 0),\n            \"SafeERC20: approve from non-zero to non-zero allowance\"\n        );\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n    }\n\n    function safeIncreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        uint256 newAllowance = token.allowance(address(this), spender) + value;\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n    }\n\n    function safeDecreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        unchecked {\n            uint256 oldAllowance = token.allowance(address(this), spender);\n            require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n            uint256 newAllowance = oldAllowance - value;\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n        if (returndata.length > 0) {\n            // Return data is optional\n            require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n        }\n    }\n}\n"}},"language":"Solidity","settings":{"metadata":{"bytecodeHash":"ipfs","useLiteralContent":true},"libraries":{},"optimizer":{"runs":800,"enabled":true},"evmVersion":"london","remappings":[]}},"stdJsonOutput":{"sources":{"contracts/Staking.sol":{"id":5},"@openzeppelin/contracts/utils/Address.sol":{"id":3},"@openzeppelin/contracts/utils/Context.sol":{"id":4},"@openzeppelin/contracts/access/Ownable.sol":{"id":0},"@openzeppelin/contracts/token/ERC20/IERC20.sol":{"id":1},"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol":{"id":2}},"contracts":{"contracts/Staking.sol":{"Staking":{"abi":[{"type":"constructor","inputs":[{"name":"_koge","type":"address","internalType":"address"},{"name":"_unstakeDelay","type":"uint256","internalType":"uint256"},{"name":"_withdrawDelay","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"name":"OwnershipTransferred","type":"event","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"Staked","type":"event","inputs":[{"name":"user","type":"address","indexed":true,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"UnstakeDelayUpdated","type":"event","inputs":[{"name":"caller","type":"address","indexed":true,"internalType":"address"},{"name":"unstakeDelay","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"Unstaked","type":"event","inputs":[{"name":"user","type":"address","indexed":true,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"WithdrawDelayUpdated","type":"event","inputs":[{"name":"caller","type":"address","indexed":true,"internalType":"address"},{"name":"withdrawDelay","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"Withdrawn","type":"event","inputs":[{"name":"user","type":"address","indexed":true,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"getStake","type":"function","inputs":[{"name":"_user","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"koge","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"owner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"renounceOwnership","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"setUnstakeDelay","type":"function","inputs":[{"name":"_unstakeDelay","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setWithdrawDelay","type":"function","inputs":[{"name":"_withdrawDelay","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"stake","type":"function","inputs":[{"name":"_amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"totalStakes","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"transferOwnership","type":"function","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"unstake","type":"function","inputs":[{"name":"_amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"unstakeDelay","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"userInfos","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"lastStakeTime","type":"uint256","internalType":"uint256"},{"name":"lastUnstakeTime","type":"uint256","internalType":"uint256"},{"name":"stake","type":"uint256","internalType":"uint256"},{"name":"lockedUnstakedAmount","type":"uint256","internalType":"uint256"},{"name":"unlockedUnstakedAmount","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"withdraw","type":"function","inputs":[{"name":"_amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"withdrawDelay","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"}],"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_koge\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_unstakeDelay\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_withdrawDelay\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Staked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"unstakeDelay\",\"type\":\"uint256\"}],\"name\":\"UnstakeDelayUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Unstaked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"withdrawDelay\",\"type\":\"uint256\"}],\"name\":\"WithdrawDelayUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawn\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getStake\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"koge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_unstakeDelay\",\"type\":\"uint256\"}],\"name\":\"setUnstakeDelay\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_withdrawDelay\",\"type\":\"uint256\"}],\"name\":\"setWithdrawDelay\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"stake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalStakes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"unstake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unstakeDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"userInfos\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"lastStakeTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lastUnstakeTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lockedUnstakedAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unlockedUnstakedAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_koge\":\"The address of the KOGE token.\",\"_unstakeDelay\":\"Required delay to unstake after a stake operation, in seconds.\",\"_withdrawDelay\":\"Required delay to withdraw after an unstake operation, in seconds.\"}},\"getStake(address)\":{\"params\":{\"_user\":\"The user address.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"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.\"},\"setUnstakeDelay(uint256)\":{\"details\":\"Sets `unstakeDelay`.\",\"params\":{\"_unstakeDelay\":\"The new `unstakeDelay`.\"}},\"setWithdrawDelay(uint256)\":{\"details\":\"Sets `withdrawDelay`.\",\"params\":{\"_withdrawDelay\":\"The new `withdrawDelay`.\"}},\"stake(uint256)\":{\"params\":{\"_amount\":\"The amount of KOGE token to stake.\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"unstake(uint256)\":{\"params\":{\"_amount\":\"The amount of KOGE token to unstake.\"}},\"withdraw(uint256)\":{\"params\":{\"_amount\":\"The amount of KOGE token to withdraw.\"}}},\"title\":\"A simple staking contract with delays for unstake and withdraw operations. Staking KOGE is required for participating in BNB48 DAO governance.\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Staking constructor.\"},\"getStake(address)\":{\"notice\":\"Gets the current stake of a user.\"},\"stake(uint256)\":{\"notice\":\"Stake into the contract. Resets `lastStakeTime`.\"},\"unstake(uint256)\":{\"notice\":\"Unstake from the contract after `unstakeDelay` has passed. This reduces the stake of the user immediately, but the tokens are not withdrawable until `withdrawDelay` has passed. Resets `lastUnstakeTime`. NOTE: This unlocks unstaked amount only after `withdrawDelay` has passed since `lastUnstakeTime`. Additional unstake operations before `withdrawDelay` has passed since `lastUnstakeTime` will effectively extend the lockup period of the previously unstaked amount.\"},\"withdraw(uint256)\":{\"notice\":\"Withdraw KOGE from the contract after `withdrawDelay` has passed.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Staking.sol\":\"Staking\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":800},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n    address private _owner;\\n\\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n    /**\\n     * @dev Initializes the contract setting the deployer as the initial owner.\\n     */\\n    constructor() {\\n        _transferOwnership(_msgSender());\\n    }\\n\\n    /**\\n     * @dev Returns the address of the current owner.\\n     */\\n    function owner() public view virtual returns (address) {\\n        return _owner;\\n    }\\n\\n    /**\\n     * @dev Throws if called by any account other than the owner.\\n     */\\n    modifier onlyOwner() {\\n        require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n        _;\\n    }\\n\\n    /**\\n     * @dev Leaves the contract without owner. It will not be possible to call\\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\\n     *\\n     * NOTE: Renouncing ownership will leave the contract without an owner,\\n     * thereby removing any functionality that is only available to the owner.\\n     */\\n    function renounceOwnership() public virtual onlyOwner {\\n        _transferOwnership(address(0));\\n    }\\n\\n    /**\\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n     * Can only be called by the current owner.\\n     */\\n    function transferOwnership(address newOwner) public virtual onlyOwner {\\n        require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n        _transferOwnership(newOwner);\\n    }\\n\\n    /**\\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n     * Internal function without access restriction.\\n     */\\n    function _transferOwnership(address newOwner) internal virtual {\\n        address oldOwner = _owner;\\n        _owner = newOwner;\\n        emit OwnershipTransferred(oldOwner, newOwner);\\n    }\\n}\\n\",\"keccak256\":\"0x24e0364e503a9bbde94c715d26573a76f14cd2a202d45f96f52134ab806b67b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n    /**\\n     * @dev Returns the amount of tokens in existence.\\n     */\\n    function totalSupply() external view returns (uint256);\\n\\n    /**\\n     * @dev Returns the amount of tokens owned by `account`.\\n     */\\n    function balanceOf(address account) external view returns (uint256);\\n\\n    /**\\n     * @dev Moves `amount` tokens from the caller's account to `to`.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transfer(address to, uint256 amount) external returns (bool);\\n\\n    /**\\n     * @dev Returns the remaining number of tokens that `spender` will be\\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n     * zero by default.\\n     *\\n     * This value changes when {approve} or {transferFrom} are called.\\n     */\\n    function allowance(address owner, address spender) external view returns (uint256);\\n\\n    /**\\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n     * that someone may use both the old and the new allowance by unfortunate\\n     * transaction ordering. One possible solution to mitigate this race\\n     * condition is to first reduce the spender's allowance to 0 and set the\\n     * desired value afterwards:\\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n     *\\n     * Emits an {Approval} event.\\n     */\\n    function approve(address spender, uint256 amount) external returns (bool);\\n\\n    /**\\n     * @dev Moves `amount` tokens from `from` to `to` using the\\n     * allowance mechanism. `amount` is then deducted from the caller's\\n     * allowance.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transferFrom(\\n        address from,\\n        address to,\\n        uint256 amount\\n    ) external returns (bool);\\n\\n    /**\\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n     * another (`to`).\\n     *\\n     * Note that `value` may be zero.\\n     */\\n    event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n    /**\\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n     * a call to {approve}. `value` is the new allowance.\\n     */\\n    event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n    using Address for address;\\n\\n    function safeTransfer(\\n        IERC20 token,\\n        address to,\\n        uint256 value\\n    ) internal {\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n    }\\n\\n    function safeTransferFrom(\\n        IERC20 token,\\n        address from,\\n        address to,\\n        uint256 value\\n    ) internal {\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n    }\\n\\n    /**\\n     * @dev Deprecated. This function has issues similar to the ones found in\\n     * {IERC20-approve}, and its usage is discouraged.\\n     *\\n     * Whenever possible, use {safeIncreaseAllowance} and\\n     * {safeDecreaseAllowance} instead.\\n     */\\n    function safeApprove(\\n        IERC20 token,\\n        address spender,\\n        uint256 value\\n    ) internal {\\n        // safeApprove should only be called when setting an initial allowance,\\n        // or when resetting it to zero. To increase and decrease it, use\\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n        require(\\n            (value == 0) || (token.allowance(address(this), spender) == 0),\\n            \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n        );\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n    }\\n\\n    function safeIncreaseAllowance(\\n        IERC20 token,\\n        address spender,\\n        uint256 value\\n    ) internal {\\n        uint256 newAllowance = token.allowance(address(this), spender) + value;\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n    }\\n\\n    function safeDecreaseAllowance(\\n        IERC20 token,\\n        address spender,\\n        uint256 value\\n    ) internal {\\n        unchecked {\\n            uint256 oldAllowance = token.allowance(address(this), spender);\\n            require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n            uint256 newAllowance = oldAllowance - value;\\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n        }\\n    }\\n\\n    /**\\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\\n     * @param token The token targeted by the call.\\n     * @param data The call data (encoded using abi.encode or one of its variants).\\n     */\\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n        // the target address contains contract code and also asserts for success in the low-level call.\\n\\n        bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n        if (returndata.length > 0) {\\n            // Return data is optional\\n            require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n    /**\\n     * @dev Returns true if `account` is a contract.\\n     *\\n     * [IMPORTANT]\\n     * ====\\n     * It is unsafe to assume that an address for which this function returns\\n     * false is an externally-owned account (EOA) and not a contract.\\n     *\\n     * Among others, `isContract` will return false for the following\\n     * types of addresses:\\n     *\\n     *  - an externally-owned account\\n     *  - a contract in construction\\n     *  - an address where a contract will be created\\n     *  - an address where a contract lived, but was destroyed\\n     * ====\\n     *\\n     * [IMPORTANT]\\n     * ====\\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n     *\\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n     * constructor.\\n     * ====\\n     */\\n    function isContract(address account) internal view returns (bool) {\\n        // This method relies on extcodesize/address.code.length, which returns 0\\n        // for contracts in construction, since the code is only stored at the end\\n        // of the constructor execution.\\n\\n        return account.code.length > 0;\\n    }\\n\\n    /**\\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n     * `recipient`, forwarding all available gas and reverting on errors.\\n     *\\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n     * imposed by `transfer`, making them unable to receive funds via\\n     * `transfer`. {sendValue} removes this limitation.\\n     *\\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n     *\\n     * IMPORTANT: because control is transferred to `recipient`, care must be\\n     * taken to not create reentrancy vulnerabilities. Consider using\\n     * {ReentrancyGuard} or the\\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n     */\\n    function sendValue(address payable recipient, uint256 amount) internal {\\n        require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n        (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n        require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n    }\\n\\n    /**\\n     * @dev Performs a Solidity function call using a low level `call`. A\\n     * plain `call` is an unsafe replacement for a function call: use this\\n     * function instead.\\n     *\\n     * If `target` reverts with a revert reason, it is bubbled up by this\\n     * function (like regular Solidity function calls).\\n     *\\n     * Returns the raw returned data. To convert to the expected return value,\\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n     *\\n     * Requirements:\\n     *\\n     * - `target` must be a contract.\\n     * - calling `target` with `data` must not revert.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n        return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n     * `errorMessage` as a fallback revert reason when `target` reverts.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCall(\\n        address target,\\n        bytes memory data,\\n        string memory errorMessage\\n    ) internal returns (bytes memory) {\\n        return functionCallWithValue(target, data, 0, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n     * but also transferring `value` wei to `target`.\\n     *\\n     * Requirements:\\n     *\\n     * - the calling contract must have an ETH balance of at least `value`.\\n     * - the called Solidity function must be `payable`.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCallWithValue(\\n        address target,\\n        bytes memory data,\\n        uint256 value\\n    ) internal returns (bytes memory) {\\n        return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCallWithValue(\\n        address target,\\n        bytes memory data,\\n        uint256 value,\\n        string memory errorMessage\\n    ) internal returns (bytes memory) {\\n        require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n        require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\\n        return verifyCallResult(success, returndata, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n     * but performing a static call.\\n     *\\n     * _Available since v3.3._\\n     */\\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n        return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n     * but performing a static call.\\n     *\\n     * _Available since v3.3._\\n     */\\n    function functionStaticCall(\\n        address target,\\n        bytes memory data,\\n        string memory errorMessage\\n    ) internal view returns (bytes memory) {\\n        require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n        (bool success, bytes memory returndata) = target.staticcall(data);\\n        return verifyCallResult(success, returndata, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n     * but performing a delegate call.\\n     *\\n     * _Available since v3.4._\\n     */\\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n        return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n     * but performing a delegate call.\\n     *\\n     * _Available since v3.4._\\n     */\\n    function functionDelegateCall(\\n        address target,\\n        bytes memory data,\\n        string memory errorMessage\\n    ) internal returns (bytes memory) {\\n        require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n        (bool success, bytes memory returndata) = target.delegatecall(data);\\n        return verifyCallResult(success, returndata, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n     * revert reason using the provided one.\\n     *\\n     * _Available since v4.3._\\n     */\\n    function verifyCallResult(\\n        bool success,\\n        bytes memory returndata,\\n        string memory errorMessage\\n    ) internal pure returns (bytes memory) {\\n        if (success) {\\n            return returndata;\\n        } else {\\n            // Look for revert reason and bubble it up if present\\n            if (returndata.length > 0) {\\n                // The easiest way to bubble the revert reason is using memory via assembly\\n\\n                assembly {\\n                    let returndata_size := mload(returndata)\\n                    revert(add(32, returndata), returndata_size)\\n                }\\n            } else {\\n                revert(errorMessage);\\n            }\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n    function _msgSender() internal view virtual returns (address) {\\n        return msg.sender;\\n    }\\n\\n    function _msgData() internal view virtual returns (bytes calldata) {\\n        return msg.data;\\n    }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"contracts/Staking.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\n/**\\n * @title A simple staking contract with delays for unstake and withdraw operations.\\n * Staking KOGE is required for participating in BNB48 DAO governance.\\n */\\ncontract Staking is Ownable {\\n    using SafeERC20 for IERC20;\\n\\n    struct UserInfo {\\n        // The last time the user called `stake`.\\n        uint256 lastStakeTime;\\n        // The last time the user called `unstake`.\\n        uint256 lastUnstakeTime;\\n        // The current stake of the user.\\n        uint256 stake;\\n        // The current amount of unstaked but locked tokens for the user. These are withdrawable\\n        // after `withdrawDelay` has passed.\\n        uint256 lockedUnstakedAmount;\\n        // The current amount of unstaked and unlocked, but not-yet-withdrawn tokens for the user.\\n        uint256 unlockedUnstakedAmount;\\n    }\\n\\n    // Events\\n    event Staked(address indexed user, uint256 amount);\\n    event Unstaked(address indexed user, uint256 amount);\\n    event Withdrawn(address indexed user, uint256 amount);\\n    // Admin events\\n    event UnstakeDelayUpdated(address indexed caller, uint256 unstakeDelay);\\n    event WithdrawDelayUpdated(address indexed caller, uint256 withdrawDelay);\\n\\n    // The address of the KOGE token.\\n    address public immutable koge;\\n    // Required delay to unstake after a stake operation, in seconds.\\n    uint256 public unstakeDelay;\\n    // Required delay to withdraw after an unstake operation, in seconds.\\n    uint256 public withdrawDelay;\\n\\n    // The current total stakes.\\n    uint256 public totalStakes;\\n    // The staking info for each user.\\n    mapping(address => UserInfo) public userInfos;\\n\\n    /**\\n     * @notice Staking constructor.\\n     * @param _koge The address of the KOGE token.\\n     * @param _unstakeDelay Required delay to unstake after a stake operation, in seconds.\\n     * @param _withdrawDelay Required delay to withdraw after an unstake operation, in seconds.\\n     */\\n    constructor(\\n        address _koge,\\n        uint256 _unstakeDelay,\\n        uint256 _withdrawDelay\\n    ) {\\n        koge = _koge;\\n        unstakeDelay = _unstakeDelay;\\n        withdrawDelay = _withdrawDelay;\\n    }\\n\\n    /**\\n     * @notice Stake into the contract. Resets `lastStakeTime`.\\n     * @param _amount The amount of KOGE token to stake.\\n     */\\n    function stake(uint256 _amount) external {\\n        UserInfo storage user = userInfos[msg.sender];\\n        user.lastStakeTime = block.timestamp;\\n        user.stake += _amount;\\n        totalStakes += _amount;\\n\\n        IERC20(koge).safeTransferFrom(msg.sender, address(this), _amount);\\n        emit Staked(msg.sender, _amount);\\n    }\\n\\n    /**\\n     * @notice Unstake from the contract after `unstakeDelay` has passed. This reduces the stake of the user\\n     * immediately, but the tokens are not withdrawable until `withdrawDelay` has passed. Resets `lastUnstakeTime`.\\n     * NOTE: This unlocks unstaked amount only after `withdrawDelay` has passed since `lastUnstakeTime`. Additional\\n     * unstake operations before `withdrawDelay` has passed since `lastUnstakeTime` will effectively extend the lockup\\n     * period of the previously unstaked amount.\\n     * @param _amount The amount of KOGE token to unstake.\\n     */\\n    function unstake(uint256 _amount) external {\\n        UserInfo storage user = userInfos[msg.sender];\\n        require(block.timestamp >= user.lastStakeTime + unstakeDelay, \\\"unstake delay not passed\\\");\\n        require(user.stake >= _amount, \\\"insufficient staked amount\\\");\\n\\n        _unlockUnstakedAmount(user);\\n        user.lastUnstakeTime = block.timestamp;\\n        user.stake -= _amount;\\n        user.lockedUnstakedAmount += _amount;\\n        totalStakes -= _amount;\\n\\n        emit Unstaked(msg.sender, _amount);\\n    }\\n\\n    /**\\n     * @notice Withdraw KOGE from the contract after `withdrawDelay` has passed.\\n     * @param _amount The amount of KOGE token to withdraw.\\n     */\\n    function withdraw(uint256 _amount) external {\\n        UserInfo storage user = userInfos[msg.sender];\\n        _unlockUnstakedAmount(user);\\n\\n        require(user.unlockedUnstakedAmount >= _amount, \\\"insufficient unlocked amount\\\");\\n\\n        user.unlockedUnstakedAmount -= _amount;\\n\\n        IERC20(koge).safeTransfer(msg.sender, _amount);\\n        emit Withdrawn(msg.sender, _amount);\\n    }\\n\\n    /**\\n     * @dev Updates the unlocked unstaked amount.\\n     * @param _user The user.\\n     */\\n    function _unlockUnstakedAmount(UserInfo storage _user) internal {\\n        if (_user.lockedUnstakedAmount > 0 && block.timestamp >= _user.lastUnstakeTime + withdrawDelay) {\\n            _user.unlockedUnstakedAmount += _user.lockedUnstakedAmount;\\n            _user.lockedUnstakedAmount = 0;\\n        }\\n    }\\n\\n    /**\\n     * @notice Gets the current stake of a user.\\n     * @param _user The user address.\\n     */\\n    function getStake(address _user) external view returns (uint256) {\\n        return userInfos[_user].stake;\\n    }\\n\\n    // -------------------- Admin --------------------\\n\\n    /**\\n     * @dev Sets `unstakeDelay`.\\n     * @param _unstakeDelay The new `unstakeDelay`.\\n     */\\n    function setUnstakeDelay(uint256 _unstakeDelay) external onlyOwner {\\n        unstakeDelay = _unstakeDelay;\\n        emit UnstakeDelayUpdated(msg.sender, _unstakeDelay);\\n    }\\n\\n    /**\\n     * @dev Sets `withdrawDelay`.\\n     * @param _withdrawDelay The new `withdrawDelay`.\\n     */\\n    function setWithdrawDelay(uint256 _withdrawDelay) external onlyOwner {\\n        withdrawDelay = _withdrawDelay;\\n        emit WithdrawDelayUpdated(msg.sender, _withdrawDelay);\\n    }\\n}\\n\",\"keccak256\":\"0x203ce7cde5d1d243f7167b07508fca6fcb68a16fa02db0c72b38026aeb49a726\",\"license\":\"MIT\"}},\"version\":1}","userdoc":{"kind":"user","methods":{"constructor":{"notice":"Staking constructor."},"stake(uint256)":{"notice":"Stake into the contract. Resets `lastStakeTime`."},"unstake(uint256)":{"notice":"Unstake from the contract after `unstakeDelay` has passed. This reduces the stake of the user immediately, but the tokens are not withdrawable until `withdrawDelay` has passed. Resets `lastUnstakeTime`. NOTE: This unlocks unstaked amount only after `withdrawDelay` has passed since `lastUnstakeTime`. Additional unstake operations before `withdrawDelay` has passed since `lastUnstakeTime` will effectively extend the lockup period of the previously unstaked amount."},"getStake(address)":{"notice":"Gets the current stake of a user."},"withdraw(uint256)":{"notice":"Withdraw KOGE from the contract after `withdrawDelay` has passed."}},"version":1},"devdoc":{"kind":"dev","title":"A simple staking contract with delays for unstake and withdraw operations. Staking KOGE is required for participating in BNB48 DAO governance.","methods":{"owner()":{"details":"Returns the address of the current owner."},"constructor":{"params":{"_koge":"The address of the KOGE token.","_unstakeDelay":"Required delay to unstake after a stake operation, in seconds.","_withdrawDelay":"Required delay to withdraw after an unstake operation, in seconds."}},"stake(uint256)":{"params":{"_amount":"The amount of KOGE token to stake."}},"unstake(uint256)":{"params":{"_amount":"The amount of KOGE token to unstake."}},"getStake(address)":{"params":{"_user":"The user address."}},"withdraw(uint256)":{"params":{"_amount":"The amount of KOGE token to withdraw."}},"renounceOwnership()":{"details":"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."},"setUnstakeDelay(uint256)":{"params":{"_unstakeDelay":"The new `unstakeDelay`."},"details":"Sets `unstakeDelay`."},"setWithdrawDelay(uint256)":{"params":{"_withdrawDelay":"The new `withdrawDelay`."},"details":"Sets `withdrawDelay`."},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"version":1},"storageLayout":{"types":{"t_address":{"label":"address","encoding":"inplace","numberOfBytes":"20"},"t_uint256":{"label":"uint256","encoding":"inplace","numberOfBytes":"32"},"t_struct(UserInfo)746_storage":{"label":"struct Staking.UserInfo","members":[{"slot":"0","type":"t_uint256","astId":737,"label":"lastStakeTime","offset":0,"contract":"contracts/Staking.sol:Staking"},{"slot":"1","type":"t_uint256","astId":739,"label":"lastUnstakeTime","offset":0,"contract":"contracts/Staking.sol:Staking"},{"slot":"2","type":"t_uint256","astId":741,"label":"stake","offset":0,"contract":"contracts/Staking.sol:Staking"},{"slot":"3","type":"t_uint256","astId":743,"label":"lockedUnstakedAmount","offset":0,"contract":"contracts/Staking.sol:Staking"},{"slot":"4","type":"t_uint256","astId":745,"label":"unlockedUnstakedAmount","offset":0,"contract":"contracts/Staking.sol:Staking"}],"encoding":"inplace","numberOfBytes":"160"},"t_mapping(t_address,t_struct(UserInfo)746_storage)":{"key":"t_address","label":"mapping(address => struct Staking.UserInfo)","value":"t_struct(UserInfo)746_storage","encoding":"mapping","numberOfBytes":"32"}},"storage":[{"slot":"0","type":"t_address","astId":7,"label":"_owner","offset":0,"contract":"contracts/Staking.sol:Staking"},{"slot":"1","type":"t_uint256","astId":780,"label":"unstakeDelay","offset":0,"contract":"contracts/Staking.sol:Staking"},{"slot":"2","type":"t_uint256","astId":782,"label":"withdrawDelay","offset":0,"contract":"contracts/Staking.sol:Staking"},{"slot":"3","type":"t_uint256","astId":784,"label":"totalStakes","offset":0,"contract":"contracts/Staking.sol:Staking"},{"slot":"4","type":"t_mapping(t_address,t_struct(UserInfo)746_storage)","astId":789,"label":"userInfos","offset":0,"contract":"contracts/Staking.sol:Staking"}]},"transientStorageLayout":null,"evm":{"bytecode":{"object":"60a060405234801561001057600080fd5b50604051610e56380380610e5683398101604081905261002f916100a1565b61003833610051565b6001600160a01b039092166080526001556002556100e4565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000806000606084860312156100b657600080fd5b83516001600160a01b03811681146100cd57600080fd5b602085015160409095015190969495509392505050565b608051610d4961010d600039600081816101ba0152818161046d01526106a80152610d496000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063715018a61161008c5780638da5cb5b116100665780638da5cb5b1461023b578063a694fc3a1461024c578063bf9befb11461025f578063f2fde38b1461026857600080fd5b8063715018a6146101f457806372f0cb30146101fc5780637a7664601461020f57600080fd5b806330b75e04116100c857806330b75e04146101335780633222012f1461014657806343b0215f1461014f57806368bfce99146101b557600080fd5b80630288a39c146100ef5780632e17de781461010b5780632e1a7d4d14610120575b600080fd5b6100f860025481565b6040519081526020015b60405180910390f35b61011e610119366004610bef565b61027b565b005b61011e61012e366004610bef565b6103da565b61011e610141366004610bef565b6104c6565b6100f860015481565b61018d61015d366004610c08565b60046020819052600091825260409091208054600182015460028301546003840154939094015491939092909185565b604080519586526020860194909452928401919091526060830152608082015260a001610102565b6101dc7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610102565b61011e61055e565b61011e61020a366004610bef565b6105c4565b6100f861021d366004610c08565b6001600160a01b031660009081526004602052604090206002015490565b6000546001600160a01b03166101dc565b61011e61025a366004610bef565b610655565b6100f860035481565b61011e610276366004610c08565b610702565b33600090815260046020526040902060015481546102999190610c47565b4210156102ed5760405162461bcd60e51b815260206004820152601860248201527f756e7374616b652064656c6179206e6f7420706173736564000000000000000060448201526064015b60405180910390fd5b81816002015410156103415760405162461bcd60e51b815260206004820152601a60248201527f696e73756666696369656e74207374616b656420616d6f756e7400000000000060448201526064016102e4565b61034a816107e4565b428160010181905550818160020160008282546103679190610c5f565b92505081905550818160030160008282546103829190610c47565b92505081905550816003600082825461039b9190610c5f565b909155505060405182815233907f0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f75906020015b60405180910390a25050565b3360009081526004602052604090206103f2816107e4565b81816004015410156104465760405162461bcd60e51b815260206004820152601c60248201527f696e73756666696369656e7420756e6c6f636b656420616d6f756e740000000060448201526064016102e4565b8181600401600082825461045a9190610c5f565b9091555061049490506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163384610835565b60405182815233907f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5906020016103ce565b6000546001600160a01b031633146105205760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e4565b600181905560405181815233907f67aa75375fca757eaa536cc0b6855969ff77b119e0ddd3519c6f603dccc460df906020015b60405180910390a250565b6000546001600160a01b031633146105b85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e4565b6105c260006108ca565b565b6000546001600160a01b0316331461061e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e4565b600281905560405181815233907fa4cdbe995bf935cd31b353c9a555c4c7ceb0888e6ddc0f259d552368a319108b90602001610553565b3360009081526004602052604081204281556002810180549192849261067c908490610c47565b9250508190555081600360008282546106959190610c47565b909155506106d090506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333085610932565b60405182815233907f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d906020016103ce565b6000546001600160a01b0316331461075c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e4565b6001600160a01b0381166107d85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102e4565b6107e1816108ca565b50565b60008160030154118015610809575060025481600101546108059190610c47565b4210155b156107e15780600301548160040160008282546108269190610c47565b90915550506000600382015550565b6040516001600160a01b0383166024820152604481018290526108c590849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610970565b505050565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6040516001600160a01b038085166024830152831660448201526064810182905261096a9085906323b872dd60e01b90608401610861565b50505050565b60006109c5826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610a559092919063ffffffff16565b8051909150156108c557808060200190518101906109e39190610c76565b6108c55760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016102e4565b6060610a648484600085610a6e565b90505b9392505050565b606082471015610ae65760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016102e4565b6001600160a01b0385163b610b3d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016102e4565b600080866001600160a01b03168587604051610b599190610cc4565b60006040518083038185875af1925050503d8060008114610b96576040519150601f19603f3d011682016040523d82523d6000602084013e610b9b565b606091505b5091509150610bab828286610bb6565b979650505050505050565b60608315610bc5575081610a67565b825115610bd55782518084602001fd5b8160405162461bcd60e51b81526004016102e49190610ce0565b600060208284031215610c0157600080fd5b5035919050565b600060208284031215610c1a57600080fd5b81356001600160a01b0381168114610a6757600080fd5b634e487b7160e01b600052601160045260246000fd5b60008219821115610c5a57610c5a610c31565b500190565b600082821015610c7157610c71610c31565b500390565b600060208284031215610c8857600080fd5b81518015158114610a6757600080fd5b60005b83811015610cb3578181015183820152602001610c9b565b8381111561096a5750506000910152565b60008251610cd6818460208701610c98565b9190910192915050565b6020815260008251806020840152610cff816040850160208701610c98565b601f01601f1916919091016040019291505056fea264697066735822122029fa20caa730666231f3429f218849c1b4a81c13952dee43dd0e9e4066849c4d64736f6c634300080d0033","sourceMap":"399:5328:5:-:0;;;2140:211;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;921:32:0;719:10:4;921:18:0;:32::i;:::-;-1:-1:-1;;;;;2254:12:5;;;;;2276;:28;2314:13;:30;399:5328;;2270:187:0;2343:16;2362:6;;-1:-1:-1;;;;;2378:17:0;;;-1:-1:-1;;;;;;2378:17:0;;;;;;2410:40;;2362:6;;;;;;;2410:40;;2343:16;2410:40;2333:124;2270:187;:::o;14:412:6:-;102:6;110;118;171:2;159:9;150:7;146:23;142:32;139:52;;;187:1;184;177:12;139:52;213:16;;-1:-1:-1;;;;;258:31:6;;248:42;;238:70;;304:1;301;294:12;238:70;372:2;357:18;;351:25;416:2;401:18;;;395:25;327:5;;351:25;;-1:-1:-1;395:25:6;14:412;-1:-1:-1;;;14:412:6:o;:::-;399:5328:5;;;;;;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063715018a61161008c5780638da5cb5b116100665780638da5cb5b1461023b578063a694fc3a1461024c578063bf9befb11461025f578063f2fde38b1461026857600080fd5b8063715018a6146101f457806372f0cb30146101fc5780637a7664601461020f57600080fd5b806330b75e04116100c857806330b75e04146101335780633222012f1461014657806343b0215f1461014f57806368bfce99146101b557600080fd5b80630288a39c146100ef5780632e17de781461010b5780632e1a7d4d14610120575b600080fd5b6100f860025481565b6040519081526020015b60405180910390f35b61011e610119366004610bef565b61027b565b005b61011e61012e366004610bef565b6103da565b61011e610141366004610bef565b6104c6565b6100f860015481565b61018d61015d366004610c08565b60046020819052600091825260409091208054600182015460028301546003840154939094015491939092909185565b604080519586526020860194909452928401919091526060830152608082015260a001610102565b6101dc7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610102565b61011e61055e565b61011e61020a366004610bef565b6105c4565b6100f861021d366004610c08565b6001600160a01b031660009081526004602052604090206002015490565b6000546001600160a01b03166101dc565b61011e61025a366004610bef565b610655565b6100f860035481565b61011e610276366004610c08565b610702565b33600090815260046020526040902060015481546102999190610c47565b4210156102ed5760405162461bcd60e51b815260206004820152601860248201527f756e7374616b652064656c6179206e6f7420706173736564000000000000000060448201526064015b60405180910390fd5b81816002015410156103415760405162461bcd60e51b815260206004820152601a60248201527f696e73756666696369656e74207374616b656420616d6f756e7400000000000060448201526064016102e4565b61034a816107e4565b428160010181905550818160020160008282546103679190610c5f565b92505081905550818160030160008282546103829190610c47565b92505081905550816003600082825461039b9190610c5f565b909155505060405182815233907f0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f75906020015b60405180910390a25050565b3360009081526004602052604090206103f2816107e4565b81816004015410156104465760405162461bcd60e51b815260206004820152601c60248201527f696e73756666696369656e7420756e6c6f636b656420616d6f756e740000000060448201526064016102e4565b8181600401600082825461045a9190610c5f565b9091555061049490506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163384610835565b60405182815233907f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5906020016103ce565b6000546001600160a01b031633146105205760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e4565b600181905560405181815233907f67aa75375fca757eaa536cc0b6855969ff77b119e0ddd3519c6f603dccc460df906020015b60405180910390a250565b6000546001600160a01b031633146105b85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e4565b6105c260006108ca565b565b6000546001600160a01b0316331461061e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e4565b600281905560405181815233907fa4cdbe995bf935cd31b353c9a555c4c7ceb0888e6ddc0f259d552368a319108b90602001610553565b3360009081526004602052604081204281556002810180549192849261067c908490610c47565b9250508190555081600360008282546106959190610c47565b909155506106d090506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333085610932565b60405182815233907f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d906020016103ce565b6000546001600160a01b0316331461075c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e4565b6001600160a01b0381166107d85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102e4565b6107e1816108ca565b50565b60008160030154118015610809575060025481600101546108059190610c47565b4210155b156107e15780600301548160040160008282546108269190610c47565b90915550506000600382015550565b6040516001600160a01b0383166024820152604481018290526108c590849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610970565b505050565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6040516001600160a01b038085166024830152831660448201526064810182905261096a9085906323b872dd60e01b90608401610861565b50505050565b60006109c5826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610a559092919063ffffffff16565b8051909150156108c557808060200190518101906109e39190610c76565b6108c55760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016102e4565b6060610a648484600085610a6e565b90505b9392505050565b606082471015610ae65760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016102e4565b6001600160a01b0385163b610b3d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016102e4565b600080866001600160a01b03168587604051610b599190610cc4565b60006040518083038185875af1925050503d8060008114610b96576040519150601f19603f3d011682016040523d82523d6000602084013e610b9b565b606091505b5091509150610bab828286610bb6565b979650505050505050565b60608315610bc5575081610a67565b825115610bd55782518084602001fd5b8160405162461bcd60e51b81526004016102e49190610ce0565b600060208284031215610c0157600080fd5b5035919050565b600060208284031215610c1a57600080fd5b81356001600160a01b0381168114610a6757600080fd5b634e487b7160e01b600052601160045260246000fd5b60008219821115610c5a57610c5a610c31565b500190565b600082821015610c7157610c71610c31565b500390565b600060208284031215610c8857600080fd5b81518015158114610a6757600080fd5b60005b83811015610cb3578181015183820152602001610c9b565b8381111561096a5750506000910152565b60008251610cd6818460208701610c98565b9190910192915050565b6020815260008251806020840152610cff816040850160208701610c98565b601f01601f1916919091016040019291505056fea264697066735822122029fa20caa730666231f3429f218849c1b4a81c13952dee43dd0e9e4066849c4d64736f6c634300080d0033","sourceMap":"399:5328:5:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1659:28;;;;;;;;;160:25:6;;;148:2;133:18;1659:28:5;;;;;;;;3414:514;;;;;;:::i;:::-;;:::i;:::-;;4091:384;;;;;;:::i;:::-;;:::i;5263:173::-;;;;;;:::i;:::-;;:::i;1552:27::-;;;;;;1798:45;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;954:25:6;;;1010:2;995:18;;988:34;;;;1038:18;;;1031:34;;;;1096:2;1081:18;;1074:34;1139:3;1124:19;;1117:35;941:3;926:19;1798:45:5;695:463:6;1447:29:5;;;;;;;;-1:-1:-1;;;;;1327:55:6;;;1309:74;;1297:2;1282:18;1447:29:5;1163:226:6;1668:101:0;;;:::i;5546:179:5:-;;;;;;:::i;:::-;;:::i;4989:111::-;;;;;;:::i;:::-;-1:-1:-1;;;;;5071:16:5;5045:7;5071:16;;;:9;:16;;;;;:22;;;;4989:111;1036:85:0;1082:7;1108:6;-1:-1:-1;;;;;1108:6:0;1036:85;;2494:330:5;;;;;;:::i;:::-;;:::i;1727:26::-;;;;;;1918:198:0;;;;;;:::i;:::-;;:::i;3414:514:5:-;3501:10;3467:21;3491;;;:9;:21;;;;;3570:12;;3549:18;;:33;;3570:12;3549:33;:::i;:::-;3530:15;:52;;3522:89;;;;-1:-1:-1;;;3522:89:5;;1861:2:6;3522:89:5;;;1843:21:6;1900:2;1880:18;;;1873:30;1939:26;1919:18;;;1912:54;1983:18;;3522:89:5;;;;;;;;;3643:7;3629:4;:10;;;:21;;3621:60;;;;-1:-1:-1;;;3621:60:5;;2214:2:6;3621:60:5;;;2196:21:6;2253:2;2233:18;;;2226:30;2292:28;2272:18;;;2265:56;2338:18;;3621:60:5;2012:350:6;3621:60:5;3692:27;3714:4;3692:21;:27::i;:::-;3752:15;3729:4;:20;;:38;;;;3791:7;3777:4;:10;;;:21;;;;;;;:::i;:::-;;;;;;;;3837:7;3808:4;:25;;;:36;;;;;;;:::i;:::-;;;;;;;;3869:7;3854:11;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;3892:29:5;;160:25:6;;;3901:10:5;;3892:29;;148:2:6;133:18;3892:29:5;;;;;;;;3457:471;3414:514;:::o;4091:384::-;4179:10;4145:21;4169;;;:9;:21;;;;;4200:27;4169:21;4200;:27::i;:::-;4277:7;4246:4;:27;;;:38;;4238:79;;;;-1:-1:-1;;;4238:79:5;;2699:2:6;4238:79:5;;;2681:21:6;2738:2;2718:18;;;2711:30;2777;2757:18;;;2750:58;2825:18;;4238:79:5;2497:352:6;4238:79:5;4359:7;4328:4;:27;;;:38;;;;;;;:::i;:::-;;;;-1:-1:-1;4377:46:5;;-1:-1:-1;;;;;;4384:4:5;4377:25;4403:10;4415:7;4377:25;:46::i;:::-;4438:30;;160:25:6;;;4448:10:5;;4438:30;;148:2:6;133:18;4438:30:5;14:177:6;5263:173:5;1082:7:0;1108:6;-1:-1:-1;;;;;1108:6:0;719:10:4;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;3056:2:6;1240:68:0;;;3038:21:6;;;3075:18;;;3068:30;3134:34;3114:18;;;3107:62;3186:18;;1240:68:0;2854:356:6;1240:68:0;5340:12:5::1;:28:::0;;;5383:46:::1;::::0;160:25:6;;;5403:10:5::1;::::0;5383:46:::1;::::0;148:2:6;133:18;5383:46:5::1;;;;;;;;5263:173:::0;:::o;1668:101:0:-;1082:7;1108:6;-1:-1:-1;;;;;1108:6:0;719:10:4;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;3056:2:6;1240:68:0;;;3038:21:6;;;3075:18;;;3068:30;3134:34;3114:18;;;3107:62;3186:18;;1240:68:0;2854:356:6;1240:68:0;1732:30:::1;1759:1;1732:18;:30::i;:::-;1668:101::o:0;5546:179:5:-;1082:7:0;1108:6;-1:-1:-1;;;;;1108:6:0;719:10:4;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;3056:2:6;1240:68:0;;;3038:21:6;;;3075:18;;;3068:30;3134:34;3114:18;;;3107:62;3186:18;;1240:68:0;2854:356:6;1240:68:0;5625:13:5::1;:30:::0;;;5670:48:::1;::::0;160:25:6;;;5691:10:5::1;::::0;5670:48:::1;::::0;148:2:6;133:18;5670:48:5::1;14:177:6::0;2494:330:5;2579:10;2545:21;2569;;;:9;:21;;;;;2621:15;2600:36;;2646:10;;;:21;;2569;;2660:7;;2646:21;;2660:7;;2646:21;:::i;:::-;;;;;;;;2692:7;2677:11;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;2710:65:5;;-1:-1:-1;;;;;;2717:4:5;2710:29;2740:10;2760:4;2767:7;2710:29;:65::i;:::-;2790:27;;160:25:6;;;2797:10:5;;2790:27;;148:2:6;133:18;2790:27:5;14:177:6;1918:198:0;1082:7;1108:6;-1:-1:-1;;;;;1108:6:0;719:10:4;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;3056:2:6;1240:68:0;;;3038:21:6;;;3075:18;;;3068:30;3134:34;3114:18;;;3107:62;3186:18;;1240:68:0;2854:356:6;1240:68:0;-1:-1:-1;;;;;2006:22:0;::::1;1998:73;;;::::0;-1:-1:-1;;;1998:73:0;;3417:2:6;1998:73:0::1;::::0;::::1;3399:21:6::0;3456:2;3436:18;;;3429:30;3495:34;3475:18;;;3468:62;3566:8;3546:18;;;3539:36;3592:19;;1998:73:0::1;3215:402:6::0;1998:73:0::1;2081:28;2100:8;2081:18;:28::i;:::-;1918:198:::0;:::o;4577:303:5:-;4684:1;4655:5;:26;;;:30;:90;;;;;4732:13;;4708:5;:21;;;:37;;;;:::i;:::-;4689:15;:56;;4655:90;4651:223;;;4793:5;:26;;;4761:5;:28;;;:58;;;;;;;:::i;:::-;;;;-1:-1:-1;;4862:1:5;4833:26;;;:30;4577:303;:::o;701:205:2:-;840:58;;-1:-1:-1;;;;;3814:55:6;;840:58:2;;;3796:74:6;3886:18;;;3879:34;;;813:86:2;;833:5;;-1:-1:-1;;;863:23:2;3769:18:6;;840:58:2;;;;-1:-1:-1;;840:58:2;;;;;;;;;;;;;;;;;;;;;;;;;;;813:19;:86::i;:::-;701:205;;;:::o;2270:187:0:-;2343:16;2362:6;;-1:-1:-1;;;;;2378:17:0;;;;;;;;;;2410:40;;2362:6;;;;;;;2410:40;;2343:16;2410:40;2333:124;2270:187;:::o;912:241:2:-;1077:68;;-1:-1:-1;;;;;4205:15:6;;;1077:68:2;;;4187:34:6;4257:15;;4237:18;;;4230:43;4289:18;;;4282:34;;;1050:96:2;;1070:5;;-1:-1:-1;;;1100:27:2;4099:18:6;;1077:68:2;3924:398:6;1050:96:2;912:241;;;;:::o;3207:706::-;3626:23;3652:69;3680:4;3652:69;;;;;;;;;;;;;;;;;3660:5;-1:-1:-1;;;;;3652:27:2;;;:69;;;;;:::i;:::-;3735:17;;3626:95;;-1:-1:-1;3735:21:2;3731:176;;3830:10;3819:30;;;;;;;;;;;;:::i;:::-;3811:85;;;;-1:-1:-1;;;3811:85:2;;4811:2:6;3811:85:2;;;4793:21:6;4850:2;4830:18;;;4823:30;4889:34;4869:18;;;4862:62;4960:12;4940:18;;;4933:40;4990:19;;3811:85:2;4609:406:6;3861:223:3;3994:12;4025:52;4047:6;4055:4;4061:1;4064:12;4025:21;:52::i;:::-;4018:59;;3861:223;;;;;;:::o;4948:499::-;5113:12;5170:5;5145:21;:30;;5137:81;;;;-1:-1:-1;;;5137:81:3;;5222:2:6;5137:81:3;;;5204:21:6;5261:2;5241:18;;;5234:30;5300:34;5280:18;;;5273:62;5371:8;5351:18;;;5344:36;5397:19;;5137:81:3;5020:402:6;5137:81:3;-1:-1:-1;;;;;1465:19:3;;;5228:60;;;;-1:-1:-1;;;5228:60:3;;5629:2:6;5228:60:3;;;5611:21:6;5668:2;5648:18;;;5641:30;5707:31;5687:18;;;5680:59;5756:18;;5228:60:3;5427:353:6;5228:60:3;5300:12;5314:23;5341:6;-1:-1:-1;;;;;5341:11:3;5360:5;5367:4;5341:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5299:73;;;;5389:51;5406:7;5415:10;5427:12;5389:16;:51::i;:::-;5382:58;4948:499;-1:-1:-1;;;;;;;4948:499:3:o;7561:692::-;7707:12;7735:7;7731:516;;;-1:-1:-1;7765:10:3;7758:17;;7731:516;7876:17;;:21;7872:365;;8070:10;8064:17;8130:15;8117:10;8113:2;8109:19;8102:44;7872:365;8209:12;8202:20;;-1:-1:-1;;;8202:20:3;;;;;;;;:::i;196:180:6:-;255:6;308:2;296:9;287:7;283:23;279:32;276:52;;;324:1;321;314:12;276:52;-1:-1:-1;347:23:6;;196:180;-1:-1:-1;196:180:6:o;381:309::-;440:6;493:2;481:9;472:7;468:23;464:32;461:52;;;509:1;506;499:12;461:52;548:9;535:23;-1:-1:-1;;;;;591:5:6;587:54;580:5;577:65;567:93;;656:1;653;646:12;1394:127;1455:10;1450:3;1446:20;1443:1;1436:31;1486:4;1483:1;1476:15;1510:4;1507:1;1500:15;1526:128;1566:3;1597:1;1593:6;1590:1;1587:13;1584:39;;;1603:18;;:::i;:::-;-1:-1:-1;1639:9:6;;1526:128::o;2367:125::-;2407:4;2435:1;2432;2429:8;2426:34;;;2440:18;;:::i;:::-;-1:-1:-1;2477:9:6;;2367:125::o;4327:277::-;4394:6;4447:2;4435:9;4426:7;4422:23;4418:32;4415:52;;;4463:1;4460;4453:12;4415:52;4495:9;4489:16;4548:5;4541:13;4534:21;4527:5;4524:32;4514:60;;4570:1;4567;4560:12;5785:258;5857:1;5867:113;5881:6;5878:1;5875:13;5867:113;;;5957:11;;;5951:18;5938:11;;;5931:39;5903:2;5896:10;5867:113;;;5998:6;5995:1;5992:13;5989:48;;;-1:-1:-1;;6033:1:6;6015:16;;6008:27;5785:258::o;6048:274::-;6177:3;6215:6;6209:13;6231:53;6277:6;6272:3;6265:4;6257:6;6253:17;6231:53;:::i;:::-;6300:16;;;;;6048:274;-1:-1:-1;;6048:274:6:o;6327:383::-;6476:2;6465:9;6458:21;6439:4;6508:6;6502:13;6551:6;6546:2;6535:9;6531:18;6524:34;6567:66;6626:6;6621:2;6610:9;6606:18;6601:2;6593:6;6589:15;6567:66;:::i;:::-;6694:2;6673:15;-1:-1:-1;;6669:29:6;6654:45;;;;6701:2;6650:54;;6327:383;-1:-1:-1;;6327:383:6:o","linkReferences":{},"immutableReferences":{"778":[{"start":442,"length":32},{"start":1133,"length":32},{"start":1704,"length":32}]}}}}}}},"signatures":{"function":[{"signature":"getStake(address)","signatureHash4":"0x7a766460","signatureHash32":"0x7a7664602914e9220bf98c40cd78d8cd0036a1692fcc95af2bf47047bec10e22"},{"signature":"koge()","signatureHash4":"0x68bfce99","signatureHash32":"0x68bfce9918239439e0b4c0128e00f920a3ae4993a15425653e0462b5dd5b1698"},{"signature":"owner()","signatureHash4":"0x8da5cb5b","signatureHash32":"0x8da5cb5b36e7f68c1d2e56001220cdbdd3ba2616072f718acfda4a06441a807d"},{"signature":"renounceOwnership()","signatureHash4":"0x715018a6","signatureHash32":"0x715018a616b5f2044428f6fadb7deef4ce9ca76ef60ea57978964ad137bbe7ae"},{"signature":"setUnstakeDelay(uint256)","signatureHash4":"0x30b75e04","signatureHash32":"0x30b75e042b9fe29a7bb84b7835af4601fb7701321b49ac03f90a855f9ec26ad6"},{"signature":"setWithdrawDelay(uint256)","signatureHash4":"0x72f0cb30","signatureHash32":"0x72f0cb30e619fa0c5d2bdcf2c4c47f0d6fdc25f3174c1da35bf38c8df558f79a"},{"signature":"stake(uint256)","signatureHash4":"0xa694fc3a","signatureHash32":"0xa694fc3a9be557197d0136d5e7dd615518dbfe3af0753bf945e64e3bed38fba8"},{"signature":"totalStakes()","signatureHash4":"0xbf9befb1","signatureHash32":"0xbf9befb18304cc564a655df81de3484921ec43310fd09cfde701a046b6086187"},{"signature":"transferOwnership(address)","signatureHash4":"0xf2fde38b","signatureHash32":"0xf2fde38b092330466c661fc723d5289b90272a3e580e3187d1d7ef788506c557"},{"signature":"unstakeDelay()","signatureHash4":"0x3222012f","signatureHash32":"0x3222012f6fa62f9d86389ff6959c0debb6cf16d18deaf83880f79241c3925e74"},{"signature":"unstake(uint256)","signatureHash4":"0x2e17de78","signatureHash32":"0x2e17de78782a3e2bdf248304b8ae296b06fe4bd58bfb23fc13e9e4963635c2d4"},{"signature":"userInfos(address)","signatureHash4":"0x43b0215f","signatureHash32":"0x43b0215f60d9cf42706bb16852be152dcdd26ff930a92fd74b3b5eced14f26bd"},{"signature":"withdrawDelay()","signatureHash4":"0x0288a39c","signatureHash32":"0x0288a39c76b44b0b17544d4ca18a1f5fbe2bc18558255a60c5cb4f59628ec02d"},{"signature":"withdraw(uint256)","signatureHash4":"0x2e1a7d4d","signatureHash32":"0x2e1a7d4d13322e7b96f9a57413e1525c250fb7a9021cf91d1540d5b69f16a49f"}],"event":[{"signature":"OwnershipTransferred(address,address)","signatureHash4":"0x8be0079c","signatureHash32":"0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0"},{"signature":"Staked(address,uint256)","signatureHash4":"0x9e71bc8e","signatureHash32":"0x9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d"},{"signature":"Unstaked(address,uint256)","signatureHash4":"0x0f5bb821","signatureHash32":"0x0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f75"},{"signature":"UnstakeDelayUpdated(address,uint256)","signatureHash4":"0x67aa7537","signatureHash32":"0x67aa75375fca757eaa536cc0b6855969ff77b119e0ddd3519c6f603dccc460df"},{"signature":"WithdrawDelayUpdated(address,uint256)","signatureHash4":"0xa4cdbe99","signatureHash32":"0xa4cdbe995bf935cd31b353c9a555c4c7ceb0888e6ddc0f259d552368a319108b"},{"signature":"Withdrawn(address,uint256)","signatureHash4":"0x7084f547","signatureHash32":"0x7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5"}],"error":[]},"proxyResolution":{"isProxy":false,"proxyType":null,"implementations":[]},"match":"exact_match","chainId":"56","address":"0xa31F6B577704B4622d2ba63F6aa1b7e92fe8C8a9"}