From 606970bd29943f62e8f0553456e7d77602b9dffd Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Thu, 18 Apr 2024 18:41:27 +0200 Subject: [PATCH] chore: minify JSON --- crates/anvil/test-data/SimpleStorage.json | 118 +----- crates/anvil/test-data/emit_logs.json | 68 +-- crates/anvil/test-data/greeter.json | 45 +- crates/anvil/test-data/multicall.json | 145 +------ crates/anvil/test-data/storage_sample.json | 34 +- crates/cast/tests/fixtures/ERC20Artifact.json | 386 +----------------- crates/cast/tests/fixtures/interface.json | 142 +------ .../cast/tests/fixtures/sign_typed_data.json | 39 +- crates/evm/core/src/abi/HardhatConsole.json | 2 +- crates/evm/core/test-data/storage.json | 2 +- .../deploy.sol/31337/run-latest.json | 64 +-- .../creation_data.json | 6 +- .../metadata.json | 79 +--- .../creation_data.json | 6 +- .../metadata.json | 17 +- .../creation_data.json | 6 +- .../metadata.json | 194 +-------- .../creation_data.json | 6 +- .../metadata.json | 130 +----- .../creation_data.json | 6 +- .../metadata.json | 64 +-- .../creation_data.json | 6 +- .../metadata.json | 70 +--- .../creation_data.json | 6 +- .../metadata.json | 149 +------ 25 files changed, 25 insertions(+), 1765 deletions(-) diff --git a/crates/anvil/test-data/SimpleStorage.json b/crates/anvil/test-data/SimpleStorage.json index 3d4a8b81aa5b..8ff4ab3812fe 100644 --- a/crates/anvil/test-data/SimpleStorage.json +++ b/crates/anvil/test-data/SimpleStorage.json @@ -1,117 +1 @@ -{ - "abi": [ - { - "inputs": [ - { - "internalType": "string", - "name": "value", - "type": "string" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "author", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "oldAuthor", - "type": "address" - }, - { - "indexed": false, - "internalType": "string", - "name": "oldValue", - "type": "string" - }, - { - "indexed": false, - "internalType": "string", - "name": "newValue", - "type": "string" - } - ], - "name": "ValueChanged", - "type": "event" - }, - { - "inputs": [], - "name": "_hashPuzzle", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getValue", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "lastSender", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "value", - "type": "string" - } - ], - "name": "setValue", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "value", - "type": "string" - }, - { - "internalType": "string", - "name": "value2", - "type": "string" - } - ], - "name": "setValues", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bin": "60806040523480156200001157600080fd5b5060405162000d6a38038062000d6a83398181016040528101906200003791906200030f565b600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f999b6d464c4e3383c341bdd3a22b02dda8a7e1d69c069d252e35cb2ee2f4a3c36001846040516200009a929190620004c3565b60405180910390a38060019080519060200190620000ba929190620000c2565b5050620004fe565b828054620000d0906200038f565b90600052602060002090601f016020900481019282620000f4576000855562000140565b82601f106200010f57805160ff191683800117855562000140565b8280016001018555821562000140579182015b828111156200013f57825182559160200191906001019062000122565b5b5090506200014f919062000153565b5090565b5b808211156200016e57600081600090555060010162000154565b5090565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b620001db8262000190565b810181811067ffffffffffffffff82111715620001fd57620001fc620001a1565b5b80604052505050565b60006200021262000172565b9050620002208282620001d0565b919050565b600067ffffffffffffffff821115620002435762000242620001a1565b5b6200024e8262000190565b9050602081019050919050565b60005b838110156200027b5780820151818401526020810190506200025e565b838111156200028b576000848401525b50505050565b6000620002a8620002a28462000225565b62000206565b905082815260208101848484011115620002c757620002c66200018b565b5b620002d48482856200025b565b509392505050565b600082601f830112620002f457620002f362000186565b5b81516200030684826020860162000291565b91505092915050565b6000602082840312156200032857620003276200017c565b5b600082015167ffffffffffffffff81111562000349576200034862000181565b5b6200035784828501620002dc565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620003a857607f821691505b60208210811415620003bf57620003be62000360565b5b50919050565b600082825260208201905092915050565b60008190508160005260206000209050919050565b60008154620003fa816200038f565b620004068186620003c5565b9450600182166000811462000424576001811462000437576200046e565b60ff19831686526020860193506200046e565b6200044285620003d6565b60005b83811015620004665781548189015260018201915060208101905062000445565b808801955050505b50505092915050565b600081519050919050565b60006200048f8262000477565b6200049b8185620003c5565b9350620004ad8185602086016200025b565b620004b88162000190565b840191505092915050565b60006040820190508181036000830152620004df8185620003eb565b90508181036020830152620004f5818462000482565b90509392505050565b61085c806200050e6000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c8063018ba9911461005c578063209652551461007a578063256fec88146100985780637ffaa4b6146100b657806393a09352146100d2575b600080fd5b6100646100ee565b60405161007191906103bd565b60405180910390f35b6100826100f7565b60405161008f9190610471565b60405180910390f35b6100a0610189565b6040516100ad91906104d4565b60405180910390f35b6100d060048036038101906100cb9190610638565b6101ad565b005b6100ec60048036038101906100e791906106b0565b61021f565b005b60006064905090565b60606001805461010690610728565b80601f016020809104026020016040519081016040528092919081815260200182805461013290610728565b801561017f5780601f106101545761010080835404028352916020019161017f565b820191906000526020600020905b81548152906001019060200180831161016257829003601f168201915b5050505050905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b81600190805190602001906101c3929190610301565b5080600290805190602001906101da929190610301565b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f999b6d464c4e3383c341bdd3a22b02dda8a7e1d69c069d252e35cb2ee2f4a3c360018460405161029f9291906107ef565b60405180910390a380600190805190602001906102bd929190610301565b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b82805461030d90610728565b90600052602060002090601f01602090048101928261032f5760008555610376565b82601f1061034857805160ff1916838001178555610376565b82800160010185558215610376579182015b8281111561037557825182559160200191906001019061035a565b5b5090506103839190610387565b5090565b5b808211156103a0576000816000905550600101610388565b5090565b6000819050919050565b6103b7816103a4565b82525050565b60006020820190506103d260008301846103ae565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156104125780820151818401526020810190506103f7565b83811115610421576000848401525b50505050565b6000601f19601f8301169050919050565b6000610443826103d8565b61044d81856103e3565b935061045d8185602086016103f4565b61046681610427565b840191505092915050565b6000602082019050818103600083015261048b8184610438565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006104be82610493565b9050919050565b6104ce816104b3565b82525050565b60006020820190506104e960008301846104c5565b92915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61054582610427565b810181811067ffffffffffffffff821117156105645761056361050d565b5b80604052505050565b60006105776104ef565b9050610583828261053c565b919050565b600067ffffffffffffffff8211156105a3576105a261050d565b5b6105ac82610427565b9050602081019050919050565b82818337600083830152505050565b60006105db6105d684610588565b61056d565b9050828152602081018484840111156105f7576105f6610508565b5b6106028482856105b9565b509392505050565b600082601f83011261061f5761061e610503565b5b813561062f8482602086016105c8565b91505092915050565b6000806040838503121561064f5761064e6104f9565b5b600083013567ffffffffffffffff81111561066d5761066c6104fe565b5b6106798582860161060a565b925050602083013567ffffffffffffffff81111561069a576106996104fe565b5b6106a68582860161060a565b9150509250929050565b6000602082840312156106c6576106c56104f9565b5b600082013567ffffffffffffffff8111156106e4576106e36104fe565b5b6106f08482850161060a565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061074057607f821691505b60208210811415610754576107536106f9565b5b50919050565b60008190508160005260206000209050919050565b6000815461077c81610728565b61078681866103e3565b945060018216600081146107a157600181146107b3576107e6565b60ff19831686526020860193506107e6565b6107bc8561075a565b60005b838110156107de578154818901526001820191506020810190506107bf565b808801955050505b50505092915050565b60006040820190508181036000830152610809818561076f565b9050818103602083015261081d8184610438565b9050939250505056fea2646970667358221220e37ed4b56859ad0b3a3773f57ff7b4e7a99406933fc4ff9f8ae053c52cdf3e3264736f6c63430008090033" -} \ No newline at end of file +{"abi":[{"inputs":[{"internalType":"string","name":"value","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"author","type":"address"},{"indexed":true,"internalType":"address","name":"oldAuthor","type":"address"},{"indexed":false,"internalType":"string","name":"oldValue","type":"string"},{"indexed":false,"internalType":"string","name":"newValue","type":"string"}],"name":"ValueChanged","type":"event"},{"inputs":[],"name":"_hashPuzzle","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getValue","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastSender","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"value","type":"string"}],"name":"setValue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"value","type":"string"},{"internalType":"string","name":"value2","type":"string"}],"name":"setValues","outputs":[],"stateMutability":"nonpayable","type":"function"}],"bin":"60806040523480156200001157600080fd5b5060405162000d6a38038062000d6a83398181016040528101906200003791906200030f565b600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f999b6d464c4e3383c341bdd3a22b02dda8a7e1d69c069d252e35cb2ee2f4a3c36001846040516200009a929190620004c3565b60405180910390a38060019080519060200190620000ba929190620000c2565b5050620004fe565b828054620000d0906200038f565b90600052602060002090601f016020900481019282620000f4576000855562000140565b82601f106200010f57805160ff191683800117855562000140565b8280016001018555821562000140579182015b828111156200013f57825182559160200191906001019062000122565b5b5090506200014f919062000153565b5090565b5b808211156200016e57600081600090555060010162000154565b5090565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b620001db8262000190565b810181811067ffffffffffffffff82111715620001fd57620001fc620001a1565b5b80604052505050565b60006200021262000172565b9050620002208282620001d0565b919050565b600067ffffffffffffffff821115620002435762000242620001a1565b5b6200024e8262000190565b9050602081019050919050565b60005b838110156200027b5780820151818401526020810190506200025e565b838111156200028b576000848401525b50505050565b6000620002a8620002a28462000225565b62000206565b905082815260208101848484011115620002c757620002c66200018b565b5b620002d48482856200025b565b509392505050565b600082601f830112620002f457620002f362000186565b5b81516200030684826020860162000291565b91505092915050565b6000602082840312156200032857620003276200017c565b5b600082015167ffffffffffffffff81111562000349576200034862000181565b5b6200035784828501620002dc565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620003a857607f821691505b60208210811415620003bf57620003be62000360565b5b50919050565b600082825260208201905092915050565b60008190508160005260206000209050919050565b60008154620003fa816200038f565b620004068186620003c5565b9450600182166000811462000424576001811462000437576200046e565b60ff19831686526020860193506200046e565b6200044285620003d6565b60005b83811015620004665781548189015260018201915060208101905062000445565b808801955050505b50505092915050565b600081519050919050565b60006200048f8262000477565b6200049b8185620003c5565b9350620004ad8185602086016200025b565b620004b88162000190565b840191505092915050565b60006040820190508181036000830152620004df8185620003eb565b90508181036020830152620004f5818462000482565b90509392505050565b61085c806200050e6000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c8063018ba9911461005c578063209652551461007a578063256fec88146100985780637ffaa4b6146100b657806393a09352146100d2575b600080fd5b6100646100ee565b60405161007191906103bd565b60405180910390f35b6100826100f7565b60405161008f9190610471565b60405180910390f35b6100a0610189565b6040516100ad91906104d4565b60405180910390f35b6100d060048036038101906100cb9190610638565b6101ad565b005b6100ec60048036038101906100e791906106b0565b61021f565b005b60006064905090565b60606001805461010690610728565b80601f016020809104026020016040519081016040528092919081815260200182805461013290610728565b801561017f5780601f106101545761010080835404028352916020019161017f565b820191906000526020600020905b81548152906001019060200180831161016257829003601f168201915b5050505050905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b81600190805190602001906101c3929190610301565b5080600290805190602001906101da929190610301565b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f999b6d464c4e3383c341bdd3a22b02dda8a7e1d69c069d252e35cb2ee2f4a3c360018460405161029f9291906107ef565b60405180910390a380600190805190602001906102bd929190610301565b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b82805461030d90610728565b90600052602060002090601f01602090048101928261032f5760008555610376565b82601f1061034857805160ff1916838001178555610376565b82800160010185558215610376579182015b8281111561037557825182559160200191906001019061035a565b5b5090506103839190610387565b5090565b5b808211156103a0576000816000905550600101610388565b5090565b6000819050919050565b6103b7816103a4565b82525050565b60006020820190506103d260008301846103ae565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156104125780820151818401526020810190506103f7565b83811115610421576000848401525b50505050565b6000601f19601f8301169050919050565b6000610443826103d8565b61044d81856103e3565b935061045d8185602086016103f4565b61046681610427565b840191505092915050565b6000602082019050818103600083015261048b8184610438565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006104be82610493565b9050919050565b6104ce816104b3565b82525050565b60006020820190506104e960008301846104c5565b92915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61054582610427565b810181811067ffffffffffffffff821117156105645761056361050d565b5b80604052505050565b60006105776104ef565b9050610583828261053c565b919050565b600067ffffffffffffffff8211156105a3576105a261050d565b5b6105ac82610427565b9050602081019050919050565b82818337600083830152505050565b60006105db6105d684610588565b61056d565b9050828152602081018484840111156105f7576105f6610508565b5b6106028482856105b9565b509392505050565b600082601f83011261061f5761061e610503565b5b813561062f8482602086016105c8565b91505092915050565b6000806040838503121561064f5761064e6104f9565b5b600083013567ffffffffffffffff81111561066d5761066c6104fe565b5b6106798582860161060a565b925050602083013567ffffffffffffffff81111561069a576106996104fe565b5b6106a68582860161060a565b9150509250929050565b6000602082840312156106c6576106c56104f9565b5b600082013567ffffffffffffffff8111156106e4576106e36104fe565b5b6106f08482850161060a565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061074057607f821691505b60208210811415610754576107536106f9565b5b50919050565b60008190508160005260206000209050919050565b6000815461077c81610728565b61078681866103e3565b945060018216600081146107a157600181146107b3576107e6565b60ff19831686526020860193506107e6565b6107bc8561075a565b60005b838110156107de578154818901526001820191506020810190506107bf565b808801955050505b50505092915050565b60006040820190508181036000830152610809818561076f565b9050818103602083015261081d8184610438565b9050939250505056fea2646970667358221220e37ed4b56859ad0b3a3773f57ff7b4e7a99406933fc4ff9f8ae053c52cdf3e3264736f6c63430008090033"} \ No newline at end of file diff --git a/crates/anvil/test-data/emit_logs.json b/crates/anvil/test-data/emit_logs.json index 0113e1c49d92..635019ae3ab3 100644 --- a/crates/anvil/test-data/emit_logs.json +++ b/crates/anvil/test-data/emit_logs.json @@ -1,67 +1 @@ -{ - "abi": [ - { - "inputs": [ - { - "internalType": "string", - "name": "value", - "type": "string" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "author", - "type": "address" - }, - { - "indexed": false, - "internalType": "string", - "name": "oldValue", - "type": "string" - }, - { - "indexed": false, - "internalType": "string", - "name": "newValue", - "type": "string" - } - ], - "name": "ValueChanged", - "type": "event" - }, - { - "inputs": [], - "name": "getValue", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "value", - "type": "string" - } - ], - "name": "setValue", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bin": "608060405234801561001057600080fd5b506040516105a63803806105a68339818101604052602081101561003357600080fd5b810190808051604051939291908464010000000082111561005357600080fd5b90830190602082018581111561006857600080fd5b825164010000000081118282018810171561008257600080fd5b82525081516020918201929091019080838360005b838110156100af578181015183820152602001610097565b50505050905090810190601f1680156100dc5780820380516001836020036101000a031916815260200191505b50604052505081516100f6915060009060208401906100fd565b505061019e565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826101335760008555610179565b82601f1061014c57805160ff1916838001178555610179565b82800160010185558215610179579182015b8281111561017957825182559160200191906001019061015e565b50610185929150610189565b5090565b5b80821115610185576000815560010161018a565b6103f9806101ad6000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063209652551461003b57806393a09352146100b8575b600080fd5b610043610160565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561007d578181015183820152602001610065565b50505050905090810190601f1680156100aa5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61015e600480360360208110156100ce57600080fd5b8101906020810181356401000000008111156100e957600080fd5b8201836020820111156100fb57600080fd5b8035906020019184600183028401116401000000008311171561011d57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506101f6945050505050565b005b60008054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156101ec5780601f106101c1576101008083540402835291602001916101ec565b820191906000526020600020905b8154815290600101906020018083116101cf57829003601f168201915b5050505050905090565b60408051818152600080546002600019610100600184161502019091160492820183905233927fe826f71647b8486f2bae59832124c70792fba044036720a54ec8dacdd5df4fcb9285918190602082019060608301908690801561029b5780601f106102705761010080835404028352916020019161029b565b820191906000526020600020905b81548152906001019060200180831161027e57829003601f168201915b5050838103825284518152845160209182019186019080838360005b838110156102cf5781810151838201526020016102b7565b50505050905090810190601f1680156102fc5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a2805161031e906000906020840190610322565b5050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282610358576000855561039e565b82601f1061037157805160ff191683800117855561039e565b8280016001018555821561039e579182015b8281111561039e578251825591602001919060010190610383565b506103aa9291506103ae565b5090565b5b808211156103aa57600081556001016103af56fea2646970667358221220c1367a0db85dfe60814cdfc5141a8fe8b95c9d051a6824343085c3ba9697244a64736f6c63430007060033" -} \ No newline at end of file +{"abi":[{"inputs":[{"internalType":"string","name":"value","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"author","type":"address"},{"indexed":false,"internalType":"string","name":"oldValue","type":"string"},{"indexed":false,"internalType":"string","name":"newValue","type":"string"}],"name":"ValueChanged","type":"event"},{"inputs":[],"name":"getValue","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"value","type":"string"}],"name":"setValue","outputs":[],"stateMutability":"nonpayable","type":"function"}],"bin":"608060405234801561001057600080fd5b506040516105a63803806105a68339818101604052602081101561003357600080fd5b810190808051604051939291908464010000000082111561005357600080fd5b90830190602082018581111561006857600080fd5b825164010000000081118282018810171561008257600080fd5b82525081516020918201929091019080838360005b838110156100af578181015183820152602001610097565b50505050905090810190601f1680156100dc5780820380516001836020036101000a031916815260200191505b50604052505081516100f6915060009060208401906100fd565b505061019e565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826101335760008555610179565b82601f1061014c57805160ff1916838001178555610179565b82800160010185558215610179579182015b8281111561017957825182559160200191906001019061015e565b50610185929150610189565b5090565b5b80821115610185576000815560010161018a565b6103f9806101ad6000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063209652551461003b57806393a09352146100b8575b600080fd5b610043610160565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561007d578181015183820152602001610065565b50505050905090810190601f1680156100aa5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61015e600480360360208110156100ce57600080fd5b8101906020810181356401000000008111156100e957600080fd5b8201836020820111156100fb57600080fd5b8035906020019184600183028401116401000000008311171561011d57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506101f6945050505050565b005b60008054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156101ec5780601f106101c1576101008083540402835291602001916101ec565b820191906000526020600020905b8154815290600101906020018083116101cf57829003601f168201915b5050505050905090565b60408051818152600080546002600019610100600184161502019091160492820183905233927fe826f71647b8486f2bae59832124c70792fba044036720a54ec8dacdd5df4fcb9285918190602082019060608301908690801561029b5780601f106102705761010080835404028352916020019161029b565b820191906000526020600020905b81548152906001019060200180831161027e57829003601f168201915b5050838103825284518152845160209182019186019080838360005b838110156102cf5781810151838201526020016102b7565b50505050905090810190601f1680156102fc5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a2805161031e906000906020840190610322565b5050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282610358576000855561039e565b82601f1061037157805160ff191683800117855561039e565b8280016001018555821561039e579182015b8281111561039e578251825591602001919060010190610383565b506103aa9291506103ae565b5090565b5b808211156103aa57600081556001016103af56fea2646970667358221220c1367a0db85dfe60814cdfc5141a8fe8b95c9d051a6824343085c3ba9697244a64736f6c63430007060033"} \ No newline at end of file diff --git a/crates/anvil/test-data/greeter.json b/crates/anvil/test-data/greeter.json index 0892e4d43f92..93c50f01edb8 100644 --- a/crates/anvil/test-data/greeter.json +++ b/crates/anvil/test-data/greeter.json @@ -1,44 +1 @@ -{ - "bytecode": { - "object": "608060405234801561001057600080fd5b506040516104913803806104918339818101604052602081101561003357600080fd5b810190808051604051939291908464010000000082111561005357600080fd5b90830190602082018581111561006857600080fd5b825164010000000081118282018810171561008257600080fd5b82525081516020918201929091019080838360005b838110156100af578181015183820152602001610097565b50505050905090810190601f1680156100dc5780820380516001836020036101000a031916815260200191505b50604052505081516100f6915060009060208401906100fd565b505061019e565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826101335760008555610179565b82601f1061014c57805160ff1916838001178555610179565b82800160010185558215610179579182015b8281111561017957825182559160200191906001019061015e565b50610185929150610189565b5090565b5b80821115610185576000815560010161018a565b6102e4806101ad6000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063a41368621461003b578063cfae3217146100e3575b600080fd5b6100e16004803603602081101561005157600080fd5b81019060208101813564010000000081111561006c57600080fd5b82018360208201111561007e57600080fd5b803590602001918460018302840111640100000000831117156100a057600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610160945050505050565b005b6100eb610177565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561012557818101518382015260200161010d565b50505050905090810190601f1680156101525780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b805161017390600090602084019061020d565b5050565b60008054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156102035780601f106101d857610100808354040283529160200191610203565b820191906000526020600020905b8154815290600101906020018083116101e657829003601f168201915b5050505050905090565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826102435760008555610289565b82601f1061025c57805160ff1916838001178555610289565b82800160010185558215610289579182015b8281111561028957825182559160200191906001019061026e565b50610295929150610299565b5090565b5b80821115610295576000815560010161029a56fea26469706673582212208b9161dfd195d53618942a72a3b481d61a7b142de919925a0b34f9c986e5707e64736f6c63430007060033" - }, - "abi": [ - { - "inputs": [ - { - "internalType": "string", - "name": "_greeting", - "type": "string" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "greet", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "_greeting", - "type": "string" - } - ], - "name": "setGreeting", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ] -} \ No newline at end of file +{"bytecode":{"object":"608060405234801561001057600080fd5b506040516104913803806104918339818101604052602081101561003357600080fd5b810190808051604051939291908464010000000082111561005357600080fd5b90830190602082018581111561006857600080fd5b825164010000000081118282018810171561008257600080fd5b82525081516020918201929091019080838360005b838110156100af578181015183820152602001610097565b50505050905090810190601f1680156100dc5780820380516001836020036101000a031916815260200191505b50604052505081516100f6915060009060208401906100fd565b505061019e565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826101335760008555610179565b82601f1061014c57805160ff1916838001178555610179565b82800160010185558215610179579182015b8281111561017957825182559160200191906001019061015e565b50610185929150610189565b5090565b5b80821115610185576000815560010161018a565b6102e4806101ad6000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063a41368621461003b578063cfae3217146100e3575b600080fd5b6100e16004803603602081101561005157600080fd5b81019060208101813564010000000081111561006c57600080fd5b82018360208201111561007e57600080fd5b803590602001918460018302840111640100000000831117156100a057600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610160945050505050565b005b6100eb610177565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561012557818101518382015260200161010d565b50505050905090810190601f1680156101525780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b805161017390600090602084019061020d565b5050565b60008054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156102035780601f106101d857610100808354040283529160200191610203565b820191906000526020600020905b8154815290600101906020018083116101e657829003601f168201915b5050505050905090565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826102435760008555610289565b82601f1061025c57805160ff1916838001178555610289565b82800160010185558215610289579182015b8281111561028957825182559160200191906001019061026e565b50610295929150610299565b5090565b5b80821115610295576000815560010161029a56fea26469706673582212208b9161dfd195d53618942a72a3b481d61a7b142de919925a0b34f9c986e5707e64736f6c63430007060033"},"abi":[{"inputs":[{"internalType":"string","name":"_greeting","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"greet","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_greeting","type":"string"}],"name":"setGreeting","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/crates/anvil/test-data/multicall.json b/crates/anvil/test-data/multicall.json index e0be8fc5df4e..e7f7d9f1138f 100644 --- a/crates/anvil/test-data/multicall.json +++ b/crates/anvil/test-data/multicall.json @@ -1,144 +1 @@ -{ - "abi": [ - { - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "callData", - "type": "bytes" - } - ], - "internalType": "struct Multicall.Call[]", - "name": "calls", - "type": "tuple[]" - } - ], - "name": "aggregate", - "outputs": [ - { - "internalType": "uint256", - "name": "blockNumber", - "type": "uint256" - }, - { - "internalType": "bytes[]", - "name": "returnData", - "type": "bytes[]" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "blockNumber", - "type": "uint256" - } - ], - "name": "getBlockHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "blockHash", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getCurrentBlockCoinbase", - "outputs": [ - { - "internalType": "address", - "name": "coinbase", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getCurrentBlockDifficulty", - "outputs": [ - { - "internalType": "uint256", - "name": "difficulty", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getCurrentBlockGasLimit", - "outputs": [ - { - "internalType": "uint256", - "name": "gaslimit", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getCurrentBlockTimestamp", - "outputs": [ - { - "internalType": "uint256", - "name": "timestamp", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "addr", - "type": "address" - } - ], - "name": "getEthBalance", - "outputs": [ - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getLastBlockHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "blockHash", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "bin": "608060405234801561001057600080fd5b50610abb806100206000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c806372425d9d1161005b57806372425d9d1461012a57806386d516e814610148578063a8b0574e14610166578063ee82ac5e1461018457610088565b80630f28c97d1461008d578063252dba42146100ab57806327e86d6e146100dc5780634d2301cc146100fa575b600080fd5b6100956101b4565b6040516100a29190610381565b60405180910390f35b6100c560048036038101906100c091906106b0565b6101bc565b6040516100d3929190610843565b60405180910390f35b6100e461030f565b6040516100f1919061088c565b60405180910390f35b610114600480360381019061010f91906108a7565b610324565b6040516101219190610381565b60405180910390f35b610132610345565b60405161013f9190610381565b60405180910390f35b61015061034d565b60405161015d9190610381565b60405180910390f35b61016e610355565b60405161017b91906108e3565b60405180910390f35b61019e6004803603810190610199919061092a565b61035d565b6040516101ab919061088c565b60405180910390f35b600042905090565b60006060439150825167ffffffffffffffff8111156101de576101dd6103c6565b5b60405190808252806020026020018201604052801561021157816020015b60608152602001906001900390816101fc5790505b50905060005b83518110156103095760008085838151811061023657610235610957565b5b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1686848151811061026b5761026a610957565b5b60200260200101516020015160405161028491906109c2565b6000604051808303816000865af19150503d80600081146102c1576040519150601f19603f3d011682016040523d82523d6000602084013e6102c6565b606091505b5091509150816102d557600080fd5b808484815181106102e9576102e8610957565b5b60200260200101819052505050808061030190610a08565b915050610217565b50915091565b600060014361031e9190610a51565b40905090565b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b600044905090565b600045905090565b600041905090565b600081409050919050565b6000819050919050565b61037b81610368565b82525050565b60006020820190506103966000830184610372565b92915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6103fe826103b5565b810181811067ffffffffffffffff8211171561041d5761041c6103c6565b5b80604052505050565b600061043061039c565b905061043c82826103f5565b919050565b600067ffffffffffffffff82111561045c5761045b6103c6565b5b602082029050602081019050919050565b600080fd5b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006104a78261047c565b9050919050565b6104b78161049c565b81146104c257600080fd5b50565b6000813590506104d4816104ae565b92915050565b600080fd5b600067ffffffffffffffff8211156104fa576104f96103c6565b5b610503826103b5565b9050602081019050919050565b82818337600083830152505050565b600061053261052d846104df565b610426565b90508281526020810184848401111561054e5761054d6104da565b5b610559848285610510565b509392505050565b600082601f830112610576576105756103b0565b5b813561058684826020860161051f565b91505092915050565b6000604082840312156105a5576105a4610472565b5b6105af6040610426565b905060006105bf848285016104c5565b600083015250602082013567ffffffffffffffff8111156105e3576105e2610477565b5b6105ef84828501610561565b60208301525092915050565b600061060e61060984610441565b610426565b905080838252602082019050602084028301858111156106315761063061046d565b5b835b8181101561067857803567ffffffffffffffff811115610656576106556103b0565b5b808601610663898261058f565b85526020850194505050602081019050610633565b5050509392505050565b600082601f830112610697576106966103b0565b5b81356106a78482602086016105fb565b91505092915050565b6000602082840312156106c6576106c56103a6565b5b600082013567ffffffffffffffff8111156106e4576106e36103ab565b5b6106f084828501610682565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561075f578082015181840152602081019050610744565b8381111561076e576000848401525b50505050565b600061077f82610725565b6107898185610730565b9350610799818560208601610741565b6107a2816103b5565b840191505092915050565b60006107b98383610774565b905092915050565b6000602082019050919050565b60006107d9826106f9565b6107e38185610704565b9350836020820285016107f585610715565b8060005b85811015610831578484038952815161081285826107ad565b945061081d836107c1565b925060208a019950506001810190506107f9565b50829750879550505050505092915050565b60006040820190506108586000830185610372565b818103602083015261086a81846107ce565b90509392505050565b6000819050919050565b61088681610873565b82525050565b60006020820190506108a1600083018461087d565b92915050565b6000602082840312156108bd576108bc6103a6565b5b60006108cb848285016104c5565b91505092915050565b6108dd8161049c565b82525050565b60006020820190506108f860008301846108d4565b92915050565b61090781610368565b811461091257600080fd5b50565b600081359050610924816108fe565b92915050565b6000602082840312156109405761093f6103a6565b5b600061094e84828501610915565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081905092915050565b600061099c82610725565b6109a68185610986565b93506109b6818560208601610741565b80840191505092915050565b60006109ce8284610991565b915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610a1382610368565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415610a4657610a456109d9565b5b600182019050919050565b6000610a5c82610368565b9150610a6783610368565b925082821015610a7a57610a796109d9565b5b82820390509291505056fea2646970667358221220e5023d90063e0939116a41565414721ba1350cd3e98b12e7b65983a039644df964736f6c634300080a0033" -} \ No newline at end of file +{"abi":[{"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct Multicall.Call[]","name":"calls","type":"tuple[]"}],"name":"aggregate","outputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"bytes[]","name":"returnData","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getBlockHash","outputs":[{"internalType":"bytes32","name":"blockHash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentBlockCoinbase","outputs":[{"internalType":"address","name":"coinbase","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentBlockDifficulty","outputs":[{"internalType":"uint256","name":"difficulty","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentBlockGasLimit","outputs":[{"internalType":"uint256","name":"gaslimit","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentBlockTimestamp","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getEthBalance","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastBlockHash","outputs":[{"internalType":"bytes32","name":"blockHash","type":"bytes32"}],"stateMutability":"view","type":"function"}],"bin":"608060405234801561001057600080fd5b50610abb806100206000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c806372425d9d1161005b57806372425d9d1461012a57806386d516e814610148578063a8b0574e14610166578063ee82ac5e1461018457610088565b80630f28c97d1461008d578063252dba42146100ab57806327e86d6e146100dc5780634d2301cc146100fa575b600080fd5b6100956101b4565b6040516100a29190610381565b60405180910390f35b6100c560048036038101906100c091906106b0565b6101bc565b6040516100d3929190610843565b60405180910390f35b6100e461030f565b6040516100f1919061088c565b60405180910390f35b610114600480360381019061010f91906108a7565b610324565b6040516101219190610381565b60405180910390f35b610132610345565b60405161013f9190610381565b60405180910390f35b61015061034d565b60405161015d9190610381565b60405180910390f35b61016e610355565b60405161017b91906108e3565b60405180910390f35b61019e6004803603810190610199919061092a565b61035d565b6040516101ab919061088c565b60405180910390f35b600042905090565b60006060439150825167ffffffffffffffff8111156101de576101dd6103c6565b5b60405190808252806020026020018201604052801561021157816020015b60608152602001906001900390816101fc5790505b50905060005b83518110156103095760008085838151811061023657610235610957565b5b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1686848151811061026b5761026a610957565b5b60200260200101516020015160405161028491906109c2565b6000604051808303816000865af19150503d80600081146102c1576040519150601f19603f3d011682016040523d82523d6000602084013e6102c6565b606091505b5091509150816102d557600080fd5b808484815181106102e9576102e8610957565b5b60200260200101819052505050808061030190610a08565b915050610217565b50915091565b600060014361031e9190610a51565b40905090565b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b600044905090565b600045905090565b600041905090565b600081409050919050565b6000819050919050565b61037b81610368565b82525050565b60006020820190506103966000830184610372565b92915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6103fe826103b5565b810181811067ffffffffffffffff8211171561041d5761041c6103c6565b5b80604052505050565b600061043061039c565b905061043c82826103f5565b919050565b600067ffffffffffffffff82111561045c5761045b6103c6565b5b602082029050602081019050919050565b600080fd5b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006104a78261047c565b9050919050565b6104b78161049c565b81146104c257600080fd5b50565b6000813590506104d4816104ae565b92915050565b600080fd5b600067ffffffffffffffff8211156104fa576104f96103c6565b5b610503826103b5565b9050602081019050919050565b82818337600083830152505050565b600061053261052d846104df565b610426565b90508281526020810184848401111561054e5761054d6104da565b5b610559848285610510565b509392505050565b600082601f830112610576576105756103b0565b5b813561058684826020860161051f565b91505092915050565b6000604082840312156105a5576105a4610472565b5b6105af6040610426565b905060006105bf848285016104c5565b600083015250602082013567ffffffffffffffff8111156105e3576105e2610477565b5b6105ef84828501610561565b60208301525092915050565b600061060e61060984610441565b610426565b905080838252602082019050602084028301858111156106315761063061046d565b5b835b8181101561067857803567ffffffffffffffff811115610656576106556103b0565b5b808601610663898261058f565b85526020850194505050602081019050610633565b5050509392505050565b600082601f830112610697576106966103b0565b5b81356106a78482602086016105fb565b91505092915050565b6000602082840312156106c6576106c56103a6565b5b600082013567ffffffffffffffff8111156106e4576106e36103ab565b5b6106f084828501610682565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561075f578082015181840152602081019050610744565b8381111561076e576000848401525b50505050565b600061077f82610725565b6107898185610730565b9350610799818560208601610741565b6107a2816103b5565b840191505092915050565b60006107b98383610774565b905092915050565b6000602082019050919050565b60006107d9826106f9565b6107e38185610704565b9350836020820285016107f585610715565b8060005b85811015610831578484038952815161081285826107ad565b945061081d836107c1565b925060208a019950506001810190506107f9565b50829750879550505050505092915050565b60006040820190506108586000830185610372565b818103602083015261086a81846107ce565b90509392505050565b6000819050919050565b61088681610873565b82525050565b60006020820190506108a1600083018461087d565b92915050565b6000602082840312156108bd576108bc6103a6565b5b60006108cb848285016104c5565b91505092915050565b6108dd8161049c565b82525050565b60006020820190506108f860008301846108d4565b92915050565b61090781610368565b811461091257600080fd5b50565b600081359050610924816108fe565b92915050565b6000602082840312156109405761093f6103a6565b5b600061094e84828501610915565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081905092915050565b600061099c82610725565b6109a68185610986565b93506109b6818560208601610741565b80840191505092915050565b60006109ce8284610991565b915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610a1382610368565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415610a4657610a456109d9565b5b600182019050919050565b6000610a5c82610368565b9150610a6783610368565b925082821015610a7a57610a796109d9565b5b82820390509291505056fea2646970667358221220e5023d90063e0939116a41565414721ba1350cd3e98b12e7b65983a039644df964736f6c634300080a0033"} \ No newline at end of file diff --git a/crates/anvil/test-data/storage_sample.json b/crates/anvil/test-data/storage_sample.json index 7e2daf48f45b..5241cb08e8f7 100644 --- a/crates/anvil/test-data/storage_sample.json +++ b/crates/anvil/test-data/storage_sample.json @@ -1,33 +1 @@ -{ - "0x0000000000000000000000000000000000000000000000000000000000000022": "0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b", - "0x0000000000000000000000000000000000000000000000000000000000000023": "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", - "0x0000000000000000000000000000000000000000000000000000000000000024": "0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c", - "0x0000000000000000000000000000000000000000000000000000000000000025": "0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c", - "0x0000000000000000000000000000000000000000000000000000000000000026": "0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30", - "0x0000000000000000000000000000000000000000000000000000000000000027": "0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1", - "0x0000000000000000000000000000000000000000000000000000000000000028": "0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c", - "0x0000000000000000000000000000000000000000000000000000000000000029": "0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193", - "0x000000000000000000000000000000000000000000000000000000000000002a": "0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1", - "0x000000000000000000000000000000000000000000000000000000000000002b": "0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b", - "0x000000000000000000000000000000000000000000000000000000000000002c": "0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220", - "0x000000000000000000000000000000000000000000000000000000000000002d": "0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f", - "0x000000000000000000000000000000000000000000000000000000000000002e": "0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e", - "0x000000000000000000000000000000000000000000000000000000000000002f": "0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784", - "0x0000000000000000000000000000000000000000000000000000000000000030": "0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb", - "0x0000000000000000000000000000000000000000000000000000000000000031": "0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb", - "0x0000000000000000000000000000000000000000000000000000000000000032": "0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab", - "0x0000000000000000000000000000000000000000000000000000000000000033": "0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4", - "0x0000000000000000000000000000000000000000000000000000000000000034": "0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f", - "0x0000000000000000000000000000000000000000000000000000000000000035": "0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa", - "0x0000000000000000000000000000000000000000000000000000000000000036": "0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c", - "0x0000000000000000000000000000000000000000000000000000000000000037": "0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167", - "0x0000000000000000000000000000000000000000000000000000000000000038": "0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7", - "0x0000000000000000000000000000000000000000000000000000000000000039": "0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0", - "0x000000000000000000000000000000000000000000000000000000000000003a": "0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544", - "0x000000000000000000000000000000000000000000000000000000000000003b": "0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765", - "0x000000000000000000000000000000000000000000000000000000000000003c": "0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4", - "0x000000000000000000000000000000000000000000000000000000000000003d": "0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1", - "0x000000000000000000000000000000000000000000000000000000000000003e": "0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636", - "0x000000000000000000000000000000000000000000000000000000000000003f": "0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c", - "0x0000000000000000000000000000000000000000000000000000000000000040": "0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7" -} \ No newline at end of file +{"0x0000000000000000000000000000000000000000000000000000000000000022":"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b","0x0000000000000000000000000000000000000000000000000000000000000023":"0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71","0x0000000000000000000000000000000000000000000000000000000000000024":"0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c","0x0000000000000000000000000000000000000000000000000000000000000025":"0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c","0x0000000000000000000000000000000000000000000000000000000000000026":"0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30","0x0000000000000000000000000000000000000000000000000000000000000027":"0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1","0x0000000000000000000000000000000000000000000000000000000000000028":"0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c","0x0000000000000000000000000000000000000000000000000000000000000029":"0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193","0x000000000000000000000000000000000000000000000000000000000000002a":"0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1","0x000000000000000000000000000000000000000000000000000000000000002b":"0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b","0x000000000000000000000000000000000000000000000000000000000000002c":"0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220","0x000000000000000000000000000000000000000000000000000000000000002d":"0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f","0x000000000000000000000000000000000000000000000000000000000000002e":"0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e","0x000000000000000000000000000000000000000000000000000000000000002f":"0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784","0x0000000000000000000000000000000000000000000000000000000000000030":"0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb","0x0000000000000000000000000000000000000000000000000000000000000031":"0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb","0x0000000000000000000000000000000000000000000000000000000000000032":"0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab","0x0000000000000000000000000000000000000000000000000000000000000033":"0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4","0x0000000000000000000000000000000000000000000000000000000000000034":"0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f","0x0000000000000000000000000000000000000000000000000000000000000035":"0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa","0x0000000000000000000000000000000000000000000000000000000000000036":"0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c","0x0000000000000000000000000000000000000000000000000000000000000037":"0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167","0x0000000000000000000000000000000000000000000000000000000000000038":"0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7","0x0000000000000000000000000000000000000000000000000000000000000039":"0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0","0x000000000000000000000000000000000000000000000000000000000000003a":"0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544","0x000000000000000000000000000000000000000000000000000000000000003b":"0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765","0x000000000000000000000000000000000000000000000000000000000000003c":"0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4","0x000000000000000000000000000000000000000000000000000000000000003d":"0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1","0x000000000000000000000000000000000000000000000000000000000000003e":"0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636","0x000000000000000000000000000000000000000000000000000000000000003f":"0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c","0x0000000000000000000000000000000000000000000000000000000000000040":"0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7"} \ No newline at end of file diff --git a/crates/cast/tests/fixtures/ERC20Artifact.json b/crates/cast/tests/fixtures/ERC20Artifact.json index 4f4fd6e61fa3..508464c246ad 100644 --- a/crates/cast/tests/fixtures/ERC20Artifact.json +++ b/crates/cast/tests/fixtures/ERC20Artifact.json @@ -1,385 +1 @@ -{ - "abi": [ - { - "inputs": [ - { - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "internalType": "string", - "name": "symbol", - "type": "string" - }, - { - "internalType": "uint8", - "name": "decimals", - "type": "uint8" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "inputs": [], - "name": "DOMAIN_SEPARATOR", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "decimals", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "mint", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "nonces", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "v", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "r", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" - } - ], - "name": "permit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": { - "object": "0x60e06040523480156200001157600080fd5b5060405162000f7738038062000f7783398101604081905262000034916200029a565b82828282600090805190602001906200004f92919062000127565b5081516200006590600190602085019062000127565b5060ff81166080524660a0526200007b6200008b565b60c0525062000400945050505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000604051620000bf91906200035c565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b82805462000135906200031f565b90600052602060002090601f016020900481019282620001595760008555620001a4565b82601f106200017457805160ff1916838001178555620001a4565b82800160010185558215620001a4579182015b82811115620001a457825182559160200191906001019062000187565b50620001b2929150620001b6565b5090565b5b80821115620001b25760008155600101620001b7565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001f557600080fd5b81516001600160401b0380821115620002125762000212620001cd565b604051601f8301601f19908116603f011681019082821181831017156200023d576200023d620001cd565b816040528381526020925086838588010111156200025a57600080fd5b600091505b838210156200027e57858201830151818301840152908201906200025f565b83821115620002905760008385830101525b9695505050505050565b600080600060608486031215620002b057600080fd5b83516001600160401b0380821115620002c857600080fd5b620002d687838801620001e3565b94506020860151915080821115620002ed57600080fd5b50620002fc86828701620001e3565b925050604084015160ff811681146200031457600080fd5b809150509250925092565b600181811c908216806200033457607f821691505b602082108114156200035657634e487b7160e01b600052602260045260246000fd5b50919050565b600080835481600182811c9150808316806200037957607f831692505b60208084108214156200039a57634e487b7160e01b86526022600452602486fd5b818015620003b15760018114620003c357620003f2565b60ff19861689528489019650620003f2565b60008a81526020902060005b86811015620003ea5781548b820152908501908301620003cf565b505084890196505b509498975050505050505050565b60805160a05160c051610b476200043060003960006104530152600061041e015260006101440152610b476000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c806340c10f191161008c57806395d89b411161006657806395d89b41146101d5578063a9059cbb146101dd578063d505accf146101f0578063dd62ed3e1461020357600080fd5b806340c10f191461018057806370a08231146101955780637ecebe00146101b557600080fd5b806306fdde03146100d4578063095ea7b3146100f257806318160ddd1461011557806323b872dd1461012c578063313ce5671461013f5780633644e51514610178575b600080fd5b6100dc61022e565b6040516100e99190610856565b60405180910390f35b6101056101003660046108c7565b6102bc565b60405190151581526020016100e9565b61011e60025481565b6040519081526020016100e9565b61010561013a3660046108f1565b610328565b6101667f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016100e9565b61011e61041a565b61019361018e3660046108c7565b610475565b005b61011e6101a336600461092d565b60036020526000908152604090205481565b61011e6101c336600461092d565b60056020526000908152604090205481565b6100dc610483565b6101056101eb3660046108c7565b610490565b6101936101fe36600461094f565b610508565b61011e6102113660046109c2565b600460209081526000928352604080842090915290825290205481565b6000805461023b906109f5565b80601f0160208091040260200160405190810160405280929190818152602001828054610267906109f5565b80156102b45780601f10610289576101008083540402835291602001916102b4565b820191906000526020600020905b81548152906001019060200180831161029757829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906103179086815260200190565b60405180910390a350600192915050565b6001600160a01b038316600090815260046020908152604080832033845290915281205460001981146103845761035f8382610a46565b6001600160a01b03861660009081526004602090815260408083203384529091529020555b6001600160a01b038516600090815260036020526040812080548592906103ac908490610a46565b90915550506001600160a01b03808516600081815260036020526040908190208054870190555190918716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906104079087815260200190565b60405180910390a3506001949350505050565b60007f000000000000000000000000000000000000000000000000000000000000000046146104505761044b610751565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b61047f82826107eb565b5050565b6001805461023b906109f5565b336000908152600360205260408120805483919083906104b1908490610a46565b90915550506001600160a01b038316600081815260036020526040908190208054850190555133907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906103179086815260200190565b4284101561055d5760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f4558504952454400000000000000000060448201526064015b60405180910390fd5b6000600161056961041a565b6001600160a01b038a811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015610675573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906106ab5750876001600160a01b0316816001600160a01b0316145b6106e85760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606401610554565b6001600160a01b0390811660009081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60006040516107839190610a5d565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b80600260008282546107fd9190610af9565b90915550506001600160a01b0382166000818152600360209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b600060208083528351808285015260005b8181101561088357858101830151858201604001528201610867565b81811115610895576000604083870101525b50601f01601f1916929092016040019392505050565b80356001600160a01b03811681146108c257600080fd5b919050565b600080604083850312156108da57600080fd5b6108e3836108ab565b946020939093013593505050565b60008060006060848603121561090657600080fd5b61090f846108ab565b925061091d602085016108ab565b9150604084013590509250925092565b60006020828403121561093f57600080fd5b610948826108ab565b9392505050565b600080600080600080600060e0888a03121561096a57600080fd5b610973886108ab565b9650610981602089016108ab565b95506040880135945060608801359350608088013560ff811681146109a557600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156109d557600080fd5b6109de836108ab565b91506109ec602084016108ab565b90509250929050565b600181811c90821680610a0957607f821691505b60208210811415610a2a57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b600082821015610a5857610a58610a30565b500390565b600080835481600182811c915080831680610a7957607f831692505b6020808410821415610a9957634e487b7160e01b86526022600452602486fd5b818015610aad5760018114610abe57610aeb565b60ff19861689528489019650610aeb565b60008a81526020902060005b86811015610ae35781548b820152908501908301610aca565b505084890196505b509498975050505050505050565b60008219821115610b0c57610b0c610a30565b50019056fea26469706673582212209ca55739676d094f8ef4b3b5cfcc08f600b805843c4c3027beb2b4159a02f63664736f6c634300080a0033", - "sourceMap": "113:230:22:-:0;;;148:102;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;224:4;230:6;238:8;2098:5:10;2091:4;:12;;;;;;;;;;;;:::i;:::-;-1:-1:-1;2113:16:10;;;;:6;;:16;;;;;:::i;:::-;-1:-1:-1;2139:20:10;;;;;2189:13;2170:32;;2239:24;:22;:24::i;:::-;2212:51;;-1:-1:-1;113:230:22;;-1:-1:-1;;;;;113:230:22;5507:446:10;5572:7;5669:95;5802:4;5786:22;;;;;;:::i;:::-;;;;;;;;;;5637:295;;;3635:25:23;;;;3676:18;;3669:34;;;;5830:14:10;3719:18:23;;;3712:34;5866:13:10;3762:18:23;;;3755:34;5909:4:10;3805:19:23;;;3798:61;3607:19;;5637:295:10;;;;;;;;;;;;5610:336;;;;;;5591:355;;5507:446;:::o;113:230:22:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;113:230:22;;;-1:-1:-1;113:230:22;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:127:23;75:10;70:3;66:20;63:1;56:31;106:4;103:1;96:15;130:4;127:1;120:15;146:885;200:5;253:3;246:4;238:6;234:17;230:27;220:55;;271:1;268;261:12;220:55;294:13;;-1:-1:-1;;;;;356:10:23;;;353:36;;;369:18;;:::i;:::-;444:2;438:9;412:2;498:13;;-1:-1:-1;;494:22:23;;;518:2;490:31;486:40;474:53;;;542:18;;;562:22;;;539:46;536:72;;;588:18;;:::i;:::-;628:10;624:2;617:22;663:2;655:6;648:18;685:4;675:14;;730:3;725:2;720;712:6;708:15;704:24;701:33;698:53;;;747:1;744;737:12;698:53;769:1;760:10;;779:133;793:2;790:1;787:9;779:133;;;881:14;;;877:23;;871:30;850:14;;;846:23;;839:63;804:10;;;;779:133;;;930:2;927:1;924:9;921:80;;;989:1;984:2;979;971:6;967:15;963:24;956:35;921:80;1019:6;146:885;-1:-1:-1;;;;;;146:885:23:o;1036:712::-;1142:6;1150;1158;1211:2;1199:9;1190:7;1186:23;1182:32;1179:52;;;1227:1;1224;1217:12;1179:52;1254:16;;-1:-1:-1;;;;;1319:14:23;;;1316:34;;;1346:1;1343;1336:12;1316:34;1369:61;1422:7;1413:6;1402:9;1398:22;1369:61;:::i;:::-;1359:71;;1476:2;1465:9;1461:18;1455:25;1439:41;;1505:2;1495:8;1492:16;1489:36;;;1521:1;1518;1511:12;1489:36;;1544:63;1599:7;1588:8;1577:9;1573:24;1544:63;:::i;:::-;1534:73;;;1650:2;1639:9;1635:18;1629:25;1694:4;1687:5;1683:16;1676:5;1673:27;1663:55;;1714:1;1711;1704:12;1663:55;1737:5;1727:15;;;1036:712;;;;;:::o;1753:380::-;1832:1;1828:12;;;;1875;;;1896:61;;1950:4;1942:6;1938:17;1928:27;;1896:61;2003:2;1995:6;1992:14;1972:18;1969:38;1966:161;;;2049:10;2044:3;2040:20;2037:1;2030:31;2084:4;2081:1;2074:15;2112:4;2109:1;2102:15;1966:161;;1753:380;;;:::o;2267:1104::-;2397:3;2426:1;2459:6;2453:13;2489:3;2511:1;2539:9;2535:2;2531:18;2521:28;;2599:2;2588:9;2584:18;2621;2611:61;;2665:4;2657:6;2653:17;2643:27;;2611:61;2691:2;2739;2731:6;2728:14;2708:18;2705:38;2702:165;;;-1:-1:-1;;;2766:33:23;;2822:4;2819:1;2812:15;2852:4;2773:3;2840:17;2702:165;2883:18;2910:104;;;;3028:1;3023:323;;;;2876:470;;2910:104;-1:-1:-1;;2943:24:23;;2931:37;;2988:16;;;;-1:-1:-1;2910:104:23;;3023:323;2214:1;2207:14;;;2251:4;2238:18;;3121:1;3135:165;3149:6;3146:1;3143:13;3135:165;;;3227:14;;3214:11;;;3207:35;3270:16;;;;3164:10;;3135:165;;;3139:3;;3329:6;3324:3;3320:16;3313:23;;2876:470;-1:-1:-1;3362:3:23;;2267:1104;-1:-1:-1;;;;;;;;2267:1104:23:o;3376:489::-;113:230:22;;;;;;;;;;;;;;;;;;;;;;;;", - "linkReferences": {} - }, - "deployedBytecode": { - "object": "0x608060405234801561001057600080fd5b50600436106100cf5760003560e01c806340c10f191161008c57806395d89b411161006657806395d89b41146101d5578063a9059cbb146101dd578063d505accf146101f0578063dd62ed3e1461020357600080fd5b806340c10f191461018057806370a08231146101955780637ecebe00146101b557600080fd5b806306fdde03146100d4578063095ea7b3146100f257806318160ddd1461011557806323b872dd1461012c578063313ce5671461013f5780633644e51514610178575b600080fd5b6100dc61022e565b6040516100e99190610856565b60405180910390f35b6101056101003660046108c7565b6102bc565b60405190151581526020016100e9565b61011e60025481565b6040519081526020016100e9565b61010561013a3660046108f1565b610328565b6101667f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016100e9565b61011e61041a565b61019361018e3660046108c7565b610475565b005b61011e6101a336600461092d565b60036020526000908152604090205481565b61011e6101c336600461092d565b60056020526000908152604090205481565b6100dc610483565b6101056101eb3660046108c7565b610490565b6101936101fe36600461094f565b610508565b61011e6102113660046109c2565b600460209081526000928352604080842090915290825290205481565b6000805461023b906109f5565b80601f0160208091040260200160405190810160405280929190818152602001828054610267906109f5565b80156102b45780601f10610289576101008083540402835291602001916102b4565b820191906000526020600020905b81548152906001019060200180831161029757829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906103179086815260200190565b60405180910390a350600192915050565b6001600160a01b038316600090815260046020908152604080832033845290915281205460001981146103845761035f8382610a46565b6001600160a01b03861660009081526004602090815260408083203384529091529020555b6001600160a01b038516600090815260036020526040812080548592906103ac908490610a46565b90915550506001600160a01b03808516600081815260036020526040908190208054870190555190918716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906104079087815260200190565b60405180910390a3506001949350505050565b60007f000000000000000000000000000000000000000000000000000000000000000046146104505761044b610751565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b61047f82826107eb565b5050565b6001805461023b906109f5565b336000908152600360205260408120805483919083906104b1908490610a46565b90915550506001600160a01b038316600081815260036020526040908190208054850190555133907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906103179086815260200190565b4284101561055d5760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f4558504952454400000000000000000060448201526064015b60405180910390fd5b6000600161056961041a565b6001600160a01b038a811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015610675573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906106ab5750876001600160a01b0316816001600160a01b0316145b6106e85760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606401610554565b6001600160a01b0390811660009081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60006040516107839190610a5d565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b80600260008282546107fd9190610af9565b90915550506001600160a01b0382166000818152600360209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b600060208083528351808285015260005b8181101561088357858101830151858201604001528201610867565b81811115610895576000604083870101525b50601f01601f1916929092016040019392505050565b80356001600160a01b03811681146108c257600080fd5b919050565b600080604083850312156108da57600080fd5b6108e3836108ab565b946020939093013593505050565b60008060006060848603121561090657600080fd5b61090f846108ab565b925061091d602085016108ab565b9150604084013590509250925092565b60006020828403121561093f57600080fd5b610948826108ab565b9392505050565b600080600080600080600060e0888a03121561096a57600080fd5b610973886108ab565b9650610981602089016108ab565b95506040880135945060608801359350608088013560ff811681146109a557600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156109d557600080fd5b6109de836108ab565b91506109ec602084016108ab565b90509250929050565b600181811c90821680610a0957607f821691505b60208210811415610a2a57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b600082821015610a5857610a58610a30565b500390565b600080835481600182811c915080831680610a7957607f831692505b6020808410821415610a9957634e487b7160e01b86526022600452602486fd5b818015610aad5760018114610abe57610aeb565b60ff19861689528489019650610aeb565b60008a81526020902060005b86811015610ae35781548b820152908501908301610aca565b505084890196505b509498975050505050505050565b60008219821115610b0c57610b0c610a30565b50019056fea26469706673582212209ca55739676d094f8ef4b3b5cfcc08f600b805843c4c3027beb2b4159a02f63664736f6c634300080a0033", - "sourceMap": "113:230:22:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1028:18:10;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2458:211;;;;;;:::i;:::-;;:::i;:::-;;;1218:14:23;;1211:22;1193:41;;1181:2;1166:18;2458:211:10;1053:187:23;1301:26:10;;;;;;;;;1391:25:23;;;1379:2;1364:18;1301:26:10;1245:177:23;3054:592:10;;;;;;:::i;:::-;;:::i;1080:31::-;;;;;;;;1932:4:23;1920:17;;;1902:36;;1890:2;1875:18;1080:31:10;1760:184:23;5324:177:10;;;:::i;256:85:22:-;;;;;;:::i;:::-;;:::i;:::-;;1334:44:10;;;;;;:::i;:::-;;;;;;;;;;;;;;1748:41;;;;;;:::i;:::-;;;;;;;;;;;;;;1053:20;;;:::i;2675:373::-;;;;;;:::i;:::-;;:::i;3835:1483::-;;;;;;:::i;:::-;;:::i;1385:64::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;1028:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;2458:211::-;2558:10;2532:4;2548:21;;;:9;:21;;;;;;;;-1:-1:-1;;;;;2548:30:10;;;;;;;;;;:39;;;2603:37;2532:4;;2548:30;;2603:37;;;;2581:6;1391:25:23;;1379:2;1364:18;;1245:177;2603:37:10;;;;;;;;-1:-1:-1;2658:4:10;2458:211;;;;:::o;3054:592::-;-1:-1:-1;;;;;3206:15:10;;3172:4;3206:15;;;:9;:15;;;;;;;;3222:10;3206:27;;;;;;;;-1:-1:-1;;3284:28:10;;3280:80;;3344:16;3354:6;3344:7;:16;:::i;:::-;-1:-1:-1;;;;;3314:15:10;;;;;;:9;:15;;;;;;;;3330:10;3314:27;;;;;;;:46;3280:80;-1:-1:-1;;;;;3371:15:10;;;;;;:9;:15;;;;;:25;;3390:6;;3371:15;:25;;3390:6;;3371:25;:::i;:::-;;;;-1:-1:-1;;;;;;;3542:13:10;;;;;;;:9;:13;;;;;;;:23;;;;;;3591:26;3542:13;;3591:26;;;;;;;3559:6;1391:25:23;;1379:2;1364:18;;1245:177;3591:26:10;;;;;;;;-1:-1:-1;3635:4:10;;3054:592;-1:-1:-1;;;;3054:592:10:o;5324:177::-;5381:7;5424:16;5407:13;:33;:87;;5470:24;:22;:24::i;:::-;5400:94;;5324:177;:::o;5407:87::-;-1:-1:-1;5443:24:10;;5324:177::o;256:85:22:-;317:17;323:2;327:6;317:5;:17::i;:::-;256:85;;:::o;1053:20:10:-;;;;;;;:::i;2675:373::-;2771:10;2745:4;2761:21;;;:9;:21;;;;;:31;;2786:6;;2761:21;2745:4;;2761:31;;2786:6;;2761:31;:::i;:::-;;;;-1:-1:-1;;;;;;;2938:13:10;;;;;;:9;:13;;;;;;;:23;;;;;;2987:32;2996:10;;2987:32;;;;2955:6;1391:25:23;;1379:2;1364:18;;1245:177;3835:1483:10;4054:15;4042:8;:27;;4034:63;;;;-1:-1:-1;;;4034:63:10;;4134:2:23;4034:63:10;;;4116:21:23;4173:2;4153:18;;;4146:30;4212:25;4192:18;;;4185:53;4255:18;;4034:63:10;;;;;;;;;4262:24;4289:805;4425:18;:16;:18::i;:::-;-1:-1:-1;;;;;4870:13:10;;;;;;;:6;:13;;;;;;;;;:15;;;;;;;;4508:449;;4552:165;4508:449;;;4571:25:23;4650:18;;;4643:43;;;;4722:15;;;4702:18;;;4695:43;4754:18;;;4747:34;;;4797:19;;;4790:35;;;;4841:19;;;;4834:35;;;4508:449:10;;;;;;;;;;4543:19:23;;;4508:449:10;;;4469:514;;;;;;;;-1:-1:-1;;;4347:658:10;;;5138:27:23;5181:11;;;5174:27;;;;5217:12;;;5210:28;;;;5254:12;;4347:658:10;;;-1:-1:-1;;4347:658:10;;;;;;;;;4316:707;;4347:658;4316:707;;;;4289:805;;;;;;;;;5504:25:23;5577:4;5565:17;;5545:18;;;5538:45;5599:18;;;5592:34;;;5642:18;;;5635:34;;;5476:19;;4289:805:10;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4289:805:10;;-1:-1:-1;;4289:805:10;;;-1:-1:-1;;;;;;;5117:30:10;;;;;;:59;;;5171:5;-1:-1:-1;;;;;5151:25:10;:16;-1:-1:-1;;;;;5151:25:10;;5117:59;5109:86;;;;-1:-1:-1;;;5109:86:10;;5882:2:23;5109:86:10;;;5864:21:23;5921:2;5901:18;;;5894:30;-1:-1:-1;;;5940:18:23;;;5933:44;5994:18;;5109:86:10;5680:338:23;5109:86:10;-1:-1:-1;;;;;5210:27:10;;;;;;;:9;:27;;;;;;;;:36;;;;;;;;;;;;;:44;;;5280:31;1391:25:23;;;5210:36:10;;5280:31;;;;;1364:18:23;5280:31:10;;;;;;;3835:1483;;;;;;;:::o;5507:446::-;5572:7;5669:95;5802:4;5786:22;;;;;;:::i;:::-;;;;;;;;;;5637:295;;;7520:25:23;;;;7561:18;;7554:34;;;;5830:14:10;7604:18:23;;;7597:34;5866:13:10;7647:18:23;;;7640:34;5909:4:10;7690:19:23;;;7683:61;7492:19;;5637:295:10;;;;;;;;;;;;5610:336;;;;;;5591:355;;5507:446;:::o;6147:325::-;6232:6;6217:11;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;6384:13:10;;;;;;:9;:13;;;;;;;;:23;;;;;;6433:32;1391:25:23;;;6433:32:10;;1364:18:23;6433:32:10;;;;;;;6147:325;;:::o;14:597:23:-;126:4;155:2;184;173:9;166:21;216:6;210:13;259:6;254:2;243:9;239:18;232:34;284:1;294:140;308:6;305:1;302:13;294:140;;;403:14;;;399:23;;393:30;369:17;;;388:2;365:26;358:66;323:10;;294:140;;;452:6;449:1;446:13;443:91;;;522:1;517:2;508:6;497:9;493:22;489:31;482:42;443:91;-1:-1:-1;595:2:23;574:15;-1:-1:-1;;570:29:23;555:45;;;;602:2;551:54;;14:597;-1:-1:-1;;;14:597:23:o;616:173::-;684:20;;-1:-1:-1;;;;;733:31:23;;723:42;;713:70;;779:1;776;769:12;713:70;616:173;;;:::o;794:254::-;862:6;870;923:2;911:9;902:7;898:23;894:32;891:52;;;939:1;936;929:12;891:52;962:29;981:9;962:29;:::i;:::-;952:39;1038:2;1023:18;;;;1010:32;;-1:-1:-1;;;794:254:23:o;1427:328::-;1504:6;1512;1520;1573:2;1561:9;1552:7;1548:23;1544:32;1541:52;;;1589:1;1586;1579:12;1541:52;1612:29;1631:9;1612:29;:::i;:::-;1602:39;;1660:38;1694:2;1683:9;1679:18;1660:38;:::i;:::-;1650:48;;1745:2;1734:9;1730:18;1717:32;1707:42;;1427:328;;;;;:::o;2131:186::-;2190:6;2243:2;2231:9;2222:7;2218:23;2214:32;2211:52;;;2259:1;2256;2249:12;2211:52;2282:29;2301:9;2282:29;:::i;:::-;2272:39;2131:186;-1:-1:-1;;;2131:186:23:o;2322:693::-;2433:6;2441;2449;2457;2465;2473;2481;2534:3;2522:9;2513:7;2509:23;2505:33;2502:53;;;2551:1;2548;2541:12;2502:53;2574:29;2593:9;2574:29;:::i;:::-;2564:39;;2622:38;2656:2;2645:9;2641:18;2622:38;:::i;:::-;2612:48;;2707:2;2696:9;2692:18;2679:32;2669:42;;2758:2;2747:9;2743:18;2730:32;2720:42;;2812:3;2801:9;2797:19;2784:33;2857:4;2850:5;2846:16;2839:5;2836:27;2826:55;;2877:1;2874;2867:12;2826:55;2322:693;;;;-1:-1:-1;2322:693:23;;;;2900:5;2952:3;2937:19;;2924:33;;-1:-1:-1;3004:3:23;2989:19;;;2976:33;;2322:693;-1:-1:-1;;2322:693:23:o;3020:260::-;3088:6;3096;3149:2;3137:9;3128:7;3124:23;3120:32;3117:52;;;3165:1;3162;3155:12;3117:52;3188:29;3207:9;3188:29;:::i;:::-;3178:39;;3236:38;3270:2;3259:9;3255:18;3236:38;:::i;:::-;3226:48;;3020:260;;;;;:::o;3285:380::-;3364:1;3360:12;;;;3407;;;3428:61;;3482:4;3474:6;3470:17;3460:27;;3428:61;3535:2;3527:6;3524:14;3504:18;3501:38;3498:161;;;3581:10;3576:3;3572:20;3569:1;3562:31;3616:4;3613:1;3606:15;3644:4;3641:1;3634:15;3498:161;;3285:380;;;:::o;3670:127::-;3731:10;3726:3;3722:20;3719:1;3712:31;3762:4;3759:1;3752:15;3786:4;3783:1;3776:15;3802:125;3842:4;3870:1;3867;3864:8;3861:34;;;3875:18;;:::i;:::-;-1:-1:-1;3912:9:23;;3802:125::o;6152:1104::-;6282:3;6311:1;6344:6;6338:13;6374:3;6396:1;6424:9;6420:2;6416:18;6406:28;;6484:2;6473:9;6469:18;6506;6496:61;;6550:4;6542:6;6538:17;6528:27;;6496:61;6576:2;6624;6616:6;6613:14;6593:18;6590:38;6587:165;;;-1:-1:-1;;;6651:33:23;;6707:4;6704:1;6697:15;6737:4;6658:3;6725:17;6587:165;6768:18;6795:104;;;;6913:1;6908:323;;;;6761:470;;6795:104;-1:-1:-1;;6828:24:23;;6816:37;;6873:16;;;;-1:-1:-1;6795:104:23;;6908:323;6099:1;6092:14;;;6136:4;6123:18;;7006:1;7020:165;7034:6;7031:1;7028:13;7020:165;;;7112:14;;7099:11;;;7092:35;7155:16;;;;7049:10;;7020:165;;;7024:3;;7214:6;7209:3;7205:16;7198:23;;6761:470;-1:-1:-1;7247:3:23;;6152:1104;-1:-1:-1;;;;;;;;6152:1104:23:o;7755:128::-;7795:3;7826:1;7822:6;7819:1;7816:13;7813:39;;;7832:18;;:::i;:::-;-1:-1:-1;7868:9:23;;7755:128::o", - "linkReferences": {}, - "immutableReferences": { - "3499": [ - { - "start": 324, - "length": 32 - } - ], - "3513": [ - { - "start": 1054, - "length": 32 - } - ], - "3515": [ - { - "start": 1107, - "length": 32 - } - ] - } - }, - "methodIdentifiers": { - "DOMAIN_SEPARATOR()": "3644e515", - "allowance(address,address)": "dd62ed3e", - "approve(address,uint256)": "095ea7b3", - "balanceOf(address)": "70a08231", - "decimals()": "313ce567", - "mint(address,uint256)": "40c10f19", - "name()": "06fdde03", - "nonces(address)": "7ecebe00", - "permit(address,address,uint256,uint256,uint8,bytes32,bytes32)": "d505accf", - "symbol()": "95d89b41", - "totalSupply()": "18160ddd", - "transfer(address,uint256)": "a9059cbb", - "transferFrom(address,address,uint256)": "23b872dd" - } -} +{"abi":[{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint8","name":"decimals","type":"uint8"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}],"bytecode":{"object":"0x60e06040523480156200001157600080fd5b5060405162000f7738038062000f7783398101604081905262000034916200029a565b82828282600090805190602001906200004f92919062000127565b5081516200006590600190602085019062000127565b5060ff81166080524660a0526200007b6200008b565b60c0525062000400945050505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000604051620000bf91906200035c565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b82805462000135906200031f565b90600052602060002090601f016020900481019282620001595760008555620001a4565b82601f106200017457805160ff1916838001178555620001a4565b82800160010185558215620001a4579182015b82811115620001a457825182559160200191906001019062000187565b50620001b2929150620001b6565b5090565b5b80821115620001b25760008155600101620001b7565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001f557600080fd5b81516001600160401b0380821115620002125762000212620001cd565b604051601f8301601f19908116603f011681019082821181831017156200023d576200023d620001cd565b816040528381526020925086838588010111156200025a57600080fd5b600091505b838210156200027e57858201830151818301840152908201906200025f565b83821115620002905760008385830101525b9695505050505050565b600080600060608486031215620002b057600080fd5b83516001600160401b0380821115620002c857600080fd5b620002d687838801620001e3565b94506020860151915080821115620002ed57600080fd5b50620002fc86828701620001e3565b925050604084015160ff811681146200031457600080fd5b809150509250925092565b600181811c908216806200033457607f821691505b602082108114156200035657634e487b7160e01b600052602260045260246000fd5b50919050565b600080835481600182811c9150808316806200037957607f831692505b60208084108214156200039a57634e487b7160e01b86526022600452602486fd5b818015620003b15760018114620003c357620003f2565b60ff19861689528489019650620003f2565b60008a81526020902060005b86811015620003ea5781548b820152908501908301620003cf565b505084890196505b509498975050505050505050565b60805160a05160c051610b476200043060003960006104530152600061041e015260006101440152610b476000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c806340c10f191161008c57806395d89b411161006657806395d89b41146101d5578063a9059cbb146101dd578063d505accf146101f0578063dd62ed3e1461020357600080fd5b806340c10f191461018057806370a08231146101955780637ecebe00146101b557600080fd5b806306fdde03146100d4578063095ea7b3146100f257806318160ddd1461011557806323b872dd1461012c578063313ce5671461013f5780633644e51514610178575b600080fd5b6100dc61022e565b6040516100e99190610856565b60405180910390f35b6101056101003660046108c7565b6102bc565b60405190151581526020016100e9565b61011e60025481565b6040519081526020016100e9565b61010561013a3660046108f1565b610328565b6101667f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016100e9565b61011e61041a565b61019361018e3660046108c7565b610475565b005b61011e6101a336600461092d565b60036020526000908152604090205481565b61011e6101c336600461092d565b60056020526000908152604090205481565b6100dc610483565b6101056101eb3660046108c7565b610490565b6101936101fe36600461094f565b610508565b61011e6102113660046109c2565b600460209081526000928352604080842090915290825290205481565b6000805461023b906109f5565b80601f0160208091040260200160405190810160405280929190818152602001828054610267906109f5565b80156102b45780601f10610289576101008083540402835291602001916102b4565b820191906000526020600020905b81548152906001019060200180831161029757829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906103179086815260200190565b60405180910390a350600192915050565b6001600160a01b038316600090815260046020908152604080832033845290915281205460001981146103845761035f8382610a46565b6001600160a01b03861660009081526004602090815260408083203384529091529020555b6001600160a01b038516600090815260036020526040812080548592906103ac908490610a46565b90915550506001600160a01b03808516600081815260036020526040908190208054870190555190918716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906104079087815260200190565b60405180910390a3506001949350505050565b60007f000000000000000000000000000000000000000000000000000000000000000046146104505761044b610751565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b61047f82826107eb565b5050565b6001805461023b906109f5565b336000908152600360205260408120805483919083906104b1908490610a46565b90915550506001600160a01b038316600081815260036020526040908190208054850190555133907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906103179086815260200190565b4284101561055d5760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f4558504952454400000000000000000060448201526064015b60405180910390fd5b6000600161056961041a565b6001600160a01b038a811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015610675573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906106ab5750876001600160a01b0316816001600160a01b0316145b6106e85760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606401610554565b6001600160a01b0390811660009081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60006040516107839190610a5d565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b80600260008282546107fd9190610af9565b90915550506001600160a01b0382166000818152600360209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b600060208083528351808285015260005b8181101561088357858101830151858201604001528201610867565b81811115610895576000604083870101525b50601f01601f1916929092016040019392505050565b80356001600160a01b03811681146108c257600080fd5b919050565b600080604083850312156108da57600080fd5b6108e3836108ab565b946020939093013593505050565b60008060006060848603121561090657600080fd5b61090f846108ab565b925061091d602085016108ab565b9150604084013590509250925092565b60006020828403121561093f57600080fd5b610948826108ab565b9392505050565b600080600080600080600060e0888a03121561096a57600080fd5b610973886108ab565b9650610981602089016108ab565b95506040880135945060608801359350608088013560ff811681146109a557600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156109d557600080fd5b6109de836108ab565b91506109ec602084016108ab565b90509250929050565b600181811c90821680610a0957607f821691505b60208210811415610a2a57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b600082821015610a5857610a58610a30565b500390565b600080835481600182811c915080831680610a7957607f831692505b6020808410821415610a9957634e487b7160e01b86526022600452602486fd5b818015610aad5760018114610abe57610aeb565b60ff19861689528489019650610aeb565b60008a81526020902060005b86811015610ae35781548b820152908501908301610aca565b505084890196505b509498975050505050505050565b60008219821115610b0c57610b0c610a30565b50019056fea26469706673582212209ca55739676d094f8ef4b3b5cfcc08f600b805843c4c3027beb2b4159a02f63664736f6c634300080a0033","sourceMap":"113:230:22:-:0;;;148:102;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;224:4;230:6;238:8;2098:5:10;2091:4;:12;;;;;;;;;;;;:::i;:::-;-1:-1:-1;2113:16:10;;;;:6;;:16;;;;;:::i;:::-;-1:-1:-1;2139:20:10;;;;;2189:13;2170:32;;2239:24;:22;:24::i;:::-;2212:51;;-1:-1:-1;113:230:22;;-1:-1:-1;;;;;113:230:22;5507:446:10;5572:7;5669:95;5802:4;5786:22;;;;;;:::i;:::-;;;;;;;;;;5637:295;;;3635:25:23;;;;3676:18;;3669:34;;;;5830:14:10;3719:18:23;;;3712:34;5866:13:10;3762:18:23;;;3755:34;5909:4:10;3805:19:23;;;3798:61;3607:19;;5637:295:10;;;;;;;;;;;;5610:336;;;;;;5591:355;;5507:446;:::o;113:230:22:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;113:230:22;;;-1:-1:-1;113:230:22;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:127:23;75:10;70:3;66:20;63:1;56:31;106:4;103:1;96:15;130:4;127:1;120:15;146:885;200:5;253:3;246:4;238:6;234:17;230:27;220:55;;271:1;268;261:12;220:55;294:13;;-1:-1:-1;;;;;356:10:23;;;353:36;;;369:18;;:::i;:::-;444:2;438:9;412:2;498:13;;-1:-1:-1;;494:22:23;;;518:2;490:31;486:40;474:53;;;542:18;;;562:22;;;539:46;536:72;;;588:18;;:::i;:::-;628:10;624:2;617:22;663:2;655:6;648:18;685:4;675:14;;730:3;725:2;720;712:6;708:15;704:24;701:33;698:53;;;747:1;744;737:12;698:53;769:1;760:10;;779:133;793:2;790:1;787:9;779:133;;;881:14;;;877:23;;871:30;850:14;;;846:23;;839:63;804:10;;;;779:133;;;930:2;927:1;924:9;921:80;;;989:1;984:2;979;971:6;967:15;963:24;956:35;921:80;1019:6;146:885;-1:-1:-1;;;;;;146:885:23:o;1036:712::-;1142:6;1150;1158;1211:2;1199:9;1190:7;1186:23;1182:32;1179:52;;;1227:1;1224;1217:12;1179:52;1254:16;;-1:-1:-1;;;;;1319:14:23;;;1316:34;;;1346:1;1343;1336:12;1316:34;1369:61;1422:7;1413:6;1402:9;1398:22;1369:61;:::i;:::-;1359:71;;1476:2;1465:9;1461:18;1455:25;1439:41;;1505:2;1495:8;1492:16;1489:36;;;1521:1;1518;1511:12;1489:36;;1544:63;1599:7;1588:8;1577:9;1573:24;1544:63;:::i;:::-;1534:73;;;1650:2;1639:9;1635:18;1629:25;1694:4;1687:5;1683:16;1676:5;1673:27;1663:55;;1714:1;1711;1704:12;1663:55;1737:5;1727:15;;;1036:712;;;;;:::o;1753:380::-;1832:1;1828:12;;;;1875;;;1896:61;;1950:4;1942:6;1938:17;1928:27;;1896:61;2003:2;1995:6;1992:14;1972:18;1969:38;1966:161;;;2049:10;2044:3;2040:20;2037:1;2030:31;2084:4;2081:1;2074:15;2112:4;2109:1;2102:15;1966:161;;1753:380;;;:::o;2267:1104::-;2397:3;2426:1;2459:6;2453:13;2489:3;2511:1;2539:9;2535:2;2531:18;2521:28;;2599:2;2588:9;2584:18;2621;2611:61;;2665:4;2657:6;2653:17;2643:27;;2611:61;2691:2;2739;2731:6;2728:14;2708:18;2705:38;2702:165;;;-1:-1:-1;;;2766:33:23;;2822:4;2819:1;2812:15;2852:4;2773:3;2840:17;2702:165;2883:18;2910:104;;;;3028:1;3023:323;;;;2876:470;;2910:104;-1:-1:-1;;2943:24:23;;2931:37;;2988:16;;;;-1:-1:-1;2910:104:23;;3023:323;2214:1;2207:14;;;2251:4;2238:18;;3121:1;3135:165;3149:6;3146:1;3143:13;3135:165;;;3227:14;;3214:11;;;3207:35;3270:16;;;;3164:10;;3135:165;;;3139:3;;3329:6;3324:3;3320:16;3313:23;;2876:470;-1:-1:-1;3362:3:23;;2267:1104;-1:-1:-1;;;;;;;;2267:1104:23:o;3376:489::-;113:230:22;;;;;;;;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x608060405234801561001057600080fd5b50600436106100cf5760003560e01c806340c10f191161008c57806395d89b411161006657806395d89b41146101d5578063a9059cbb146101dd578063d505accf146101f0578063dd62ed3e1461020357600080fd5b806340c10f191461018057806370a08231146101955780637ecebe00146101b557600080fd5b806306fdde03146100d4578063095ea7b3146100f257806318160ddd1461011557806323b872dd1461012c578063313ce5671461013f5780633644e51514610178575b600080fd5b6100dc61022e565b6040516100e99190610856565b60405180910390f35b6101056101003660046108c7565b6102bc565b60405190151581526020016100e9565b61011e60025481565b6040519081526020016100e9565b61010561013a3660046108f1565b610328565b6101667f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016100e9565b61011e61041a565b61019361018e3660046108c7565b610475565b005b61011e6101a336600461092d565b60036020526000908152604090205481565b61011e6101c336600461092d565b60056020526000908152604090205481565b6100dc610483565b6101056101eb3660046108c7565b610490565b6101936101fe36600461094f565b610508565b61011e6102113660046109c2565b600460209081526000928352604080842090915290825290205481565b6000805461023b906109f5565b80601f0160208091040260200160405190810160405280929190818152602001828054610267906109f5565b80156102b45780601f10610289576101008083540402835291602001916102b4565b820191906000526020600020905b81548152906001019060200180831161029757829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906103179086815260200190565b60405180910390a350600192915050565b6001600160a01b038316600090815260046020908152604080832033845290915281205460001981146103845761035f8382610a46565b6001600160a01b03861660009081526004602090815260408083203384529091529020555b6001600160a01b038516600090815260036020526040812080548592906103ac908490610a46565b90915550506001600160a01b03808516600081815260036020526040908190208054870190555190918716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906104079087815260200190565b60405180910390a3506001949350505050565b60007f000000000000000000000000000000000000000000000000000000000000000046146104505761044b610751565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b61047f82826107eb565b5050565b6001805461023b906109f5565b336000908152600360205260408120805483919083906104b1908490610a46565b90915550506001600160a01b038316600081815260036020526040908190208054850190555133907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906103179086815260200190565b4284101561055d5760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f4558504952454400000000000000000060448201526064015b60405180910390fd5b6000600161056961041a565b6001600160a01b038a811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015610675573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906106ab5750876001600160a01b0316816001600160a01b0316145b6106e85760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606401610554565b6001600160a01b0390811660009081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60006040516107839190610a5d565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b80600260008282546107fd9190610af9565b90915550506001600160a01b0382166000818152600360209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b600060208083528351808285015260005b8181101561088357858101830151858201604001528201610867565b81811115610895576000604083870101525b50601f01601f1916929092016040019392505050565b80356001600160a01b03811681146108c257600080fd5b919050565b600080604083850312156108da57600080fd5b6108e3836108ab565b946020939093013593505050565b60008060006060848603121561090657600080fd5b61090f846108ab565b925061091d602085016108ab565b9150604084013590509250925092565b60006020828403121561093f57600080fd5b610948826108ab565b9392505050565b600080600080600080600060e0888a03121561096a57600080fd5b610973886108ab565b9650610981602089016108ab565b95506040880135945060608801359350608088013560ff811681146109a557600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156109d557600080fd5b6109de836108ab565b91506109ec602084016108ab565b90509250929050565b600181811c90821680610a0957607f821691505b60208210811415610a2a57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b600082821015610a5857610a58610a30565b500390565b600080835481600182811c915080831680610a7957607f831692505b6020808410821415610a9957634e487b7160e01b86526022600452602486fd5b818015610aad5760018114610abe57610aeb565b60ff19861689528489019650610aeb565b60008a81526020902060005b86811015610ae35781548b820152908501908301610aca565b505084890196505b509498975050505050505050565b60008219821115610b0c57610b0c610a30565b50019056fea26469706673582212209ca55739676d094f8ef4b3b5cfcc08f600b805843c4c3027beb2b4159a02f63664736f6c634300080a0033","sourceMap":"113:230:22:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1028:18:10;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2458:211;;;;;;:::i;:::-;;:::i;:::-;;;1218:14:23;;1211:22;1193:41;;1181:2;1166:18;2458:211:10;1053:187:23;1301:26:10;;;;;;;;;1391:25:23;;;1379:2;1364:18;1301:26:10;1245:177:23;3054:592:10;;;;;;:::i;:::-;;:::i;1080:31::-;;;;;;;;1932:4:23;1920:17;;;1902:36;;1890:2;1875:18;1080:31:10;1760:184:23;5324:177:10;;;:::i;256:85:22:-;;;;;;:::i;:::-;;:::i;:::-;;1334:44:10;;;;;;:::i;:::-;;;;;;;;;;;;;;1748:41;;;;;;:::i;:::-;;;;;;;;;;;;;;1053:20;;;:::i;2675:373::-;;;;;;:::i;:::-;;:::i;3835:1483::-;;;;;;:::i;:::-;;:::i;1385:64::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;1028:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;2458:211::-;2558:10;2532:4;2548:21;;;:9;:21;;;;;;;;-1:-1:-1;;;;;2548:30:10;;;;;;;;;;:39;;;2603:37;2532:4;;2548:30;;2603:37;;;;2581:6;1391:25:23;;1379:2;1364:18;;1245:177;2603:37:10;;;;;;;;-1:-1:-1;2658:4:10;2458:211;;;;:::o;3054:592::-;-1:-1:-1;;;;;3206:15:10;;3172:4;3206:15;;;:9;:15;;;;;;;;3222:10;3206:27;;;;;;;;-1:-1:-1;;3284:28:10;;3280:80;;3344:16;3354:6;3344:7;:16;:::i;:::-;-1:-1:-1;;;;;3314:15:10;;;;;;:9;:15;;;;;;;;3330:10;3314:27;;;;;;;:46;3280:80;-1:-1:-1;;;;;3371:15:10;;;;;;:9;:15;;;;;:25;;3390:6;;3371:15;:25;;3390:6;;3371:25;:::i;:::-;;;;-1:-1:-1;;;;;;;3542:13:10;;;;;;;:9;:13;;;;;;;:23;;;;;;3591:26;3542:13;;3591:26;;;;;;;3559:6;1391:25:23;;1379:2;1364:18;;1245:177;3591:26:10;;;;;;;;-1:-1:-1;3635:4:10;;3054:592;-1:-1:-1;;;;3054:592:10:o;5324:177::-;5381:7;5424:16;5407:13;:33;:87;;5470:24;:22;:24::i;:::-;5400:94;;5324:177;:::o;5407:87::-;-1:-1:-1;5443:24:10;;5324:177::o;256:85:22:-;317:17;323:2;327:6;317:5;:17::i;:::-;256:85;;:::o;1053:20:10:-;;;;;;;:::i;2675:373::-;2771:10;2745:4;2761:21;;;:9;:21;;;;;:31;;2786:6;;2761:21;2745:4;;2761:31;;2786:6;;2761:31;:::i;:::-;;;;-1:-1:-1;;;;;;;2938:13:10;;;;;;:9;:13;;;;;;;:23;;;;;;2987:32;2996:10;;2987:32;;;;2955:6;1391:25:23;;1379:2;1364:18;;1245:177;3835:1483:10;4054:15;4042:8;:27;;4034:63;;;;-1:-1:-1;;;4034:63:10;;4134:2:23;4034:63:10;;;4116:21:23;4173:2;4153:18;;;4146:30;4212:25;4192:18;;;4185:53;4255:18;;4034:63:10;;;;;;;;;4262:24;4289:805;4425:18;:16;:18::i;:::-;-1:-1:-1;;;;;4870:13:10;;;;;;;:6;:13;;;;;;;;;:15;;;;;;;;4508:449;;4552:165;4508:449;;;4571:25:23;4650:18;;;4643:43;;;;4722:15;;;4702:18;;;4695:43;4754:18;;;4747:34;;;4797:19;;;4790:35;;;;4841:19;;;;4834:35;;;4508:449:10;;;;;;;;;;4543:19:23;;;4508:449:10;;;4469:514;;;;;;;;-1:-1:-1;;;4347:658:10;;;5138:27:23;5181:11;;;5174:27;;;;5217:12;;;5210:28;;;;5254:12;;4347:658:10;;;-1:-1:-1;;4347:658:10;;;;;;;;;4316:707;;4347:658;4316:707;;;;4289:805;;;;;;;;;5504:25:23;5577:4;5565:17;;5545:18;;;5538:45;5599:18;;;5592:34;;;5642:18;;;5635:34;;;5476:19;;4289:805:10;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4289:805:10;;-1:-1:-1;;4289:805:10;;;-1:-1:-1;;;;;;;5117:30:10;;;;;;:59;;;5171:5;-1:-1:-1;;;;;5151:25:10;:16;-1:-1:-1;;;;;5151:25:10;;5117:59;5109:86;;;;-1:-1:-1;;;5109:86:10;;5882:2:23;5109:86:10;;;5864:21:23;5921:2;5901:18;;;5894:30;-1:-1:-1;;;5940:18:23;;;5933:44;5994:18;;5109:86:10;5680:338:23;5109:86:10;-1:-1:-1;;;;;5210:27:10;;;;;;;:9;:27;;;;;;;;:36;;;;;;;;;;;;;:44;;;5280:31;1391:25:23;;;5210:36:10;;5280:31;;;;;1364:18:23;5280:31:10;;;;;;;3835:1483;;;;;;;:::o;5507:446::-;5572:7;5669:95;5802:4;5786:22;;;;;;:::i;:::-;;;;;;;;;;5637:295;;;7520:25:23;;;;7561:18;;7554:34;;;;5830:14:10;7604:18:23;;;7597:34;5866:13:10;7647:18:23;;;7640:34;5909:4:10;7690:19:23;;;7683:61;7492:19;;5637:295:10;;;;;;;;;;;;5610:336;;;;;;5591:355;;5507:446;:::o;6147:325::-;6232:6;6217:11;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;6384:13:10;;;;;;:9;:13;;;;;;;;:23;;;;;;6433:32;1391:25:23;;;6433:32:10;;1364:18:23;6433:32:10;;;;;;;6147:325;;:::o;14:597:23:-;126:4;155:2;184;173:9;166:21;216:6;210:13;259:6;254:2;243:9;239:18;232:34;284:1;294:140;308:6;305:1;302:13;294:140;;;403:14;;;399:23;;393:30;369:17;;;388:2;365:26;358:66;323:10;;294:140;;;452:6;449:1;446:13;443:91;;;522:1;517:2;508:6;497:9;493:22;489:31;482:42;443:91;-1:-1:-1;595:2:23;574:15;-1:-1:-1;;570:29:23;555:45;;;;602:2;551:54;;14:597;-1:-1:-1;;;14:597:23:o;616:173::-;684:20;;-1:-1:-1;;;;;733:31:23;;723:42;;713:70;;779:1;776;769:12;713:70;616:173;;;:::o;794:254::-;862:6;870;923:2;911:9;902:7;898:23;894:32;891:52;;;939:1;936;929:12;891:52;962:29;981:9;962:29;:::i;:::-;952:39;1038:2;1023:18;;;;1010:32;;-1:-1:-1;;;794:254:23:o;1427:328::-;1504:6;1512;1520;1573:2;1561:9;1552:7;1548:23;1544:32;1541:52;;;1589:1;1586;1579:12;1541:52;1612:29;1631:9;1612:29;:::i;:::-;1602:39;;1660:38;1694:2;1683:9;1679:18;1660:38;:::i;:::-;1650:48;;1745:2;1734:9;1730:18;1717:32;1707:42;;1427:328;;;;;:::o;2131:186::-;2190:6;2243:2;2231:9;2222:7;2218:23;2214:32;2211:52;;;2259:1;2256;2249:12;2211:52;2282:29;2301:9;2282:29;:::i;:::-;2272:39;2131:186;-1:-1:-1;;;2131:186:23:o;2322:693::-;2433:6;2441;2449;2457;2465;2473;2481;2534:3;2522:9;2513:7;2509:23;2505:33;2502:53;;;2551:1;2548;2541:12;2502:53;2574:29;2593:9;2574:29;:::i;:::-;2564:39;;2622:38;2656:2;2645:9;2641:18;2622:38;:::i;:::-;2612:48;;2707:2;2696:9;2692:18;2679:32;2669:42;;2758:2;2747:9;2743:18;2730:32;2720:42;;2812:3;2801:9;2797:19;2784:33;2857:4;2850:5;2846:16;2839:5;2836:27;2826:55;;2877:1;2874;2867:12;2826:55;2322:693;;;;-1:-1:-1;2322:693:23;;;;2900:5;2952:3;2937:19;;2924:33;;-1:-1:-1;3004:3:23;2989:19;;;2976:33;;2322:693;-1:-1:-1;;2322:693:23:o;3020:260::-;3088:6;3096;3149:2;3137:9;3128:7;3124:23;3120:32;3117:52;;;3165:1;3162;3155:12;3117:52;3188:29;3207:9;3188:29;:::i;:::-;3178:39;;3236:38;3270:2;3259:9;3255:18;3236:38;:::i;:::-;3226:48;;3020:260;;;;;:::o;3285:380::-;3364:1;3360:12;;;;3407;;;3428:61;;3482:4;3474:6;3470:17;3460:27;;3428:61;3535:2;3527:6;3524:14;3504:18;3501:38;3498:161;;;3581:10;3576:3;3572:20;3569:1;3562:31;3616:4;3613:1;3606:15;3644:4;3641:1;3634:15;3498:161;;3285:380;;;:::o;3670:127::-;3731:10;3726:3;3722:20;3719:1;3712:31;3762:4;3759:1;3752:15;3786:4;3783:1;3776:15;3802:125;3842:4;3870:1;3867;3864:8;3861:34;;;3875:18;;:::i;:::-;-1:-1:-1;3912:9:23;;3802:125::o;6152:1104::-;6282:3;6311:1;6344:6;6338:13;6374:3;6396:1;6424:9;6420:2;6416:18;6406:28;;6484:2;6473:9;6469:18;6506;6496:61;;6550:4;6542:6;6538:17;6528:27;;6496:61;6576:2;6624;6616:6;6613:14;6593:18;6590:38;6587:165;;;-1:-1:-1;;;6651:33:23;;6707:4;6704:1;6697:15;6737:4;6658:3;6725:17;6587:165;6768:18;6795:104;;;;6913:1;6908:323;;;;6761:470;;6795:104;-1:-1:-1;;6828:24:23;;6816:37;;6873:16;;;;-1:-1:-1;6795:104:23;;6908:323;6099:1;6092:14;;;6136:4;6123:18;;7006:1;7020:165;7034:6;7031:1;7028:13;7020:165;;;7112:14;;7099:11;;;7092:35;7155:16;;;;7049:10;;7020:165;;;7024:3;;7214:6;7209:3;7205:16;7198:23;;6761:470;-1:-1:-1;7247:3:23;;6152:1104;-1:-1:-1;;;;;;;;6152:1104:23:o;7755:128::-;7795:3;7826:1;7822:6;7819:1;7816:13;7813:39;;;7832:18;;:::i;:::-;-1:-1:-1;7868:9:23;;7755:128::o","linkReferences":{},"immutableReferences":{"3499":[{"start":324,"length":32}],"3513":[{"start":1054,"length":32}],"3515":[{"start":1107,"length":32}]}},"methodIdentifiers":{"DOMAIN_SEPARATOR()":"3644e515","allowance(address,address)":"dd62ed3e","approve(address,uint256)":"095ea7b3","balanceOf(address)":"70a08231","decimals()":"313ce567","mint(address,uint256)":"40c10f19","name()":"06fdde03","nonces(address)":"7ecebe00","permit(address,address,uint256,uint256,uint8,bytes32,bytes32)":"d505accf","symbol()":"95d89b41","totalSupply()":"18160ddd","transfer(address,uint256)":"a9059cbb","transferFrom(address,address,uint256)":"23b872dd"}} \ No newline at end of file diff --git a/crates/cast/tests/fixtures/interface.json b/crates/cast/tests/fixtures/interface.json index 73e561886a96..26163abeec0d 100644 --- a/crates/cast/tests/fixtures/interface.json +++ b/crates/cast/tests/fixtures/interface.json @@ -1,141 +1 @@ -[ - { - "type": "constructor", - "inputs": [ - { - "name": "_integrationManager", - "type": "address", - "internalType": "address" - }, - { - "name": "_addressListRegistry", - "type": "address", - "internalType": "address" - }, - { - "name": "_aTokenListId", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "_pool", - "type": "address", - "internalType": "address" - }, - { - "name": "_referralCode", - "type": "uint16", - "internalType": "uint16" - } - ], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "getIntegrationManager", - "inputs": [], - "outputs": [ - { - "name": "integrationManager_", - "type": "address", - "internalType": "address" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "lend", - "inputs": [ - { - "name": "_vaultProxy", - "type": "address", - "internalType": "address" - }, - { - "name": "", - "type": "bytes", - "internalType": "bytes" - }, - { - "name": "_assetData", - "type": "bytes", - "internalType": "bytes" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "parseAssetsForAction", - "inputs": [ - { - "name": "", - "type": "address", - "internalType": "address" - }, - { - "name": "_selector", - "type": "bytes4", - "internalType": "bytes4" - }, - { - "name": "_actionData", - "type": "bytes", - "internalType": "bytes" - } - ], - "outputs": [ - { - "name": "spendAssetsHandleType_", - "type": "uint8", - "internalType": "enum IIntegrationManager.SpendAssetsHandleType" - }, - { - "name": "spendAssets_", - "type": "address[]", - "internalType": "address[]" - }, - { - "name": "spendAssetAmounts_", - "type": "uint256[]", - "internalType": "uint256[]" - }, - { - "name": "incomingAssets_", - "type": "address[]", - "internalType": "address[]" - }, - { - "name": "minIncomingAssetAmounts_", - "type": "uint256[]", - "internalType": "uint256[]" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "redeem", - "inputs": [ - { - "name": "_vaultProxy", - "type": "address", - "internalType": "address" - }, - { - "name": "", - "type": "bytes", - "internalType": "bytes" - }, - { - "name": "_assetData", - "type": "bytes", - "internalType": "bytes" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - } -] \ No newline at end of file +[{"type":"constructor","inputs":[{"name":"_integrationManager","type":"address","internalType":"address"},{"name":"_addressListRegistry","type":"address","internalType":"address"},{"name":"_aTokenListId","type":"uint256","internalType":"uint256"},{"name":"_pool","type":"address","internalType":"address"},{"name":"_referralCode","type":"uint16","internalType":"uint16"}],"stateMutability":"nonpayable"},{"type":"function","name":"getIntegrationManager","inputs":[],"outputs":[{"name":"integrationManager_","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"lend","inputs":[{"name":"_vaultProxy","type":"address","internalType":"address"},{"name":"","type":"bytes","internalType":"bytes"},{"name":"_assetData","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"parseAssetsForAction","inputs":[{"name":"","type":"address","internalType":"address"},{"name":"_selector","type":"bytes4","internalType":"bytes4"},{"name":"_actionData","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"spendAssetsHandleType_","type":"uint8","internalType":"enum IIntegrationManager.SpendAssetsHandleType"},{"name":"spendAssets_","type":"address[]","internalType":"address[]"},{"name":"spendAssetAmounts_","type":"uint256[]","internalType":"uint256[]"},{"name":"incomingAssets_","type":"address[]","internalType":"address[]"},{"name":"minIncomingAssetAmounts_","type":"uint256[]","internalType":"uint256[]"}],"stateMutability":"view"},{"type":"function","name":"redeem","inputs":[{"name":"_vaultProxy","type":"address","internalType":"address"},{"name":"","type":"bytes","internalType":"bytes"},{"name":"_assetData","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"}] \ No newline at end of file diff --git a/crates/cast/tests/fixtures/sign_typed_data.json b/crates/cast/tests/fixtures/sign_typed_data.json index a6002810a6ee..8dc45f2e7409 100644 --- a/crates/cast/tests/fixtures/sign_typed_data.json +++ b/crates/cast/tests/fixtures/sign_typed_data.json @@ -1,38 +1 @@ -{ - "types": { - "EIP712Domain": [ - { - "name": "name", - "type": "string" - }, - { - "name": "version", - "type": "string" - }, - { - "name": "chainId", - "type": "uint256" - }, - { - "name": "verifyingContract", - "type": "address" - } - ], - "Message": [ - { - "name": "data", - "type": "string" - } - ] - }, - "primaryType": "Message", - "domain": { - "name": "example.metamask.io", - "version": "1", - "chainId": "1", - "verifyingContract": "0x0000000000000000000000000000000000000000" - }, - "message": { - "data": "Hello!" - } -} \ No newline at end of file +{"types":{"EIP712Domain":[{"name":"name","type":"string"},{"name":"version","type":"string"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"}],"Message":[{"name":"data","type":"string"}]},"primaryType":"Message","domain":{"name":"example.metamask.io","version":"1","chainId":"1","verifyingContract":"0x0000000000000000000000000000000000000000"},"message":{"data":"Hello!"}} \ No newline at end of file diff --git a/crates/evm/core/src/abi/HardhatConsole.json b/crates/evm/core/src/abi/HardhatConsole.json index c1b1b46cf4fb..4013d875357e 100644 --- a/crates/evm/core/src/abi/HardhatConsole.json +++ b/crates/evm/core/src/abi/HardhatConsole.json @@ -1 +1 @@ -[{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"}],"name":"logAddress","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"}],"name":"logBool","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"p0","type":"bytes"}],"name":"logBytes","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes1","name":"p0","type":"bytes1"}],"name":"logBytes1","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes10","name":"p0","type":"bytes10"}],"name":"logBytes10","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes11","name":"p0","type":"bytes11"}],"name":"logBytes11","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes12","name":"p0","type":"bytes12"}],"name":"logBytes12","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes13","name":"p0","type":"bytes13"}],"name":"logBytes13","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes14","name":"p0","type":"bytes14"}],"name":"logBytes14","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes15","name":"p0","type":"bytes15"}],"name":"logBytes15","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes16","name":"p0","type":"bytes16"}],"name":"logBytes16","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes17","name":"p0","type":"bytes17"}],"name":"logBytes17","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes18","name":"p0","type":"bytes18"}],"name":"logBytes18","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes19","name":"p0","type":"bytes19"}],"name":"logBytes19","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes2","name":"p0","type":"bytes2"}],"name":"logBytes2","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes20","name":"p0","type":"bytes20"}],"name":"logBytes20","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes21","name":"p0","type":"bytes21"}],"name":"logBytes21","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes22","name":"p0","type":"bytes22"}],"name":"logBytes22","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes23","name":"p0","type":"bytes23"}],"name":"logBytes23","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes24","name":"p0","type":"bytes24"}],"name":"logBytes24","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes25","name":"p0","type":"bytes25"}],"name":"logBytes25","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes26","name":"p0","type":"bytes26"}],"name":"logBytes26","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes27","name":"p0","type":"bytes27"}],"name":"logBytes27","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes28","name":"p0","type":"bytes28"}],"name":"logBytes28","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes29","name":"p0","type":"bytes29"}],"name":"logBytes29","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes3","name":"p0","type":"bytes3"}],"name":"logBytes3","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes30","name":"p0","type":"bytes30"}],"name":"logBytes30","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes31","name":"p0","type":"bytes31"}],"name":"logBytes31","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"p0","type":"bytes32"}],"name":"logBytes32","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"p0","type":"bytes4"}],"name":"logBytes4","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes5","name":"p0","type":"bytes5"}],"name":"logBytes5","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes6","name":"p0","type":"bytes6"}],"name":"logBytes6","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes7","name":"p0","type":"bytes7"}],"name":"logBytes7","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes8","name":"p0","type":"bytes8"}],"name":"logBytes8","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes9","name":"p0","type":"bytes9"}],"name":"logBytes9","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int256","name":"p0","type":"int256"}],"name":"logInt","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"}],"name":"logString","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"}],"name":"logUint","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int256","name":"p0","type":"int256"}],"outputs":[],"stateMutability":"view","type":"function","name":"log"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"int256","name":"p1","type":"int256"}],"outputs":[],"stateMutability":"view","type":"function","name":"log"}] +[{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"bool","name":"p2","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"uint256","name":"p3","type":"uint256"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"bool","name":"p1","type":"bool"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"bool","name":"p3","type":"bool"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"address","name":"p2","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"},{"internalType":"address","name":"p1","type":"address"},{"internalType":"uint256","name":"p2","type":"uint256"},{"internalType":"string","name":"p3","type":"string"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"},{"internalType":"uint256","name":"p1","type":"uint256"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"address","name":"p3","type":"address"}],"name":"log","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p0","type":"address"}],"name":"logAddress","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"p0","type":"bool"}],"name":"logBool","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"p0","type":"bytes"}],"name":"logBytes","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes1","name":"p0","type":"bytes1"}],"name":"logBytes1","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes10","name":"p0","type":"bytes10"}],"name":"logBytes10","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes11","name":"p0","type":"bytes11"}],"name":"logBytes11","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes12","name":"p0","type":"bytes12"}],"name":"logBytes12","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes13","name":"p0","type":"bytes13"}],"name":"logBytes13","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes14","name":"p0","type":"bytes14"}],"name":"logBytes14","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes15","name":"p0","type":"bytes15"}],"name":"logBytes15","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes16","name":"p0","type":"bytes16"}],"name":"logBytes16","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes17","name":"p0","type":"bytes17"}],"name":"logBytes17","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes18","name":"p0","type":"bytes18"}],"name":"logBytes18","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes19","name":"p0","type":"bytes19"}],"name":"logBytes19","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes2","name":"p0","type":"bytes2"}],"name":"logBytes2","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes20","name":"p0","type":"bytes20"}],"name":"logBytes20","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes21","name":"p0","type":"bytes21"}],"name":"logBytes21","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes22","name":"p0","type":"bytes22"}],"name":"logBytes22","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes23","name":"p0","type":"bytes23"}],"name":"logBytes23","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes24","name":"p0","type":"bytes24"}],"name":"logBytes24","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes25","name":"p0","type":"bytes25"}],"name":"logBytes25","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes26","name":"p0","type":"bytes26"}],"name":"logBytes26","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes27","name":"p0","type":"bytes27"}],"name":"logBytes27","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes28","name":"p0","type":"bytes28"}],"name":"logBytes28","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes29","name":"p0","type":"bytes29"}],"name":"logBytes29","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes3","name":"p0","type":"bytes3"}],"name":"logBytes3","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes30","name":"p0","type":"bytes30"}],"name":"logBytes30","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes31","name":"p0","type":"bytes31"}],"name":"logBytes31","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"p0","type":"bytes32"}],"name":"logBytes32","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"p0","type":"bytes4"}],"name":"logBytes4","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes5","name":"p0","type":"bytes5"}],"name":"logBytes5","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes6","name":"p0","type":"bytes6"}],"name":"logBytes6","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes7","name":"p0","type":"bytes7"}],"name":"logBytes7","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes8","name":"p0","type":"bytes8"}],"name":"logBytes8","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes9","name":"p0","type":"bytes9"}],"name":"logBytes9","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int256","name":"p0","type":"int256"}],"name":"logInt","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"p0","type":"string"}],"name":"logString","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p0","type":"uint256"}],"name":"logUint","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int256","name":"p0","type":"int256"}],"outputs":[],"stateMutability":"view","type":"function","name":"log"},{"inputs":[{"internalType":"string","name":"p0","type":"string"},{"internalType":"int256","name":"p1","type":"int256"}],"outputs":[],"stateMutability":"view","type":"function","name":"log"}] \ No newline at end of file diff --git a/crates/evm/core/test-data/storage.json b/crates/evm/core/test-data/storage.json index 4f25625919b2..6a602f7a642a 100644 --- a/crates/evm/core/test-data/storage.json +++ b/crates/evm/core/test-data/storage.json @@ -1 +1 @@ -{"meta":{"cfg_env":{"chain_id":1,"spec_id":"LATEST","perf_all_precompiles_have_balance":false,"memory_limit":4294967295, "perf_analyse_created_bytecodes":"Analyse", "limit_contract_code_size": 24576, "disable_coinbase_tip": false},"block_env":{"number":"0xdc42b8","coinbase":"0x0000000000000000000000000000000000000000","timestamp":"0x1","difficulty":"0x0","basefee":"0x0","gas_limit":"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},"hosts":["mainnet.infura.io"]},"accounts":{"0x63091244180ae240c87d1f528f5f269134cb07b3":{"balance":"0x0","code_hash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","code":null,"nonce":0}},"storage":{"0x63091244180ae240c87d1f528f5f269134cb07b3":{"0x0":"0x0","0x1":"0x0","0x2":"0x0","0x3":"0x0","0x4":"0x0","0x5":"0x0","0x6":"0x0","0x7":"0x0","0x8":"0x0","0x9":"0x0"}},"block_hashes":{}} \ No newline at end of file +{"meta":{"cfg_env":{"chain_id":1,"spec_id":"LATEST","perf_all_precompiles_have_balance":false,"memory_limit":4294967295,"perf_analyse_created_bytecodes":"Analyse","limit_contract_code_size":24576,"disable_coinbase_tip":false},"block_env":{"number":"0xdc42b8","coinbase":"0x0000000000000000000000000000000000000000","timestamp":"0x1","difficulty":"0x0","basefee":"0x0","gas_limit":"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},"hosts":["mainnet.infura.io"]},"accounts":{"0x63091244180ae240c87d1f528f5f269134cb07b3":{"balance":"0x0","code_hash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","code":null,"nonce":0}},"storage":{"0x63091244180ae240c87d1f528f5f269134cb07b3":{"0x0":"0x0","0x1":"0x0","0x2":"0x0","0x3":"0x0","0x4":"0x0","0x5":"0x0","0x6":"0x0","0x7":"0x0","0x8":"0x0","0x9":"0x0"}},"block_hashes":{}} \ No newline at end of file diff --git a/testdata/default/script/broadcast/deploy.sol/31337/run-latest.json b/testdata/default/script/broadcast/deploy.sol/31337/run-latest.json index 9a05e1cb7ac2..1a8bccb39248 100644 --- a/testdata/default/script/broadcast/deploy.sol/31337/run-latest.json +++ b/testdata/default/script/broadcast/deploy.sol/31337/run-latest.json @@ -1,63 +1 @@ -{ - "transactions": [ - { - "hash": null, - "type": "CREATE", - "contractName": null, - "contractAddress": "0x731a10897d267e19b34503ad902d0a29173ba4b1", - "function": null, - "arguments": null, - "transaction": { - "type": "0x02", - "from": "0x00a329c0648769a73afac7f9381e08fb43dbea72", - "gas": "0x54653", - "value": "0x0", - "data": "0x608060405234801561001057600080fd5b506103d9806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063d5dcf1271461003b578063f8194e4814610050575b600080fd5b61004e6100493660046100e9565b600155565b005b61006361005e366004610118565b610079565b60405161007091906101f9565b60405180910390f35b6060600061008783826102b5565b5060008260405160200161009b9190610375565b60405160208183030381529060405290507fefdeaaf566f7751d16a12c7fa8909eb74120f42cba334d07dd5246c48f1fba81816040516100db91906101f9565b60405180910390a192915050565b6000602082840312156100fb57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561012a57600080fd5b813567ffffffffffffffff8082111561014257600080fd5b818401915084601f83011261015657600080fd5b81358181111561016857610168610102565b604051601f8201601f19908116603f0116810190838211818310171561019057610190610102565b816040528281528760208487010111156101a957600080fd5b826020860160208301376000928101602001929092525095945050505050565b60005b838110156101e45781810151838201526020016101cc565b838111156101f3576000848401525b50505050565b60208152600082518060208401526102188160408501602087016101c9565b601f01601f19169190910160400192915050565b600181811c9082168061024057607f821691505b60208210810361026057634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156102b057600081815260208120601f850160051c8101602086101561028d5750805b601f850160051c820191505b818110156102ac57828155600101610299565b5050505b505050565b815167ffffffffffffffff8111156102cf576102cf610102565b6102e3816102dd845461022c565b84610266565b602080601f83116001811461031857600084156103005750858301515b600019600386901b1c1916600185901b1785556102ac565b600085815260208120601f198616915b8281101561034757888601518255948401946001909101908401610328565b50858210156103655787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6502432b63637960d51b8152600082516103968160068501602087016101c9565b919091016006019291505056fea2646970667358221220a380cb042b6ca762a5a0f97e497c4cffa21c45dc21e2dab4107e5415921a704a64736f6c634300080f0033", - "nonce": "0x0", - "accessList": [] - } - }, - { - "hash": null, - "type": "CALL", - "contractName": null, - "contractAddress": "0x731a10897d267e19b34503ad902d0a29173ba4b1", - "function": null, - "arguments": null, - "transaction": { - "type": "0x02", - "from": "0x00a329c0648769a73afac7f9381e08fb43dbea72", - "to": "0x731a10897d267e19b34503ad902d0a29173ba4b1", - "gas": "0xef15", - "value": "0x0", - "data": "0xf8194e48000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000046a6f686e00000000000000000000000000000000000000000000000000000000", - "nonce": "0x1", - "accessList": [] - } - }, - { - "hash": null, - "type": "CALL", - "contractName": null, - "contractAddress": "0x731a10897d267e19b34503ad902d0a29173ba4b1", - "function": null, - "arguments": null, - "transaction": { - "type": "0x02", - "from": "0x00a329c0648769a73afac7f9381e08fb43dbea72", - "to": "0x731a10897d267e19b34503ad902d0a29173ba4b1", - "gas": "0xdcde", - "value": "0x0", - "data": "0xd5dcf127000000000000000000000000000000000000000000000000000000000000007b", - "nonce": "0x2", - "accessList": [] - } - } - ], - "receipts": [], - "libraries": [], - "pending": [], - "path": "broadcast/deploy.sol/31337/run-latest.json", - "returns": {}, - "timestamp": 1658913881 -} \ No newline at end of file +{"transactions":[{"hash":null,"type":"CREATE","contractName":null,"contractAddress":"0x731a10897d267e19b34503ad902d0a29173ba4b1","function":null,"arguments":null,"transaction":{"type":"0x02","from":"0x00a329c0648769a73afac7f9381e08fb43dbea72","gas":"0x54653","value":"0x0","data":"0x608060405234801561001057600080fd5b506103d9806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063d5dcf1271461003b578063f8194e4814610050575b600080fd5b61004e6100493660046100e9565b600155565b005b61006361005e366004610118565b610079565b60405161007091906101f9565b60405180910390f35b6060600061008783826102b5565b5060008260405160200161009b9190610375565b60405160208183030381529060405290507fefdeaaf566f7751d16a12c7fa8909eb74120f42cba334d07dd5246c48f1fba81816040516100db91906101f9565b60405180910390a192915050565b6000602082840312156100fb57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561012a57600080fd5b813567ffffffffffffffff8082111561014257600080fd5b818401915084601f83011261015657600080fd5b81358181111561016857610168610102565b604051601f8201601f19908116603f0116810190838211818310171561019057610190610102565b816040528281528760208487010111156101a957600080fd5b826020860160208301376000928101602001929092525095945050505050565b60005b838110156101e45781810151838201526020016101cc565b838111156101f3576000848401525b50505050565b60208152600082518060208401526102188160408501602087016101c9565b601f01601f19169190910160400192915050565b600181811c9082168061024057607f821691505b60208210810361026057634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156102b057600081815260208120601f850160051c8101602086101561028d5750805b601f850160051c820191505b818110156102ac57828155600101610299565b5050505b505050565b815167ffffffffffffffff8111156102cf576102cf610102565b6102e3816102dd845461022c565b84610266565b602080601f83116001811461031857600084156103005750858301515b600019600386901b1c1916600185901b1785556102ac565b600085815260208120601f198616915b8281101561034757888601518255948401946001909101908401610328565b50858210156103655787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6502432b63637960d51b8152600082516103968160068501602087016101c9565b919091016006019291505056fea2646970667358221220a380cb042b6ca762a5a0f97e497c4cffa21c45dc21e2dab4107e5415921a704a64736f6c634300080f0033","nonce":"0x0","accessList":[]}},{"hash":null,"type":"CALL","contractName":null,"contractAddress":"0x731a10897d267e19b34503ad902d0a29173ba4b1","function":null,"arguments":null,"transaction":{"type":"0x02","from":"0x00a329c0648769a73afac7f9381e08fb43dbea72","to":"0x731a10897d267e19b34503ad902d0a29173ba4b1","gas":"0xef15","value":"0x0","data":"0xf8194e48000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000046a6f686e00000000000000000000000000000000000000000000000000000000","nonce":"0x1","accessList":[]}},{"hash":null,"type":"CALL","contractName":null,"contractAddress":"0x731a10897d267e19b34503ad902d0a29173ba4b1","function":null,"arguments":null,"transaction":{"type":"0x02","from":"0x00a329c0648769a73afac7f9381e08fb43dbea72","to":"0x731a10897d267e19b34503ad902d0a29173ba4b1","gas":"0xdcde","value":"0x0","data":"0xd5dcf127000000000000000000000000000000000000000000000000000000000000007b","nonce":"0x2","accessList":[]}}],"receipts":[],"libraries":[],"pending":[],"path":"broadcast/deploy.sol/31337/run-latest.json","returns":{},"timestamp":1658913881} \ No newline at end of file diff --git a/testdata/etherscan/0x044b75f554b886A065b9567891e45c79542d7357/creation_data.json b/testdata/etherscan/0x044b75f554b886A065b9567891e45c79542d7357/creation_data.json index d709187b8b9b..899a44c1514b 100644 --- a/testdata/etherscan/0x044b75f554b886A065b9567891e45c79542d7357/creation_data.json +++ b/testdata/etherscan/0x044b75f554b886A065b9567891e45c79542d7357/creation_data.json @@ -1,5 +1 @@ -{ - "contractAddress": "0x044b75f554b886a065b9567891e45c79542d7357", - "contractCreator": "0xf87bc5535602077d340806d71f805ea9907a843d", - "txHash": "0x9a89d2f5528bf07661e92f3f78a3311396f11f15da19e3ec4d880be1ad1a4bec" -} \ No newline at end of file +{"contractAddress":"0x044b75f554b886a065b9567891e45c79542d7357","contractCreator":"0xf87bc5535602077d340806d71f805ea9907a843d","txHash":"0x9a89d2f5528bf07661e92f3f78a3311396f11f15da19e3ec4d880be1ad1a4bec"} \ No newline at end of file diff --git a/testdata/etherscan/0x044b75f554b886A065b9567891e45c79542d7357/metadata.json b/testdata/etherscan/0x044b75f554b886A065b9567891e45c79542d7357/metadata.json index 12f7f6a3bfcb..54aec7d6a61f 100644 --- a/testdata/etherscan/0x044b75f554b886A065b9567891e45c79542d7357/metadata.json +++ b/testdata/etherscan/0x044b75f554b886A065b9567891e45c79542d7357/metadata.json @@ -1,78 +1 @@ -[ - { - "SourceCode": { - "language": "Solidity", - "sources": { - "contracts/InputStream.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\n\npragma solidity 0.8.10;\n\nlibrary InputStream {\n function createStream(bytes memory data) internal pure returns (uint256 stream) {\n assembly {\n stream := mload(0x40)\n mstore(0x40, add(stream, 64))\n mstore(stream, data)\n let length := mload(data)\n mstore(add(stream, 32), add(data, length))\n }\n }\n\n function isNotEmpty(uint256 stream) internal pure returns (bool) {\n uint256 pos;\n uint256 finish;\n assembly {\n pos := mload(stream)\n finish := mload(add(stream, 32))\n }\n return pos < finish;\n }\n\n function readUint8(uint256 stream) internal pure returns (uint8 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 1)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint16(uint256 stream) internal pure returns (uint16 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 2)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint32(uint256 stream) internal pure returns (uint32 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 4)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint(uint256 stream) internal pure returns (uint256 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 32)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readAddress(uint256 stream) internal pure returns (address res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 20)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readBytes(uint256 stream) internal pure returns (bytes memory res) {\n assembly {\n let pos := mload(stream)\n res := add(pos, 32)\n let length := mload(res)\n mstore(stream, add(res, length))\n }\n }\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.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 function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\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" - }, - "interfaces/IBentoBoxMinimal.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\n\npragma solidity >=0.8.0;\n\nstruct Rebase {\n uint128 elastic;\n uint128 base;\n}\n\nstruct StrategyData {\n uint64 strategyStartDate;\n uint64 targetPercentage;\n uint128 balance; // the balance of the strategy that BentoBox thinks is in there\n}\n\n/// @notice A rebasing library\nlibrary RebaseLibrary {\n /// @notice Calculates the base value in relationship to `elastic` and `total`.\n function toBase(Rebase memory total, uint256 elastic) internal pure returns (uint256 base) {\n if (total.elastic == 0) {\n base = elastic;\n } else {\n base = (elastic * total.base) / total.elastic;\n }\n }\n\n /// @notice Calculates the elastic value in relationship to `base` and `total`.\n function toElastic(Rebase memory total, uint256 base) internal pure returns (uint256 elastic) {\n if (total.base == 0) {\n elastic = base;\n } else {\n elastic = (base * total.elastic) / total.base;\n }\n }\n}\n\n/// @notice Minimal BentoBox vault interface.\n/// @dev `token` is aliased as `address` from `IERC20` for simplicity.\ninterface IBentoBoxMinimal {\n /// @notice Balance per ERC-20 token per account in shares.\n function balanceOf(address, address) external view returns (uint256);\n\n /// @dev Helper function to represent an `amount` of `token` in shares.\n /// @param token The ERC-20 token.\n /// @param amount The `token` amount.\n /// @param roundUp If the result `share` should be rounded up.\n /// @return share The token amount represented in shares.\n function toShare(\n address token,\n uint256 amount,\n bool roundUp\n ) external view returns (uint256 share);\n\n /// @dev Helper function to represent shares back into the `token` amount.\n /// @param token The ERC-20 token.\n /// @param share The amount of shares.\n /// @param roundUp If the result should be rounded up.\n /// @return amount The share amount back into native representation.\n function toAmount(\n address token,\n uint256 share,\n bool roundUp\n ) external view returns (uint256 amount);\n\n /// @notice Registers this contract so that users can approve it for BentoBox.\n function registerProtocol() external;\n\n /// @notice Deposit an amount of `token` represented in either `amount` or `share`.\n /// @param token The ERC-20 token to deposit.\n /// @param from which account to pull the tokens.\n /// @param to which account to push the tokens.\n /// @param amount Token amount in native representation to deposit.\n /// @param share Token amount represented in shares to deposit. Takes precedence over `amount`.\n /// @return amountOut The amount deposited.\n /// @return shareOut The deposited amount represented in shares.\n function deposit(\n address token,\n address from,\n address to,\n uint256 amount,\n uint256 share\n ) external payable returns (uint256 amountOut, uint256 shareOut);\n\n /// @notice Withdraws an amount of `token` from a user account.\n /// @param token_ The ERC-20 token to withdraw.\n /// @param from which user to pull the tokens.\n /// @param to which user to push the tokens.\n /// @param amount of tokens. Either one of `amount` or `share` needs to be supplied.\n /// @param share Like above, but `share` takes precedence over `amount`.\n function withdraw(\n address token_,\n address from,\n address to,\n uint256 amount,\n uint256 share\n ) external returns (uint256 amountOut, uint256 shareOut);\n\n /// @notice Transfer shares from a user account to another one.\n /// @param token The ERC-20 token to transfer.\n /// @param from which user to pull the tokens.\n /// @param to which user to push the tokens.\n /// @param share The amount of `token` in shares.\n function transfer(\n address token,\n address from,\n address to,\n uint256 share\n ) external;\n\n /// @dev Reads the Rebase `totals`from storage for a given token\n function totals(address token) external view returns (Rebase memory total);\n\n function strategyData(address token) external view returns (StrategyData memory total);\n\n /// @dev Approves users' BentoBox assets to a \"master\" contract.\n function setMasterContractApproval(\n address user,\n address masterContract,\n bool approved,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n function harvest(\n address token,\n bool balance,\n uint256 maxChangeAmount\n ) external;\n}\n" - }, - "@openzeppelin/contracts/utils/Address.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.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 functionCallWithValue(target, data, 0, \"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 (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, 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 (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, 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 (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or 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 _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\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 /// @solidity memory-safe-assembly\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" - }, - "interfaces/IPool.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n\npragma solidity >=0.5.0;\npragma experimental ABIEncoderV2;\n\n/// @notice Trident pool interface.\ninterface IPool {\n /// @notice Executes a swap from one token to another.\n /// @dev The input tokens must've already been sent to the pool.\n /// @param data ABI-encoded params that the pool requires.\n /// @return finalAmountOut The amount of output tokens that were sent to the user.\n function swap(bytes calldata data) external returns (uint256 finalAmountOut);\n\n /// @notice Executes a swap from one token to another with a callback.\n /// @dev This function allows borrowing the output tokens and sending the input tokens in the callback.\n /// @param data ABI-encoded params that the pool requires.\n /// @return finalAmountOut The amount of output tokens that were sent to the user.\n function flashSwap(bytes calldata data) external returns (uint256 finalAmountOut);\n\n /// @notice Mints liquidity tokens.\n /// @param data ABI-encoded params that the pool requires.\n /// @return liquidity The amount of liquidity tokens that were minted for the user.\n function mint(bytes calldata data) external returns (uint256 liquidity);\n\n /// @notice Burns liquidity tokens.\n /// @dev The input LP tokens must've already been sent to the pool.\n /// @param data ABI-encoded params that the pool requires.\n /// @return withdrawnAmounts The amount of various output tokens that were sent to the user.\n function burn(bytes calldata data) external returns (TokenAmount[] memory withdrawnAmounts);\n\n /// @notice Burns liquidity tokens for a single output token.\n /// @dev The input LP tokens must've already been sent to the pool.\n /// @param data ABI-encoded params that the pool requires.\n /// @return amountOut The amount of output tokens that were sent to the user.\n function burnSingle(bytes calldata data) external returns (uint256 amountOut);\n\n /// @return A unique identifier for the pool type.\n function poolIdentifier() external pure returns (bytes32);\n\n /// @return An array of tokens supported by the pool.\n function getAssets() external view returns (address[] memory);\n\n /// @notice Simulates a trade and returns the expected output.\n /// @dev The pool does not need to include a trade simulator directly in itself - it can use a library.\n /// @param data ABI-encoded params that the pool requires.\n /// @return finalAmountOut The amount of output tokens that will be sent to the user if the trade is executed.\n function getAmountOut(bytes calldata data) external view returns (uint256 finalAmountOut);\n\n /// @notice Simulates a trade and returns the expected output.\n /// @dev The pool does not need to include a trade simulator directly in itself - it can use a library.\n /// @param data ABI-encoded params that the pool requires.\n /// @return finalAmountIn The amount of input tokens that are required from the user if the trade is executed.\n function getAmountIn(bytes calldata data) external view returns (uint256 finalAmountIn);\n\n /// @dev This event must be emitted on all swaps.\n event Swap(address indexed recipient, address indexed tokenIn, address indexed tokenOut, uint256 amountIn, uint256 amountOut);\n\n /// @dev This struct frames output tokens for burns.\n struct TokenAmount {\n address token;\n uint256 amount;\n }\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/IERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.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 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 /**\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" - }, - "contracts/RouteProcessor2.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\n\npragma solidity 0.8.10;\n\nimport '../interfaces/IUniswapV2Pair.sol';\nimport '../interfaces/IUniswapV3Pool.sol';\nimport '../interfaces/ITridentCLPool.sol';\nimport '../interfaces/IBentoBoxMinimal.sol';\nimport '../interfaces/IPool.sol';\nimport '../interfaces/IWETH.sol';\nimport './InputStream.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\naddress constant NATIVE_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\naddress constant IMPOSSIBLE_POOL_ADDRESS = 0x0000000000000000000000000000000000000001;\n\n/// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\nuint160 constant MIN_SQRT_RATIO = 4295128739;\n/// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\nuint160 constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\n\n/// @title A route processor for the Sushi Aggregator\n/// @author Ilya Lyalin\ncontract RouteProcessor2 {\n using SafeERC20 for IERC20;\n using InputStream for uint256;\n\n IBentoBoxMinimal public immutable bentoBox;\n address private lastCalledPool;\n\n uint private unlocked = 1;\n modifier lock() {\n require(unlocked == 1, 'RouteProcessor is locked');\n unlocked = 2;\n _;\n unlocked = 1;\n }\n\n constructor(address _bentoBox) {\n bentoBox = IBentoBoxMinimal(_bentoBox);\n lastCalledPool = IMPOSSIBLE_POOL_ADDRESS;\n }\n\n /// @notice For native unwrapping\n receive() external payable {}\n\n /// @notice Processes the route generated off-chain. Has a lock\n /// @param tokenIn Address of the input token\n /// @param amountIn Amount of the input token\n /// @param tokenOut Address of the output token\n /// @param amountOutMin Minimum amount of the output token\n /// @return amountOut Actual amount of the output token\n function processRoute(\n address tokenIn,\n uint256 amountIn,\n address tokenOut,\n uint256 amountOutMin,\n address to,\n bytes memory route\n ) external payable lock returns (uint256 amountOut) {\n return processRouteInternal(tokenIn, amountIn, tokenOut, amountOutMin, to, route);\n }\n\n /// @notice Transfers some value to and then processes the route\n /// @param transferValueTo Address where the value should be transferred\n /// @param amountValueTransfer How much value to transfer\n /// @param tokenIn Address of the input token\n /// @param amountIn Amount of the input token\n /// @param tokenOut Address of the output token\n /// @param amountOutMin Minimum amount of the output token\n /// @return amountOut Actual amount of the output token\n function transferValueAndprocessRoute(\n address payable transferValueTo,\n uint256 amountValueTransfer,\n address tokenIn,\n uint256 amountIn,\n address tokenOut,\n uint256 amountOutMin,\n address to,\n bytes memory route\n ) external payable lock returns (uint256 amountOut) {\n (bool success, bytes memory returnBytes) = transferValueTo.call{value: amountValueTransfer}('');\n require(success, string(abi.encodePacked(returnBytes)));\n return processRouteInternal(tokenIn, amountIn, tokenOut, amountOutMin, to, route);\n }\n\n /// @notice Processes the route generated off-chain\n /// @param tokenIn Address of the input token\n /// @param amountIn Amount of the input token\n /// @param tokenOut Address of the output token\n /// @param amountOutMin Minimum amount of the output token\n /// @return amountOut Actual amount of the output token\n function processRouteInternal(\n address tokenIn,\n uint256 amountIn,\n address tokenOut,\n uint256 amountOutMin,\n address to,\n bytes memory route\n ) private returns (uint256 amountOut) {\n uint256 balanceInInitial = tokenIn == NATIVE_ADDRESS ? address(this).balance : IERC20(tokenIn).balanceOf(msg.sender);\n uint256 balanceOutInitial = tokenOut == NATIVE_ADDRESS ? address(to).balance : IERC20(tokenOut).balanceOf(to);\n\n uint256 stream = InputStream.createStream(route);\n while (stream.isNotEmpty()) {\n uint8 commandCode = stream.readUint8();\n if (commandCode == 1) processMyERC20(stream);\n else if (commandCode == 2) processUserERC20(stream, amountIn);\n else if (commandCode == 3) processNative(stream);\n else if (commandCode == 4) processOnePool(stream);\n else if (commandCode == 5) processInsideBento(stream);\n else revert('RouteProcessor: Unknown command code');\n }\n\n uint256 balanceInFinal = tokenIn == NATIVE_ADDRESS ? address(this).balance : IERC20(tokenIn).balanceOf(msg.sender);\n require(balanceInFinal + amountIn >= balanceInInitial, 'RouteProcessor: Minimal imput balance violation');\n\n uint256 balanceOutFinal = tokenOut == NATIVE_ADDRESS ? address(to).balance : IERC20(tokenOut).balanceOf(to);\n require(balanceOutFinal >= balanceOutInitial + amountOutMin, 'RouteProcessor: Minimal ouput balance violation');\n\n amountOut = balanceOutFinal - balanceOutInitial;\n }\n\n /// @notice Processes native coin: call swap for all pools that swap from native coin\n /// @param stream Streamed process program\n function processNative(uint256 stream) private {\n uint256 amountTotal = address(this).balance;\n distributeAndSwap(stream, address(this), NATIVE_ADDRESS, amountTotal);\n }\n\n /// @notice Processes ERC20 token from this contract balance:\n /// @notice Call swap for all pools that swap from this token\n /// @param stream Streamed process program\n function processMyERC20(uint256 stream) private {\n address token = stream.readAddress();\n uint256 amountTotal = IERC20(token).balanceOf(address(this));\n unchecked {\n if (amountTotal > 0) amountTotal -= 1; // slot undrain protection\n }\n distributeAndSwap(stream, address(this), token, amountTotal);\n }\n \n /// @notice Processes ERC20 token from msg.sender balance:\n /// @notice Call swap for all pools that swap from this token\n /// @param stream Streamed process program\n /// @param amountTotal Amount of tokens to take from msg.sender\n function processUserERC20(uint256 stream, uint256 amountTotal) private {\n address token = stream.readAddress();\n distributeAndSwap(stream, msg.sender, token, amountTotal);\n }\n\n /// @notice Distributes amountTotal to several pools according to their shares and calls swap for each pool\n /// @param stream Streamed process program\n /// @param from Where to take liquidity for swap\n /// @param tokenIn Input token\n /// @param amountTotal Total amount of tokenIn for swaps \n function distributeAndSwap(uint256 stream, address from, address tokenIn, uint256 amountTotal) private {\n uint8 num = stream.readUint8();\n unchecked {\n for (uint256 i = 0; i < num; ++i) {\n uint16 share = stream.readUint16();\n uint256 amount = (amountTotal * share) / 65535;\n amountTotal -= amount;\n swap(stream, from, tokenIn, amount);\n }\n }\n }\n\n /// @notice Processes ERC20 token for cases when the token has only one output pool\n /// @notice In this case liquidity is already at pool balance. This is an optimization\n /// @notice Call swap for all pools that swap from this token\n /// @param stream Streamed process program\n function processOnePool(uint256 stream) private {\n address token = stream.readAddress();\n swap(stream, address(this), token, 0);\n }\n\n /// @notice Processes Bento tokens \n /// @notice Call swap for all pools that swap from this token\n /// @param stream Streamed process program\n function processInsideBento(uint256 stream) private {\n address token = stream.readAddress();\n uint8 num = stream.readUint8();\n\n uint256 amountTotal = bentoBox.balanceOf(token, address(this));\n unchecked {\n if (amountTotal > 0) amountTotal -= 1; // slot undrain protection\n for (uint256 i = 0; i < num; ++i) {\n uint16 share = stream.readUint16();\n uint256 amount = (amountTotal * share) / 65535;\n amountTotal -= amount;\n swap(stream, address(this), token, amount);\n }\n }\n }\n\n /// @notice Makes swap\n /// @param stream Streamed process program\n /// @param from Where to take liquidity for swap\n /// @param tokenIn Input token\n /// @param amountIn Amount of tokenIn to take for swap\n function swap(uint256 stream, address from, address tokenIn, uint256 amountIn) private {\n uint8 poolType = stream.readUint8();\n if (poolType == 0) swapUniV2(stream, from, tokenIn, amountIn);\n else if (poolType == 1) swapUniV3(stream, from, tokenIn, amountIn);\n else if (poolType == 2) wrapNative(stream, from, tokenIn, amountIn);\n else if (poolType == 3) bentoBridge(stream, from, tokenIn, amountIn);\n else if (poolType == 4) swapTrident(stream, from, tokenIn, amountIn);\n else if (poolType == 5) swapTridentCL(stream, from, tokenIn, amountIn);\n else revert('RouteProcessor: Unknown pool type');\n }\n\n /// @notice Wraps/unwraps native token\n /// @param stream [direction & fake, recipient, wrapToken?]\n /// @param from Where to take liquidity for swap\n /// @param tokenIn Input token\n /// @param amountIn Amount of tokenIn to take for swap\n function wrapNative(uint256 stream, address from, address tokenIn, uint256 amountIn) private {\n uint8 directionAndFake = stream.readUint8();\n address to = stream.readAddress();\n\n if (directionAndFake & 1 == 1) { // wrap native\n address wrapToken = stream.readAddress();\n if (directionAndFake & 2 == 0) IWETH(wrapToken).deposit{value: amountIn}();\n if (to != address(this)) IERC20(wrapToken).safeTransfer(to, amountIn);\n } else { // unwrap native\n if (directionAndFake & 2 == 0) {\n if (from != address(this)) IERC20(tokenIn).safeTransferFrom(from, address(this), amountIn);\n IWETH(tokenIn).withdraw(amountIn);\n }\n payable(to).transfer(address(this).balance);\n }\n }\n\n /// @notice Bridge/unbridge tokens to/from Bento\n /// @param stream [direction, recipient]\n /// @param from Where to take liquidity for swap\n /// @param tokenIn Input token\n /// @param amountIn Amount of tokenIn to take for swap\n function bentoBridge(uint256 stream, address from, address tokenIn, uint256 amountIn) private {\n uint8 direction = stream.readUint8();\n address to = stream.readAddress();\n\n if (direction > 0) { // outside to Bento\n // deposit to arbitrary recipient is possible only from address(bentoBox)\n if (amountIn != 0) {\n if (from == address(this)) IERC20(tokenIn).safeTransfer(address(bentoBox), amountIn);\n else IERC20(tokenIn).safeTransferFrom(from, address(bentoBox), amountIn);\n } else {\n // tokens already are at address(bentoBox)\n amountIn = IERC20(tokenIn).balanceOf(address(bentoBox)) +\n bentoBox.strategyData(tokenIn).balance -\n bentoBox.totals(tokenIn).elastic;\n }\n bentoBox.deposit(tokenIn, address(bentoBox), to, amountIn, 0);\n } else { // Bento to outside\n if (amountIn > 0) {\n bentoBox.transfer(tokenIn, from, address(this), amountIn);\n } else amountIn = bentoBox.balanceOf(tokenIn, address(this));\n bentoBox.withdraw(tokenIn, address(this), to, 0, amountIn);\n }\n }\n\n /// @notice UniswapV2 pool swap\n /// @param stream [pool, direction, recipient]\n /// @param from Where to take liquidity for swap\n /// @param tokenIn Input token\n /// @param amountIn Amount of tokenIn to take for swap\n function swapUniV2(uint256 stream, address from, address tokenIn, uint256 amountIn) private {\n address pool = stream.readAddress();\n uint8 direction = stream.readUint8();\n address to = stream.readAddress();\n\n (uint256 r0, uint256 r1, ) = IUniswapV2Pair(pool).getReserves();\n require(r0 > 0 && r1 > 0, 'Wrong pool reserves');\n (uint256 reserveIn, uint256 reserveOut) = direction == 1 ? (r0, r1) : (r1, r0);\n\n if (amountIn != 0) {\n if (from == address(this)) IERC20(tokenIn).safeTransfer(pool, amountIn);\n else IERC20(tokenIn).safeTransferFrom(from, pool, amountIn);\n } else amountIn = IERC20(tokenIn).balanceOf(pool) - reserveIn; // tokens already were transferred\n\n uint256 amountInWithFee = amountIn * 997;\n uint256 amountOut = (amountInWithFee * reserveOut) / (reserveIn * 1000 + amountInWithFee);\n (uint256 amount0Out, uint256 amount1Out) = direction == 1 ? (uint256(0), amountOut) : (amountOut, uint256(0));\n IUniswapV2Pair(pool).swap(amount0Out, amount1Out, to, new bytes(0));\n }\n\n /// @notice Trident pool swap\n /// @param stream [pool, swapData]\n /// @param from Where to take liquidity for swap\n /// @param tokenIn Input token\n /// @param amountIn Amount of tokenIn to take for swap\n function swapTrident(uint256 stream, address from, address tokenIn, uint256 amountIn) private {\n address pool = stream.readAddress();\n bytes memory swapData = stream.readBytes();\n\n if (amountIn != 0) {\n bentoBox.transfer(tokenIn, from, pool, amountIn);\n }\n \n IPool(pool).swap(swapData);\n }\n\n /// @notice UniswapV3 pool swap\n /// @param stream [pool, direction, recipient]\n /// @param from Where to take liquidity for swap\n /// @param tokenIn Input token\n /// @param amountIn Amount of tokenIn to take for swap\n function swapUniV3(uint256 stream, address from, address tokenIn, uint256 amountIn) private {\n address pool = stream.readAddress();\n bool zeroForOne = stream.readUint8() > 0;\n address recipient = stream.readAddress();\n\n lastCalledPool = pool;\n IUniswapV3Pool(pool).swap(\n recipient,\n zeroForOne,\n int256(amountIn),\n zeroForOne ? MIN_SQRT_RATIO + 1 : MAX_SQRT_RATIO - 1,\n abi.encode(tokenIn, from)\n );\n require(lastCalledPool == IMPOSSIBLE_POOL_ADDRESS, 'RouteProcessor.swapUniV3: unexpected'); // Just to be sure\n }\n\n /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap.\n /// @dev In the implementation you must pay the pool tokens owed for the swap.\n /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory.\n /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped.\n /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by\n /// the end of the swap. If positive, the callback must send that amount of token0 to the pool.\n /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by\n /// the end of the swap. If positive, the callback must send that amount of token1 to the pool.\n /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call\n function uniswapV3SwapCallback(\n int256 amount0Delta,\n int256 amount1Delta,\n bytes calldata data\n ) external {\n require(msg.sender == lastCalledPool, 'RouteProcessor.uniswapV3SwapCallback: call from unknown source');\n lastCalledPool = IMPOSSIBLE_POOL_ADDRESS;\n (address tokenIn, address from) = abi.decode(data, (address, address));\n int256 amount = amount0Delta > 0 ? amount0Delta : amount1Delta;\n require(amount > 0, 'RouteProcessor.uniswapV3SwapCallback: not positive amount');\n\n if (from == address(this)) IERC20(tokenIn).safeTransfer(msg.sender, uint256(amount));\n else IERC20(tokenIn).safeTransferFrom(from, msg.sender, uint256(amount));\n }\n\n /// @notice TridentCL pool swap\n /// @param stream [pool, direction, recipient]\n /// @param from Where to take liquidity for swap\n /// @param tokenIn Input token\n /// @param amountIn Amount of tokenIn to take for swap\n function swapTridentCL(uint256 stream, address from, address tokenIn, uint256 amountIn) private {\n address pool = stream.readAddress();\n bool zeroForOne = stream.readUint8() > 0;\n address recipient = stream.readAddress();\n\n lastCalledPool = pool;\n ITridentCLPool(pool).swap(\n recipient,\n zeroForOne,\n int256(amountIn),\n zeroForOne ? MIN_SQRT_RATIO + 1 : MAX_SQRT_RATIO - 1,\n false,\n abi.encode(tokenIn, from)\n );\n require(lastCalledPool == IMPOSSIBLE_POOL_ADDRESS, 'RouteProcessor.swapTridentCL: unexpected'); // Just to be sure\n }\n\n /// @notice Called to `msg.sender` after executing a swap via ITridentCLPool#swap.\n /// @dev In the implementation you must pay the pool tokens owed for the swap.\n /// The caller of this method must be checked to be a TridentCLPool deployed by the canonical TridentCLFactory.\n /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped.\n /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by\n /// the end of the swap. If positive, the callback must send that amount of token0 to the pool.\n /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by\n /// the end of the swap. If positive, the callback must send that amount of token1 to the pool.\n /// @param data Any data passed through by the caller via the ITridentCLPoolActions#swap call\n function tridentCLSwapCallback(\n int256 amount0Delta,\n int256 amount1Delta,\n bytes calldata data\n ) external {\n require(msg.sender == lastCalledPool, 'RouteProcessor.TridentCLSwapCallback: call from unknown source');\n lastCalledPool = IMPOSSIBLE_POOL_ADDRESS;\n (address tokenIn, address from) = abi.decode(data, (address, address));\n int256 amount = amount0Delta > 0 ? amount0Delta : amount1Delta;\n require(amount > 0, 'RouteProcessor.TridentCLSwapCallback: not positive amount');\n\n if (from == address(this)) IERC20(tokenIn).safeTransfer(msg.sender, uint256(amount));\n else IERC20(tokenIn).safeTransferFrom(from, msg.sender, uint256(amount));\n }\n}\n" - }, - "interfaces/ITridentCLPool.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n\npragma solidity 0.8.10;\n\ninterface ITridentCLPool {\n function token0() external returns (address);\n function token1() external returns (address);\n\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bool unwrapBento,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" - }, - "interfaces/IUniswapV2Pair.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.5.0;\n\ninterface IUniswapV2Pair {\n event Approval(address indexed owner, address indexed spender, uint value);\n event Transfer(address indexed from, address indexed to, uint value);\n\n function name() external pure returns (string memory);\n function symbol() external pure returns (string memory);\n function decimals() external pure returns (uint8);\n function totalSupply() external view returns (uint);\n function balanceOf(address owner) external view returns (uint);\n function allowance(address owner, address spender) external view returns (uint);\n\n function approve(address spender, uint value) external returns (bool);\n function transfer(address to, uint value) external returns (bool);\n function transferFrom(address from, address to, uint value) external returns (bool);\n\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n function PERMIT_TYPEHASH() external pure returns (bytes32);\n function nonces(address owner) external view returns (uint);\n\n function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;\n\n event Mint(address indexed sender, uint amount0, uint amount1);\n event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);\n event Swap(\n address indexed sender,\n uint amount0In,\n uint amount1In,\n uint amount0Out,\n uint amount1Out,\n address indexed to\n );\n event Sync(uint112 reserve0, uint112 reserve1);\n\n function MINIMUM_LIQUIDITY() external pure returns (uint);\n function factory() external view returns (address);\n function token0() external view returns (address);\n function token1() external view returns (address);\n function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n function price0CumulativeLast() external view returns (uint);\n function price1CumulativeLast() external view returns (uint);\n function kLast() external view returns (uint);\n\n function mint(address to) external returns (uint liquidity);\n function burn(address to) external returns (uint amount0, uint amount1);\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\n function skim(address to) external;\n function sync() external;\n\n function initialize(address, address) external;\n}" - }, - "interfaces/IUniswapV3Pool.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n\npragma solidity 0.8.10;\n\ninterface IUniswapV3Pool {\n function token0() external returns (address);\n function token1() external returns (address);\n\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n}\n" - }, - "interfaces/IWETH.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n\npragma solidity 0.8.10;\n\ninterface IWETH {\n function deposit() external payable;\n\n function transfer(address to, uint256 value) external returns (bool);\n\n function withdraw(uint256) external;\n}\n" - } - }, - "settings": { - "optimizer": { - "enabled": true, - "runs": 10000000 - }, - "outputSelection": { - "*": { - "*": [ - "evm.bytecode", - "evm.deployedBytecode", - "devdoc", - "userdoc", - "metadata", - "abi" - ] - } - }, - "metadata": { - "useLiteralContent": true - }, - "libraries": {} - } - }, - "ABI": "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bentoBox\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"bentoBox\",\"outputs\":[{\"internalType\":\"contract IBentoBoxMinimal\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountOutMin\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"route\",\"type\":\"bytes\"}],\"name\":\"processRoute\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"transferValueTo\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountValueTransfer\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountOutMin\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"route\",\"type\":\"bytes\"}],\"name\":\"transferValueAndprocessRoute\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"amount0Delta\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"amount1Delta\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"tridentCLSwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"amount0Delta\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"amount1Delta\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"uniswapV3SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", - "ContractName": "RouteProcessor2", - "CompilerVersion": "v0.8.10+commit.fc410830", - "OptimizationUsed": 1, - "Runs": 10000000, - "ConstructorArguments": "0x000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd643966", - "EVMVersion": "Default", - "Library": "", - "LicenseType": "", - "Proxy": 0, - "SwarmSource": "" - } -] \ No newline at end of file +[{"SourceCode":{"language":"Solidity","sources":{"contracts/InputStream.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\n\npragma solidity 0.8.10;\n\nlibrary InputStream {\n function createStream(bytes memory data) internal pure returns (uint256 stream) {\n assembly {\n stream := mload(0x40)\n mstore(0x40, add(stream, 64))\n mstore(stream, data)\n let length := mload(data)\n mstore(add(stream, 32), add(data, length))\n }\n }\n\n function isNotEmpty(uint256 stream) internal pure returns (bool) {\n uint256 pos;\n uint256 finish;\n assembly {\n pos := mload(stream)\n finish := mload(add(stream, 32))\n }\n return pos < finish;\n }\n\n function readUint8(uint256 stream) internal pure returns (uint8 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 1)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint16(uint256 stream) internal pure returns (uint16 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 2)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint32(uint256 stream) internal pure returns (uint32 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 4)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint(uint256 stream) internal pure returns (uint256 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 32)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readAddress(uint256 stream) internal pure returns (address res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 20)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readBytes(uint256 stream) internal pure returns (bytes memory res) {\n assembly {\n let pos := mload(stream)\n res := add(pos, 32)\n let length := mload(res)\n mstore(stream, add(res, length))\n }\n }\n}\n"},"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.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 function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\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"},"interfaces/IBentoBoxMinimal.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\n\npragma solidity >=0.8.0;\n\nstruct Rebase {\n uint128 elastic;\n uint128 base;\n}\n\nstruct StrategyData {\n uint64 strategyStartDate;\n uint64 targetPercentage;\n uint128 balance; // the balance of the strategy that BentoBox thinks is in there\n}\n\n/// @notice A rebasing library\nlibrary RebaseLibrary {\n /// @notice Calculates the base value in relationship to `elastic` and `total`.\n function toBase(Rebase memory total, uint256 elastic) internal pure returns (uint256 base) {\n if (total.elastic == 0) {\n base = elastic;\n } else {\n base = (elastic * total.base) / total.elastic;\n }\n }\n\n /// @notice Calculates the elastic value in relationship to `base` and `total`.\n function toElastic(Rebase memory total, uint256 base) internal pure returns (uint256 elastic) {\n if (total.base == 0) {\n elastic = base;\n } else {\n elastic = (base * total.elastic) / total.base;\n }\n }\n}\n\n/// @notice Minimal BentoBox vault interface.\n/// @dev `token` is aliased as `address` from `IERC20` for simplicity.\ninterface IBentoBoxMinimal {\n /// @notice Balance per ERC-20 token per account in shares.\n function balanceOf(address, address) external view returns (uint256);\n\n /// @dev Helper function to represent an `amount` of `token` in shares.\n /// @param token The ERC-20 token.\n /// @param amount The `token` amount.\n /// @param roundUp If the result `share` should be rounded up.\n /// @return share The token amount represented in shares.\n function toShare(\n address token,\n uint256 amount,\n bool roundUp\n ) external view returns (uint256 share);\n\n /// @dev Helper function to represent shares back into the `token` amount.\n /// @param token The ERC-20 token.\n /// @param share The amount of shares.\n /// @param roundUp If the result should be rounded up.\n /// @return amount The share amount back into native representation.\n function toAmount(\n address token,\n uint256 share,\n bool roundUp\n ) external view returns (uint256 amount);\n\n /// @notice Registers this contract so that users can approve it for BentoBox.\n function registerProtocol() external;\n\n /// @notice Deposit an amount of `token` represented in either `amount` or `share`.\n /// @param token The ERC-20 token to deposit.\n /// @param from which account to pull the tokens.\n /// @param to which account to push the tokens.\n /// @param amount Token amount in native representation to deposit.\n /// @param share Token amount represented in shares to deposit. Takes precedence over `amount`.\n /// @return amountOut The amount deposited.\n /// @return shareOut The deposited amount represented in shares.\n function deposit(\n address token,\n address from,\n address to,\n uint256 amount,\n uint256 share\n ) external payable returns (uint256 amountOut, uint256 shareOut);\n\n /// @notice Withdraws an amount of `token` from a user account.\n /// @param token_ The ERC-20 token to withdraw.\n /// @param from which user to pull the tokens.\n /// @param to which user to push the tokens.\n /// @param amount of tokens. Either one of `amount` or `share` needs to be supplied.\n /// @param share Like above, but `share` takes precedence over `amount`.\n function withdraw(\n address token_,\n address from,\n address to,\n uint256 amount,\n uint256 share\n ) external returns (uint256 amountOut, uint256 shareOut);\n\n /// @notice Transfer shares from a user account to another one.\n /// @param token The ERC-20 token to transfer.\n /// @param from which user to pull the tokens.\n /// @param to which user to push the tokens.\n /// @param share The amount of `token` in shares.\n function transfer(\n address token,\n address from,\n address to,\n uint256 share\n ) external;\n\n /// @dev Reads the Rebase `totals`from storage for a given token\n function totals(address token) external view returns (Rebase memory total);\n\n function strategyData(address token) external view returns (StrategyData memory total);\n\n /// @dev Approves users' BentoBox assets to a \"master\" contract.\n function setMasterContractApproval(\n address user,\n address masterContract,\n bool approved,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n function harvest(\n address token,\n bool balance,\n uint256 maxChangeAmount\n ) external;\n}\n"},"@openzeppelin/contracts/utils/Address.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.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 functionCallWithValue(target, data, 0, \"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 (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, 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 (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, 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 (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or 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 _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\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 /// @solidity memory-safe-assembly\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"},"interfaces/IPool.sol":{"content":"// SPDX-License-Identifier: GPL-3.0-or-later\n\npragma solidity >=0.5.0;\npragma experimental ABIEncoderV2;\n\n/// @notice Trident pool interface.\ninterface IPool {\n /// @notice Executes a swap from one token to another.\n /// @dev The input tokens must've already been sent to the pool.\n /// @param data ABI-encoded params that the pool requires.\n /// @return finalAmountOut The amount of output tokens that were sent to the user.\n function swap(bytes calldata data) external returns (uint256 finalAmountOut);\n\n /// @notice Executes a swap from one token to another with a callback.\n /// @dev This function allows borrowing the output tokens and sending the input tokens in the callback.\n /// @param data ABI-encoded params that the pool requires.\n /// @return finalAmountOut The amount of output tokens that were sent to the user.\n function flashSwap(bytes calldata data) external returns (uint256 finalAmountOut);\n\n /// @notice Mints liquidity tokens.\n /// @param data ABI-encoded params that the pool requires.\n /// @return liquidity The amount of liquidity tokens that were minted for the user.\n function mint(bytes calldata data) external returns (uint256 liquidity);\n\n /// @notice Burns liquidity tokens.\n /// @dev The input LP tokens must've already been sent to the pool.\n /// @param data ABI-encoded params that the pool requires.\n /// @return withdrawnAmounts The amount of various output tokens that were sent to the user.\n function burn(bytes calldata data) external returns (TokenAmount[] memory withdrawnAmounts);\n\n /// @notice Burns liquidity tokens for a single output token.\n /// @dev The input LP tokens must've already been sent to the pool.\n /// @param data ABI-encoded params that the pool requires.\n /// @return amountOut The amount of output tokens that were sent to the user.\n function burnSingle(bytes calldata data) external returns (uint256 amountOut);\n\n /// @return A unique identifier for the pool type.\n function poolIdentifier() external pure returns (bytes32);\n\n /// @return An array of tokens supported by the pool.\n function getAssets() external view returns (address[] memory);\n\n /// @notice Simulates a trade and returns the expected output.\n /// @dev The pool does not need to include a trade simulator directly in itself - it can use a library.\n /// @param data ABI-encoded params that the pool requires.\n /// @return finalAmountOut The amount of output tokens that will be sent to the user if the trade is executed.\n function getAmountOut(bytes calldata data) external view returns (uint256 finalAmountOut);\n\n /// @notice Simulates a trade and returns the expected output.\n /// @dev The pool does not need to include a trade simulator directly in itself - it can use a library.\n /// @param data ABI-encoded params that the pool requires.\n /// @return finalAmountIn The amount of input tokens that are required from the user if the trade is executed.\n function getAmountIn(bytes calldata data) external view returns (uint256 finalAmountIn);\n\n /// @dev This event must be emitted on all swaps.\n event Swap(address indexed recipient, address indexed tokenIn, address indexed tokenOut, uint256 amountIn, uint256 amountOut);\n\n /// @dev This struct frames output tokens for burns.\n struct TokenAmount {\n address token;\n uint256 amount;\n }\n}\n"},"@openzeppelin/contracts/token/ERC20/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.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 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 /**\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"},"contracts/RouteProcessor2.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\n\npragma solidity 0.8.10;\n\nimport '../interfaces/IUniswapV2Pair.sol';\nimport '../interfaces/IUniswapV3Pool.sol';\nimport '../interfaces/ITridentCLPool.sol';\nimport '../interfaces/IBentoBoxMinimal.sol';\nimport '../interfaces/IPool.sol';\nimport '../interfaces/IWETH.sol';\nimport './InputStream.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\naddress constant NATIVE_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\naddress constant IMPOSSIBLE_POOL_ADDRESS = 0x0000000000000000000000000000000000000001;\n\n/// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\nuint160 constant MIN_SQRT_RATIO = 4295128739;\n/// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\nuint160 constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\n\n/// @title A route processor for the Sushi Aggregator\n/// @author Ilya Lyalin\ncontract RouteProcessor2 {\n using SafeERC20 for IERC20;\n using InputStream for uint256;\n\n IBentoBoxMinimal public immutable bentoBox;\n address private lastCalledPool;\n\n uint private unlocked = 1;\n modifier lock() {\n require(unlocked == 1, 'RouteProcessor is locked');\n unlocked = 2;\n _;\n unlocked = 1;\n }\n\n constructor(address _bentoBox) {\n bentoBox = IBentoBoxMinimal(_bentoBox);\n lastCalledPool = IMPOSSIBLE_POOL_ADDRESS;\n }\n\n /// @notice For native unwrapping\n receive() external payable {}\n\n /// @notice Processes the route generated off-chain. Has a lock\n /// @param tokenIn Address of the input token\n /// @param amountIn Amount of the input token\n /// @param tokenOut Address of the output token\n /// @param amountOutMin Minimum amount of the output token\n /// @return amountOut Actual amount of the output token\n function processRoute(\n address tokenIn,\n uint256 amountIn,\n address tokenOut,\n uint256 amountOutMin,\n address to,\n bytes memory route\n ) external payable lock returns (uint256 amountOut) {\n return processRouteInternal(tokenIn, amountIn, tokenOut, amountOutMin, to, route);\n }\n\n /// @notice Transfers some value to and then processes the route\n /// @param transferValueTo Address where the value should be transferred\n /// @param amountValueTransfer How much value to transfer\n /// @param tokenIn Address of the input token\n /// @param amountIn Amount of the input token\n /// @param tokenOut Address of the output token\n /// @param amountOutMin Minimum amount of the output token\n /// @return amountOut Actual amount of the output token\n function transferValueAndprocessRoute(\n address payable transferValueTo,\n uint256 amountValueTransfer,\n address tokenIn,\n uint256 amountIn,\n address tokenOut,\n uint256 amountOutMin,\n address to,\n bytes memory route\n ) external payable lock returns (uint256 amountOut) {\n (bool success, bytes memory returnBytes) = transferValueTo.call{value: amountValueTransfer}('');\n require(success, string(abi.encodePacked(returnBytes)));\n return processRouteInternal(tokenIn, amountIn, tokenOut, amountOutMin, to, route);\n }\n\n /// @notice Processes the route generated off-chain\n /// @param tokenIn Address of the input token\n /// @param amountIn Amount of the input token\n /// @param tokenOut Address of the output token\n /// @param amountOutMin Minimum amount of the output token\n /// @return amountOut Actual amount of the output token\n function processRouteInternal(\n address tokenIn,\n uint256 amountIn,\n address tokenOut,\n uint256 amountOutMin,\n address to,\n bytes memory route\n ) private returns (uint256 amountOut) {\n uint256 balanceInInitial = tokenIn == NATIVE_ADDRESS ? address(this).balance : IERC20(tokenIn).balanceOf(msg.sender);\n uint256 balanceOutInitial = tokenOut == NATIVE_ADDRESS ? address(to).balance : IERC20(tokenOut).balanceOf(to);\n\n uint256 stream = InputStream.createStream(route);\n while (stream.isNotEmpty()) {\n uint8 commandCode = stream.readUint8();\n if (commandCode == 1) processMyERC20(stream);\n else if (commandCode == 2) processUserERC20(stream, amountIn);\n else if (commandCode == 3) processNative(stream);\n else if (commandCode == 4) processOnePool(stream);\n else if (commandCode == 5) processInsideBento(stream);\n else revert('RouteProcessor: Unknown command code');\n }\n\n uint256 balanceInFinal = tokenIn == NATIVE_ADDRESS ? address(this).balance : IERC20(tokenIn).balanceOf(msg.sender);\n require(balanceInFinal + amountIn >= balanceInInitial, 'RouteProcessor: Minimal imput balance violation');\n\n uint256 balanceOutFinal = tokenOut == NATIVE_ADDRESS ? address(to).balance : IERC20(tokenOut).balanceOf(to);\n require(balanceOutFinal >= balanceOutInitial + amountOutMin, 'RouteProcessor: Minimal ouput balance violation');\n\n amountOut = balanceOutFinal - balanceOutInitial;\n }\n\n /// @notice Processes native coin: call swap for all pools that swap from native coin\n /// @param stream Streamed process program\n function processNative(uint256 stream) private {\n uint256 amountTotal = address(this).balance;\n distributeAndSwap(stream, address(this), NATIVE_ADDRESS, amountTotal);\n }\n\n /// @notice Processes ERC20 token from this contract balance:\n /// @notice Call swap for all pools that swap from this token\n /// @param stream Streamed process program\n function processMyERC20(uint256 stream) private {\n address token = stream.readAddress();\n uint256 amountTotal = IERC20(token).balanceOf(address(this));\n unchecked {\n if (amountTotal > 0) amountTotal -= 1; // slot undrain protection\n }\n distributeAndSwap(stream, address(this), token, amountTotal);\n }\n \n /// @notice Processes ERC20 token from msg.sender balance:\n /// @notice Call swap for all pools that swap from this token\n /// @param stream Streamed process program\n /// @param amountTotal Amount of tokens to take from msg.sender\n function processUserERC20(uint256 stream, uint256 amountTotal) private {\n address token = stream.readAddress();\n distributeAndSwap(stream, msg.sender, token, amountTotal);\n }\n\n /// @notice Distributes amountTotal to several pools according to their shares and calls swap for each pool\n /// @param stream Streamed process program\n /// @param from Where to take liquidity for swap\n /// @param tokenIn Input token\n /// @param amountTotal Total amount of tokenIn for swaps \n function distributeAndSwap(uint256 stream, address from, address tokenIn, uint256 amountTotal) private {\n uint8 num = stream.readUint8();\n unchecked {\n for (uint256 i = 0; i < num; ++i) {\n uint16 share = stream.readUint16();\n uint256 amount = (amountTotal * share) / 65535;\n amountTotal -= amount;\n swap(stream, from, tokenIn, amount);\n }\n }\n }\n\n /// @notice Processes ERC20 token for cases when the token has only one output pool\n /// @notice In this case liquidity is already at pool balance. This is an optimization\n /// @notice Call swap for all pools that swap from this token\n /// @param stream Streamed process program\n function processOnePool(uint256 stream) private {\n address token = stream.readAddress();\n swap(stream, address(this), token, 0);\n }\n\n /// @notice Processes Bento tokens \n /// @notice Call swap for all pools that swap from this token\n /// @param stream Streamed process program\n function processInsideBento(uint256 stream) private {\n address token = stream.readAddress();\n uint8 num = stream.readUint8();\n\n uint256 amountTotal = bentoBox.balanceOf(token, address(this));\n unchecked {\n if (amountTotal > 0) amountTotal -= 1; // slot undrain protection\n for (uint256 i = 0; i < num; ++i) {\n uint16 share = stream.readUint16();\n uint256 amount = (amountTotal * share) / 65535;\n amountTotal -= amount;\n swap(stream, address(this), token, amount);\n }\n }\n }\n\n /// @notice Makes swap\n /// @param stream Streamed process program\n /// @param from Where to take liquidity for swap\n /// @param tokenIn Input token\n /// @param amountIn Amount of tokenIn to take for swap\n function swap(uint256 stream, address from, address tokenIn, uint256 amountIn) private {\n uint8 poolType = stream.readUint8();\n if (poolType == 0) swapUniV2(stream, from, tokenIn, amountIn);\n else if (poolType == 1) swapUniV3(stream, from, tokenIn, amountIn);\n else if (poolType == 2) wrapNative(stream, from, tokenIn, amountIn);\n else if (poolType == 3) bentoBridge(stream, from, tokenIn, amountIn);\n else if (poolType == 4) swapTrident(stream, from, tokenIn, amountIn);\n else if (poolType == 5) swapTridentCL(stream, from, tokenIn, amountIn);\n else revert('RouteProcessor: Unknown pool type');\n }\n\n /// @notice Wraps/unwraps native token\n /// @param stream [direction & fake, recipient, wrapToken?]\n /// @param from Where to take liquidity for swap\n /// @param tokenIn Input token\n /// @param amountIn Amount of tokenIn to take for swap\n function wrapNative(uint256 stream, address from, address tokenIn, uint256 amountIn) private {\n uint8 directionAndFake = stream.readUint8();\n address to = stream.readAddress();\n\n if (directionAndFake & 1 == 1) { // wrap native\n address wrapToken = stream.readAddress();\n if (directionAndFake & 2 == 0) IWETH(wrapToken).deposit{value: amountIn}();\n if (to != address(this)) IERC20(wrapToken).safeTransfer(to, amountIn);\n } else { // unwrap native\n if (directionAndFake & 2 == 0) {\n if (from != address(this)) IERC20(tokenIn).safeTransferFrom(from, address(this), amountIn);\n IWETH(tokenIn).withdraw(amountIn);\n }\n payable(to).transfer(address(this).balance);\n }\n }\n\n /// @notice Bridge/unbridge tokens to/from Bento\n /// @param stream [direction, recipient]\n /// @param from Where to take liquidity for swap\n /// @param tokenIn Input token\n /// @param amountIn Amount of tokenIn to take for swap\n function bentoBridge(uint256 stream, address from, address tokenIn, uint256 amountIn) private {\n uint8 direction = stream.readUint8();\n address to = stream.readAddress();\n\n if (direction > 0) { // outside to Bento\n // deposit to arbitrary recipient is possible only from address(bentoBox)\n if (amountIn != 0) {\n if (from == address(this)) IERC20(tokenIn).safeTransfer(address(bentoBox), amountIn);\n else IERC20(tokenIn).safeTransferFrom(from, address(bentoBox), amountIn);\n } else {\n // tokens already are at address(bentoBox)\n amountIn = IERC20(tokenIn).balanceOf(address(bentoBox)) +\n bentoBox.strategyData(tokenIn).balance -\n bentoBox.totals(tokenIn).elastic;\n }\n bentoBox.deposit(tokenIn, address(bentoBox), to, amountIn, 0);\n } else { // Bento to outside\n if (amountIn > 0) {\n bentoBox.transfer(tokenIn, from, address(this), amountIn);\n } else amountIn = bentoBox.balanceOf(tokenIn, address(this));\n bentoBox.withdraw(tokenIn, address(this), to, 0, amountIn);\n }\n }\n\n /// @notice UniswapV2 pool swap\n /// @param stream [pool, direction, recipient]\n /// @param from Where to take liquidity for swap\n /// @param tokenIn Input token\n /// @param amountIn Amount of tokenIn to take for swap\n function swapUniV2(uint256 stream, address from, address tokenIn, uint256 amountIn) private {\n address pool = stream.readAddress();\n uint8 direction = stream.readUint8();\n address to = stream.readAddress();\n\n (uint256 r0, uint256 r1, ) = IUniswapV2Pair(pool).getReserves();\n require(r0 > 0 && r1 > 0, 'Wrong pool reserves');\n (uint256 reserveIn, uint256 reserveOut) = direction == 1 ? (r0, r1) : (r1, r0);\n\n if (amountIn != 0) {\n if (from == address(this)) IERC20(tokenIn).safeTransfer(pool, amountIn);\n else IERC20(tokenIn).safeTransferFrom(from, pool, amountIn);\n } else amountIn = IERC20(tokenIn).balanceOf(pool) - reserveIn; // tokens already were transferred\n\n uint256 amountInWithFee = amountIn * 997;\n uint256 amountOut = (amountInWithFee * reserveOut) / (reserveIn * 1000 + amountInWithFee);\n (uint256 amount0Out, uint256 amount1Out) = direction == 1 ? (uint256(0), amountOut) : (amountOut, uint256(0));\n IUniswapV2Pair(pool).swap(amount0Out, amount1Out, to, new bytes(0));\n }\n\n /// @notice Trident pool swap\n /// @param stream [pool, swapData]\n /// @param from Where to take liquidity for swap\n /// @param tokenIn Input token\n /// @param amountIn Amount of tokenIn to take for swap\n function swapTrident(uint256 stream, address from, address tokenIn, uint256 amountIn) private {\n address pool = stream.readAddress();\n bytes memory swapData = stream.readBytes();\n\n if (amountIn != 0) {\n bentoBox.transfer(tokenIn, from, pool, amountIn);\n }\n \n IPool(pool).swap(swapData);\n }\n\n /// @notice UniswapV3 pool swap\n /// @param stream [pool, direction, recipient]\n /// @param from Where to take liquidity for swap\n /// @param tokenIn Input token\n /// @param amountIn Amount of tokenIn to take for swap\n function swapUniV3(uint256 stream, address from, address tokenIn, uint256 amountIn) private {\n address pool = stream.readAddress();\n bool zeroForOne = stream.readUint8() > 0;\n address recipient = stream.readAddress();\n\n lastCalledPool = pool;\n IUniswapV3Pool(pool).swap(\n recipient,\n zeroForOne,\n int256(amountIn),\n zeroForOne ? MIN_SQRT_RATIO + 1 : MAX_SQRT_RATIO - 1,\n abi.encode(tokenIn, from)\n );\n require(lastCalledPool == IMPOSSIBLE_POOL_ADDRESS, 'RouteProcessor.swapUniV3: unexpected'); // Just to be sure\n }\n\n /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap.\n /// @dev In the implementation you must pay the pool tokens owed for the swap.\n /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory.\n /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped.\n /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by\n /// the end of the swap. If positive, the callback must send that amount of token0 to the pool.\n /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by\n /// the end of the swap. If positive, the callback must send that amount of token1 to the pool.\n /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call\n function uniswapV3SwapCallback(\n int256 amount0Delta,\n int256 amount1Delta,\n bytes calldata data\n ) external {\n require(msg.sender == lastCalledPool, 'RouteProcessor.uniswapV3SwapCallback: call from unknown source');\n lastCalledPool = IMPOSSIBLE_POOL_ADDRESS;\n (address tokenIn, address from) = abi.decode(data, (address, address));\n int256 amount = amount0Delta > 0 ? amount0Delta : amount1Delta;\n require(amount > 0, 'RouteProcessor.uniswapV3SwapCallback: not positive amount');\n\n if (from == address(this)) IERC20(tokenIn).safeTransfer(msg.sender, uint256(amount));\n else IERC20(tokenIn).safeTransferFrom(from, msg.sender, uint256(amount));\n }\n\n /// @notice TridentCL pool swap\n /// @param stream [pool, direction, recipient]\n /// @param from Where to take liquidity for swap\n /// @param tokenIn Input token\n /// @param amountIn Amount of tokenIn to take for swap\n function swapTridentCL(uint256 stream, address from, address tokenIn, uint256 amountIn) private {\n address pool = stream.readAddress();\n bool zeroForOne = stream.readUint8() > 0;\n address recipient = stream.readAddress();\n\n lastCalledPool = pool;\n ITridentCLPool(pool).swap(\n recipient,\n zeroForOne,\n int256(amountIn),\n zeroForOne ? MIN_SQRT_RATIO + 1 : MAX_SQRT_RATIO - 1,\n false,\n abi.encode(tokenIn, from)\n );\n require(lastCalledPool == IMPOSSIBLE_POOL_ADDRESS, 'RouteProcessor.swapTridentCL: unexpected'); // Just to be sure\n }\n\n /// @notice Called to `msg.sender` after executing a swap via ITridentCLPool#swap.\n /// @dev In the implementation you must pay the pool tokens owed for the swap.\n /// The caller of this method must be checked to be a TridentCLPool deployed by the canonical TridentCLFactory.\n /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped.\n /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by\n /// the end of the swap. If positive, the callback must send that amount of token0 to the pool.\n /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by\n /// the end of the swap. If positive, the callback must send that amount of token1 to the pool.\n /// @param data Any data passed through by the caller via the ITridentCLPoolActions#swap call\n function tridentCLSwapCallback(\n int256 amount0Delta,\n int256 amount1Delta,\n bytes calldata data\n ) external {\n require(msg.sender == lastCalledPool, 'RouteProcessor.TridentCLSwapCallback: call from unknown source');\n lastCalledPool = IMPOSSIBLE_POOL_ADDRESS;\n (address tokenIn, address from) = abi.decode(data, (address, address));\n int256 amount = amount0Delta > 0 ? amount0Delta : amount1Delta;\n require(amount > 0, 'RouteProcessor.TridentCLSwapCallback: not positive amount');\n\n if (from == address(this)) IERC20(tokenIn).safeTransfer(msg.sender, uint256(amount));\n else IERC20(tokenIn).safeTransferFrom(from, msg.sender, uint256(amount));\n }\n}\n"},"interfaces/ITridentCLPool.sol":{"content":"// SPDX-License-Identifier: GPL-3.0-or-later\n\npragma solidity 0.8.10;\n\ninterface ITridentCLPool {\n function token0() external returns (address);\n function token1() external returns (address);\n\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bool unwrapBento,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n}\n"},"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n"},"interfaces/IUniswapV2Pair.sol":{"content":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.5.0;\n\ninterface IUniswapV2Pair {\n event Approval(address indexed owner, address indexed spender, uint value);\n event Transfer(address indexed from, address indexed to, uint value);\n\n function name() external pure returns (string memory);\n function symbol() external pure returns (string memory);\n function decimals() external pure returns (uint8);\n function totalSupply() external view returns (uint);\n function balanceOf(address owner) external view returns (uint);\n function allowance(address owner, address spender) external view returns (uint);\n\n function approve(address spender, uint value) external returns (bool);\n function transfer(address to, uint value) external returns (bool);\n function transferFrom(address from, address to, uint value) external returns (bool);\n\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n function PERMIT_TYPEHASH() external pure returns (bytes32);\n function nonces(address owner) external view returns (uint);\n\n function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;\n\n event Mint(address indexed sender, uint amount0, uint amount1);\n event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);\n event Swap(\n address indexed sender,\n uint amount0In,\n uint amount1In,\n uint amount0Out,\n uint amount1Out,\n address indexed to\n );\n event Sync(uint112 reserve0, uint112 reserve1);\n\n function MINIMUM_LIQUIDITY() external pure returns (uint);\n function factory() external view returns (address);\n function token0() external view returns (address);\n function token1() external view returns (address);\n function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n function price0CumulativeLast() external view returns (uint);\n function price1CumulativeLast() external view returns (uint);\n function kLast() external view returns (uint);\n\n function mint(address to) external returns (uint liquidity);\n function burn(address to) external returns (uint amount0, uint amount1);\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\n function skim(address to) external;\n function sync() external;\n\n function initialize(address, address) external;\n}"},"interfaces/IUniswapV3Pool.sol":{"content":"// SPDX-License-Identifier: GPL-3.0-or-later\n\npragma solidity 0.8.10;\n\ninterface IUniswapV3Pool {\n function token0() external returns (address);\n function token1() external returns (address);\n\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n}\n"},"interfaces/IWETH.sol":{"content":"// SPDX-License-Identifier: GPL-3.0-or-later\n\npragma solidity 0.8.10;\n\ninterface IWETH {\n function deposit() external payable;\n\n function transfer(address to, uint256 value) external returns (bool);\n\n function withdraw(uint256) external;\n}\n"}},"settings":{"optimizer":{"enabled":true,"runs":10000000},"outputSelection":{"*":{"*":["evm.bytecode","evm.deployedBytecode","devdoc","userdoc","metadata","abi"]}},"metadata":{"useLiteralContent":true},"libraries":{}}},"ABI":"[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bentoBox\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"bentoBox\",\"outputs\":[{\"internalType\":\"contract IBentoBoxMinimal\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountOutMin\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"route\",\"type\":\"bytes\"}],\"name\":\"processRoute\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"transferValueTo\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountValueTransfer\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountOutMin\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"route\",\"type\":\"bytes\"}],\"name\":\"transferValueAndprocessRoute\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"amount0Delta\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"amount1Delta\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"tridentCLSwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"amount0Delta\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"amount1Delta\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"uniswapV3SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]","ContractName":"RouteProcessor2","CompilerVersion":"v0.8.10+commit.fc410830","OptimizationUsed":1,"Runs":10000000,"ConstructorArguments":"0x000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd643966","EVMVersion":"Default","Library":"","LicenseType":"","Proxy":0,"SwarmSource":""}] \ No newline at end of file diff --git a/testdata/etherscan/0x35Fb958109b70799a8f9Bc2a8b1Ee4cC62034193/creation_data.json b/testdata/etherscan/0x35Fb958109b70799a8f9Bc2a8b1Ee4cC62034193/creation_data.json index 2c3135353586..e3433ef20019 100644 --- a/testdata/etherscan/0x35Fb958109b70799a8f9Bc2a8b1Ee4cC62034193/creation_data.json +++ b/testdata/etherscan/0x35Fb958109b70799a8f9Bc2a8b1Ee4cC62034193/creation_data.json @@ -1,5 +1 @@ -{ - "contractAddress": "0x35fb958109b70799a8f9bc2a8b1ee4cc62034193", - "contractCreator": "0x3e32324277e96b69750bc6f7c4ba27e122413e07", - "txHash": "0x41e3517f8262b55e1eb1707ba0760b603a70e89ea4a86eff56072fcc80c3d0a1" -} \ No newline at end of file +{"contractAddress":"0x35fb958109b70799a8f9bc2a8b1ee4cc62034193","contractCreator":"0x3e32324277e96b69750bc6f7c4ba27e122413e07","txHash":"0x41e3517f8262b55e1eb1707ba0760b603a70e89ea4a86eff56072fcc80c3d0a1"} \ No newline at end of file diff --git a/testdata/etherscan/0x35Fb958109b70799a8f9Bc2a8b1Ee4cC62034193/metadata.json b/testdata/etherscan/0x35Fb958109b70799a8f9Bc2a8b1Ee4cC62034193/metadata.json index 7601e4d6ee1e..bd48a2efbea4 100644 --- a/testdata/etherscan/0x35Fb958109b70799a8f9Bc2a8b1Ee4cC62034193/metadata.json +++ b/testdata/etherscan/0x35Fb958109b70799a8f9Bc2a8b1Ee4cC62034193/metadata.json @@ -1,16 +1 @@ -[ - { - "SourceCode": "/**\r\n *Submitted for verification at Etherscan.io on 2022-02-19\r\n*/\r\n\r\n/**\r\n *Submitted for verification at Etherscan.io on 2022-02-18\r\n*/\r\n\r\n/**\r\n *Submitted for verification at Etherscan.io on 2022-02-14\r\n*/\r\n\r\n/**\r\n *Submitted for verification at Etherscan.io on 2022-02-10\r\n*/\r\n\r\n/**\r\n *Submitted for verification at Etherscan.io on 2022-02-09\r\n*/\r\n\r\n/**\r\n *Submitted for verification at Etherscan.io on 2022-02-08\r\n*/\r\n\r\n/**\r\n *Submitted for verification at Etherscan.io on 2022-02-05\r\n*/\r\n\r\n/**\r\n *Submitted for verification at Etherscan.io on 2022-01-22\r\n*/\r\n\r\n// SPDX-License-Identifier: UNLICENSED\r\n/*\r\nmade by cty0312\r\n2022.01.22\r\n**/\r\n\r\npragma solidity >=0.7.0 <0.9.0;\r\n\r\nlibrary StringsUpgradeable {\r\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\r\n\r\n /**\r\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\r\n */\r\n function toString(uint256 value) internal pure returns (string memory) {\r\n // Inspired by OraclizeAPI's implementation - MIT licence\r\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\r\n\r\n if (value == 0) {\r\n return \"0\";\r\n }\r\n uint256 temp = value;\r\n uint256 digits;\r\n while (temp != 0) {\r\n digits++;\r\n temp /= 10;\r\n }\r\n bytes memory buffer = new bytes(digits);\r\n while (value != 0) {\r\n digits -= 1;\r\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\r\n value /= 10;\r\n }\r\n return string(buffer);\r\n }\r\n\r\n /**\r\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\r\n */\r\n function toHexString(uint256 value) internal pure returns (string memory) {\r\n if (value == 0) {\r\n return \"0x00\";\r\n }\r\n uint256 temp = value;\r\n uint256 length = 0;\r\n while (temp != 0) {\r\n length++;\r\n temp >>= 8;\r\n }\r\n return toHexString(value, length);\r\n }\r\n\r\n /**\r\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\r\n */\r\n function toHexString(uint256 value, uint256 length)\r\n internal\r\n pure\r\n returns (string memory)\r\n {\r\n bytes memory buffer = new bytes(2 * length + 2);\r\n buffer[0] = \"0\";\r\n buffer[1] = \"x\";\r\n for (uint256 i = 2 * length + 1; i > 1; --i) {\r\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\r\n value >>= 4;\r\n }\r\n require(value == 0, \"Strings: hex length insufficient\");\r\n return string(buffer);\r\n }\r\n}\r\n\r\nlibrary AddressUpgradeable {\r\n /**\r\n * @dev Returns true if `account` is a contract.\r\n *\r\n * [IMPORTANT]\r\n * ====\r\n * It is unsafe to assume that an address for which this function returns\r\n * false is an externally-owned account (EOA) and not a contract.\r\n *\r\n * Among others, `isContract` will return false for the following\r\n * types of addresses:\r\n *\r\n * - an externally-owned account\r\n * - a contract in construction\r\n * - an address where a contract will be created\r\n * - an address where a contract lived, but was destroyed\r\n * ====\r\n */\r\n function isContract(address account) internal view returns (bool) {\r\n // This method relies on extcodesize, which returns 0 for contracts in\r\n // construction, since the code is only stored at the end of the\r\n // constructor execution.\r\n\r\n uint256 size;\r\n assembly {\r\n size := extcodesize(account)\r\n }\r\n return size > 0;\r\n }\r\n\r\n /**\r\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\r\n * `recipient`, forwarding all available gas and reverting on errors.\r\n *\r\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\r\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\r\n * imposed by `transfer`, making them unable to receive funds via\r\n * `transfer`. {sendValue} removes this limitation.\r\n *\r\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\r\n *\r\n * IMPORTANT: because control is transferred to `recipient`, care must be\r\n * taken to not create reentrancy vulnerabilities. Consider using\r\n * {ReentrancyGuard} or the\r\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\r\n */\r\n function sendValue(address payable recipient, uint256 amount) internal {\r\n require(\r\n address(this).balance >= amount,\r\n \"Address: insufficient balance\"\r\n );\r\n\r\n (bool success, ) = recipient.call{value: amount}(\"\");\r\n require(\r\n success,\r\n \"Address: unable to send value, recipient may have reverted\"\r\n );\r\n }\r\n\r\n /**\r\n * @dev Performs a Solidity function call using a low level `call`. A\r\n * plain `call` is an unsafe replacement for a function call: use this\r\n * function instead.\r\n *\r\n * If `target` reverts with a revert reason, it is bubbled up by this\r\n * function (like regular Solidity function calls).\r\n *\r\n * Returns the raw returned data. To convert to the expected return value,\r\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\r\n *\r\n * Requirements:\r\n *\r\n * - `target` must be a contract.\r\n * - calling `target` with `data` must not revert.\r\n *\r\n * _Available since v3.1._\r\n */\r\n function functionCall(address target, bytes memory data)\r\n internal\r\n returns (bytes memory)\r\n {\r\n return functionCall(target, data, \"Address: low-level call failed\");\r\n }\r\n\r\n /**\r\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\r\n * `errorMessage` as a fallback revert reason when `target` reverts.\r\n *\r\n * _Available since v3.1._\r\n */\r\n function functionCall(\r\n address target,\r\n bytes memory data,\r\n string memory errorMessage\r\n ) internal returns (bytes memory) {\r\n return functionCallWithValue(target, data, 0, errorMessage);\r\n }\r\n\r\n /**\r\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\r\n * but also transferring `value` wei to `target`.\r\n *\r\n * Requirements:\r\n *\r\n * - the calling contract must have an ETH balance of at least `value`.\r\n * - the called Solidity function must be `payable`.\r\n *\r\n * _Available since v3.1._\r\n */\r\n function functionCallWithValue(\r\n address target,\r\n bytes memory data,\r\n uint256 value\r\n ) internal returns (bytes memory) {\r\n return\r\n functionCallWithValue(\r\n target,\r\n data,\r\n value,\r\n \"Address: low-level call with value failed\"\r\n );\r\n }\r\n\r\n /**\r\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\r\n * with `errorMessage` as a fallback revert reason when `target` reverts.\r\n *\r\n * _Available since v3.1._\r\n */\r\n function functionCallWithValue(\r\n address target,\r\n bytes memory data,\r\n uint256 value,\r\n string memory errorMessage\r\n ) internal returns (bytes memory) {\r\n require(\r\n address(this).balance >= value,\r\n \"Address: insufficient balance for call\"\r\n );\r\n require(isContract(target), \"Address: call to non-contract\");\r\n\r\n (bool success, bytes memory returndata) = target.call{value: value}(\r\n data\r\n );\r\n return verifyCallResult(success, returndata, errorMessage);\r\n }\r\n\r\n /**\r\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\r\n * but performing a static call.\r\n *\r\n * _Available since v3.3._\r\n */\r\n function functionStaticCall(address target, bytes memory data)\r\n internal\r\n view\r\n returns (bytes memory)\r\n {\r\n return\r\n functionStaticCall(\r\n target,\r\n data,\r\n \"Address: low-level static call failed\"\r\n );\r\n }\r\n\r\n /**\r\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\r\n * but performing a static call.\r\n *\r\n * _Available since v3.3._\r\n */\r\n function functionStaticCall(\r\n address target,\r\n bytes memory data,\r\n string memory errorMessage\r\n ) internal view returns (bytes memory) {\r\n require(isContract(target), \"Address: static call to non-contract\");\r\n\r\n (bool success, bytes memory returndata) = target.staticcall(data);\r\n return verifyCallResult(success, returndata, errorMessage);\r\n }\r\n\r\n /**\r\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\r\n * revert reason using the provided one.\r\n *\r\n * _Available since v4.3._\r\n */\r\n function verifyCallResult(\r\n bool success,\r\n bytes memory returndata,\r\n string memory errorMessage\r\n ) internal pure returns (bytes memory) {\r\n if (success) {\r\n return returndata;\r\n } else {\r\n // Look for revert reason and bubble it up if present\r\n if (returndata.length > 0) {\r\n // The easiest way to bubble the revert reason is using memory via assembly\r\n\r\n assembly {\r\n let returndata_size := mload(returndata)\r\n revert(add(32, returndata), returndata_size)\r\n }\r\n } else {\r\n revert(errorMessage);\r\n }\r\n }\r\n }\r\n}\r\n\r\nlibrary SafeMathUpgradeable {\r\n /**\r\n * @dev Returns the addition of two unsigned integers, reverting on\r\n * overflow.\r\n *\r\n * Counterpart to Solidity's `+` operator.\r\n *\r\n * Requirements:\r\n *\r\n * - Addition cannot overflow.\r\n */\r\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\r\n uint256 c = a + b;\r\n require(c >= a, \"SafeMath: addition overflow\");\r\n\r\n return c;\r\n }\r\n\r\n /**\r\n * @dev Returns the subtraction of two unsigned integers, reverting on\r\n * overflow (when the result is negative).\r\n *\r\n * Counterpart to Solidity's `-` operator.\r\n *\r\n * Requirements:\r\n *\r\n * - Subtraction cannot overflow.\r\n */\r\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\r\n return sub(a, b, \"SafeMath: subtraction overflow\");\r\n }\r\n\r\n /**\r\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\r\n * overflow (when the result is negative).\r\n *\r\n * Counterpart to Solidity's `-` operator.\r\n *\r\n * Requirements:\r\n *\r\n * - Subtraction cannot overflow.\r\n */\r\n function sub(\r\n uint256 a,\r\n uint256 b,\r\n string memory errorMessage\r\n ) internal pure returns (uint256) {\r\n require(b <= a, errorMessage);\r\n uint256 c = a - b;\r\n\r\n return c;\r\n }\r\n\r\n /**\r\n * @dev Returns the multiplication of two unsigned integers, reverting on\r\n * overflow.\r\n *\r\n * Counterpart to Solidity's `*` operator.\r\n *\r\n * Requirements:\r\n *\r\n * - Multiplication cannot overflow.\r\n */\r\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\r\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\r\n // benefit is lost if 'b' is also tested.\r\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\r\n if (a == 0) {\r\n return 0;\r\n }\r\n\r\n uint256 c = a * b;\r\n require(c / a == b, \"SafeMath: multiplication overflow\");\r\n\r\n return c;\r\n }\r\n\r\n /**\r\n * @dev Returns the integer division of two unsigned integers. Reverts on\r\n * division by zero. The result is rounded towards zero.\r\n *\r\n * Counterpart to Solidity's `/` operator. Note: this function uses a\r\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\r\n * uses an invalid opcode to revert (consuming all remaining gas).\r\n *\r\n * Requirements:\r\n *\r\n * - The divisor cannot be zero.\r\n */\r\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\r\n return div(a, b, \"SafeMath: division by zero\");\r\n }\r\n\r\n /**\r\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\r\n * division by zero. The result is rounded towards zero.\r\n *\r\n * Counterpart to Solidity's `/` operator. Note: this function uses a\r\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\r\n * uses an invalid opcode to revert (consuming all remaining gas).\r\n *\r\n * Requirements:\r\n *\r\n * - The divisor cannot be zero.\r\n */\r\n function div(\r\n uint256 a,\r\n uint256 b,\r\n string memory errorMessage\r\n ) internal pure returns (uint256) {\r\n require(b > 0, errorMessage);\r\n uint256 c = a / b;\r\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\r\n\r\n return c;\r\n }\r\n\r\n /**\r\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\r\n * Reverts when dividing by zero.\r\n *\r\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\r\n * opcode (which leaves remaining gas untouched) while Solidity uses an\r\n * invalid opcode to revert (consuming all remaining gas).\r\n *\r\n * Requirements:\r\n *\r\n * - The divisor cannot be zero.\r\n */\r\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\r\n return mod(a, b, \"SafeMath: modulo by zero\");\r\n }\r\n\r\n /**\r\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\r\n * Reverts with custom message when dividing by zero.\r\n *\r\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\r\n * opcode (which leaves remaining gas untouched) while Solidity uses an\r\n * invalid opcode to revert (consuming all remaining gas).\r\n *\r\n * Requirements:\r\n *\r\n * - The divisor cannot be zero.\r\n */\r\n function mod(\r\n uint256 a,\r\n uint256 b,\r\n string memory errorMessage\r\n ) internal pure returns (uint256) {\r\n require(b != 0, errorMessage);\r\n return a % b;\r\n }\r\n}\r\n\r\nabstract contract Initializable {\r\n /**\r\n * @dev Indicates that the contract has been initialized.\r\n */\r\n bool private _initialized;\r\n\r\n /**\r\n * @dev Indicates that the contract is in the process of being initialized.\r\n */\r\n bool private _initializing;\r\n\r\n /**\r\n * @dev Modifier to protect an initializer function from being invoked twice.\r\n */\r\n modifier initializer() {\r\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\r\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\r\n // contract may have been reentered.\r\n require(\r\n _initializing ? _isConstructor() : !_initialized,\r\n \"Initializable: contract is already initialized\"\r\n );\r\n\r\n bool isTopLevelCall = !_initializing;\r\n if (isTopLevelCall) {\r\n _initializing = true;\r\n _initialized = true;\r\n }\r\n\r\n _;\r\n\r\n if (isTopLevelCall) {\r\n _initializing = false;\r\n }\r\n }\r\n\r\n /**\r\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\r\n * {initializer} modifier, directly or indirectly.\r\n */\r\n modifier onlyInitializing() {\r\n require(_initializing, \"Initializable: contract is not initializing\");\r\n _;\r\n }\r\n\r\n function _isConstructor() private view returns (bool) {\r\n return !AddressUpgradeable.isContract(address(this));\r\n }\r\n}\r\n\r\nabstract contract ContextUpgradeable is Initializable {\r\n function __Context_init() internal onlyInitializing {\r\n __Context_init_unchained();\r\n }\r\n\r\n function __Context_init_unchained() internal onlyInitializing {}\r\n\r\n function _msgSender() internal view virtual returns (address) {\r\n return msg.sender;\r\n }\r\n\r\n function _msgData() internal view virtual returns (bytes calldata) {\r\n return msg.data;\r\n }\r\n\r\n uint256[50] private __gap;\r\n}\r\n\r\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\r\n address private _owner;\r\n\r\n event OwnershipTransferred(\r\n address indexed previousOwner,\r\n address indexed newOwner\r\n );\r\n\r\n /**\r\n * @dev Initializes the contract setting the deployer as the initial owner.\r\n */\r\n function __Ownable_init() internal onlyInitializing {\r\n __Context_init_unchained();\r\n __Ownable_init_unchained();\r\n }\r\n\r\n function __Ownable_init_unchained() internal onlyInitializing {\r\n _transferOwnership(_msgSender());\r\n }\r\n\r\n /**\r\n * @dev Returns the address of the current owner.\r\n */\r\n function owner() public view virtual returns (address) {\r\n return _owner;\r\n }\r\n\r\n /**\r\n * @dev Throws if called by any account other than the owner.\r\n */\r\n modifier onlyOwner() {\r\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\r\n _;\r\n }\r\n\r\n /**\r\n * @dev Leaves the contract without owner. It will not be possible to call\r\n * `onlyOwner` functions anymore. Can only be called by the current owner.\r\n *\r\n * NOTE: Renouncing ownership will leave the contract without an owner,\r\n * thereby removing any functionality that is only available to the owner.\r\n */\r\n function renounceOwnership() public virtual onlyOwner {\r\n _transferOwnership(address(0));\r\n }\r\n\r\n /**\r\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\r\n * Can only be called by the current owner.\r\n */\r\n function transferOwnership(address newOwner) public virtual onlyOwner {\r\n require(\r\n newOwner != address(0),\r\n \"Ownable: new owner is the zero address\"\r\n );\r\n _transferOwnership(newOwner);\r\n }\r\n\r\n /**\r\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\r\n * Internal function without access restriction.\r\n */\r\n function _transferOwnership(address newOwner) internal virtual {\r\n address oldOwner = _owner;\r\n _owner = newOwner;\r\n emit OwnershipTransferred(oldOwner, newOwner);\r\n }\r\n\r\n uint256[49] private __gap;\r\n}\r\n\r\ninterface IERC165Upgradeable {\r\n /**\r\n * @dev Returns true if this contract implements the interface defined by\r\n * `interfaceId`. See the corresponding\r\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\r\n * to learn more about how these ids are created.\r\n *\r\n * This function call must use less than 30 000 gas.\r\n */\r\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\r\n}\r\n\r\ninterface IERC721Upgradeable is IERC165Upgradeable {\r\n /**\r\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\r\n */\r\n event Transfer(\r\n address indexed from,\r\n address indexed to,\r\n uint256 indexed tokenId\r\n );\r\n\r\n /**\r\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\r\n */\r\n event Approval(\r\n address indexed owner,\r\n address indexed approved,\r\n uint256 indexed tokenId\r\n );\r\n\r\n /**\r\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\r\n */\r\n event ApprovalForAll(\r\n address indexed owner,\r\n address indexed operator,\r\n bool approved\r\n );\r\n\r\n /**\r\n * @dev Returns the number of tokens in ``owner``'s account.\r\n */\r\n function balanceOf(address owner) external view returns (uint256 balance);\r\n\r\n /**\r\n * @dev Returns the owner of the `tokenId` token.\r\n *\r\n * Requirements:\r\n *\r\n * - `tokenId` must exist.\r\n */\r\n function ownerOf(uint256 tokenId) external view returns (address owner);\r\n\r\n /**\r\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\r\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\r\n *\r\n * Requirements:\r\n *\r\n * - `from` cannot be the zero address.\r\n * - `to` cannot be the zero address.\r\n * - `tokenId` token must exist and be owned by `from`.\r\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\r\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function safeTransferFrom(\r\n address from,\r\n address to,\r\n uint256 tokenId\r\n ) external;\r\n\r\n /**\r\n * @dev Transfers `tokenId` token from `from` to `to`.\r\n *\r\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\r\n *\r\n * Requirements:\r\n *\r\n * - `from` cannot be the zero address.\r\n * - `to` cannot be the zero address.\r\n * - `tokenId` token must be owned by `from`.\r\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function transferFrom(\r\n address from,\r\n address to,\r\n uint256 tokenId\r\n ) external;\r\n\r\n /**\r\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\r\n * The approval is cleared when the token is transferred.\r\n *\r\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\r\n *\r\n * Requirements:\r\n *\r\n * - The caller must own the token or be an approved operator.\r\n * - `tokenId` must exist.\r\n *\r\n * Emits an {Approval} event.\r\n */\r\n function approve(address to, uint256 tokenId) external;\r\n\r\n /**\r\n * @dev Returns the account approved for `tokenId` token.\r\n *\r\n * Requirements:\r\n *\r\n * - `tokenId` must exist.\r\n */\r\n function getApproved(uint256 tokenId)\r\n external\r\n view\r\n returns (address operator);\r\n\r\n /**\r\n * @dev Approve or remove `operator` as an operator for the caller.\r\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\r\n *\r\n * Requirements:\r\n *\r\n * - The `operator` cannot be the caller.\r\n *\r\n * Emits an {ApprovalForAll} event.\r\n */\r\n function setApprovalForAll(address operator, bool _approved) external;\r\n\r\n /**\r\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\r\n *\r\n * See {setApprovalForAll}\r\n */\r\n function isApprovedForAll(address owner, address operator)\r\n external\r\n view\r\n returns (bool);\r\n\r\n /**\r\n * @dev Safely transfers `tokenId` token from `from` to `to`.\r\n *\r\n * Requirements:\r\n *\r\n * - `from` cannot be the zero address.\r\n * - `to` cannot be the zero address.\r\n * - `tokenId` token must exist and be owned by `from`.\r\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\r\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function safeTransferFrom(\r\n address from,\r\n address to,\r\n uint256 tokenId,\r\n bytes calldata data\r\n ) external;\r\n}\r\n\r\ninterface IERC20Upgradeable {\r\n /**\r\n * @dev Returns the amount of tokens in existence.\r\n */\r\n function totalSupply() external view returns (uint256);\r\n\r\n /**\r\n * @dev Returns the amount of tokens owned by `account`.\r\n */\r\n function balanceOf(address account) external view returns (uint256);\r\n\r\n /**\r\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\r\n *\r\n * Returns a boolean value indicating whether the operation succeeded.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function transfer(address recipient, uint256 amount)\r\n external\r\n returns (bool);\r\n\r\n /**\r\n * @dev Returns the remaining number of tokens that `spender` will be\r\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\r\n * zero by default.\r\n *\r\n * This value changes when {approve} or {transferFrom} are called.\r\n */\r\n function allowance(address owner, address spender)\r\n external\r\n view\r\n returns (uint256);\r\n\r\n /**\r\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\r\n *\r\n * Returns a boolean value indicating whether the operation succeeded.\r\n *\r\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\r\n * that someone may use both the old and the new allowance by unfortunate\r\n * transaction ordering. One possible solution to mitigate this race\r\n * condition is to first reduce the spender's allowance to 0 and set the\r\n * desired value afterwards:\r\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\r\n *\r\n * Emits an {Approval} event.\r\n */\r\n function approve(address spender, uint256 amount) external returns (bool);\r\n\r\n /**\r\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\r\n * allowance mechanism. `amount` is then deducted from the caller's\r\n * allowance.\r\n *\r\n * Returns a boolean value indicating whether the operation succeeded.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function transferFrom(\r\n address sender,\r\n address recipient,\r\n uint256 amount\r\n ) external returns (bool);\r\n\r\n\r\n function mintToken(address _address, uint256 _amount) external;\r\n /**\r\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\r\n * another (`to`).\r\n *\r\n * Note that `value` may be zero.\r\n */\r\n event Transfer(address indexed from, address indexed to, uint256 value);\r\n\r\n /**\r\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\r\n * a call to {approve}. `value` is the new allowance.\r\n */\r\n event Approval(\r\n address indexed owner,\r\n address indexed spender,\r\n uint256 value\r\n );\r\n}\r\n\r\ninterface IUniswapV2Factory {\r\n event PairCreated(\r\n address indexed token0,\r\n address indexed token1,\r\n address pair,\r\n uint256\r\n );\r\n\r\n function feeTo() external view returns (address);\r\n\r\n function feeToSetter() external view returns (address);\r\n\r\n function getPair(address tokenA, address tokenB)\r\n external\r\n view\r\n returns (address pair);\r\n\r\n function allPairs(uint256) external view returns (address pair);\r\n\r\n function allPairsLength() external view returns (uint256);\r\n\r\n function createPair(address tokenA, address tokenB)\r\n external\r\n returns (address pair);\r\n\r\n function setFeeTo(address) external;\r\n\r\n function setFeeToSetter(address) external;\r\n}\r\n\r\ninterface IUniswapV2Pair {\r\n event Approval(\r\n address indexed owner,\r\n address indexed spender,\r\n uint256 value\r\n );\r\n event Transfer(address indexed from, address indexed to, uint256 value);\r\n\r\n function name() external pure returns (string memory);\r\n\r\n function symbol() external pure returns (string memory);\r\n\r\n function decimals() external pure returns (uint8);\r\n\r\n function totalSupply() external view returns (uint256);\r\n\r\n function balanceOf(address owner) external view returns (uint256);\r\n\r\n function allowance(address owner, address spender)\r\n external\r\n view\r\n returns (uint256);\r\n\r\n function approve(address spender, uint256 value) external returns (bool);\r\n\r\n function transfer(address to, uint256 value) external returns (bool);\r\n\r\n function transferFrom(\r\n address from,\r\n address to,\r\n uint256 value\r\n ) external returns (bool);\r\n\r\n function DOMAIN_SEPARATOR() external view returns (bytes32);\r\n\r\n function PERMIT_TYPEHASH() external pure returns (bytes32);\r\n\r\n function nonces(address owner) external view returns (uint256);\r\n\r\n function permit(\r\n address owner,\r\n address spender,\r\n uint256 value,\r\n uint256 deadline,\r\n uint8 v,\r\n bytes32 r,\r\n bytes32 s\r\n ) external;\r\n\r\n event Mint(address indexed sender, uint256 amount0, uint256 amount1);\r\n event Burn(\r\n address indexed sender,\r\n uint256 amount0,\r\n uint256 amount1,\r\n address indexed to\r\n );\r\n event Swap(\r\n address indexed sender,\r\n uint256 amount0In,\r\n uint256 amount1In,\r\n uint256 amount0Out,\r\n uint256 amount1Out,\r\n address indexed to\r\n );\r\n event Sync(uint112 reserve0, uint112 reserve1);\r\n\r\n function MINIMUM_LIQUIDITY() external pure returns (uint256);\r\n\r\n function factory() external view returns (address);\r\n\r\n function token0() external view returns (address);\r\n\r\n function token1() external view returns (address);\r\n\r\n function getReserves()\r\n external\r\n view\r\n returns (\r\n uint112 reserve0,\r\n uint112 reserve1,\r\n uint32 blockTimestampLast\r\n );\r\n\r\n function price0CumulativeLast() external view returns (uint256);\r\n\r\n function price1CumulativeLast() external view returns (uint256);\r\n\r\n function kLast() external view returns (uint256);\r\n\r\n function mint(address to) external returns (uint256 liquidity);\r\n\r\n function burn(address to)\r\n external\r\n returns (uint256 amount0, uint256 amount1);\r\n\r\n function swap(\r\n uint256 amount0Out,\r\n uint256 amount1Out,\r\n address to,\r\n bytes calldata data\r\n ) external;\r\n\r\n function skim(address to) external;\r\n\r\n function sync() external;\r\n\r\n function initialize(address, address) external;\r\n}\r\n\r\ninterface IUniswapV2Router01 {\r\n function factory() external pure returns (address);\r\n\r\n function WETH() external pure returns (address);\r\n\r\n function addLiquidity(\r\n address tokenA,\r\n address tokenB,\r\n uint256 amountADesired,\r\n uint256 amountBDesired,\r\n uint256 amountAMin,\r\n uint256 amountBMin,\r\n address to,\r\n uint256 deadline\r\n )\r\n external\r\n returns (\r\n uint256 amountA,\r\n uint256 amountB,\r\n uint256 liquidity\r\n );\r\n\r\n function addLiquidityETH(\r\n address token,\r\n uint256 amountTokenDesired,\r\n uint256 amountTokenMin,\r\n uint256 amountETHMin,\r\n address to,\r\n uint256 deadline\r\n )\r\n external\r\n payable\r\n returns (\r\n uint256 amountToken,\r\n uint256 amountETH,\r\n uint256 liquidity\r\n );\r\n\r\n function removeLiquidity(\r\n address tokenA,\r\n address tokenB,\r\n uint256 liquidity,\r\n uint256 amountAMin,\r\n uint256 amountBMin,\r\n address to,\r\n uint256 deadline\r\n ) external returns (uint256 amountA, uint256 amountB);\r\n\r\n function removeLiquidityETH(\r\n address token,\r\n uint256 liquidity,\r\n uint256 amountTokenMin,\r\n uint256 amountETHMin,\r\n address to,\r\n uint256 deadline\r\n ) external returns (uint256 amountToken, uint256 amountETH);\r\n\r\n function removeLiquidityWithPermit(\r\n address tokenA,\r\n address tokenB,\r\n uint256 liquidity,\r\n uint256 amountAMin,\r\n uint256 amountBMin,\r\n address to,\r\n uint256 deadline,\r\n bool approveMax,\r\n uint8 v,\r\n bytes32 r,\r\n bytes32 s\r\n ) external returns (uint256 amountA, uint256 amountB);\r\n\r\n function removeLiquidityETHWithPermit(\r\n address token,\r\n uint256 liquidity,\r\n uint256 amountTokenMin,\r\n uint256 amountETHMin,\r\n address to,\r\n uint256 deadline,\r\n bool approveMax,\r\n uint8 v,\r\n bytes32 r,\r\n bytes32 s\r\n ) external returns (uint256 amountToken, uint256 amountETH);\r\n\r\n function swapExactTokensForTokens(\r\n uint256 amountIn,\r\n uint256 amountOutMin,\r\n address[] calldata path,\r\n address to,\r\n uint256 deadline\r\n ) external returns (uint256[] memory amounts);\r\n\r\n function swapTokensForExactTokens(\r\n uint256 amountOut,\r\n uint256 amountInMax,\r\n address[] calldata path,\r\n address to,\r\n uint256 deadline\r\n ) external returns (uint256[] memory amounts);\r\n\r\n function swapExactETHForTokens(\r\n uint256 amountOutMin,\r\n address[] calldata path,\r\n address to,\r\n uint256 deadline\r\n ) external payable returns (uint256[] memory amounts);\r\n\r\n function swapTokensForExactETH(\r\n uint256 amountOut,\r\n uint256 amountInMax,\r\n address[] calldata path,\r\n address to,\r\n uint256 deadline\r\n ) external returns (uint256[] memory amounts);\r\n\r\n function swapExactTokensForETH(\r\n uint256 amountIn,\r\n uint256 amountOutMin,\r\n address[] calldata path,\r\n address to,\r\n uint256 deadline\r\n ) external returns (uint256[] memory amounts);\r\n\r\n function swapETHForExactTokens(\r\n uint256 amountOut,\r\n address[] calldata path,\r\n address to,\r\n uint256 deadline\r\n ) external payable returns (uint256[] memory amounts);\r\n\r\n function quote(\r\n uint256 amountA,\r\n uint256 reserveA,\r\n uint256 reserveB\r\n ) external pure returns (uint256 amountB);\r\n\r\n function getAmountOut(\r\n uint256 amountIn,\r\n uint256 reserveIn,\r\n uint256 reserveOut\r\n ) external pure returns (uint256 amountOut);\r\n\r\n function getAmountIn(\r\n uint256 amountOut,\r\n uint256 reserveIn,\r\n uint256 reserveOut\r\n ) external pure returns (uint256 amountIn);\r\n\r\n function getAmountsOut(uint256 amountIn, address[] calldata path)\r\n external\r\n view\r\n returns (uint256[] memory amounts);\r\n\r\n function getAmountsIn(uint256 amountOut, address[] calldata path)\r\n external\r\n view\r\n returns (uint256[] memory amounts);\r\n}\r\n\r\ninterface IUniswapV2Router is IUniswapV2Router01 {\r\n function removeLiquidityETHSupportingFeeOnTransferTokens(\r\n address token,\r\n uint256 liquidity,\r\n uint256 amountTokenMin,\r\n uint256 amountETHMin,\r\n address to,\r\n uint256 deadline\r\n ) external returns (uint256 amountETH);\r\n\r\n function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(\r\n address token,\r\n uint256 liquidity,\r\n uint256 amountTokenMin,\r\n uint256 amountETHMin,\r\n address to,\r\n uint256 deadline,\r\n bool approveMax,\r\n uint8 v,\r\n bytes32 r,\r\n bytes32 s\r\n ) external returns (uint256 amountETH);\r\n\r\n function swapExactTokensForTokensSupportingFeeOnTransferTokens(\r\n uint256 amountIn,\r\n uint256 amountOutMin,\r\n address[] calldata path,\r\n address to,\r\n uint256 deadline\r\n ) external;\r\n\r\n function swapExactETHForTokensSupportingFeeOnTransferTokens(\r\n uint256 amountOutMin,\r\n address[] calldata path,\r\n address to,\r\n uint256 deadline\r\n ) external payable;\r\n\r\n function swapExactTokensForETHSupportingFeeOnTransferTokens(\r\n uint256 amountIn,\r\n uint256 amountOutMin,\r\n address[] calldata path,\r\n address to,\r\n uint256 deadline\r\n ) external;\r\n}\r\n\r\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\r\n /**\r\n * @dev Returns the name of the token.\r\n */\r\n function name() external view returns (string memory);\r\n\r\n /**\r\n * @dev Returns the symbol of the token.\r\n */\r\n function symbol() external view returns (string memory);\r\n\r\n /**\r\n * @dev Returns the decimals places of the token.\r\n */\r\n function decimals() external view returns (uint8);\r\n}\r\n\r\nabstract contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\r\n using SafeMathUpgradeable for uint256;\r\n\r\n mapping(address => uint256) private _balances;\r\n\r\n mapping(address => mapping(address => uint256)) private _allowances;\r\n\r\n uint256 private _totalSupply;\r\n\r\n string private _name;\r\n string private _symbol;\r\n\r\n /**\r\n * @dev Sets the values for {name} and {symbol}.\r\n *\r\n * The default value of {decimals} is 18. To select a different value for\r\n * {decimals} you should overload it.\r\n *\r\n * All two of these values are immutable: they can only be set once during\r\n * construction.\r\n */\r\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\r\n __ERC20_init_unchained(name_, symbol_);\r\n }\r\n\r\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\r\n _name = name_;\r\n _symbol = symbol_;\r\n }\r\n\r\n /**\r\n * @dev Returns the name of the token.\r\n */\r\n function name() public view virtual override returns (string memory) {\r\n return _name;\r\n }\r\n\r\n /**\r\n * @dev Returns the symbol of the token, usually a shorter version of the\r\n * name.\r\n */\r\n function symbol() public view virtual override returns (string memory) {\r\n return _symbol;\r\n }\r\n\r\n /**\r\n * @dev Returns the number of decimals used to get its user representation.\r\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\r\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\r\n *\r\n * Tokens usually opt for a value of 18, imitating the relationship between\r\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\r\n * overridden;\r\n *\r\n * NOTE: This information is only used for _display_ purposes: it in\r\n * no way affects any of the arithmetic of the contract, including\r\n * {IERC20-balanceOf} and {IERC20-transfer}.\r\n */\r\n function decimals() public view virtual override returns (uint8) {\r\n return 18;\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-totalSupply}.\r\n */\r\n function totalSupply() public view virtual override returns (uint256) {\r\n return _totalSupply;\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-balanceOf}.\r\n */\r\n function balanceOf(address account) public view virtual override returns (uint256) {\r\n return _balances[account];\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-transfer}.\r\n *\r\n * Requirements:\r\n *\r\n * - `to` cannot be the zero address.\r\n * - the caller must have a balance of at least `amount`.\r\n */\r\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\r\n address owner = _msgSender();\r\n _transfer(owner, to, amount);\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-allowance}.\r\n */\r\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\r\n return _allowances[owner][spender];\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-approve}.\r\n *\r\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\r\n * `transferFrom`. This is semantically equivalent to an infinite approval.\r\n *\r\n * Requirements:\r\n *\r\n * - `spender` cannot be the zero address.\r\n */\r\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\r\n address owner = _msgSender();\r\n _approve(owner, spender, amount);\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-transferFrom}.\r\n *\r\n * Emits an {Approval} event indicating the updated allowance. This is not\r\n * required by the EIP. See the note at the beginning of {ERC20}.\r\n *\r\n * NOTE: Does not update the allowance if the current allowance\r\n * is the maximum `uint256`.\r\n *\r\n * Requirements:\r\n *\r\n * - `from` and `to` cannot be the zero address.\r\n * - `from` must have a balance of at least `amount`.\r\n * - the caller must have allowance for ``from``'s tokens of at least\r\n * `amount`.\r\n */\r\n function transferFrom(\r\n address from,\r\n address to,\r\n uint256 amount\r\n ) public virtual override returns (bool) {\r\n address spender = _msgSender();\r\n _spendAllowance(from, spender, amount);\r\n _transfer(from, to, amount);\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev Atomically increases the allowance granted to `spender` by the caller.\r\n *\r\n * This is an alternative to {approve} that can be used as a mitigation for\r\n * problems described in {IERC20-approve}.\r\n *\r\n * Emits an {Approval} event indicating the updated allowance.\r\n *\r\n * Requirements:\r\n *\r\n * - `spender` cannot be the zero address.\r\n */\r\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\r\n address owner = _msgSender();\r\n _approve(owner, spender, _allowances[owner][spender] + addedValue);\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\r\n *\r\n * This is an alternative to {approve} that can be used as a mitigation for\r\n * problems described in {IERC20-approve}.\r\n *\r\n * Emits an {Approval} event indicating the updated allowance.\r\n *\r\n * Requirements:\r\n *\r\n * - `spender` cannot be the zero address.\r\n * - `spender` must have allowance for the caller of at least\r\n * `subtractedValue`.\r\n */\r\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\r\n address owner = _msgSender();\r\n uint256 currentAllowance = _allowances[owner][spender];\r\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\r\n unchecked {\r\n _approve(owner, spender, currentAllowance - subtractedValue);\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\r\n *\r\n * This internal function is equivalent to {transfer}, and can be used to\r\n * e.g. implement automatic token fees, slashing mechanisms, etc.\r\n *\r\n * Emits a {Transfer} event.\r\n *\r\n * Requirements:\r\n *\r\n * - `from` cannot be the zero address.\r\n * - `to` cannot be the zero address.\r\n * - `from` must have a balance of at least `amount`.\r\n */\r\n function _transfer(\r\n address from,\r\n address to,\r\n uint256 amount\r\n ) internal virtual {\r\n require(from != address(0), \"ERC20: transfer from the zero address\");\r\n require(to != address(0), \"ERC20: transfer to the zero address\");\r\n\r\n _beforeTokenTransfer(from, to, amount);\r\n\r\n uint256 fromBalance = _balances[from];\r\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\r\n unchecked {\r\n _balances[from] = fromBalance - amount;\r\n }\r\n _balances[to] += amount;\r\n\r\n emit Transfer(from, to, amount);\r\n\r\n _afterTokenTransfer(from, to, amount);\r\n }\r\n\r\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\r\n * the total supply.\r\n *\r\n * Emits a {Transfer} event with `from` set to the zero address.\r\n *\r\n * Requirements:\r\n *\r\n * - `account` cannot be the zero address.\r\n */\r\n function _mint(address account, uint256 amount) internal virtual {\r\n require(account != address(0), \"ERC20: mint to the zero address\");\r\n\r\n _beforeTokenTransfer(address(0), account, amount);\r\n\r\n _totalSupply += amount;\r\n _balances[account] += amount;\r\n emit Transfer(address(0), account, amount);\r\n\r\n _afterTokenTransfer(address(0), account, amount);\r\n }\r\n\r\n /**\r\n * @dev Destroys `amount` tokens from `account`, reducing the\r\n * total supply.\r\n *\r\n * Emits a {Transfer} event with `to` set to the zero address.\r\n *\r\n * Requirements:\r\n *\r\n * - `account` cannot be the zero address.\r\n * - `account` must have at least `amount` tokens.\r\n */\r\n function _burn(uint256 amount) public virtual {\r\n // require(_balances[msg.sender] >= amount,'insufficient balance!');\r\n\r\n // _beforeTokenTransfer(msg.sender, address(0x000000000000000000000000000000000000dEaD), amount);\r\n\r\n // _balances[msg.sender] = _balances[msg.sender].sub(amount, \"ERC20: burn amount exceeds balance\");\r\n // _totalSupply = _totalSupply.sub(amount);\r\n // emit Transfer(msg.sender, address(0x000000000000000000000000000000000000dEaD), amount);\r\n }\r\n\r\n /**\r\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\r\n *\r\n * This internal function is equivalent to `approve`, and can be used to\r\n * e.g. set automatic allowances for certain subsystems, etc.\r\n *\r\n * Emits an {Approval} event.\r\n *\r\n * Requirements:\r\n *\r\n * - `owner` cannot be the zero address.\r\n * - `spender` cannot be the zero address.\r\n */\r\n function _approve(\r\n address owner,\r\n address spender,\r\n uint256 amount\r\n ) internal virtual {\r\n require(owner != address(0), \"ERC20: approve from the zero address\");\r\n require(spender != address(0), \"ERC20: approve to the zero address\");\r\n\r\n _allowances[owner][spender] = amount;\r\n emit Approval(owner, spender, amount);\r\n }\r\n\r\n /**\r\n * @dev Spend `amount` form the allowance of `owner` toward `spender`.\r\n *\r\n * Does not update the allowance amount in case of infinite allowance.\r\n * Revert if not enough allowance is available.\r\n *\r\n * Might emit an {Approval} event.\r\n */\r\n function _spendAllowance(\r\n address owner,\r\n address spender,\r\n uint256 amount\r\n ) internal virtual {\r\n uint256 currentAllowance = allowance(owner, spender);\r\n if (currentAllowance != type(uint256).max) {\r\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\r\n unchecked {\r\n _approve(owner, spender, currentAllowance - amount);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @dev Hook that is called before any transfer of tokens. This includes\r\n * minting and burning.\r\n *\r\n * Calling conditions:\r\n *\r\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\r\n * will be transferred to `to`.\r\n * - when `from` is zero, `amount` tokens will be minted for `to`.\r\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\r\n * - `from` and `to` are never both zero.\r\n *\r\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\r\n */\r\n function _beforeTokenTransfer(\r\n address from,\r\n address to,\r\n uint256 amount\r\n ) internal virtual {}\r\n\r\n /**\r\n * @dev Hook that is called after any transfer of tokens. This includes\r\n * minting and burning.\r\n *\r\n * Calling conditions:\r\n *\r\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\r\n * has been transferred to `to`.\r\n * - when `from` is zero, `amount` tokens have been minted for `to`.\r\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\r\n * - `from` and `to` are never both zero.\r\n *\r\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\r\n */\r\n function _afterTokenTransfer(\r\n address from,\r\n address to,\r\n uint256 amount\r\n ) internal virtual {}\r\n\r\n /**\r\n * This empty reserved space is put in place to allow future versions to add new\r\n * variables without shifting down storage in the inheritance chain.\r\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\r\n */\r\n uint256[45] private __gap;\r\n}\r\n\r\ncontract BearXNFTStaking is OwnableUpgradeable {\r\n using SafeMathUpgradeable for uint256;\r\n using AddressUpgradeable for address;\r\n\r\n //-------------constant value------------------//\r\n address private UNISWAP_V2_ROUTER;\r\n address private WETH;\r\n uint256 DURATION_FOR_REWARDS;\r\n uint256 DURATION_FOR_STOP_REWARDS;\r\n\r\n address public BearXNFTAddress;\r\n address public ROOTxTokenAddress;\r\n address public SROOTxTokenAddress;\r\n uint256 public totalStakes;\r\n\r\n uint256 public MaxSROOTXrate;\r\n uint256 public MinSROOTXrate;\r\n uint256 public MaxRate;\r\n uint256 public MinRate;\r\n uint256 public maxprovision;\r\n uint256 public RateValue;\r\n uint256 public SROOTRateValue;\r\n\r\n struct stakingInfo {\r\n uint256 nft_id;\r\n uint256 stakedDate;\r\n uint256 claimedDate_SROOT;\r\n uint256 claimedDate_WETH;\r\n uint256 claimedDate_ROOTX;\r\n }\r\n\r\n mapping(address => stakingInfo[]) internal stakes;\r\n address[] internal stakers;\r\n uint256 public RootX_Store;\r\n\r\n // 1.29 update\r\n mapping(address => bool) internal m_stakers;\r\n bool ismaptransfered;\r\n\r\n // 2.15 update\r\n bool public islocked;\r\n\r\n function initialize() public initializer{\r\n __Ownable_init();\r\n UNISWAP_V2_ROUTER = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;\r\n WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;\r\n DURATION_FOR_REWARDS = 1 days;\r\n DURATION_FOR_STOP_REWARDS = 3650 days;\r\n BearXNFTAddress = 0xE22e1e620dffb03065CD77dB0162249c0c91bf01;\r\n ROOTxTokenAddress = 0xd718Ad25285d65eF4D79262a6CD3AEA6A8e01023;\r\n SROOTxTokenAddress = 0x99CFDf48d0ba4885A73786148A2f89d86c702170;\r\n totalStakes = 0; \r\n MaxSROOTXrate = 100*10**18;\r\n MinSROOTXrate = 50*10**18;\r\n MaxRate = 11050*10**18;\r\n MinRate = 500*10**18; \r\n maxprovision = 3000;\r\n RateValue = ((MaxRate - MinRate) / maxprovision);\r\n SROOTRateValue = (( MaxSROOTXrate - MinSROOTXrate ) / maxprovision);\r\n RootX_Store=0;\r\n ismaptransfered = false;\r\n }\r\n // 1.29 update\r\n function transferStakers() public {\r\n if(!ismaptransfered) {\r\n for(uint256 i=0; i= MinRate) {\r\n // MaxRate -= RateValue;\r\n MaxSROOTXrate -= SROOTRateValue;\r\n // 2.1 updated\r\n MaxRate = MaxRate.sub(10*(10**18));\r\n }\r\n require(\r\n IERC721Upgradeable(BearXNFTAddress).ownerOf(_id) == _addr,\r\n \"You are not a owner of the nft\"\r\n );\r\n require(\r\n IERC721Upgradeable(BearXNFTAddress).isApprovedForAll(msg.sender, address(this)) ==\r\n true,\r\n \"You should approve nft to the staking contract\"\r\n );\r\n IERC721Upgradeable(BearXNFTAddress).transferFrom(\r\n _addr,\r\n address(this),\r\n _id\r\n );\r\n // (bool _isStaker, ) = isStaker(_addr);\r\n (bool _isStaker, ) = is_m_Staker(_addr);\r\n stakingInfo memory sInfo = stakingInfo(\r\n _id,\r\n block.timestamp,\r\n block.timestamp,\r\n block.timestamp,\r\n block.timestamp\r\n );\r\n totalStakes = totalStakes.add(1);\r\n stakes[_addr].push(sInfo);\r\n if (_isStaker == false) {\r\n // addStaker(_addr);\r\n m_stakers[_addr] = true;\r\n }\r\n }\r\n\r\n function unStake(uint256[] memory _ids) public isOnlyStaker {\r\n // 2.15 update\r\n\r\n require(!islocked, \"Locked\");\r\n uint256[] memory ownerIds = stakeOf(msg.sender);\r\n require(_ids.length <= ownerIds.length, \"Id errors\");\r\n uint256 temp = 0;\r\n\r\n for(uint256 i=0; i<_ids.length;i++) {\r\n for(uint256 j=0;j 0) {\r\n IERC20Upgradeable(ROOTxTokenAddress).transfer(_addr, Rootamount);\r\n\r\n for (uint256 i = 0; i < stakes[_addr].length; i++) {\r\n stakes[_addr][i].claimedDate_ROOTX = block.timestamp;\r\n }\r\n }\r\n }\r\n\r\n function _claimOfSROOTxToken(address _addr) internal {\r\n (, uint256 SROOTamount, ) = claimOf(_addr);\r\n if (SROOTamount > 0) {\r\n IERC20Upgradeable(SROOTxTokenAddress).transfer(_addr, SROOTamount);\r\n\r\n for (uint256 i = 0; i < stakes[_addr].length; i++) {\r\n stakes[_addr][i].claimedDate_SROOT = block.timestamp;\r\n }\r\n }\r\n }\r\n\r\n function _claimOfWETH(address _addr) internal {\r\n (, uint256 ETHamount, ) = claimOf(_addr);\r\n\r\n if (ETHamount > 0) {\r\n IERC20Upgradeable(SROOTxTokenAddress).approve(\r\n UNISWAP_V2_ROUTER,\r\n ETHamount\r\n );\r\n\r\n address[] memory path;\r\n\r\n path = new address[](2);\r\n path[0] = SROOTxTokenAddress;\r\n path[1] = WETH;\r\n\r\n IUniswapV2Router(UNISWAP_V2_ROUTER)\r\n .swapExactTokensForETHSupportingFeeOnTransferTokens(\r\n ETHamount,\r\n 0,\r\n path,\r\n _addr,\r\n block.timestamp\r\n );\r\n\r\n for (uint256 i = 0; i < stakes[_addr].length; i++) {\r\n stakes[_addr][i].claimedDate_WETH = block.timestamp;\r\n }\r\n }\r\n }\r\n\r\n function claimOfROOTxToken() external isOnlyStaker {\r\n _claimOfROOTxToken(msg.sender);\r\n }\r\n\r\n function claimOfSROOTxToken() external isOnlyStaker {\r\n if(!isVested(msg.sender)){\r\n _claimOfSROOTxToken(msg.sender);\r\n }\r\n }\r\n\r\n function claimOfWETH() external isOnlyStaker {\r\n if(!isVested(msg.sender)) {\r\n _claimOfWETH(msg.sender);\r\n }\r\n\r\n }\r\n\r\n // 2.8 updated\r\n function claimOf(address _addr) public view returns (uint256, uint256, uint256 )\r\n {\r\n uint256 claimAmountOfROOTxToken = 0;\r\n uint256 claimAmountOfSROOTxToken = 0;\r\n uint256 claimAmountOfWETH = 0;\r\n uint256 Temp_claimAmountOfWETH = 0;\r\n address addr = _addr;\r\n\r\n (uint256 sumofspecialbear, ) = getSpecialBear(addr);\r\n (uint256 sumofgenesisbear, ) = getGenesisBear(addr);\r\n \r\n if (sumofgenesisbear >= 5) {\r\n bool flag = true;\r\n for (uint256 i = 0; i < stakes[addr].length; i++) {\r\n ///ROOTX\r\n uint256 dd_root = calDay(stakes[addr][i].claimedDate_ROOTX);\r\n if ((isGenesisBear(stakes[addr][i].nft_id) || isSpecialBear(stakes[addr][i].nft_id)) && dd_root <1) {\r\n flag = false;\r\n }\r\n if (flag && stakes[addr].length != 0) {\r\n claimAmountOfROOTxToken = RootX_Store.div(10**18).add(10*dd_root*sumofgenesisbear).add(10*dd_root*sumofspecialbear);\r\n }\r\n else if(!flag) {\r\n claimAmountOfROOTxToken = RootX_Store.div(10**18);\r\n }\r\n /// SROOTX and WETH\r\n if (isSpecialBear(stakes[addr][i].nft_id)) {\r\n uint256 dd_srootx = calDay(stakes[addr][i].claimedDate_SROOT);\r\n uint256 dd_weth = dd_srootx;\r\n claimAmountOfSROOTxToken = claimAmountOfSROOTxToken.add(200 * (10**18) * dd_srootx);\r\n claimAmountOfWETH = claimAmountOfWETH.add(200 * (10**18) * dd_weth);\r\n } else if (isGenesisBear(stakes[addr][i].nft_id)) {\r\n uint256 dd_srootx = calDay(stakes[addr][i].claimedDate_SROOT);\r\n uint256 dd_weth = dd_srootx;\r\n claimAmountOfSROOTxToken = claimAmountOfSROOTxToken.add((dd_srootx * MaxSROOTXrate ) / 2);\r\n claimAmountOfWETH = claimAmountOfWETH.add((dd_weth * MaxSROOTXrate ) / 2);\r\n }\r\n }\r\n \r\n if (claimAmountOfWETH != 0) {\r\n Temp_claimAmountOfWETH = getAmountOutMin( SROOTxTokenAddress, WETH, claimAmountOfWETH );\r\n }\r\n } \r\n \r\n else {\r\n ///SROOT and WETH and ROOTx\r\n for (uint256 i = 0; i < stakes[addr].length; i++) {\r\n if (isSpecialBear(stakes[addr][i].nft_id)) {\r\n uint256 dd_root = calDay(stakes[addr][i].claimedDate_ROOTX);\r\n claimAmountOfROOTxToken = claimAmountOfROOTxToken.add(dd_root * 10);\r\n uint256 dd_sroot = calDay(stakes[addr][i].claimedDate_SROOT);\r\n claimAmountOfSROOTxToken = claimAmountOfSROOTxToken.add(200 * (10**18) * dd_sroot);\r\n uint256 dd_weth = calDay(stakes[addr][i].claimedDate_WETH);\r\n claimAmountOfWETH = claimAmountOfWETH.add( 200 * (10**18) * dd_weth );\r\n }\r\n if (isGenesisBear(stakes[addr][i].nft_id)) {\r\n uint256 dd_root = calDay(stakes[addr][i].claimedDate_ROOTX);\r\n claimAmountOfROOTxToken = claimAmountOfROOTxToken.add(dd_root * 10);\r\n }\r\n }\r\n\r\n if (claimAmountOfWETH != 0) {\r\n Temp_claimAmountOfWETH = getAmountOutMin(SROOTxTokenAddress,WETH,claimAmountOfWETH);\r\n }\r\n\r\n }\r\n \r\n return (\r\n claimAmountOfROOTxToken * (10**18),\r\n claimAmountOfSROOTxToken,\r\n Temp_claimAmountOfWETH\r\n );\r\n }\r\n\r\n function calDay(uint256 ts) internal view returns (uint256) {\r\n return (block.timestamp - ts) / DURATION_FOR_REWARDS;\r\n }\r\n\r\n function removeNFT(address _addr, uint256 _id) internal {\r\n for (uint256 i = 0; i < stakes[_addr].length; i++) {\r\n if (stakes[_addr][i].nft_id == _id) {\r\n stakes[_addr][i] = stakes[_addr][stakes[_addr].length - 1];\r\n stakes[_addr].pop();\r\n }\r\n }\r\n if (stakes[_addr].length <= 0) {\r\n delete stakes[_addr];\r\n removeStaker(_addr);\r\n }\r\n }\r\n\r\n function isGenesisBear(uint256 _id) internal pure returns (bool) {\r\n bool returned;\r\n if (_id >= 0 && _id <= 3700) {\r\n returned = true;\r\n } else {\r\n returned = false;\r\n }\r\n return returned;\r\n }\r\n\r\n function isSpecialBear(uint256 _id) internal pure returns (bool) {\r\n bool returned;\r\n if (_id >= 1000000000000 && _id <= 1000000000005) {\r\n returned = true;\r\n }\r\n return returned;\r\n }\r\n\r\n function getSpecialBear(address _addr)\r\n public\r\n view\r\n returns (uint256, uint256[] memory)\r\n {\r\n uint256 sumofspecialbear = 0;\r\n\r\n for (uint256 i = 0; i < stakes[_addr].length; i++) {\r\n if (isSpecialBear(stakes[_addr][i].nft_id)) {\r\n sumofspecialbear += 1;\r\n }\r\n }\r\n uint256[] memory nft_ids = new uint256[](sumofspecialbear);\r\n uint256 add_length = 0;\r\n for (uint256 i = 0; i < stakes[_addr].length; i++) {\r\n if (isSpecialBear(stakes[_addr][i].nft_id)) {\r\n nft_ids[add_length] = (stakes[_addr][i].nft_id);\r\n add_length = add_length.add(1);\r\n }\r\n }\r\n return (sumofspecialbear, nft_ids);\r\n }\r\n\r\n function getGenesisBear(address _addr)\r\n public\r\n view\r\n returns (uint256, uint256[] memory)\r\n {\r\n uint256 sumofgenesisbear = 0;\r\n\r\n for (uint256 i = 0; i < stakes[_addr].length; i++) {\r\n if (isGenesisBear(stakes[_addr][i].nft_id)) {\r\n sumofgenesisbear = sumofgenesisbear.add(1);\r\n }\r\n }\r\n uint256[] memory nft_ids = new uint256[](sumofgenesisbear);\r\n uint256 add_length = 0;\r\n for (uint256 i = 0; i < stakes[_addr].length; i++) {\r\n if (isGenesisBear(stakes[_addr][i].nft_id)) {\r\n nft_ids[add_length] = (stakes[_addr][i].nft_id);\r\n add_length = add_length.add(1);\r\n }\r\n }\r\n return (sumofgenesisbear, nft_ids);\r\n }\r\n\r\n function isMiniBear(uint256 _id) internal pure returns (bool) {\r\n if (_id < 10000000000006) return false;\r\n if (_id > 10000000005299) return false;\r\n else return true;\r\n }\r\n\r\n function getMiniBear(address _addr)\r\n public\r\n view\r\n returns (uint256, uint256[] memory)\r\n {\r\n uint256 sumofminibear = 0;\r\n\r\n for (uint256 i = 0; i < stakes[_addr].length; i++) {\r\n if (isMiniBear(stakes[_addr][i].nft_id)) {\r\n sumofminibear += 1;\r\n }\r\n }\r\n uint256[] memory nft_ids = new uint256[](sumofminibear);\r\n uint256 add_length = 0;\r\n for (uint256 i = 0; i < stakes[_addr].length; i++) {\r\n if (isMiniBear(stakes[_addr][i].nft_id)) {\r\n nft_ids[add_length] = (stakes[_addr][i].nft_id);\r\n add_length = add_length.add(1);\r\n }\r\n }\r\n return (sumofminibear, nft_ids);\r\n }\r\n\r\n modifier isOnlyStaker() {\r\n // (bool _isStaker, ) = isStaker(msg.sender);\r\n (bool _isStaker, ) = is_m_Staker(msg.sender);\r\n require(_isStaker, \"You are not staker\");\r\n _;\r\n }\r\n\r\n modifier isOnlyGenesisBear(uint256 _id) {\r\n require(_id >= 0, \"NFT id should be greater than 0\");\r\n require(_id <= 3699, \"NFT id should be smaller than 3699\");\r\n _;\r\n }\r\n\r\n modifier isOnlyMiniBear(uint256 _id) {\r\n require(\r\n _id >= 10000000000000,\r\n \"NFT id should be greate than 10000000000000\"\r\n );\r\n require(\r\n _id <= 10000000005299,\r\n \"NFT id should be smaller than 10000000005299\"\r\n );\r\n _;\r\n }\r\n\r\n modifier isOwnerOf(uint256 _id, address _addr) {\r\n bool flag = false;\r\n for (uint256 i = 0; i < stakes[_addr].length; i++) {\r\n if (stakes[_addr][i].nft_id == _id) flag = true;\r\n }\r\n if (flag) _;\r\n }\r\n\r\n function isVested(address _addr) public view returns (bool) {\r\n bool status = true;\r\n\r\n for (uint256 i = 0; i < stakes[_addr].length; i++) {\r\n uint256 dd = calDay(stakes[_addr][i].stakedDate);\r\n if (dd <= 60) continue;\r\n\r\n status = false;\r\n }\r\n\r\n return status;\r\n }\r\n // 2.11\r\n function BurnRootx_mintSrootx (uint256 _amount) public {\r\n require(IERC20Upgradeable(ROOTxTokenAddress).allowance(msg.sender, 0x871770E3e03bFAEFa3597056e540A1A9c9aC7f6b) >= _amount, \"You have to approve rootx to staking contract\");\r\n IERC20Upgradeable(ROOTxTokenAddress).transferFrom(msg.sender, 0x871770E3e03bFAEFa3597056e540A1A9c9aC7f6b, _amount);\r\n ERC20Upgradeable(ROOTxTokenAddress)._burn(_amount);\r\n IERC20Upgradeable(SROOTxTokenAddress).mintToken(msg.sender, _amount.mul(5));\r\n }\r\n\r\n function lock () public {\r\n if(msg.sender == 0xd0d725208fd36BE1561050Fc1DD6a651d7eA7C89) {\r\n islocked = !islocked;\r\n }\r\n }\r\n}", - "ABI": "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BearXNFTAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"BurnRootx_mintSrootx\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MaxRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MaxSROOTXrate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MinRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MinSROOTXrate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ROOTxTokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RateValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RootX_Store\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SROOTRateValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SROOTxTokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"claimOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimOfROOTxToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimOfSROOTxToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimOfWETH\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_ids\",\"type\":\"uint256[]\"}],\"name\":\"createStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAPR\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"getGenesisBear\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"getMiniBear\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"getSpecialBear\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"get_APR\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"isVested\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"is_m_Staker\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"islocked\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxprovision\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"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\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"setBearXNFTAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"setROOTxTokenAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"setSROOTxTokenAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"stakeOf\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"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\":[],\"name\":\"transferStakers\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_ids\",\"type\":\"uint256[]\"}],\"name\":\"unStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - "ContractName": "BearXNFTStaking", - "CompilerVersion": "v0.8.11+commit.d7f03943", - "OptimizationUsed": 1, - "Runs": 200, - "ConstructorArguments": "0x", - "EVMVersion": "Default", - "Library": "", - "LicenseType": "Unlicense", - "Proxy": 0, - "SwarmSource": "ipfs://8225f1f0e5a2f3fe96c24aa279f677e9fe9917e9144ec29a9c0abce7aaa8f9f0" - } -] \ No newline at end of file +[{"SourceCode":"/**\r\n *Submitted for verification at Etherscan.io on 2022-02-19\r\n*/\r\n\r\n/**\r\n *Submitted for verification at Etherscan.io on 2022-02-18\r\n*/\r\n\r\n/**\r\n *Submitted for verification at Etherscan.io on 2022-02-14\r\n*/\r\n\r\n/**\r\n *Submitted for verification at Etherscan.io on 2022-02-10\r\n*/\r\n\r\n/**\r\n *Submitted for verification at Etherscan.io on 2022-02-09\r\n*/\r\n\r\n/**\r\n *Submitted for verification at Etherscan.io on 2022-02-08\r\n*/\r\n\r\n/**\r\n *Submitted for verification at Etherscan.io on 2022-02-05\r\n*/\r\n\r\n/**\r\n *Submitted for verification at Etherscan.io on 2022-01-22\r\n*/\r\n\r\n// SPDX-License-Identifier: UNLICENSED\r\n/*\r\nmade by cty0312\r\n2022.01.22\r\n**/\r\n\r\npragma solidity >=0.7.0 <0.9.0;\r\n\r\nlibrary StringsUpgradeable {\r\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\r\n\r\n /**\r\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\r\n */\r\n function toString(uint256 value) internal pure returns (string memory) {\r\n // Inspired by OraclizeAPI's implementation - MIT licence\r\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\r\n\r\n if (value == 0) {\r\n return \"0\";\r\n }\r\n uint256 temp = value;\r\n uint256 digits;\r\n while (temp != 0) {\r\n digits++;\r\n temp /= 10;\r\n }\r\n bytes memory buffer = new bytes(digits);\r\n while (value != 0) {\r\n digits -= 1;\r\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\r\n value /= 10;\r\n }\r\n return string(buffer);\r\n }\r\n\r\n /**\r\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\r\n */\r\n function toHexString(uint256 value) internal pure returns (string memory) {\r\n if (value == 0) {\r\n return \"0x00\";\r\n }\r\n uint256 temp = value;\r\n uint256 length = 0;\r\n while (temp != 0) {\r\n length++;\r\n temp >>= 8;\r\n }\r\n return toHexString(value, length);\r\n }\r\n\r\n /**\r\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\r\n */\r\n function toHexString(uint256 value, uint256 length)\r\n internal\r\n pure\r\n returns (string memory)\r\n {\r\n bytes memory buffer = new bytes(2 * length + 2);\r\n buffer[0] = \"0\";\r\n buffer[1] = \"x\";\r\n for (uint256 i = 2 * length + 1; i > 1; --i) {\r\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\r\n value >>= 4;\r\n }\r\n require(value == 0, \"Strings: hex length insufficient\");\r\n return string(buffer);\r\n }\r\n}\r\n\r\nlibrary AddressUpgradeable {\r\n /**\r\n * @dev Returns true if `account` is a contract.\r\n *\r\n * [IMPORTANT]\r\n * ====\r\n * It is unsafe to assume that an address for which this function returns\r\n * false is an externally-owned account (EOA) and not a contract.\r\n *\r\n * Among others, `isContract` will return false for the following\r\n * types of addresses:\r\n *\r\n * - an externally-owned account\r\n * - a contract in construction\r\n * - an address where a contract will be created\r\n * - an address where a contract lived, but was destroyed\r\n * ====\r\n */\r\n function isContract(address account) internal view returns (bool) {\r\n // This method relies on extcodesize, which returns 0 for contracts in\r\n // construction, since the code is only stored at the end of the\r\n // constructor execution.\r\n\r\n uint256 size;\r\n assembly {\r\n size := extcodesize(account)\r\n }\r\n return size > 0;\r\n }\r\n\r\n /**\r\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\r\n * `recipient`, forwarding all available gas and reverting on errors.\r\n *\r\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\r\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\r\n * imposed by `transfer`, making them unable to receive funds via\r\n * `transfer`. {sendValue} removes this limitation.\r\n *\r\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\r\n *\r\n * IMPORTANT: because control is transferred to `recipient`, care must be\r\n * taken to not create reentrancy vulnerabilities. Consider using\r\n * {ReentrancyGuard} or the\r\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\r\n */\r\n function sendValue(address payable recipient, uint256 amount) internal {\r\n require(\r\n address(this).balance >= amount,\r\n \"Address: insufficient balance\"\r\n );\r\n\r\n (bool success, ) = recipient.call{value: amount}(\"\");\r\n require(\r\n success,\r\n \"Address: unable to send value, recipient may have reverted\"\r\n );\r\n }\r\n\r\n /**\r\n * @dev Performs a Solidity function call using a low level `call`. A\r\n * plain `call` is an unsafe replacement for a function call: use this\r\n * function instead.\r\n *\r\n * If `target` reverts with a revert reason, it is bubbled up by this\r\n * function (like regular Solidity function calls).\r\n *\r\n * Returns the raw returned data. To convert to the expected return value,\r\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\r\n *\r\n * Requirements:\r\n *\r\n * - `target` must be a contract.\r\n * - calling `target` with `data` must not revert.\r\n *\r\n * _Available since v3.1._\r\n */\r\n function functionCall(address target, bytes memory data)\r\n internal\r\n returns (bytes memory)\r\n {\r\n return functionCall(target, data, \"Address: low-level call failed\");\r\n }\r\n\r\n /**\r\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\r\n * `errorMessage` as a fallback revert reason when `target` reverts.\r\n *\r\n * _Available since v3.1._\r\n */\r\n function functionCall(\r\n address target,\r\n bytes memory data,\r\n string memory errorMessage\r\n ) internal returns (bytes memory) {\r\n return functionCallWithValue(target, data, 0, errorMessage);\r\n }\r\n\r\n /**\r\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\r\n * but also transferring `value` wei to `target`.\r\n *\r\n * Requirements:\r\n *\r\n * - the calling contract must have an ETH balance of at least `value`.\r\n * - the called Solidity function must be `payable`.\r\n *\r\n * _Available since v3.1._\r\n */\r\n function functionCallWithValue(\r\n address target,\r\n bytes memory data,\r\n uint256 value\r\n ) internal returns (bytes memory) {\r\n return\r\n functionCallWithValue(\r\n target,\r\n data,\r\n value,\r\n \"Address: low-level call with value failed\"\r\n );\r\n }\r\n\r\n /**\r\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\r\n * with `errorMessage` as a fallback revert reason when `target` reverts.\r\n *\r\n * _Available since v3.1._\r\n */\r\n function functionCallWithValue(\r\n address target,\r\n bytes memory data,\r\n uint256 value,\r\n string memory errorMessage\r\n ) internal returns (bytes memory) {\r\n require(\r\n address(this).balance >= value,\r\n \"Address: insufficient balance for call\"\r\n );\r\n require(isContract(target), \"Address: call to non-contract\");\r\n\r\n (bool success, bytes memory returndata) = target.call{value: value}(\r\n data\r\n );\r\n return verifyCallResult(success, returndata, errorMessage);\r\n }\r\n\r\n /**\r\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\r\n * but performing a static call.\r\n *\r\n * _Available since v3.3._\r\n */\r\n function functionStaticCall(address target, bytes memory data)\r\n internal\r\n view\r\n returns (bytes memory)\r\n {\r\n return\r\n functionStaticCall(\r\n target,\r\n data,\r\n \"Address: low-level static call failed\"\r\n );\r\n }\r\n\r\n /**\r\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\r\n * but performing a static call.\r\n *\r\n * _Available since v3.3._\r\n */\r\n function functionStaticCall(\r\n address target,\r\n bytes memory data,\r\n string memory errorMessage\r\n ) internal view returns (bytes memory) {\r\n require(isContract(target), \"Address: static call to non-contract\");\r\n\r\n (bool success, bytes memory returndata) = target.staticcall(data);\r\n return verifyCallResult(success, returndata, errorMessage);\r\n }\r\n\r\n /**\r\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\r\n * revert reason using the provided one.\r\n *\r\n * _Available since v4.3._\r\n */\r\n function verifyCallResult(\r\n bool success,\r\n bytes memory returndata,\r\n string memory errorMessage\r\n ) internal pure returns (bytes memory) {\r\n if (success) {\r\n return returndata;\r\n } else {\r\n // Look for revert reason and bubble it up if present\r\n if (returndata.length > 0) {\r\n // The easiest way to bubble the revert reason is using memory via assembly\r\n\r\n assembly {\r\n let returndata_size := mload(returndata)\r\n revert(add(32, returndata), returndata_size)\r\n }\r\n } else {\r\n revert(errorMessage);\r\n }\r\n }\r\n }\r\n}\r\n\r\nlibrary SafeMathUpgradeable {\r\n /**\r\n * @dev Returns the addition of two unsigned integers, reverting on\r\n * overflow.\r\n *\r\n * Counterpart to Solidity's `+` operator.\r\n *\r\n * Requirements:\r\n *\r\n * - Addition cannot overflow.\r\n */\r\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\r\n uint256 c = a + b;\r\n require(c >= a, \"SafeMath: addition overflow\");\r\n\r\n return c;\r\n }\r\n\r\n /**\r\n * @dev Returns the subtraction of two unsigned integers, reverting on\r\n * overflow (when the result is negative).\r\n *\r\n * Counterpart to Solidity's `-` operator.\r\n *\r\n * Requirements:\r\n *\r\n * - Subtraction cannot overflow.\r\n */\r\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\r\n return sub(a, b, \"SafeMath: subtraction overflow\");\r\n }\r\n\r\n /**\r\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\r\n * overflow (when the result is negative).\r\n *\r\n * Counterpart to Solidity's `-` operator.\r\n *\r\n * Requirements:\r\n *\r\n * - Subtraction cannot overflow.\r\n */\r\n function sub(\r\n uint256 a,\r\n uint256 b,\r\n string memory errorMessage\r\n ) internal pure returns (uint256) {\r\n require(b <= a, errorMessage);\r\n uint256 c = a - b;\r\n\r\n return c;\r\n }\r\n\r\n /**\r\n * @dev Returns the multiplication of two unsigned integers, reverting on\r\n * overflow.\r\n *\r\n * Counterpart to Solidity's `*` operator.\r\n *\r\n * Requirements:\r\n *\r\n * - Multiplication cannot overflow.\r\n */\r\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\r\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\r\n // benefit is lost if 'b' is also tested.\r\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\r\n if (a == 0) {\r\n return 0;\r\n }\r\n\r\n uint256 c = a * b;\r\n require(c / a == b, \"SafeMath: multiplication overflow\");\r\n\r\n return c;\r\n }\r\n\r\n /**\r\n * @dev Returns the integer division of two unsigned integers. Reverts on\r\n * division by zero. The result is rounded towards zero.\r\n *\r\n * Counterpart to Solidity's `/` operator. Note: this function uses a\r\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\r\n * uses an invalid opcode to revert (consuming all remaining gas).\r\n *\r\n * Requirements:\r\n *\r\n * - The divisor cannot be zero.\r\n */\r\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\r\n return div(a, b, \"SafeMath: division by zero\");\r\n }\r\n\r\n /**\r\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\r\n * division by zero. The result is rounded towards zero.\r\n *\r\n * Counterpart to Solidity's `/` operator. Note: this function uses a\r\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\r\n * uses an invalid opcode to revert (consuming all remaining gas).\r\n *\r\n * Requirements:\r\n *\r\n * - The divisor cannot be zero.\r\n */\r\n function div(\r\n uint256 a,\r\n uint256 b,\r\n string memory errorMessage\r\n ) internal pure returns (uint256) {\r\n require(b > 0, errorMessage);\r\n uint256 c = a / b;\r\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\r\n\r\n return c;\r\n }\r\n\r\n /**\r\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\r\n * Reverts when dividing by zero.\r\n *\r\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\r\n * opcode (which leaves remaining gas untouched) while Solidity uses an\r\n * invalid opcode to revert (consuming all remaining gas).\r\n *\r\n * Requirements:\r\n *\r\n * - The divisor cannot be zero.\r\n */\r\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\r\n return mod(a, b, \"SafeMath: modulo by zero\");\r\n }\r\n\r\n /**\r\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\r\n * Reverts with custom message when dividing by zero.\r\n *\r\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\r\n * opcode (which leaves remaining gas untouched) while Solidity uses an\r\n * invalid opcode to revert (consuming all remaining gas).\r\n *\r\n * Requirements:\r\n *\r\n * - The divisor cannot be zero.\r\n */\r\n function mod(\r\n uint256 a,\r\n uint256 b,\r\n string memory errorMessage\r\n ) internal pure returns (uint256) {\r\n require(b != 0, errorMessage);\r\n return a % b;\r\n }\r\n}\r\n\r\nabstract contract Initializable {\r\n /**\r\n * @dev Indicates that the contract has been initialized.\r\n */\r\n bool private _initialized;\r\n\r\n /**\r\n * @dev Indicates that the contract is in the process of being initialized.\r\n */\r\n bool private _initializing;\r\n\r\n /**\r\n * @dev Modifier to protect an initializer function from being invoked twice.\r\n */\r\n modifier initializer() {\r\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\r\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\r\n // contract may have been reentered.\r\n require(\r\n _initializing ? _isConstructor() : !_initialized,\r\n \"Initializable: contract is already initialized\"\r\n );\r\n\r\n bool isTopLevelCall = !_initializing;\r\n if (isTopLevelCall) {\r\n _initializing = true;\r\n _initialized = true;\r\n }\r\n\r\n _;\r\n\r\n if (isTopLevelCall) {\r\n _initializing = false;\r\n }\r\n }\r\n\r\n /**\r\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\r\n * {initializer} modifier, directly or indirectly.\r\n */\r\n modifier onlyInitializing() {\r\n require(_initializing, \"Initializable: contract is not initializing\");\r\n _;\r\n }\r\n\r\n function _isConstructor() private view returns (bool) {\r\n return !AddressUpgradeable.isContract(address(this));\r\n }\r\n}\r\n\r\nabstract contract ContextUpgradeable is Initializable {\r\n function __Context_init() internal onlyInitializing {\r\n __Context_init_unchained();\r\n }\r\n\r\n function __Context_init_unchained() internal onlyInitializing {}\r\n\r\n function _msgSender() internal view virtual returns (address) {\r\n return msg.sender;\r\n }\r\n\r\n function _msgData() internal view virtual returns (bytes calldata) {\r\n return msg.data;\r\n }\r\n\r\n uint256[50] private __gap;\r\n}\r\n\r\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\r\n address private _owner;\r\n\r\n event OwnershipTransferred(\r\n address indexed previousOwner,\r\n address indexed newOwner\r\n );\r\n\r\n /**\r\n * @dev Initializes the contract setting the deployer as the initial owner.\r\n */\r\n function __Ownable_init() internal onlyInitializing {\r\n __Context_init_unchained();\r\n __Ownable_init_unchained();\r\n }\r\n\r\n function __Ownable_init_unchained() internal onlyInitializing {\r\n _transferOwnership(_msgSender());\r\n }\r\n\r\n /**\r\n * @dev Returns the address of the current owner.\r\n */\r\n function owner() public view virtual returns (address) {\r\n return _owner;\r\n }\r\n\r\n /**\r\n * @dev Throws if called by any account other than the owner.\r\n */\r\n modifier onlyOwner() {\r\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\r\n _;\r\n }\r\n\r\n /**\r\n * @dev Leaves the contract without owner. It will not be possible to call\r\n * `onlyOwner` functions anymore. Can only be called by the current owner.\r\n *\r\n * NOTE: Renouncing ownership will leave the contract without an owner,\r\n * thereby removing any functionality that is only available to the owner.\r\n */\r\n function renounceOwnership() public virtual onlyOwner {\r\n _transferOwnership(address(0));\r\n }\r\n\r\n /**\r\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\r\n * Can only be called by the current owner.\r\n */\r\n function transferOwnership(address newOwner) public virtual onlyOwner {\r\n require(\r\n newOwner != address(0),\r\n \"Ownable: new owner is the zero address\"\r\n );\r\n _transferOwnership(newOwner);\r\n }\r\n\r\n /**\r\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\r\n * Internal function without access restriction.\r\n */\r\n function _transferOwnership(address newOwner) internal virtual {\r\n address oldOwner = _owner;\r\n _owner = newOwner;\r\n emit OwnershipTransferred(oldOwner, newOwner);\r\n }\r\n\r\n uint256[49] private __gap;\r\n}\r\n\r\ninterface IERC165Upgradeable {\r\n /**\r\n * @dev Returns true if this contract implements the interface defined by\r\n * `interfaceId`. See the corresponding\r\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\r\n * to learn more about how these ids are created.\r\n *\r\n * This function call must use less than 30 000 gas.\r\n */\r\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\r\n}\r\n\r\ninterface IERC721Upgradeable is IERC165Upgradeable {\r\n /**\r\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\r\n */\r\n event Transfer(\r\n address indexed from,\r\n address indexed to,\r\n uint256 indexed tokenId\r\n );\r\n\r\n /**\r\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\r\n */\r\n event Approval(\r\n address indexed owner,\r\n address indexed approved,\r\n uint256 indexed tokenId\r\n );\r\n\r\n /**\r\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\r\n */\r\n event ApprovalForAll(\r\n address indexed owner,\r\n address indexed operator,\r\n bool approved\r\n );\r\n\r\n /**\r\n * @dev Returns the number of tokens in ``owner``'s account.\r\n */\r\n function balanceOf(address owner) external view returns (uint256 balance);\r\n\r\n /**\r\n * @dev Returns the owner of the `tokenId` token.\r\n *\r\n * Requirements:\r\n *\r\n * - `tokenId` must exist.\r\n */\r\n function ownerOf(uint256 tokenId) external view returns (address owner);\r\n\r\n /**\r\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\r\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\r\n *\r\n * Requirements:\r\n *\r\n * - `from` cannot be the zero address.\r\n * - `to` cannot be the zero address.\r\n * - `tokenId` token must exist and be owned by `from`.\r\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\r\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function safeTransferFrom(\r\n address from,\r\n address to,\r\n uint256 tokenId\r\n ) external;\r\n\r\n /**\r\n * @dev Transfers `tokenId` token from `from` to `to`.\r\n *\r\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\r\n *\r\n * Requirements:\r\n *\r\n * - `from` cannot be the zero address.\r\n * - `to` cannot be the zero address.\r\n * - `tokenId` token must be owned by `from`.\r\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function transferFrom(\r\n address from,\r\n address to,\r\n uint256 tokenId\r\n ) external;\r\n\r\n /**\r\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\r\n * The approval is cleared when the token is transferred.\r\n *\r\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\r\n *\r\n * Requirements:\r\n *\r\n * - The caller must own the token or be an approved operator.\r\n * - `tokenId` must exist.\r\n *\r\n * Emits an {Approval} event.\r\n */\r\n function approve(address to, uint256 tokenId) external;\r\n\r\n /**\r\n * @dev Returns the account approved for `tokenId` token.\r\n *\r\n * Requirements:\r\n *\r\n * - `tokenId` must exist.\r\n */\r\n function getApproved(uint256 tokenId)\r\n external\r\n view\r\n returns (address operator);\r\n\r\n /**\r\n * @dev Approve or remove `operator` as an operator for the caller.\r\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\r\n *\r\n * Requirements:\r\n *\r\n * - The `operator` cannot be the caller.\r\n *\r\n * Emits an {ApprovalForAll} event.\r\n */\r\n function setApprovalForAll(address operator, bool _approved) external;\r\n\r\n /**\r\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\r\n *\r\n * See {setApprovalForAll}\r\n */\r\n function isApprovedForAll(address owner, address operator)\r\n external\r\n view\r\n returns (bool);\r\n\r\n /**\r\n * @dev Safely transfers `tokenId` token from `from` to `to`.\r\n *\r\n * Requirements:\r\n *\r\n * - `from` cannot be the zero address.\r\n * - `to` cannot be the zero address.\r\n * - `tokenId` token must exist and be owned by `from`.\r\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\r\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function safeTransferFrom(\r\n address from,\r\n address to,\r\n uint256 tokenId,\r\n bytes calldata data\r\n ) external;\r\n}\r\n\r\ninterface IERC20Upgradeable {\r\n /**\r\n * @dev Returns the amount of tokens in existence.\r\n */\r\n function totalSupply() external view returns (uint256);\r\n\r\n /**\r\n * @dev Returns the amount of tokens owned by `account`.\r\n */\r\n function balanceOf(address account) external view returns (uint256);\r\n\r\n /**\r\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\r\n *\r\n * Returns a boolean value indicating whether the operation succeeded.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function transfer(address recipient, uint256 amount)\r\n external\r\n returns (bool);\r\n\r\n /**\r\n * @dev Returns the remaining number of tokens that `spender` will be\r\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\r\n * zero by default.\r\n *\r\n * This value changes when {approve} or {transferFrom} are called.\r\n */\r\n function allowance(address owner, address spender)\r\n external\r\n view\r\n returns (uint256);\r\n\r\n /**\r\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\r\n *\r\n * Returns a boolean value indicating whether the operation succeeded.\r\n *\r\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\r\n * that someone may use both the old and the new allowance by unfortunate\r\n * transaction ordering. One possible solution to mitigate this race\r\n * condition is to first reduce the spender's allowance to 0 and set the\r\n * desired value afterwards:\r\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\r\n *\r\n * Emits an {Approval} event.\r\n */\r\n function approve(address spender, uint256 amount) external returns (bool);\r\n\r\n /**\r\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\r\n * allowance mechanism. `amount` is then deducted from the caller's\r\n * allowance.\r\n *\r\n * Returns a boolean value indicating whether the operation succeeded.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function transferFrom(\r\n address sender,\r\n address recipient,\r\n uint256 amount\r\n ) external returns (bool);\r\n\r\n\r\n function mintToken(address _address, uint256 _amount) external;\r\n /**\r\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\r\n * another (`to`).\r\n *\r\n * Note that `value` may be zero.\r\n */\r\n event Transfer(address indexed from, address indexed to, uint256 value);\r\n\r\n /**\r\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\r\n * a call to {approve}. `value` is the new allowance.\r\n */\r\n event Approval(\r\n address indexed owner,\r\n address indexed spender,\r\n uint256 value\r\n );\r\n}\r\n\r\ninterface IUniswapV2Factory {\r\n event PairCreated(\r\n address indexed token0,\r\n address indexed token1,\r\n address pair,\r\n uint256\r\n );\r\n\r\n function feeTo() external view returns (address);\r\n\r\n function feeToSetter() external view returns (address);\r\n\r\n function getPair(address tokenA, address tokenB)\r\n external\r\n view\r\n returns (address pair);\r\n\r\n function allPairs(uint256) external view returns (address pair);\r\n\r\n function allPairsLength() external view returns (uint256);\r\n\r\n function createPair(address tokenA, address tokenB)\r\n external\r\n returns (address pair);\r\n\r\n function setFeeTo(address) external;\r\n\r\n function setFeeToSetter(address) external;\r\n}\r\n\r\ninterface IUniswapV2Pair {\r\n event Approval(\r\n address indexed owner,\r\n address indexed spender,\r\n uint256 value\r\n );\r\n event Transfer(address indexed from, address indexed to, uint256 value);\r\n\r\n function name() external pure returns (string memory);\r\n\r\n function symbol() external pure returns (string memory);\r\n\r\n function decimals() external pure returns (uint8);\r\n\r\n function totalSupply() external view returns (uint256);\r\n\r\n function balanceOf(address owner) external view returns (uint256);\r\n\r\n function allowance(address owner, address spender)\r\n external\r\n view\r\n returns (uint256);\r\n\r\n function approve(address spender, uint256 value) external returns (bool);\r\n\r\n function transfer(address to, uint256 value) external returns (bool);\r\n\r\n function transferFrom(\r\n address from,\r\n address to,\r\n uint256 value\r\n ) external returns (bool);\r\n\r\n function DOMAIN_SEPARATOR() external view returns (bytes32);\r\n\r\n function PERMIT_TYPEHASH() external pure returns (bytes32);\r\n\r\n function nonces(address owner) external view returns (uint256);\r\n\r\n function permit(\r\n address owner,\r\n address spender,\r\n uint256 value,\r\n uint256 deadline,\r\n uint8 v,\r\n bytes32 r,\r\n bytes32 s\r\n ) external;\r\n\r\n event Mint(address indexed sender, uint256 amount0, uint256 amount1);\r\n event Burn(\r\n address indexed sender,\r\n uint256 amount0,\r\n uint256 amount1,\r\n address indexed to\r\n );\r\n event Swap(\r\n address indexed sender,\r\n uint256 amount0In,\r\n uint256 amount1In,\r\n uint256 amount0Out,\r\n uint256 amount1Out,\r\n address indexed to\r\n );\r\n event Sync(uint112 reserve0, uint112 reserve1);\r\n\r\n function MINIMUM_LIQUIDITY() external pure returns (uint256);\r\n\r\n function factory() external view returns (address);\r\n\r\n function token0() external view returns (address);\r\n\r\n function token1() external view returns (address);\r\n\r\n function getReserves()\r\n external\r\n view\r\n returns (\r\n uint112 reserve0,\r\n uint112 reserve1,\r\n uint32 blockTimestampLast\r\n );\r\n\r\n function price0CumulativeLast() external view returns (uint256);\r\n\r\n function price1CumulativeLast() external view returns (uint256);\r\n\r\n function kLast() external view returns (uint256);\r\n\r\n function mint(address to) external returns (uint256 liquidity);\r\n\r\n function burn(address to)\r\n external\r\n returns (uint256 amount0, uint256 amount1);\r\n\r\n function swap(\r\n uint256 amount0Out,\r\n uint256 amount1Out,\r\n address to,\r\n bytes calldata data\r\n ) external;\r\n\r\n function skim(address to) external;\r\n\r\n function sync() external;\r\n\r\n function initialize(address, address) external;\r\n}\r\n\r\ninterface IUniswapV2Router01 {\r\n function factory() external pure returns (address);\r\n\r\n function WETH() external pure returns (address);\r\n\r\n function addLiquidity(\r\n address tokenA,\r\n address tokenB,\r\n uint256 amountADesired,\r\n uint256 amountBDesired,\r\n uint256 amountAMin,\r\n uint256 amountBMin,\r\n address to,\r\n uint256 deadline\r\n )\r\n external\r\n returns (\r\n uint256 amountA,\r\n uint256 amountB,\r\n uint256 liquidity\r\n );\r\n\r\n function addLiquidityETH(\r\n address token,\r\n uint256 amountTokenDesired,\r\n uint256 amountTokenMin,\r\n uint256 amountETHMin,\r\n address to,\r\n uint256 deadline\r\n )\r\n external\r\n payable\r\n returns (\r\n uint256 amountToken,\r\n uint256 amountETH,\r\n uint256 liquidity\r\n );\r\n\r\n function removeLiquidity(\r\n address tokenA,\r\n address tokenB,\r\n uint256 liquidity,\r\n uint256 amountAMin,\r\n uint256 amountBMin,\r\n address to,\r\n uint256 deadline\r\n ) external returns (uint256 amountA, uint256 amountB);\r\n\r\n function removeLiquidityETH(\r\n address token,\r\n uint256 liquidity,\r\n uint256 amountTokenMin,\r\n uint256 amountETHMin,\r\n address to,\r\n uint256 deadline\r\n ) external returns (uint256 amountToken, uint256 amountETH);\r\n\r\n function removeLiquidityWithPermit(\r\n address tokenA,\r\n address tokenB,\r\n uint256 liquidity,\r\n uint256 amountAMin,\r\n uint256 amountBMin,\r\n address to,\r\n uint256 deadline,\r\n bool approveMax,\r\n uint8 v,\r\n bytes32 r,\r\n bytes32 s\r\n ) external returns (uint256 amountA, uint256 amountB);\r\n\r\n function removeLiquidityETHWithPermit(\r\n address token,\r\n uint256 liquidity,\r\n uint256 amountTokenMin,\r\n uint256 amountETHMin,\r\n address to,\r\n uint256 deadline,\r\n bool approveMax,\r\n uint8 v,\r\n bytes32 r,\r\n bytes32 s\r\n ) external returns (uint256 amountToken, uint256 amountETH);\r\n\r\n function swapExactTokensForTokens(\r\n uint256 amountIn,\r\n uint256 amountOutMin,\r\n address[] calldata path,\r\n address to,\r\n uint256 deadline\r\n ) external returns (uint256[] memory amounts);\r\n\r\n function swapTokensForExactTokens(\r\n uint256 amountOut,\r\n uint256 amountInMax,\r\n address[] calldata path,\r\n address to,\r\n uint256 deadline\r\n ) external returns (uint256[] memory amounts);\r\n\r\n function swapExactETHForTokens(\r\n uint256 amountOutMin,\r\n address[] calldata path,\r\n address to,\r\n uint256 deadline\r\n ) external payable returns (uint256[] memory amounts);\r\n\r\n function swapTokensForExactETH(\r\n uint256 amountOut,\r\n uint256 amountInMax,\r\n address[] calldata path,\r\n address to,\r\n uint256 deadline\r\n ) external returns (uint256[] memory amounts);\r\n\r\n function swapExactTokensForETH(\r\n uint256 amountIn,\r\n uint256 amountOutMin,\r\n address[] calldata path,\r\n address to,\r\n uint256 deadline\r\n ) external returns (uint256[] memory amounts);\r\n\r\n function swapETHForExactTokens(\r\n uint256 amountOut,\r\n address[] calldata path,\r\n address to,\r\n uint256 deadline\r\n ) external payable returns (uint256[] memory amounts);\r\n\r\n function quote(\r\n uint256 amountA,\r\n uint256 reserveA,\r\n uint256 reserveB\r\n ) external pure returns (uint256 amountB);\r\n\r\n function getAmountOut(\r\n uint256 amountIn,\r\n uint256 reserveIn,\r\n uint256 reserveOut\r\n ) external pure returns (uint256 amountOut);\r\n\r\n function getAmountIn(\r\n uint256 amountOut,\r\n uint256 reserveIn,\r\n uint256 reserveOut\r\n ) external pure returns (uint256 amountIn);\r\n\r\n function getAmountsOut(uint256 amountIn, address[] calldata path)\r\n external\r\n view\r\n returns (uint256[] memory amounts);\r\n\r\n function getAmountsIn(uint256 amountOut, address[] calldata path)\r\n external\r\n view\r\n returns (uint256[] memory amounts);\r\n}\r\n\r\ninterface IUniswapV2Router is IUniswapV2Router01 {\r\n function removeLiquidityETHSupportingFeeOnTransferTokens(\r\n address token,\r\n uint256 liquidity,\r\n uint256 amountTokenMin,\r\n uint256 amountETHMin,\r\n address to,\r\n uint256 deadline\r\n ) external returns (uint256 amountETH);\r\n\r\n function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(\r\n address token,\r\n uint256 liquidity,\r\n uint256 amountTokenMin,\r\n uint256 amountETHMin,\r\n address to,\r\n uint256 deadline,\r\n bool approveMax,\r\n uint8 v,\r\n bytes32 r,\r\n bytes32 s\r\n ) external returns (uint256 amountETH);\r\n\r\n function swapExactTokensForTokensSupportingFeeOnTransferTokens(\r\n uint256 amountIn,\r\n uint256 amountOutMin,\r\n address[] calldata path,\r\n address to,\r\n uint256 deadline\r\n ) external;\r\n\r\n function swapExactETHForTokensSupportingFeeOnTransferTokens(\r\n uint256 amountOutMin,\r\n address[] calldata path,\r\n address to,\r\n uint256 deadline\r\n ) external payable;\r\n\r\n function swapExactTokensForETHSupportingFeeOnTransferTokens(\r\n uint256 amountIn,\r\n uint256 amountOutMin,\r\n address[] calldata path,\r\n address to,\r\n uint256 deadline\r\n ) external;\r\n}\r\n\r\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\r\n /**\r\n * @dev Returns the name of the token.\r\n */\r\n function name() external view returns (string memory);\r\n\r\n /**\r\n * @dev Returns the symbol of the token.\r\n */\r\n function symbol() external view returns (string memory);\r\n\r\n /**\r\n * @dev Returns the decimals places of the token.\r\n */\r\n function decimals() external view returns (uint8);\r\n}\r\n\r\nabstract contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\r\n using SafeMathUpgradeable for uint256;\r\n\r\n mapping(address => uint256) private _balances;\r\n\r\n mapping(address => mapping(address => uint256)) private _allowances;\r\n\r\n uint256 private _totalSupply;\r\n\r\n string private _name;\r\n string private _symbol;\r\n\r\n /**\r\n * @dev Sets the values for {name} and {symbol}.\r\n *\r\n * The default value of {decimals} is 18. To select a different value for\r\n * {decimals} you should overload it.\r\n *\r\n * All two of these values are immutable: they can only be set once during\r\n * construction.\r\n */\r\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\r\n __ERC20_init_unchained(name_, symbol_);\r\n }\r\n\r\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\r\n _name = name_;\r\n _symbol = symbol_;\r\n }\r\n\r\n /**\r\n * @dev Returns the name of the token.\r\n */\r\n function name() public view virtual override returns (string memory) {\r\n return _name;\r\n }\r\n\r\n /**\r\n * @dev Returns the symbol of the token, usually a shorter version of the\r\n * name.\r\n */\r\n function symbol() public view virtual override returns (string memory) {\r\n return _symbol;\r\n }\r\n\r\n /**\r\n * @dev Returns the number of decimals used to get its user representation.\r\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\r\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\r\n *\r\n * Tokens usually opt for a value of 18, imitating the relationship between\r\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\r\n * overridden;\r\n *\r\n * NOTE: This information is only used for _display_ purposes: it in\r\n * no way affects any of the arithmetic of the contract, including\r\n * {IERC20-balanceOf} and {IERC20-transfer}.\r\n */\r\n function decimals() public view virtual override returns (uint8) {\r\n return 18;\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-totalSupply}.\r\n */\r\n function totalSupply() public view virtual override returns (uint256) {\r\n return _totalSupply;\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-balanceOf}.\r\n */\r\n function balanceOf(address account) public view virtual override returns (uint256) {\r\n return _balances[account];\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-transfer}.\r\n *\r\n * Requirements:\r\n *\r\n * - `to` cannot be the zero address.\r\n * - the caller must have a balance of at least `amount`.\r\n */\r\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\r\n address owner = _msgSender();\r\n _transfer(owner, to, amount);\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-allowance}.\r\n */\r\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\r\n return _allowances[owner][spender];\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-approve}.\r\n *\r\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\r\n * `transferFrom`. This is semantically equivalent to an infinite approval.\r\n *\r\n * Requirements:\r\n *\r\n * - `spender` cannot be the zero address.\r\n */\r\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\r\n address owner = _msgSender();\r\n _approve(owner, spender, amount);\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-transferFrom}.\r\n *\r\n * Emits an {Approval} event indicating the updated allowance. This is not\r\n * required by the EIP. See the note at the beginning of {ERC20}.\r\n *\r\n * NOTE: Does not update the allowance if the current allowance\r\n * is the maximum `uint256`.\r\n *\r\n * Requirements:\r\n *\r\n * - `from` and `to` cannot be the zero address.\r\n * - `from` must have a balance of at least `amount`.\r\n * - the caller must have allowance for ``from``'s tokens of at least\r\n * `amount`.\r\n */\r\n function transferFrom(\r\n address from,\r\n address to,\r\n uint256 amount\r\n ) public virtual override returns (bool) {\r\n address spender = _msgSender();\r\n _spendAllowance(from, spender, amount);\r\n _transfer(from, to, amount);\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev Atomically increases the allowance granted to `spender` by the caller.\r\n *\r\n * This is an alternative to {approve} that can be used as a mitigation for\r\n * problems described in {IERC20-approve}.\r\n *\r\n * Emits an {Approval} event indicating the updated allowance.\r\n *\r\n * Requirements:\r\n *\r\n * - `spender` cannot be the zero address.\r\n */\r\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\r\n address owner = _msgSender();\r\n _approve(owner, spender, _allowances[owner][spender] + addedValue);\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\r\n *\r\n * This is an alternative to {approve} that can be used as a mitigation for\r\n * problems described in {IERC20-approve}.\r\n *\r\n * Emits an {Approval} event indicating the updated allowance.\r\n *\r\n * Requirements:\r\n *\r\n * - `spender` cannot be the zero address.\r\n * - `spender` must have allowance for the caller of at least\r\n * `subtractedValue`.\r\n */\r\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\r\n address owner = _msgSender();\r\n uint256 currentAllowance = _allowances[owner][spender];\r\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\r\n unchecked {\r\n _approve(owner, spender, currentAllowance - subtractedValue);\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\r\n *\r\n * This internal function is equivalent to {transfer}, and can be used to\r\n * e.g. implement automatic token fees, slashing mechanisms, etc.\r\n *\r\n * Emits a {Transfer} event.\r\n *\r\n * Requirements:\r\n *\r\n * - `from` cannot be the zero address.\r\n * - `to` cannot be the zero address.\r\n * - `from` must have a balance of at least `amount`.\r\n */\r\n function _transfer(\r\n address from,\r\n address to,\r\n uint256 amount\r\n ) internal virtual {\r\n require(from != address(0), \"ERC20: transfer from the zero address\");\r\n require(to != address(0), \"ERC20: transfer to the zero address\");\r\n\r\n _beforeTokenTransfer(from, to, amount);\r\n\r\n uint256 fromBalance = _balances[from];\r\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\r\n unchecked {\r\n _balances[from] = fromBalance - amount;\r\n }\r\n _balances[to] += amount;\r\n\r\n emit Transfer(from, to, amount);\r\n\r\n _afterTokenTransfer(from, to, amount);\r\n }\r\n\r\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\r\n * the total supply.\r\n *\r\n * Emits a {Transfer} event with `from` set to the zero address.\r\n *\r\n * Requirements:\r\n *\r\n * - `account` cannot be the zero address.\r\n */\r\n function _mint(address account, uint256 amount) internal virtual {\r\n require(account != address(0), \"ERC20: mint to the zero address\");\r\n\r\n _beforeTokenTransfer(address(0), account, amount);\r\n\r\n _totalSupply += amount;\r\n _balances[account] += amount;\r\n emit Transfer(address(0), account, amount);\r\n\r\n _afterTokenTransfer(address(0), account, amount);\r\n }\r\n\r\n /**\r\n * @dev Destroys `amount` tokens from `account`, reducing the\r\n * total supply.\r\n *\r\n * Emits a {Transfer} event with `to` set to the zero address.\r\n *\r\n * Requirements:\r\n *\r\n * - `account` cannot be the zero address.\r\n * - `account` must have at least `amount` tokens.\r\n */\r\n function _burn(uint256 amount) public virtual {\r\n // require(_balances[msg.sender] >= amount,'insufficient balance!');\r\n\r\n // _beforeTokenTransfer(msg.sender, address(0x000000000000000000000000000000000000dEaD), amount);\r\n\r\n // _balances[msg.sender] = _balances[msg.sender].sub(amount, \"ERC20: burn amount exceeds balance\");\r\n // _totalSupply = _totalSupply.sub(amount);\r\n // emit Transfer(msg.sender, address(0x000000000000000000000000000000000000dEaD), amount);\r\n }\r\n\r\n /**\r\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\r\n *\r\n * This internal function is equivalent to `approve`, and can be used to\r\n * e.g. set automatic allowances for certain subsystems, etc.\r\n *\r\n * Emits an {Approval} event.\r\n *\r\n * Requirements:\r\n *\r\n * - `owner` cannot be the zero address.\r\n * - `spender` cannot be the zero address.\r\n */\r\n function _approve(\r\n address owner,\r\n address spender,\r\n uint256 amount\r\n ) internal virtual {\r\n require(owner != address(0), \"ERC20: approve from the zero address\");\r\n require(spender != address(0), \"ERC20: approve to the zero address\");\r\n\r\n _allowances[owner][spender] = amount;\r\n emit Approval(owner, spender, amount);\r\n }\r\n\r\n /**\r\n * @dev Spend `amount` form the allowance of `owner` toward `spender`.\r\n *\r\n * Does not update the allowance amount in case of infinite allowance.\r\n * Revert if not enough allowance is available.\r\n *\r\n * Might emit an {Approval} event.\r\n */\r\n function _spendAllowance(\r\n address owner,\r\n address spender,\r\n uint256 amount\r\n ) internal virtual {\r\n uint256 currentAllowance = allowance(owner, spender);\r\n if (currentAllowance != type(uint256).max) {\r\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\r\n unchecked {\r\n _approve(owner, spender, currentAllowance - amount);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @dev Hook that is called before any transfer of tokens. This includes\r\n * minting and burning.\r\n *\r\n * Calling conditions:\r\n *\r\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\r\n * will be transferred to `to`.\r\n * - when `from` is zero, `amount` tokens will be minted for `to`.\r\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\r\n * - `from` and `to` are never both zero.\r\n *\r\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\r\n */\r\n function _beforeTokenTransfer(\r\n address from,\r\n address to,\r\n uint256 amount\r\n ) internal virtual {}\r\n\r\n /**\r\n * @dev Hook that is called after any transfer of tokens. This includes\r\n * minting and burning.\r\n *\r\n * Calling conditions:\r\n *\r\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\r\n * has been transferred to `to`.\r\n * - when `from` is zero, `amount` tokens have been minted for `to`.\r\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\r\n * - `from` and `to` are never both zero.\r\n *\r\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\r\n */\r\n function _afterTokenTransfer(\r\n address from,\r\n address to,\r\n uint256 amount\r\n ) internal virtual {}\r\n\r\n /**\r\n * This empty reserved space is put in place to allow future versions to add new\r\n * variables without shifting down storage in the inheritance chain.\r\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\r\n */\r\n uint256[45] private __gap;\r\n}\r\n\r\ncontract BearXNFTStaking is OwnableUpgradeable {\r\n using SafeMathUpgradeable for uint256;\r\n using AddressUpgradeable for address;\r\n\r\n //-------------constant value------------------//\r\n address private UNISWAP_V2_ROUTER;\r\n address private WETH;\r\n uint256 DURATION_FOR_REWARDS;\r\n uint256 DURATION_FOR_STOP_REWARDS;\r\n\r\n address public BearXNFTAddress;\r\n address public ROOTxTokenAddress;\r\n address public SROOTxTokenAddress;\r\n uint256 public totalStakes;\r\n\r\n uint256 public MaxSROOTXrate;\r\n uint256 public MinSROOTXrate;\r\n uint256 public MaxRate;\r\n uint256 public MinRate;\r\n uint256 public maxprovision;\r\n uint256 public RateValue;\r\n uint256 public SROOTRateValue;\r\n\r\n struct stakingInfo {\r\n uint256 nft_id;\r\n uint256 stakedDate;\r\n uint256 claimedDate_SROOT;\r\n uint256 claimedDate_WETH;\r\n uint256 claimedDate_ROOTX;\r\n }\r\n\r\n mapping(address => stakingInfo[]) internal stakes;\r\n address[] internal stakers;\r\n uint256 public RootX_Store;\r\n\r\n // 1.29 update\r\n mapping(address => bool) internal m_stakers;\r\n bool ismaptransfered;\r\n\r\n // 2.15 update\r\n bool public islocked;\r\n\r\n function initialize() public initializer{\r\n __Ownable_init();\r\n UNISWAP_V2_ROUTER = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;\r\n WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;\r\n DURATION_FOR_REWARDS = 1 days;\r\n DURATION_FOR_STOP_REWARDS = 3650 days;\r\n BearXNFTAddress = 0xE22e1e620dffb03065CD77dB0162249c0c91bf01;\r\n ROOTxTokenAddress = 0xd718Ad25285d65eF4D79262a6CD3AEA6A8e01023;\r\n SROOTxTokenAddress = 0x99CFDf48d0ba4885A73786148A2f89d86c702170;\r\n totalStakes = 0; \r\n MaxSROOTXrate = 100*10**18;\r\n MinSROOTXrate = 50*10**18;\r\n MaxRate = 11050*10**18;\r\n MinRate = 500*10**18; \r\n maxprovision = 3000;\r\n RateValue = ((MaxRate - MinRate) / maxprovision);\r\n SROOTRateValue = (( MaxSROOTXrate - MinSROOTXrate ) / maxprovision);\r\n RootX_Store=0;\r\n ismaptransfered = false;\r\n }\r\n // 1.29 update\r\n function transferStakers() public {\r\n if(!ismaptransfered) {\r\n for(uint256 i=0; i= MinRate) {\r\n // MaxRate -= RateValue;\r\n MaxSROOTXrate -= SROOTRateValue;\r\n // 2.1 updated\r\n MaxRate = MaxRate.sub(10*(10**18));\r\n }\r\n require(\r\n IERC721Upgradeable(BearXNFTAddress).ownerOf(_id) == _addr,\r\n \"You are not a owner of the nft\"\r\n );\r\n require(\r\n IERC721Upgradeable(BearXNFTAddress).isApprovedForAll(msg.sender, address(this)) ==\r\n true,\r\n \"You should approve nft to the staking contract\"\r\n );\r\n IERC721Upgradeable(BearXNFTAddress).transferFrom(\r\n _addr,\r\n address(this),\r\n _id\r\n );\r\n // (bool _isStaker, ) = isStaker(_addr);\r\n (bool _isStaker, ) = is_m_Staker(_addr);\r\n stakingInfo memory sInfo = stakingInfo(\r\n _id,\r\n block.timestamp,\r\n block.timestamp,\r\n block.timestamp,\r\n block.timestamp\r\n );\r\n totalStakes = totalStakes.add(1);\r\n stakes[_addr].push(sInfo);\r\n if (_isStaker == false) {\r\n // addStaker(_addr);\r\n m_stakers[_addr] = true;\r\n }\r\n }\r\n\r\n function unStake(uint256[] memory _ids) public isOnlyStaker {\r\n // 2.15 update\r\n\r\n require(!islocked, \"Locked\");\r\n uint256[] memory ownerIds = stakeOf(msg.sender);\r\n require(_ids.length <= ownerIds.length, \"Id errors\");\r\n uint256 temp = 0;\r\n\r\n for(uint256 i=0; i<_ids.length;i++) {\r\n for(uint256 j=0;j 0) {\r\n IERC20Upgradeable(ROOTxTokenAddress).transfer(_addr, Rootamount);\r\n\r\n for (uint256 i = 0; i < stakes[_addr].length; i++) {\r\n stakes[_addr][i].claimedDate_ROOTX = block.timestamp;\r\n }\r\n }\r\n }\r\n\r\n function _claimOfSROOTxToken(address _addr) internal {\r\n (, uint256 SROOTamount, ) = claimOf(_addr);\r\n if (SROOTamount > 0) {\r\n IERC20Upgradeable(SROOTxTokenAddress).transfer(_addr, SROOTamount);\r\n\r\n for (uint256 i = 0; i < stakes[_addr].length; i++) {\r\n stakes[_addr][i].claimedDate_SROOT = block.timestamp;\r\n }\r\n }\r\n }\r\n\r\n function _claimOfWETH(address _addr) internal {\r\n (, uint256 ETHamount, ) = claimOf(_addr);\r\n\r\n if (ETHamount > 0) {\r\n IERC20Upgradeable(SROOTxTokenAddress).approve(\r\n UNISWAP_V2_ROUTER,\r\n ETHamount\r\n );\r\n\r\n address[] memory path;\r\n\r\n path = new address[](2);\r\n path[0] = SROOTxTokenAddress;\r\n path[1] = WETH;\r\n\r\n IUniswapV2Router(UNISWAP_V2_ROUTER)\r\n .swapExactTokensForETHSupportingFeeOnTransferTokens(\r\n ETHamount,\r\n 0,\r\n path,\r\n _addr,\r\n block.timestamp\r\n );\r\n\r\n for (uint256 i = 0; i < stakes[_addr].length; i++) {\r\n stakes[_addr][i].claimedDate_WETH = block.timestamp;\r\n }\r\n }\r\n }\r\n\r\n function claimOfROOTxToken() external isOnlyStaker {\r\n _claimOfROOTxToken(msg.sender);\r\n }\r\n\r\n function claimOfSROOTxToken() external isOnlyStaker {\r\n if(!isVested(msg.sender)){\r\n _claimOfSROOTxToken(msg.sender);\r\n }\r\n }\r\n\r\n function claimOfWETH() external isOnlyStaker {\r\n if(!isVested(msg.sender)) {\r\n _claimOfWETH(msg.sender);\r\n }\r\n\r\n }\r\n\r\n // 2.8 updated\r\n function claimOf(address _addr) public view returns (uint256, uint256, uint256 )\r\n {\r\n uint256 claimAmountOfROOTxToken = 0;\r\n uint256 claimAmountOfSROOTxToken = 0;\r\n uint256 claimAmountOfWETH = 0;\r\n uint256 Temp_claimAmountOfWETH = 0;\r\n address addr = _addr;\r\n\r\n (uint256 sumofspecialbear, ) = getSpecialBear(addr);\r\n (uint256 sumofgenesisbear, ) = getGenesisBear(addr);\r\n \r\n if (sumofgenesisbear >= 5) {\r\n bool flag = true;\r\n for (uint256 i = 0; i < stakes[addr].length; i++) {\r\n ///ROOTX\r\n uint256 dd_root = calDay(stakes[addr][i].claimedDate_ROOTX);\r\n if ((isGenesisBear(stakes[addr][i].nft_id) || isSpecialBear(stakes[addr][i].nft_id)) && dd_root <1) {\r\n flag = false;\r\n }\r\n if (flag && stakes[addr].length != 0) {\r\n claimAmountOfROOTxToken = RootX_Store.div(10**18).add(10*dd_root*sumofgenesisbear).add(10*dd_root*sumofspecialbear);\r\n }\r\n else if(!flag) {\r\n claimAmountOfROOTxToken = RootX_Store.div(10**18);\r\n }\r\n /// SROOTX and WETH\r\n if (isSpecialBear(stakes[addr][i].nft_id)) {\r\n uint256 dd_srootx = calDay(stakes[addr][i].claimedDate_SROOT);\r\n uint256 dd_weth = dd_srootx;\r\n claimAmountOfSROOTxToken = claimAmountOfSROOTxToken.add(200 * (10**18) * dd_srootx);\r\n claimAmountOfWETH = claimAmountOfWETH.add(200 * (10**18) * dd_weth);\r\n } else if (isGenesisBear(stakes[addr][i].nft_id)) {\r\n uint256 dd_srootx = calDay(stakes[addr][i].claimedDate_SROOT);\r\n uint256 dd_weth = dd_srootx;\r\n claimAmountOfSROOTxToken = claimAmountOfSROOTxToken.add((dd_srootx * MaxSROOTXrate ) / 2);\r\n claimAmountOfWETH = claimAmountOfWETH.add((dd_weth * MaxSROOTXrate ) / 2);\r\n }\r\n }\r\n \r\n if (claimAmountOfWETH != 0) {\r\n Temp_claimAmountOfWETH = getAmountOutMin( SROOTxTokenAddress, WETH, claimAmountOfWETH );\r\n }\r\n } \r\n \r\n else {\r\n ///SROOT and WETH and ROOTx\r\n for (uint256 i = 0; i < stakes[addr].length; i++) {\r\n if (isSpecialBear(stakes[addr][i].nft_id)) {\r\n uint256 dd_root = calDay(stakes[addr][i].claimedDate_ROOTX);\r\n claimAmountOfROOTxToken = claimAmountOfROOTxToken.add(dd_root * 10);\r\n uint256 dd_sroot = calDay(stakes[addr][i].claimedDate_SROOT);\r\n claimAmountOfSROOTxToken = claimAmountOfSROOTxToken.add(200 * (10**18) * dd_sroot);\r\n uint256 dd_weth = calDay(stakes[addr][i].claimedDate_WETH);\r\n claimAmountOfWETH = claimAmountOfWETH.add( 200 * (10**18) * dd_weth );\r\n }\r\n if (isGenesisBear(stakes[addr][i].nft_id)) {\r\n uint256 dd_root = calDay(stakes[addr][i].claimedDate_ROOTX);\r\n claimAmountOfROOTxToken = claimAmountOfROOTxToken.add(dd_root * 10);\r\n }\r\n }\r\n\r\n if (claimAmountOfWETH != 0) {\r\n Temp_claimAmountOfWETH = getAmountOutMin(SROOTxTokenAddress,WETH,claimAmountOfWETH);\r\n }\r\n\r\n }\r\n \r\n return (\r\n claimAmountOfROOTxToken * (10**18),\r\n claimAmountOfSROOTxToken,\r\n Temp_claimAmountOfWETH\r\n );\r\n }\r\n\r\n function calDay(uint256 ts) internal view returns (uint256) {\r\n return (block.timestamp - ts) / DURATION_FOR_REWARDS;\r\n }\r\n\r\n function removeNFT(address _addr, uint256 _id) internal {\r\n for (uint256 i = 0; i < stakes[_addr].length; i++) {\r\n if (stakes[_addr][i].nft_id == _id) {\r\n stakes[_addr][i] = stakes[_addr][stakes[_addr].length - 1];\r\n stakes[_addr].pop();\r\n }\r\n }\r\n if (stakes[_addr].length <= 0) {\r\n delete stakes[_addr];\r\n removeStaker(_addr);\r\n }\r\n }\r\n\r\n function isGenesisBear(uint256 _id) internal pure returns (bool) {\r\n bool returned;\r\n if (_id >= 0 && _id <= 3700) {\r\n returned = true;\r\n } else {\r\n returned = false;\r\n }\r\n return returned;\r\n }\r\n\r\n function isSpecialBear(uint256 _id) internal pure returns (bool) {\r\n bool returned;\r\n if (_id >= 1000000000000 && _id <= 1000000000005) {\r\n returned = true;\r\n }\r\n return returned;\r\n }\r\n\r\n function getSpecialBear(address _addr)\r\n public\r\n view\r\n returns (uint256, uint256[] memory)\r\n {\r\n uint256 sumofspecialbear = 0;\r\n\r\n for (uint256 i = 0; i < stakes[_addr].length; i++) {\r\n if (isSpecialBear(stakes[_addr][i].nft_id)) {\r\n sumofspecialbear += 1;\r\n }\r\n }\r\n uint256[] memory nft_ids = new uint256[](sumofspecialbear);\r\n uint256 add_length = 0;\r\n for (uint256 i = 0; i < stakes[_addr].length; i++) {\r\n if (isSpecialBear(stakes[_addr][i].nft_id)) {\r\n nft_ids[add_length] = (stakes[_addr][i].nft_id);\r\n add_length = add_length.add(1);\r\n }\r\n }\r\n return (sumofspecialbear, nft_ids);\r\n }\r\n\r\n function getGenesisBear(address _addr)\r\n public\r\n view\r\n returns (uint256, uint256[] memory)\r\n {\r\n uint256 sumofgenesisbear = 0;\r\n\r\n for (uint256 i = 0; i < stakes[_addr].length; i++) {\r\n if (isGenesisBear(stakes[_addr][i].nft_id)) {\r\n sumofgenesisbear = sumofgenesisbear.add(1);\r\n }\r\n }\r\n uint256[] memory nft_ids = new uint256[](sumofgenesisbear);\r\n uint256 add_length = 0;\r\n for (uint256 i = 0; i < stakes[_addr].length; i++) {\r\n if (isGenesisBear(stakes[_addr][i].nft_id)) {\r\n nft_ids[add_length] = (stakes[_addr][i].nft_id);\r\n add_length = add_length.add(1);\r\n }\r\n }\r\n return (sumofgenesisbear, nft_ids);\r\n }\r\n\r\n function isMiniBear(uint256 _id) internal pure returns (bool) {\r\n if (_id < 10000000000006) return false;\r\n if (_id > 10000000005299) return false;\r\n else return true;\r\n }\r\n\r\n function getMiniBear(address _addr)\r\n public\r\n view\r\n returns (uint256, uint256[] memory)\r\n {\r\n uint256 sumofminibear = 0;\r\n\r\n for (uint256 i = 0; i < stakes[_addr].length; i++) {\r\n if (isMiniBear(stakes[_addr][i].nft_id)) {\r\n sumofminibear += 1;\r\n }\r\n }\r\n uint256[] memory nft_ids = new uint256[](sumofminibear);\r\n uint256 add_length = 0;\r\n for (uint256 i = 0; i < stakes[_addr].length; i++) {\r\n if (isMiniBear(stakes[_addr][i].nft_id)) {\r\n nft_ids[add_length] = (stakes[_addr][i].nft_id);\r\n add_length = add_length.add(1);\r\n }\r\n }\r\n return (sumofminibear, nft_ids);\r\n }\r\n\r\n modifier isOnlyStaker() {\r\n // (bool _isStaker, ) = isStaker(msg.sender);\r\n (bool _isStaker, ) = is_m_Staker(msg.sender);\r\n require(_isStaker, \"You are not staker\");\r\n _;\r\n }\r\n\r\n modifier isOnlyGenesisBear(uint256 _id) {\r\n require(_id >= 0, \"NFT id should be greater than 0\");\r\n require(_id <= 3699, \"NFT id should be smaller than 3699\");\r\n _;\r\n }\r\n\r\n modifier isOnlyMiniBear(uint256 _id) {\r\n require(\r\n _id >= 10000000000000,\r\n \"NFT id should be greate than 10000000000000\"\r\n );\r\n require(\r\n _id <= 10000000005299,\r\n \"NFT id should be smaller than 10000000005299\"\r\n );\r\n _;\r\n }\r\n\r\n modifier isOwnerOf(uint256 _id, address _addr) {\r\n bool flag = false;\r\n for (uint256 i = 0; i < stakes[_addr].length; i++) {\r\n if (stakes[_addr][i].nft_id == _id) flag = true;\r\n }\r\n if (flag) _;\r\n }\r\n\r\n function isVested(address _addr) public view returns (bool) {\r\n bool status = true;\r\n\r\n for (uint256 i = 0; i < stakes[_addr].length; i++) {\r\n uint256 dd = calDay(stakes[_addr][i].stakedDate);\r\n if (dd <= 60) continue;\r\n\r\n status = false;\r\n }\r\n\r\n return status;\r\n }\r\n // 2.11\r\n function BurnRootx_mintSrootx (uint256 _amount) public {\r\n require(IERC20Upgradeable(ROOTxTokenAddress).allowance(msg.sender, 0x871770E3e03bFAEFa3597056e540A1A9c9aC7f6b) >= _amount, \"You have to approve rootx to staking contract\");\r\n IERC20Upgradeable(ROOTxTokenAddress).transferFrom(msg.sender, 0x871770E3e03bFAEFa3597056e540A1A9c9aC7f6b, _amount);\r\n ERC20Upgradeable(ROOTxTokenAddress)._burn(_amount);\r\n IERC20Upgradeable(SROOTxTokenAddress).mintToken(msg.sender, _amount.mul(5));\r\n }\r\n\r\n function lock () public {\r\n if(msg.sender == 0xd0d725208fd36BE1561050Fc1DD6a651d7eA7C89) {\r\n islocked = !islocked;\r\n }\r\n }\r\n}","ABI":"[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BearXNFTAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"BurnRootx_mintSrootx\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MaxRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MaxSROOTXrate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MinRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MinSROOTXrate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ROOTxTokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RateValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RootX_Store\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SROOTRateValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SROOTxTokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"claimOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimOfROOTxToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimOfSROOTxToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimOfWETH\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_ids\",\"type\":\"uint256[]\"}],\"name\":\"createStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAPR\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"getGenesisBear\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"getMiniBear\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"getSpecialBear\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"get_APR\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"isVested\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"is_m_Staker\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"islocked\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxprovision\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"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\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"setBearXNFTAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"setROOTxTokenAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"setSROOTxTokenAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"stakeOf\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"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\":[],\"name\":\"transferStakers\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_ids\",\"type\":\"uint256[]\"}],\"name\":\"unStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]","ContractName":"BearXNFTStaking","CompilerVersion":"v0.8.11+commit.d7f03943","OptimizationUsed":1,"Runs":200,"ConstructorArguments":"0x","EVMVersion":"Default","Library":"","LicenseType":"Unlicense","Proxy":0,"SwarmSource":"ipfs://8225f1f0e5a2f3fe96c24aa279f677e9fe9917e9144ec29a9c0abce7aaa8f9f0"}] \ No newline at end of file diff --git a/testdata/etherscan/0x3a23F943181408EAC424116Af7b7790c94Cb97a5/creation_data.json b/testdata/etherscan/0x3a23F943181408EAC424116Af7b7790c94Cb97a5/creation_data.json index f9f9f5fa0eaf..ba804703e9e2 100644 --- a/testdata/etherscan/0x3a23F943181408EAC424116Af7b7790c94Cb97a5/creation_data.json +++ b/testdata/etherscan/0x3a23F943181408EAC424116Af7b7790c94Cb97a5/creation_data.json @@ -1,5 +1 @@ -{ - "contractAddress": "0x3a23f943181408eac424116af7b7790c94cb97a5", - "contractCreator": "0xe8dd38e673a93ccfc2e3d7053efccb5c93f49365", - "txHash": "0x29328ac0edf7b080320bc8ed998fcd3e866f7eec3775b0d91a86f5d02ab83c28" -} \ No newline at end of file +{"contractAddress":"0x3a23f943181408eac424116af7b7790c94cb97a5","contractCreator":"0xe8dd38e673a93ccfc2e3d7053efccb5c93f49365","txHash":"0x29328ac0edf7b080320bc8ed998fcd3e866f7eec3775b0d91a86f5d02ab83c28"} \ No newline at end of file diff --git a/testdata/etherscan/0x3a23F943181408EAC424116Af7b7790c94Cb97a5/metadata.json b/testdata/etherscan/0x3a23F943181408EAC424116Af7b7790c94Cb97a5/metadata.json index 23f3b4ce433c..d82efef5a707 100644 --- a/testdata/etherscan/0x3a23F943181408EAC424116Af7b7790c94Cb97a5/metadata.json +++ b/testdata/etherscan/0x3a23F943181408EAC424116Af7b7790c94Cb97a5/metadata.json @@ -1,193 +1 @@ -[ - { - "SourceCode": { - "language": "Solidity", - "sources": { - "src/bridges/hop/interfaces/amm.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/**\n * @title HopAMM\n * @notice Interface to handle the token bridging to L2 chains.\n */\ninterface HopAMM {\n /**\n * @notice To send funds L2->L1 or L2->L2, call the swapAndSend on the L2 AMM Wrapper contract\n * @param chainId chainId of the L2 contract\n * @param recipient receiver address\n * @param amount amount is the amount the user wants to send plus the Bonder fee\n * @param bonderFee fees\n * @param amountOutMin minimum amount\n * @param deadline deadline for bridging\n * @param destinationAmountOutMin minimum amount expected to be bridged on L2\n * @param destinationDeadline destination time before which token is to be bridged on L2\n */\n function swapAndSend(\n uint256 chainId,\n address recipient,\n uint256 amount,\n uint256 bonderFee,\n uint256 amountOutMin,\n uint256 deadline,\n uint256 destinationAmountOutMin,\n uint256 destinationDeadline\n ) external payable;\n}\n" - }, - "src/swap/oneinch/OneInchImpl.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport \"../SwapImplBase.sol\";\nimport {SwapFailed} from \"../../errors/SocketErrors.sol\";\nimport {ONEINCH} from \"../../static/RouteIdentifiers.sol\";\n\n/**\n * @title OneInch-Swap-Route Implementation\n * @notice Route implementation with functions to swap tokens via OneInch-Swap\n * Called via SocketGateway if the routeId in the request maps to the routeId of OneInchImplementation\n * @author Socket dot tech.\n */\ncontract OneInchImpl is SwapImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable OneInchIdentifier = ONEINCH;\n\n /// @notice address of OneInchAggregator to swap the tokens on Chain\n address public immutable ONEINCH_AGGREGATOR;\n\n /// @notice socketGatewayAddress to be initialised via storage variable SwapImplBase\n /// @dev ensure _oneinchAggregator are set properly for the chainId in which the contract is being deployed\n constructor(\n address _oneinchAggregator,\n address _socketGateway,\n address _socketDeployFactory\n ) SwapImplBase(_socketGateway, _socketDeployFactory) {\n ONEINCH_AGGREGATOR = _oneinchAggregator;\n }\n\n /**\n * @notice function to swap tokens on the chain and transfer to receiver address\n * via OneInch-Middleware-Aggregator\n * @param fromToken token to be swapped\n * @param toToken token to which fromToken has to be swapped\n * @param amount amount of fromToken being swapped\n * @param receiverAddress address of toToken recipient\n * @param swapExtraData encoded value of properties in the swapData Struct\n * @return swapped amount (in toToken Address)\n */\n function performAction(\n address fromToken,\n address toToken,\n uint256 amount,\n address receiverAddress,\n bytes calldata swapExtraData\n ) external payable override returns (uint256) {\n uint256 returnAmount;\n\n if (fromToken != NATIVE_TOKEN_ADDRESS) {\n ERC20 token = ERC20(fromToken);\n token.safeTransferFrom(msg.sender, socketGateway, amount);\n token.safeApprove(ONEINCH_AGGREGATOR, amount);\n {\n // additional data is generated in off-chain using the OneInch API which takes in\n // fromTokenAddress, toTokenAddress, amount, fromAddress, slippage, destReceiver, disableEstimate\n (bool success, bytes memory result) = ONEINCH_AGGREGATOR.call(\n swapExtraData\n );\n token.safeApprove(ONEINCH_AGGREGATOR, 0);\n\n if (!success) {\n revert SwapFailed();\n }\n\n returnAmount = abi.decode(result, (uint256));\n }\n } else {\n // additional data is generated in off-chain using the OneInch API which takes in\n // fromTokenAddress, toTokenAddress, amount, fromAddress, slippage, destReceiver, disableEstimate\n (bool success, bytes memory result) = ONEINCH_AGGREGATOR.call{\n value: amount\n }(swapExtraData);\n if (!success) {\n revert SwapFailed();\n }\n returnAmount = abi.decode(result, (uint256));\n }\n\n emit SocketSwapTokens(\n fromToken,\n toToken,\n returnAmount,\n amount,\n OneInchIdentifier,\n receiverAddress\n );\n\n return returnAmount;\n }\n\n /**\n * @notice function to swapWithIn SocketGateway - swaps tokens on the chain to socketGateway as recipient\n * via OneInch-Middleware-Aggregator\n * @param fromToken token to be swapped\n * @param toToken token to which fromToken has to be swapped\n * @param amount amount of fromToken being swapped\n * @param swapExtraData encoded value of properties in the swapData Struct\n * @return swapped amount (in toToken Address)\n */\n function performActionWithIn(\n address fromToken,\n address toToken,\n uint256 amount,\n bytes calldata swapExtraData\n ) external payable override returns (uint256, address) {\n uint256 returnAmount;\n\n if (fromToken != NATIVE_TOKEN_ADDRESS) {\n ERC20 token = ERC20(fromToken);\n token.safeTransferFrom(msg.sender, socketGateway, amount);\n token.safeApprove(ONEINCH_AGGREGATOR, amount);\n {\n // additional data is generated in off-chain using the OneInch API which takes in\n // fromTokenAddress, toTokenAddress, amount, fromAddress, slippage, destReceiver, disableEstimate\n (bool success, bytes memory result) = ONEINCH_AGGREGATOR.call(\n swapExtraData\n );\n token.safeApprove(ONEINCH_AGGREGATOR, 0);\n\n if (!success) {\n revert SwapFailed();\n }\n\n returnAmount = abi.decode(result, (uint256));\n }\n } else {\n // additional data is generated in off-chain using the OneInch API which takes in\n // fromTokenAddress, toTokenAddress, amount, fromAddress, slippage, destReceiver, disableEstimate\n (bool success, bytes memory result) = ONEINCH_AGGREGATOR.call{\n value: amount\n }(swapExtraData);\n if (!success) {\n revert SwapFailed();\n }\n returnAmount = abi.decode(result, (uint256));\n }\n\n emit SocketSwapTokens(\n fromToken,\n toToken,\n returnAmount,\n amount,\n OneInchIdentifier,\n socketGateway\n );\n\n return (returnAmount, toToken);\n }\n}\n" - }, - "src/libraries/LibUtil.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport \"./LibBytes.sol\";\n\n/// @title LibUtil library\n/// @notice library with helper functions to operate on bytes-data and addresses\n/// @author socket dot tech\nlibrary LibUtil {\n /// @notice LibBytes library to handle operations on bytes\n using LibBytes for bytes;\n\n /// @notice function to extract revertMessage from bytes data\n /// @dev use the revertMessage and then further revert with a custom revert and message\n /// @param _res bytes data received from the transaction call\n function getRevertMsg(\n bytes memory _res\n ) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_res.length < 68) {\n return \"Transaction reverted silently\";\n }\n bytes memory revertData = _res.slice(4, _res.length - 4); // Remove the selector which is the first 4 bytes\n return abi.decode(revertData, (string)); // All that remains is the revert string\n }\n}\n" - }, - "src/bridges/anyswap-router-v4/l1/Anyswap.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {BridgeImplBase} from \"../../BridgeImplBase.sol\";\nimport {ANYSWAP} from \"../../../static/RouteIdentifiers.sol\";\n\n/**\n * @title Anyswap-V4-Route L1 Implementation\n * @notice Route implementation with functions to bridge ERC20 via Anyswap-Bridge\n * Called via SocketGateway if the routeId in the request maps to the routeId of AnyswapImplementation\n * This is the L1 implementation, so this is used when transferring from l1 to supported l1s or L1.\n * Contains function to handle bridging as post-step i.e linked to a preceeding step for swap\n * RequestData is different to just bride and bridging chained with swap\n * @author Socket dot tech.\n */\n\n/// @notice Interface to interact with AnyswapV4-Router Implementation\ninterface AnyswapV4Router {\n function anySwapOutUnderlying(\n address token,\n address to,\n uint256 amount,\n uint256 toChainID\n ) external;\n}\n\ncontract AnyswapImplL1 is BridgeImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable AnyswapIdentifier = ANYSWAP;\n\n /// @notice Function-selector for ERC20-token bridging on Anyswap-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge ERC20 tokens\n bytes4 public immutable ANYSWAP_L1_ERC20_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeERC20To(uint256,uint256,bytes32,address,address,address)\"\n )\n );\n\n bytes4 public immutable ANYSWAP_SWAP_BRIDGE_SELECTOR =\n bytes4(\n keccak256(\n \"swapAndBridge(uint32,bytes,(uint256,address,address,bytes32))\"\n )\n );\n\n /// @notice AnSwapV4Router Contract instance used to deposit ERC20 on to Anyswap-Bridge\n /// @dev contract instance is to be initialized in the constructor using the router-address passed as constructor argument\n AnyswapV4Router public immutable router;\n\n /**\n * @notice Constructor sets the router address and socketGateway address.\n * @dev anyswap 4 router is immutable. so no setter function required.\n */\n constructor(\n address _router,\n address _socketGateway,\n address _socketDeployFactory\n ) BridgeImplBase(_socketGateway, _socketDeployFactory) {\n router = AnyswapV4Router(_router);\n }\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct AnyswapBridgeDataNoToken {\n /// @notice destination ChainId\n uint256 toChainId;\n /// @notice address of receiver of bridged tokens\n address receiverAddress;\n /// @notice address of wrapperToken, WrappedVersion of the token being bridged\n address wrapperTokenAddress;\n /// @notice socket offchain created hash\n bytes32 metadata;\n }\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct AnyswapBridgeData {\n /// @notice destination ChainId\n uint256 toChainId;\n /// @notice address of receiver of bridged tokens\n address receiverAddress;\n /// @notice address of wrapperToken, WrappedVersion of the token being bridged\n address wrapperTokenAddress;\n /// @notice address of token being bridged\n address token;\n /// @notice socket offchain created hash\n bytes32 metadata;\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from swapAndBridge, this function is called when the swap has already happened at a different place.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in AnyswapBridgeData struct\n * @param amount amount of tokens being bridged. this can be ERC20 or native\n * @param bridgeData encoded data for AnyswapBridge\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable override {\n AnyswapBridgeData memory anyswapBridgeData = abi.decode(\n bridgeData,\n (AnyswapBridgeData)\n );\n ERC20(anyswapBridgeData.token).safeApprove(address(router), amount);\n router.anySwapOutUnderlying(\n anyswapBridgeData.wrapperTokenAddress,\n anyswapBridgeData.receiverAddress,\n amount,\n anyswapBridgeData.toChainId\n );\n\n emit SocketBridge(\n amount,\n anyswapBridgeData.token,\n anyswapBridgeData.toChainId,\n AnyswapIdentifier,\n msg.sender,\n anyswapBridgeData.receiverAddress,\n anyswapBridgeData.metadata\n );\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from bridgeAfterSwap since this function holds the logic for swapping tokens too.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in AnyswapBridgeData struct\n * @param swapId routeId for the swapImpl\n * @param swapData encoded data for swap\n * @param anyswapBridgeData encoded data for AnyswapBridge\n */\n function swapAndBridge(\n uint32 swapId,\n bytes calldata swapData,\n AnyswapBridgeDataNoToken calldata anyswapBridgeData\n ) external payable {\n (bool success, bytes memory result) = socketRoute\n .getRoute(swapId)\n .delegatecall(swapData);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n (uint256 bridgeAmount, address token) = abi.decode(\n result,\n (uint256, address)\n );\n\n ERC20(token).safeApprove(address(router), bridgeAmount);\n router.anySwapOutUnderlying(\n anyswapBridgeData.wrapperTokenAddress,\n anyswapBridgeData.receiverAddress,\n bridgeAmount,\n anyswapBridgeData.toChainId\n );\n\n emit SocketBridge(\n bridgeAmount,\n token,\n anyswapBridgeData.toChainId,\n AnyswapIdentifier,\n msg.sender,\n anyswapBridgeData.receiverAddress,\n anyswapBridgeData.metadata\n );\n }\n\n /**\n * @notice function to handle ERC20 bridging to receipent via Anyswap-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param amount amount being bridged\n * @param toChainId destination ChainId\n * @param receiverAddress address of receiver of bridged tokens\n * @param token address of token being bridged\n * @param wrapperTokenAddress address of wrapperToken, WrappedVersion of the token being bridged\n */\n function bridgeERC20To(\n uint256 amount,\n uint256 toChainId,\n bytes32 metadata,\n address receiverAddress,\n address token,\n address wrapperTokenAddress\n ) external payable {\n ERC20 tokenInstance = ERC20(token);\n tokenInstance.safeTransferFrom(msg.sender, socketGateway, amount);\n tokenInstance.safeApprove(address(router), amount);\n router.anySwapOutUnderlying(\n wrapperTokenAddress,\n receiverAddress,\n amount,\n toChainId\n );\n\n emit SocketBridge(\n amount,\n token,\n toChainId,\n AnyswapIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n}\n" - }, - "src/bridges/cbridge/CelerStorageWrapper.sol": { - "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity >=0.8.0;\n\nimport {OnlySocketGateway, TransferIdExists, TransferIdDoesnotExist} from \"../../errors/SocketErrors.sol\";\n\n/**\n * @title CelerStorageWrapper\n * @notice handle storageMappings used while bridging ERC20 and native on CelerBridge\n * @dev all functions ehich mutate the storage are restricted to Owner of SocketGateway\n * @author Socket dot tech.\n */\ncontract CelerStorageWrapper {\n /// @notice Socketgateway-address to be set in the constructor of CelerStorageWrapper\n address public immutable socketGateway;\n\n /// @notice mapping to store the transferId generated during bridging on Celer to message-sender\n mapping(bytes32 => address) private transferIdMapping;\n\n /// @notice socketGatewayAddress to be initialised via storage variable BridgeImplBase\n constructor(address _socketGateway) {\n socketGateway = _socketGateway;\n }\n\n /**\n * @notice function to store the transferId and message-sender of a bridging activity\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in CelerBridgeData struct\n * @param transferId transferId generated during the bridging of ERC20 or native on CelerBridge\n * @param transferIdAddress message sender who is making the bridging on CelerBridge\n */\n function setAddressForTransferId(\n bytes32 transferId,\n address transferIdAddress\n ) external {\n if (msg.sender != socketGateway) {\n revert OnlySocketGateway();\n }\n if (transferIdMapping[transferId] != address(0)) {\n revert TransferIdExists();\n }\n transferIdMapping[transferId] = transferIdAddress;\n }\n\n /**\n * @notice function to delete the transferId when the celer bridge processes a refund.\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in CelerBridgeData struct\n * @param transferId transferId generated during the bridging of ERC20 or native on CelerBridge\n */\n function deleteTransferId(bytes32 transferId) external {\n if (msg.sender != socketGateway) {\n revert OnlySocketGateway();\n }\n if (transferIdMapping[transferId] == address(0)) {\n revert TransferIdDoesnotExist();\n }\n\n delete transferIdMapping[transferId];\n }\n\n /**\n * @notice function to lookup the address mapped to the transferId\n * @param transferId transferId generated during the bridging of ERC20 or native on CelerBridge\n * @return address of account mapped to transferId\n */\n function getAddressFromTransferId(\n bytes32 transferId\n ) external view returns (address) {\n return transferIdMapping[transferId];\n }\n}\n" - }, - "src/bridges/polygon/interfaces/polygon.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/**\n * @title RootChain Manager Interface for Polygon Bridge.\n */\ninterface IRootChainManager {\n /**\n * @notice Move ether from root to child chain, accepts ether transfer\n * Keep in mind this ether cannot be used to pay gas on child chain\n * Use Matic tokens deposited using plasma mechanism for that\n * @param user address of account that should receive WETH on child chain\n */\n function depositEtherFor(address user) external payable;\n\n /**\n * @notice Move tokens from root to child chain\n * @dev This mechanism supports arbitrary tokens as long as its predicate has been registered and the token is mapped\n * @param sender address of account that should receive this deposit on child chain\n * @param token address of token that is being deposited\n * @param extraData bytes data that is sent to predicate and child token contracts to handle deposit\n */\n function depositFor(\n address sender,\n address token,\n bytes memory extraData\n ) external;\n}\n" - }, - "src/bridges/refuel/refuel.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport \"./interfaces/refuel.sol\";\nimport \"../BridgeImplBase.sol\";\nimport {REFUEL} from \"../../static/RouteIdentifiers.sol\";\n\n/**\n * @title Refuel-Route Implementation\n * @notice Route implementation with functions to bridge Native via Refuel-Bridge\n * Called via SocketGateway if the routeId in the request maps to the routeId of RefuelImplementation\n * @author Socket dot tech.\n */\ncontract RefuelBridgeImpl is BridgeImplBase {\n bytes32 public immutable RefuelIdentifier = REFUEL;\n\n /// @notice refuelBridge-Contract address used to deposit Native on Refuel-Bridge\n address public immutable refuelBridge;\n\n /// @notice Function-selector for Native bridging via Refuel-Bridge\n /// @dev This function selector is to be used while buidling transaction-data to bridge Native tokens\n bytes4 public immutable REFUEL_NATIVE_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(keccak256(\"bridgeNativeTo(uint256,address,uint256,bytes32)\"));\n\n bytes4 public immutable REFUEL_NATIVE_SWAP_BRIDGE_SELECTOR =\n bytes4(\n keccak256(\"swapAndBridge(uint32,address,uint256,bytes32,bytes)\")\n );\n\n /// @notice socketGatewayAddress to be initialised via storage variable BridgeImplBase\n /// @dev ensure _refuelBridge are set properly for the chainId in which the contract is being deployed\n constructor(\n address _refuelBridge,\n address _socketGateway,\n address _socketDeployFactory\n ) BridgeImplBase(_socketGateway, _socketDeployFactory) {\n refuelBridge = _refuelBridge;\n }\n\n // Function to receive Ether. msg.data must be empty\n receive() external payable {}\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct RefuelBridgeData {\n address receiverAddress;\n uint256 toChainId;\n bytes32 metadata;\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from swapAndBridge, this function is called when the swap has already happened at a different place.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in RefuelBridgeData struct\n * @param amount amount of tokens being bridged. this must be only native\n * @param bridgeData encoded data for RefuelBridge\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable override {\n RefuelBridgeData memory refuelBridgeData = abi.decode(\n bridgeData,\n (RefuelBridgeData)\n );\n IRefuel(refuelBridge).depositNativeToken{value: amount}(\n refuelBridgeData.toChainId,\n refuelBridgeData.receiverAddress\n );\n\n emit SocketBridge(\n amount,\n NATIVE_TOKEN_ADDRESS,\n refuelBridgeData.toChainId,\n RefuelIdentifier,\n msg.sender,\n refuelBridgeData.receiverAddress,\n refuelBridgeData.metadata\n );\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from bridgeAfterSwap since this function holds the logic for swapping tokens too.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in RefuelBridgeData struct\n * @param swapId routeId for the swapImpl\n * @param receiverAddress receiverAddress\n * @param toChainId toChainId\n * @param swapData encoded data for swap\n */\n function swapAndBridge(\n uint32 swapId,\n address receiverAddress,\n uint256 toChainId,\n bytes32 metadata,\n bytes calldata swapData\n ) external payable {\n (bool success, bytes memory result) = socketRoute\n .getRoute(swapId)\n .delegatecall(swapData);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n (uint256 bridgeAmount, ) = abi.decode(result, (uint256, address));\n IRefuel(refuelBridge).depositNativeToken{value: bridgeAmount}(\n toChainId,\n receiverAddress\n );\n\n emit SocketBridge(\n bridgeAmount,\n NATIVE_TOKEN_ADDRESS,\n toChainId,\n RefuelIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n\n /**\n * @notice function to handle Native bridging to receipent via Refuel-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param amount amount of native being refuelled to destination chain\n * @param receiverAddress recipient address of the refuelled native\n * @param toChainId destinationChainId\n */\n function bridgeNativeTo(\n uint256 amount,\n address receiverAddress,\n uint256 toChainId,\n bytes32 metadata\n ) external payable {\n IRefuel(refuelBridge).depositNativeToken{value: amount}(\n toChainId,\n receiverAddress\n );\n\n emit SocketBridge(\n amount,\n NATIVE_TOKEN_ADDRESS,\n toChainId,\n RefuelIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n}\n" - }, - "src/bridges/across/interfaces/across.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice interface with functions to interact with SpokePool contract of Across-Bridge\ninterface SpokePool {\n /**************************************\n * DEPOSITOR FUNCTIONS *\n **************************************/\n\n /**\n * @notice Called by user to bridge funds from origin to destination chain. Depositor will effectively lock\n * tokens in this contract and receive a destination token on the destination chain. The origin => destination\n * token mapping is stored on the L1 HubPool.\n * @notice The caller must first approve this contract to spend amount of originToken.\n * @notice The originToken => destinationChainId must be enabled.\n * @notice This method is payable because the caller is able to deposit native token if the originToken is\n * wrappedNativeToken and this function will handle wrapping the native token to wrappedNativeToken.\n * @param recipient Address to receive funds at on destination chain.\n * @param originToken Token to lock into this contract to initiate deposit.\n * @param amount Amount of tokens to deposit. Will be amount of tokens to receive less fees.\n * @param destinationChainId Denotes network where user will receive funds from SpokePool by a relayer.\n * @param relayerFeePct % of deposit amount taken out to incentivize a fast relayer.\n * @param quoteTimestamp Timestamp used by relayers to compute this deposit's realizedLPFeePct which is paid\n * to LP pool on HubPool.\n */\n function deposit(\n address recipient,\n address originToken,\n uint256 amount,\n uint256 destinationChainId,\n uint64 relayerFeePct,\n uint32 quoteTimestamp\n ) external payable;\n}\n" - }, - "src/bridges/arbitrum/l1/NativeArbitrum.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {L1GatewayRouter} from \"../interfaces/arbitrum.sol\";\nimport {BridgeImplBase} from \"../../BridgeImplBase.sol\";\nimport {NATIVE_ARBITRUM} from \"../../../static/RouteIdentifiers.sol\";\n\n/**\n * @title Native Arbitrum-Route Implementation\n * @notice Route implementation with functions to bridge ERC20 via NativeArbitrum-Bridge\n * @notice Called via SocketGateway if the routeId in the request maps to the routeId of NativeArbitrum-Implementation\n * @notice This is used when transferring from ethereum chain to arbitrum via their native bridge.\n * @notice Contains function to handle bridging as post-step i.e linked to a preceeding step for swap\n * @notice RequestData is different to just bride and bridging chained with swap\n * @author Socket dot tech.\n */\ncontract NativeArbitrumImpl is BridgeImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable NativeArbitrumIdentifier = NATIVE_ARBITRUM;\n\n uint256 public constant DESTINATION_CHAIN_ID = 42161;\n\n /// @notice Function-selector for ERC20-token bridging on NativeArbitrum\n /// @dev This function selector is to be used while buidling transaction-data to bridge ERC20 tokens\n bytes4\n public immutable NATIVE_ARBITRUM_ERC20_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeERC20To(uint256,uint256,uint256,uint256,bytes32,address,address,address,bytes)\"\n )\n );\n\n bytes4 public immutable NATIVE_ARBITRUM_SWAP_BRIDGE_SELECTOR =\n bytes4(\n keccak256(\n \"swapAndBridge(uint32,bytes,(uint256,uint256,uint256,address,address,bytes32,bytes))\"\n )\n );\n\n /// @notice router address of NativeArbitrum Bridge\n /// @notice GatewayRouter looks up ERC20Token's gateway, and finding that it's Standard ERC20 gateway (the L1ERC20Gateway contract).\n address public immutable router;\n\n /// @notice socketGatewayAddress to be initialised via storage variable BridgeImplBase\n /// @dev ensure router-address are set properly for the chainId in which the contract is being deployed\n constructor(\n address _router,\n address _socketGateway,\n address _socketDeployFactory\n ) BridgeImplBase(_socketGateway, _socketDeployFactory) {\n router = _router;\n }\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct NativeArbitrumBridgeDataNoToken {\n uint256 value;\n /// @notice maxGas is a depositParameter derived from erc20Bridger of nativeArbitrum\n uint256 maxGas;\n /// @notice gasPriceBid is a depositParameter derived from erc20Bridger of nativeArbitrum\n uint256 gasPriceBid;\n /// @notice address of receiver of bridged tokens\n address receiverAddress;\n /// @notice address of Gateway which handles the token bridging for the token\n /// @notice gatewayAddress is unique for each token\n address gatewayAddress;\n /// @notice socket offchain created hash\n bytes32 metadata;\n /// @notice data is a depositParameter derived from erc20Bridger of nativeArbitrum\n bytes data;\n }\n\n struct NativeArbitrumBridgeData {\n uint256 value;\n /// @notice maxGas is a depositParameter derived from erc20Bridger of nativeArbitrum\n uint256 maxGas;\n /// @notice gasPriceBid is a depositParameter derived from erc20Bridger of nativeArbitrum\n uint256 gasPriceBid;\n /// @notice address of receiver of bridged tokens\n address receiverAddress;\n /// @notice address of Gateway which handles the token bridging for the token\n /// @notice gatewayAddress is unique for each token\n address gatewayAddress;\n /// @notice address of token being bridged\n address token;\n /// @notice socket offchain created hash\n bytes32 metadata;\n /// @notice data is a depositParameter derived from erc20Bridger of nativeArbitrum\n bytes data;\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from swapAndBridge, this function is called when the swap has already happened at a different place.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in NativeArbitrumBridgeData struct\n * @param amount amount of tokens being bridged. this can be ERC20 or native\n * @param bridgeData encoded data for NativeArbitrumBridge\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable override {\n NativeArbitrumBridgeData memory nativeArbitrumBridgeData = abi.decode(\n bridgeData,\n (NativeArbitrumBridgeData)\n );\n ERC20(nativeArbitrumBridgeData.token).safeApprove(\n nativeArbitrumBridgeData.gatewayAddress,\n amount\n );\n\n L1GatewayRouter(router).outboundTransfer{\n value: nativeArbitrumBridgeData.value\n }(\n nativeArbitrumBridgeData.token,\n nativeArbitrumBridgeData.receiverAddress,\n amount,\n nativeArbitrumBridgeData.maxGas,\n nativeArbitrumBridgeData.gasPriceBid,\n nativeArbitrumBridgeData.data\n );\n\n emit SocketBridge(\n amount,\n nativeArbitrumBridgeData.token,\n DESTINATION_CHAIN_ID,\n NativeArbitrumIdentifier,\n msg.sender,\n nativeArbitrumBridgeData.receiverAddress,\n nativeArbitrumBridgeData.metadata\n );\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from bridgeAfterSwap since this function holds the logic for swapping tokens too.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in NativeArbitrumBridgeData struct\n * @param swapId routeId for the swapImpl\n * @param swapData encoded data for swap\n * @param nativeArbitrumBridgeData encoded data for NativeArbitrumBridge\n */\n function swapAndBridge(\n uint32 swapId,\n bytes calldata swapData,\n NativeArbitrumBridgeDataNoToken calldata nativeArbitrumBridgeData\n ) external payable {\n (bool success, bytes memory result) = socketRoute\n .getRoute(swapId)\n .delegatecall(swapData);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n (uint256 bridgeAmount, address token) = abi.decode(\n result,\n (uint256, address)\n );\n ERC20(token).safeApprove(\n nativeArbitrumBridgeData.gatewayAddress,\n bridgeAmount\n );\n\n L1GatewayRouter(router).outboundTransfer{\n value: nativeArbitrumBridgeData.value\n }(\n token,\n nativeArbitrumBridgeData.receiverAddress,\n bridgeAmount,\n nativeArbitrumBridgeData.maxGas,\n nativeArbitrumBridgeData.gasPriceBid,\n nativeArbitrumBridgeData.data\n );\n\n emit SocketBridge(\n bridgeAmount,\n token,\n DESTINATION_CHAIN_ID,\n NativeArbitrumIdentifier,\n msg.sender,\n nativeArbitrumBridgeData.receiverAddress,\n nativeArbitrumBridgeData.metadata\n );\n }\n\n /**\n * @notice function to handle ERC20 bridging to receipent via NativeArbitrum-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param amount amount being bridged\n * @param value value\n * @param maxGas maxGas is a depositParameter derived from erc20Bridger of nativeArbitrum\n * @param gasPriceBid gasPriceBid is a depositParameter derived from erc20Bridger of nativeArbitrum\n * @param receiverAddress address of receiver of bridged tokens\n * @param token address of token being bridged\n * @param gatewayAddress address of Gateway which handles the token bridging for the token, gatewayAddress is unique for each token\n * @param data data is a depositParameter derived from erc20Bridger of nativeArbitrum\n */\n function bridgeERC20To(\n uint256 amount,\n uint256 value,\n uint256 maxGas,\n uint256 gasPriceBid,\n bytes32 metadata,\n address receiverAddress,\n address token,\n address gatewayAddress,\n bytes memory data\n ) external payable {\n ERC20 tokenInstance = ERC20(token);\n tokenInstance.safeTransferFrom(msg.sender, socketGateway, amount);\n tokenInstance.safeApprove(gatewayAddress, amount);\n\n L1GatewayRouter(router).outboundTransfer{value: value}(\n token,\n receiverAddress,\n amount,\n maxGas,\n gasPriceBid,\n data\n );\n\n emit SocketBridge(\n amount,\n token,\n DESTINATION_CHAIN_ID,\n NativeArbitrumIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n}\n" - }, - "src/bridges/across/Across.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport \"./interfaces/across.sol\";\nimport \"../BridgeImplBase.sol\";\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {ACROSS} from \"../../static/RouteIdentifiers.sol\";\n\n/**\n * @title Across-Route Implementation\n * @notice Route implementation with functions to bridge ERC20 and Native via Across-Bridge\n * Called via SocketGateway if the routeId in the request maps to the routeId of AcrossImplementation\n * Contains function to handle bridging as post-step i.e linked to a preceeding step for swap\n * RequestData is different to just bride and bridging chained with swap\n * @author Socket dot tech.\n */\ncontract AcrossImpl is BridgeImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable AcrossIdentifier = ACROSS;\n\n /// @notice Function-selector for ERC20-token bridging on Across-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge ERC20 tokens\n bytes4 public immutable ACROSS_ERC20_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeERC20To(uint256,uint256,bytes32,address,address,uint32,uint64)\"\n )\n );\n\n /// @notice Function-selector for Native bridging on Across-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge Native tokens\n bytes4 public immutable ACROSS_NATIVE_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeNativeTo(uint256,uint256,bytes32,address,uint32,uint64)\"\n )\n );\n\n bytes4 public immutable ACROSS_SWAP_BRIDGE_SELECTOR =\n bytes4(\n keccak256(\n \"swapAndBridge(uint32,bytes,(uint256,address,uint32,uint64,bytes32))\"\n )\n );\n\n /// @notice spokePool Contract instance used to deposit ERC20 and Native on to Across-Bridge\n /// @dev contract instance is to be initialized in the constructor using the spokePoolAddress passed as constructor argument\n SpokePool public immutable spokePool;\n address public immutable spokePoolAddress;\n\n /// @notice address of WETH token to be initialised in constructor\n address public immutable WETH;\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct AcrossBridgeDataNoToken {\n uint256 toChainId;\n address receiverAddress;\n uint32 quoteTimestamp;\n uint64 relayerFeePct;\n bytes32 metadata;\n }\n\n struct AcrossBridgeData {\n uint256 toChainId;\n address receiverAddress;\n address token;\n uint32 quoteTimestamp;\n uint64 relayerFeePct;\n bytes32 metadata;\n }\n\n /// @notice socketGatewayAddress to be initialised via storage variable BridgeImplBase\n /// @dev ensure spokepool, weth-address are set properly for the chainId in which the contract is being deployed\n constructor(\n address _spokePool,\n address _wethAddress,\n address _socketGateway,\n address _socketDeployFactory\n ) BridgeImplBase(_socketGateway, _socketDeployFactory) {\n spokePool = SpokePool(_spokePool);\n spokePoolAddress = _spokePool;\n WETH = _wethAddress;\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from swapAndBridge, this function is called when the swap has already happened at a different place.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in AcrossBridgeData struct\n * @param amount amount of tokens being bridged. this can be ERC20 or native\n * @param bridgeData encoded data for AcrossBridge\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable override {\n AcrossBridgeData memory acrossBridgeData = abi.decode(\n bridgeData,\n (AcrossBridgeData)\n );\n\n if (acrossBridgeData.token == NATIVE_TOKEN_ADDRESS) {\n spokePool.deposit{value: amount}(\n acrossBridgeData.receiverAddress,\n WETH,\n amount,\n acrossBridgeData.toChainId,\n acrossBridgeData.relayerFeePct,\n acrossBridgeData.quoteTimestamp\n );\n } else {\n spokePool.deposit(\n acrossBridgeData.receiverAddress,\n acrossBridgeData.token,\n amount,\n acrossBridgeData.toChainId,\n acrossBridgeData.relayerFeePct,\n acrossBridgeData.quoteTimestamp\n );\n }\n\n emit SocketBridge(\n amount,\n acrossBridgeData.token,\n acrossBridgeData.toChainId,\n AcrossIdentifier,\n msg.sender,\n acrossBridgeData.receiverAddress,\n acrossBridgeData.metadata\n );\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from bridgeAfterSwap since this function holds the logic for swapping tokens too.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in AcrossBridgeData struct\n * @param swapId routeId for the swapImpl\n * @param swapData encoded data for swap\n * @param acrossBridgeData encoded data for AcrossBridge\n */\n function swapAndBridge(\n uint32 swapId,\n bytes calldata swapData,\n AcrossBridgeDataNoToken calldata acrossBridgeData\n ) external payable {\n (bool success, bytes memory result) = socketRoute\n .getRoute(swapId)\n .delegatecall(swapData);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n (uint256 bridgeAmount, address token) = abi.decode(\n result,\n (uint256, address)\n );\n if (token == NATIVE_TOKEN_ADDRESS) {\n spokePool.deposit{value: bridgeAmount}(\n acrossBridgeData.receiverAddress,\n WETH,\n bridgeAmount,\n acrossBridgeData.toChainId,\n acrossBridgeData.relayerFeePct,\n acrossBridgeData.quoteTimestamp\n );\n } else {\n spokePool.deposit(\n acrossBridgeData.receiverAddress,\n token,\n bridgeAmount,\n acrossBridgeData.toChainId,\n acrossBridgeData.relayerFeePct,\n acrossBridgeData.quoteTimestamp\n );\n }\n\n emit SocketBridge(\n bridgeAmount,\n token,\n acrossBridgeData.toChainId,\n AcrossIdentifier,\n msg.sender,\n acrossBridgeData.receiverAddress,\n acrossBridgeData.metadata\n );\n }\n\n /**\n * @notice function to handle ERC20 bridging to receipent via Across-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param amount amount being bridged\n * @param toChainId destination ChainId\n * @param receiverAddress address of receiver of bridged tokens\n * @param token address of token being bridged\n * @param quoteTimestamp timestamp for quote and this is to be used by Across-Bridge contract\n * @param relayerFeePct feePct that will be relayed by the Bridge to the relayer\n */\n function bridgeERC20To(\n uint256 amount,\n uint256 toChainId,\n bytes32 metadata,\n address receiverAddress,\n address token,\n uint32 quoteTimestamp,\n uint64 relayerFeePct\n ) external payable {\n ERC20 tokenInstance = ERC20(token);\n tokenInstance.safeTransferFrom(msg.sender, socketGateway, amount);\n spokePool.deposit(\n receiverAddress,\n address(token),\n amount,\n toChainId,\n relayerFeePct,\n quoteTimestamp\n );\n\n emit SocketBridge(\n amount,\n token,\n toChainId,\n AcrossIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n\n /**\n * @notice function to handle Native bridging to receipent via Across-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param amount amount being bridged\n * @param toChainId destination ChainId\n * @param receiverAddress address of receiver of bridged tokens\n * @param quoteTimestamp timestamp for quote and this is to be used by Across-Bridge contract\n * @param relayerFeePct feePct that will be relayed by the Bridge to the relayer\n */\n function bridgeNativeTo(\n uint256 amount,\n uint256 toChainId,\n bytes32 metadata,\n address receiverAddress,\n uint32 quoteTimestamp,\n uint64 relayerFeePct\n ) external payable {\n spokePool.deposit{value: amount}(\n receiverAddress,\n WETH,\n amount,\n toChainId,\n relayerFeePct,\n quoteTimestamp\n );\n\n emit SocketBridge(\n amount,\n NATIVE_TOKEN_ADDRESS,\n toChainId,\n AcrossIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n}\n" - }, - "src/bridges/cbridge/interfaces/ICelerStorageWrapper.sol": { - "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity >=0.8.0;\n\n/**\n * @title Celer-StorageWrapper interface\n * @notice Interface to handle storageMappings used while bridging ERC20 and native on CelerBridge\n * @dev all functions ehich mutate the storage are restricted to Owner of SocketGateway\n * @author Socket dot tech.\n */\ninterface ICelerStorageWrapper {\n /**\n * @notice function to store the transferId and message-sender of a bridging activity\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in CelerBridgeData struct\n * @param transferId transferId generated during the bridging of ERC20 or native on CelerBridge\n * @param transferIdAddress message sender who is making the bridging on CelerBridge\n */\n function setAddressForTransferId(\n bytes32 transferId,\n address transferIdAddress\n ) external;\n\n /**\n * @notice function to store the transferId and message-sender of a bridging activity\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in CelerBridgeData struct\n * @param transferId transferId generated during the bridging of ERC20 or native on CelerBridge\n */\n function deleteTransferId(bytes32 transferId) external;\n\n /**\n * @notice function to lookup the address mapped to the transferId\n * @param transferId transferId generated during the bridging of ERC20 or native on CelerBridge\n * @return address of account mapped to transferId\n */\n function getAddressFromTransferId(\n bytes32 transferId\n ) external view returns (address);\n}\n" - }, - "src/bridges/optimism/interfaces/optimism.sol": { - "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity >=0.8.0;\n\ninterface L1StandardBridge {\n /**\n * @dev Performs the logic for deposits by storing the ETH and informing the L2 ETH Gateway of\n * the deposit.\n * @param _to Account to give the deposit to on L2.\n * @param _l2Gas Gas limit required to complete the deposit on L2.\n * @param _data Optional data to forward to L2. This data is provided\n * solely as a convenience for external contracts. Aside from enforcing a maximum\n * length, these contracts provide no guarantees about its content.\n */\n function depositETHTo(\n address _to,\n uint32 _l2Gas,\n bytes calldata _data\n ) external payable;\n\n /**\n * @dev deposit an amount of ERC20 to a recipient's balance on L2.\n * @param _l1Token Address of the L1 ERC20 we are depositing\n * @param _l2Token Address of the L1 respective L2 ERC20\n * @param _to L2 address to credit the withdrawal to.\n * @param _amount Amount of the ERC20 to deposit.\n * @param _l2Gas Gas limit required to complete the deposit on L2.\n * @param _data Optional data to forward to L2. This data is provided\n * solely as a convenience for external contracts. Aside from enforcing a maximum\n * length, these contracts provide no guarantees about its content.\n */\n function depositERC20To(\n address _l1Token,\n address _l2Token,\n address _to,\n uint256 _amount,\n uint32 _l2Gas,\n bytes calldata _data\n ) external;\n}\n\ninterface OldL1TokenGateway {\n /**\n * @dev Transfer SNX to L2 First, moves the SNX into the deposit escrow\n *\n * @param _to Account to give the deposit to on L2\n * @param _amount Amount of the ERC20 to deposit.\n */\n function depositTo(address _to, uint256 _amount) external;\n\n /**\n * @dev Transfer SNX to L2 First, moves the SNX into the deposit escrow\n *\n * @param currencyKey currencyKey for the SynthToken\n * @param destination Account to give the deposit to on L2\n * @param amount Amount of the ERC20 to deposit.\n */\n function initiateSynthTransfer(\n bytes32 currencyKey,\n address destination,\n uint256 amount\n ) external;\n}\n" - }, - "src/bridges/arbitrum/interfaces/arbitrum.sol": { - "content": "// SPDX-License-Identifier: Apache-2.0\n\n/*\n * Copyright 2021, Offchain Labs, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npragma solidity >=0.8.0;\n\n/**\n * @title L1gatewayRouter for native-arbitrum\n */\ninterface L1GatewayRouter {\n /**\n * @notice outbound function to bridge ERC20 via NativeArbitrum-Bridge\n * @param _token address of token being bridged via GatewayRouter\n * @param _to recipient of the token on arbitrum chain\n * @param _amount amount of ERC20 token being bridged\n * @param _maxGas a depositParameter for bridging the token\n * @param _gasPriceBid a depositParameter for bridging the token\n * @param _data a depositParameter for bridging the token\n * @return calldata returns the output of transactioncall made on gatewayRouter\n */\n function outboundTransfer(\n address _token,\n address _to,\n uint256 _amount,\n uint256 _maxGas,\n uint256 _gasPriceBid,\n bytes calldata _data\n ) external payable returns (bytes calldata);\n}\n" - }, - "src/deployFactory/DisabledSocketRoute.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {ISocketGateway} from \"../interfaces/ISocketGateway.sol\";\nimport {OnlySocketGatewayOwner} from \"../errors/SocketErrors.sol\";\n\ncontract DisabledSocketRoute {\n using SafeTransferLib for ERC20;\n\n /// @notice immutable variable to store the socketGateway address\n address public immutable socketGateway;\n error RouteDisabled();\n\n /**\n * @notice Construct the base for all BridgeImplementations.\n * @param _socketGateway Socketgateway address, an immutable variable to set.\n */\n constructor(address _socketGateway) {\n socketGateway = _socketGateway;\n }\n\n /// @notice Implementing contract needs to make use of the modifier where restricted access is to be used\n modifier isSocketGatewayOwner() {\n if (msg.sender != ISocketGateway(socketGateway).owner()) {\n revert OnlySocketGatewayOwner();\n }\n _;\n }\n\n /**\n * @notice function to rescue the ERC20 tokens in the bridge Implementation contract\n * @notice this is a function restricted to Owner of SocketGateway only\n * @param token address of ERC20 token being rescued\n * @param userAddress receipient address to which ERC20 tokens will be rescued to\n * @param amount amount of ERC20 tokens being rescued\n */\n function rescueFunds(\n address token,\n address userAddress,\n uint256 amount\n ) external isSocketGatewayOwner {\n ERC20(token).safeTransfer(userAddress, amount);\n }\n\n /**\n * @notice function to rescue the native-balance in the bridge Implementation contract\n * @notice this is a function restricted to Owner of SocketGateway only\n * @param userAddress receipient address to which native-balance will be rescued to\n * @param amount amount of native balance tokens being rescued\n */\n function rescueEther(\n address payable userAddress,\n uint256 amount\n ) external isSocketGatewayOwner {\n userAddress.transfer(amount);\n }\n\n /**\n * @notice Handle route function calls gracefully.\n */\n fallback() external payable {\n revert RouteDisabled();\n }\n\n /**\n * @notice Support receiving ether to handle refunds etc.\n */\n receive() external payable {}\n}\n" - }, - "src/bridges/polygon/NativePolygon.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport \"./interfaces/polygon.sol\";\nimport {BridgeImplBase} from \"../BridgeImplBase.sol\";\nimport {NATIVE_POLYGON} from \"../../static/RouteIdentifiers.sol\";\n\n/**\n * @title NativePolygon-Route Implementation\n * @notice This is the L1 implementation, so this is used when transferring from ethereum to polygon via their native bridge.\n * @author Socket dot tech.\n */\ncontract NativePolygonImpl is BridgeImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable NativePolyonIdentifier = NATIVE_POLYGON;\n\n /// @notice destination-chain-Id for this router is always arbitrum\n uint256 public constant DESTINATION_CHAIN_ID = 137;\n\n /// @notice Function-selector for ERC20-token bridging on NativePolygon-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge ERC20 tokens\n bytes4\n public immutable NATIVE_POLYGON_ERC20_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(keccak256(\"bridgeERC20To(uint256,bytes32,address,address)\"));\n\n /// @notice Function-selector for Native bridging on NativePolygon-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge Native tokens\n bytes4\n public immutable NATIVE_POLYGON_NATIVE_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(keccak256(\"bridgeNativeTo(uint256,bytes32,address)\"));\n\n bytes4 public immutable NATIVE_POLYGON_SWAP_BRIDGE_SELECTOR =\n bytes4(keccak256(\"swapAndBridge(uint32,address,bytes32,bytes)\"));\n\n /// @notice root chain manager proxy on the ethereum chain\n /// @dev to be initialised in the constructor\n IRootChainManager public immutable rootChainManagerProxy;\n\n /// @notice ERC20 Predicate proxy on the ethereum chain\n /// @dev to be initialised in the constructor\n address public immutable erc20PredicateProxy;\n\n /**\n * // @notice We set all the required addresses in the constructor while deploying the contract.\n * // These will be constant addresses.\n * // @dev Please use the Proxy addresses and not the implementation addresses while setting these\n * // @param _rootChainManagerProxy address of the root chain manager proxy on the ethereum chain\n * // @param _erc20PredicateProxy address of the ERC20 Predicate proxy on the ethereum chain.\n * // @param _socketGateway address of the socketGateway contract that calls this contract\n */\n constructor(\n address _rootChainManagerProxy,\n address _erc20PredicateProxy,\n address _socketGateway,\n address _socketDeployFactory\n ) BridgeImplBase(_socketGateway, _socketDeployFactory) {\n rootChainManagerProxy = IRootChainManager(_rootChainManagerProxy);\n erc20PredicateProxy = _erc20PredicateProxy;\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from swapAndBridge, this function is called when the swap has already happened at a different place.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in NativePolygon-BridgeData struct\n * @param amount amount of tokens being bridged. this can be ERC20 or native\n * @param bridgeData encoded data for NativePolygon-Bridge\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable override {\n (address token, address receiverAddress, bytes32 metadata) = abi.decode(\n bridgeData,\n (address, address, bytes32)\n );\n\n if (token == NATIVE_TOKEN_ADDRESS) {\n IRootChainManager(rootChainManagerProxy).depositEtherFor{\n value: amount\n }(receiverAddress);\n } else {\n ERC20(token).safeApprove(erc20PredicateProxy, amount);\n\n // deposit into rootchain manager\n IRootChainManager(rootChainManagerProxy).depositFor(\n receiverAddress,\n token,\n abi.encodePacked(amount)\n );\n }\n\n emit SocketBridge(\n amount,\n token,\n DESTINATION_CHAIN_ID,\n NativePolyonIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from bridgeAfterSwap since this function holds the logic for swapping tokens too.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in NativePolygon-BridgeData struct\n * @param swapId routeId for the swapImpl\n * @param receiverAddress address of the receiver\n * @param swapData encoded data for swap\n */\n function swapAndBridge(\n uint32 swapId,\n address receiverAddress,\n bytes32 metadata,\n bytes calldata swapData\n ) external payable {\n (bool success, bytes memory result) = socketRoute\n .getRoute(swapId)\n .delegatecall(swapData);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n (uint256 bridgeAmount, address token) = abi.decode(\n result,\n (uint256, address)\n );\n\n if (token == NATIVE_TOKEN_ADDRESS) {\n IRootChainManager(rootChainManagerProxy).depositEtherFor{\n value: bridgeAmount\n }(receiverAddress);\n } else {\n ERC20(token).safeApprove(erc20PredicateProxy, bridgeAmount);\n\n // deposit into rootchain manager\n IRootChainManager(rootChainManagerProxy).depositFor(\n receiverAddress,\n token,\n abi.encodePacked(bridgeAmount)\n );\n }\n\n emit SocketBridge(\n bridgeAmount,\n token,\n DESTINATION_CHAIN_ID,\n NativePolyonIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n\n /**\n * @notice function to handle ERC20 bridging to receipent via NativePolygon-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param amount amount of tokens being bridged\n * @param receiverAddress recipient address\n * @param token address of token being bridged\n */\n function bridgeERC20To(\n uint256 amount,\n bytes32 metadata,\n address receiverAddress,\n address token\n ) external payable {\n ERC20 tokenInstance = ERC20(token);\n\n // set allowance for erc20 predicate\n tokenInstance.safeTransferFrom(msg.sender, socketGateway, amount);\n tokenInstance.safeApprove(erc20PredicateProxy, amount);\n\n // deposit into rootchain manager\n rootChainManagerProxy.depositFor(\n receiverAddress,\n token,\n abi.encodePacked(amount)\n );\n\n emit SocketBridge(\n amount,\n token,\n DESTINATION_CHAIN_ID,\n NativePolyonIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n\n /**\n * @notice function to handle Native bridging to receipent via NativePolygon-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param amount amount of tokens being bridged\n * @param receiverAddress recipient address\n */\n function bridgeNativeTo(\n uint256 amount,\n bytes32 metadata,\n address receiverAddress\n ) external payable {\n rootChainManagerProxy.depositEtherFor{value: amount}(receiverAddress);\n\n emit SocketBridge(\n amount,\n NATIVE_TOKEN_ADDRESS,\n DESTINATION_CHAIN_ID,\n NativePolyonIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n}\n" - }, - "src/bridges/stargate/l1/Stargate.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport \"../interfaces/stargate.sol\";\nimport {BridgeImplBase} from \"../../BridgeImplBase.sol\";\nimport {STARGATE} from \"../../../static/RouteIdentifiers.sol\";\n\n/**\n * @title Stargate-L1-Route Implementation\n * @notice Route implementation with functions to bridge ERC20 and Native via Stargate-L1-Bridge\n * Called via SocketGateway if the routeId in the request maps to the routeId of Stargate-L1-Implementation\n * Contains function to handle bridging as post-step i.e linked to a preceeding step for swap\n * RequestData is different to just bride and bridging chained with swap\n * @author Socket dot tech.\n */\ncontract StargateImplL1 is BridgeImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable StargateIdentifier = STARGATE;\n\n /// @notice Function-selector for ERC20-token bridging on Stargate-L1-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge ERC20 tokens\n bytes4\n public immutable STARGATE_L1_ERC20_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeERC20To(address,address,address,uint256,uint256,(uint256,uint256,uint256,uint256,bytes32,bytes,uint16))\"\n )\n );\n\n /// @notice Function-selector for Native bridging on Stargate-L1-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge Native tokens\n bytes4\n public immutable STARGATE_L1_NATIVE_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeNativeTo(address,address,uint16,uint256,uint256,uint256,bytes32)\"\n )\n );\n\n bytes4 public immutable STARGATE_L1_SWAP_BRIDGE_SELECTOR =\n bytes4(\n keccak256(\n \"swapAndBridge(uint32,bytes,(address,address,uint16,uint256,uint256,uint256,uint256,uint256,uint256,bytes32,bytes))\"\n )\n );\n\n /// @notice Stargate Router to bridge ERC20 tokens\n IBridgeStargate public immutable router;\n\n /// @notice Stargate Router to bridge native tokens\n IBridgeStargate public immutable routerETH;\n\n /// @notice socketGatewayAddress to be initialised via storage variable BridgeImplBase\n /// @dev ensure router, routerEth are set properly for the chainId in which the contract is being deployed\n constructor(\n address _router,\n address _routerEth,\n address _socketGateway,\n address _socketDeployFactory\n ) BridgeImplBase(_socketGateway, _socketDeployFactory) {\n router = IBridgeStargate(_router);\n routerETH = IBridgeStargate(_routerEth);\n }\n\n struct StargateBridgeExtraData {\n uint256 srcPoolId;\n uint256 dstPoolId;\n uint256 destinationGasLimit;\n uint256 minReceivedAmt;\n bytes32 metadata;\n bytes destinationPayload;\n uint16 stargateDstChainId; // stargate defines chain id in its way\n }\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct StargateBridgeDataNoToken {\n address receiverAddress;\n address senderAddress;\n uint16 stargateDstChainId; // stargate defines chain id in its way\n uint256 value;\n // a unique identifier that is uses to dedup transfers\n // this value is the a timestamp sent from frontend, but in theory can be any unique number\n uint256 srcPoolId;\n uint256 dstPoolId;\n uint256 minReceivedAmt; // defines the slippage, the min qty you would accept on the destination\n uint256 optionalValue;\n uint256 destinationGasLimit;\n bytes32 metadata;\n bytes destinationPayload;\n }\n\n struct StargateBridgeData {\n address token;\n address receiverAddress;\n address senderAddress;\n uint16 stargateDstChainId; // stargate defines chain id in its way\n uint256 value;\n // a unique identifier that is uses to dedup transfers\n // this value is the a timestamp sent from frontend, but in theory can be any unique number\n uint256 srcPoolId;\n uint256 dstPoolId;\n uint256 minReceivedAmt; // defines the slippage, the min qty you would accept on the destination\n uint256 optionalValue;\n uint256 destinationGasLimit;\n bytes32 metadata;\n bytes destinationPayload;\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from swapAndBridge, this function is called when the swap has already happened at a different place.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in Stargate-BridgeData struct\n * @param amount amount of tokens being bridged. this can be ERC20 or native\n * @param bridgeData encoded data for Stargate-L1-Bridge\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable override {\n StargateBridgeData memory stargateBridgeData = abi.decode(\n bridgeData,\n (StargateBridgeData)\n );\n\n if (stargateBridgeData.token == NATIVE_TOKEN_ADDRESS) {\n // perform bridging\n routerETH.swapETH{value: amount + stargateBridgeData.optionalValue}(\n stargateBridgeData.stargateDstChainId,\n payable(stargateBridgeData.senderAddress),\n abi.encodePacked(stargateBridgeData.receiverAddress),\n amount,\n stargateBridgeData.minReceivedAmt\n );\n } else {\n ERC20(stargateBridgeData.token).safeApprove(\n address(router),\n amount\n );\n {\n router.swap{value: stargateBridgeData.value}(\n stargateBridgeData.stargateDstChainId,\n stargateBridgeData.srcPoolId,\n stargateBridgeData.dstPoolId,\n payable(stargateBridgeData.senderAddress), // default to refund to main contract\n amount,\n stargateBridgeData.minReceivedAmt,\n IBridgeStargate.lzTxObj(\n stargateBridgeData.destinationGasLimit,\n 0, // zero amount since this is a ERC20 bridging\n \"0x\" //empty data since this is for only ERC20\n ),\n abi.encodePacked(stargateBridgeData.receiverAddress),\n stargateBridgeData.destinationPayload\n );\n }\n }\n\n emit SocketBridge(\n amount,\n stargateBridgeData.token,\n stargateBridgeData.stargateDstChainId,\n StargateIdentifier,\n msg.sender,\n stargateBridgeData.receiverAddress,\n stargateBridgeData.metadata\n );\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from bridgeAfterSwap since this function holds the logic for swapping tokens too.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in Stargate-BridgeData struct\n * @param swapId routeId for the swapImpl\n * @param swapData encoded data for swap\n * @param stargateBridgeData encoded data for StargateBridgeData\n */\n function swapAndBridge(\n uint32 swapId,\n bytes calldata swapData,\n StargateBridgeDataNoToken calldata stargateBridgeData\n ) external payable {\n (bool success, bytes memory result) = socketRoute\n .getRoute(swapId)\n .delegatecall(swapData);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n (uint256 bridgeAmount, address token) = abi.decode(\n result,\n (uint256, address)\n );\n\n if (token == NATIVE_TOKEN_ADDRESS) {\n // perform bridging\n routerETH.swapETH{\n value: bridgeAmount + stargateBridgeData.optionalValue\n }(\n stargateBridgeData.stargateDstChainId,\n payable(stargateBridgeData.senderAddress),\n abi.encodePacked(stargateBridgeData.receiverAddress),\n bridgeAmount,\n stargateBridgeData.minReceivedAmt\n );\n } else {\n ERC20(token).safeApprove(address(router), bridgeAmount);\n {\n router.swap{value: stargateBridgeData.value}(\n stargateBridgeData.stargateDstChainId,\n stargateBridgeData.srcPoolId,\n stargateBridgeData.dstPoolId,\n payable(stargateBridgeData.senderAddress), // default to refund to main contract\n bridgeAmount,\n stargateBridgeData.minReceivedAmt,\n IBridgeStargate.lzTxObj(\n stargateBridgeData.destinationGasLimit,\n 0, // zero amount since this is a ERC20 bridging\n \"0x\" //empty data since this is for only ERC20\n ),\n abi.encodePacked(stargateBridgeData.receiverAddress),\n stargateBridgeData.destinationPayload\n );\n }\n }\n\n emit SocketBridge(\n bridgeAmount,\n token,\n stargateBridgeData.stargateDstChainId,\n StargateIdentifier,\n msg.sender,\n stargateBridgeData.receiverAddress,\n stargateBridgeData.metadata\n );\n }\n\n /**\n * @notice function to handle ERC20 bridging to receipent via Stargate-L1-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param token address of token being bridged\n * @param senderAddress address of sender\n * @param receiverAddress address of recipient\n * @param amount amount of token being bridge\n * @param value value\n * @param stargateBridgeExtraData stargate bridge extradata\n */\n function bridgeERC20To(\n address token,\n address senderAddress,\n address receiverAddress,\n uint256 amount,\n uint256 value,\n StargateBridgeExtraData calldata stargateBridgeExtraData\n ) external payable {\n ERC20 tokenInstance = ERC20(token);\n tokenInstance.safeTransferFrom(msg.sender, socketGateway, amount);\n tokenInstance.safeApprove(address(router), amount);\n {\n router.swap{value: value}(\n stargateBridgeExtraData.stargateDstChainId,\n stargateBridgeExtraData.srcPoolId,\n stargateBridgeExtraData.dstPoolId,\n payable(senderAddress), // default to refund to main contract\n amount,\n stargateBridgeExtraData.minReceivedAmt,\n IBridgeStargate.lzTxObj(\n stargateBridgeExtraData.destinationGasLimit,\n 0, // zero amount since this is a ERC20 bridging\n \"0x\" //empty data since this is for only ERC20\n ),\n abi.encodePacked(receiverAddress),\n stargateBridgeExtraData.destinationPayload\n );\n }\n\n emit SocketBridge(\n amount,\n token,\n stargateBridgeExtraData.stargateDstChainId,\n StargateIdentifier,\n msg.sender,\n receiverAddress,\n stargateBridgeExtraData.metadata\n );\n }\n\n /**\n * @notice function to handle Native bridging to receipent via Stargate-L1-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param receiverAddress address of receipient\n * @param senderAddress address of sender\n * @param stargateDstChainId stargate defines chain id in its way\n * @param amount amount of token being bridge\n * @param minReceivedAmt defines the slippage, the min qty you would accept on the destination\n * @param optionalValue optionalValue Native amount\n */\n function bridgeNativeTo(\n address receiverAddress,\n address senderAddress,\n uint16 stargateDstChainId,\n uint256 amount,\n uint256 minReceivedAmt,\n uint256 optionalValue,\n bytes32 metadata\n ) external payable {\n // perform bridging\n routerETH.swapETH{value: amount + optionalValue}(\n stargateDstChainId,\n payable(senderAddress),\n abi.encodePacked(receiverAddress),\n amount,\n minReceivedAmt\n );\n\n emit SocketBridge(\n amount,\n NATIVE_TOKEN_ADDRESS,\n stargateDstChainId,\n StargateIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n}\n" - }, - "src/bridges/hop/l2/HopImplL2.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport \"../interfaces/amm.sol\";\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {BridgeImplBase} from \"../../BridgeImplBase.sol\";\nimport {HOP} from \"../../../static/RouteIdentifiers.sol\";\n\n/**\n * @title Hop-L2 Route Implementation\n * @notice This is the L2 implementation, so this is used when transferring from l2 to supported l2s\n * Called via SocketGateway if the routeId in the request maps to the routeId of HopL2-Implementation\n * Contains function to handle bridging as post-step i.e linked to a preceeding step for swap\n * RequestData is different to just bride and bridging chained with swap\n * @author Socket dot tech.\n */\ncontract HopImplL2 is BridgeImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable HopIdentifier = HOP;\n\n /// @notice Function-selector for ERC20-token bridging on Hop-L2-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge ERC20 tokens\n bytes4 public immutable HOP_L2_ERC20_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeERC20To(address,address,address,uint256,uint256,(uint256,uint256,uint256,uint256,uint256,bytes32))\"\n )\n );\n\n /// @notice Function-selector for Native bridging on Hop-L2-Route\n /// @dev This function selector is to be used while building transaction-data to bridge Native tokens\n bytes4 public immutable HOP_L2_NATIVE_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeNativeTo(address,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,bytes32)\"\n )\n );\n\n bytes4 public immutable HOP_L2_SWAP_BRIDGE_SELECTOR =\n bytes4(\n keccak256(\n \"swapAndBridge(uint32,bytes,(address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes32))\"\n )\n );\n\n /// @notice socketGatewayAddress to be initialised via storage variable BridgeImplBase\n constructor(\n address _socketGateway,\n address _socketDeployFactory\n ) BridgeImplBase(_socketGateway, _socketDeployFactory) {}\n\n /// @notice Struct to be used as a input parameter for Bridging tokens via Hop-L2-route\n /// @dev while building transactionData,values should be set in this sequence of properties in this struct\n struct HopBridgeRequestData {\n // fees passed to relayer\n uint256 bonderFee;\n // The minimum amount received after attempting to swap in the destination AMM market. 0 if no swap is intended.\n uint256 amountOutMin;\n // The deadline for swapping in the destination AMM market. 0 if no swap is intended.\n uint256 deadline;\n // Minimum amount expected to be received or bridged to destination\n uint256 amountOutMinDestination;\n // deadline for bridging to destination\n uint256 deadlineDestination;\n // socket offchain created hash\n bytes32 metadata;\n }\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct HopBridgeDataNoToken {\n // The address receiving funds at the destination\n address receiverAddress;\n // AMM address of Hop on L2\n address hopAMM;\n // The chainId of the destination chain\n uint256 toChainId;\n // fees passed to relayer\n uint256 bonderFee;\n // The minimum amount received after attempting to swap in the destination AMM market. 0 if no swap is intended.\n uint256 amountOutMin;\n // The deadline for swapping in the destination AMM market. 0 if no swap is intended.\n uint256 deadline;\n // Minimum amount expected to be received or bridged to destination\n uint256 amountOutMinDestination;\n // deadline for bridging to destination\n uint256 deadlineDestination;\n // socket offchain created hash\n bytes32 metadata;\n }\n\n struct HopBridgeData {\n /// @notice address of token being bridged\n address token;\n // The address receiving funds at the destination\n address receiverAddress;\n // AMM address of Hop on L2\n address hopAMM;\n // The chainId of the destination chain\n uint256 toChainId;\n // fees passed to relayer\n uint256 bonderFee;\n // The minimum amount received after attempting to swap in the destination AMM market. 0 if no swap is intended.\n uint256 amountOutMin;\n // The deadline for swapping in the destination AMM market. 0 if no swap is intended.\n uint256 deadline;\n // Minimum amount expected to be received or bridged to destination\n uint256 amountOutMinDestination;\n // deadline for bridging to destination\n uint256 deadlineDestination;\n // socket offchain created hash\n bytes32 metadata;\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from swapAndBridge, this function is called when the swap has already happened at a different place.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in HopBridgeData struct\n * @param amount amount of tokens being bridged. this can be ERC20 or native\n * @param bridgeData encoded data for Hop-L2-Bridge\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable override {\n HopBridgeData memory hopData = abi.decode(bridgeData, (HopBridgeData));\n\n if (hopData.token == NATIVE_TOKEN_ADDRESS) {\n HopAMM(hopData.hopAMM).swapAndSend{value: amount}(\n hopData.toChainId,\n hopData.receiverAddress,\n amount,\n hopData.bonderFee,\n hopData.amountOutMin,\n hopData.deadline,\n hopData.amountOutMinDestination,\n hopData.deadlineDestination\n );\n } else {\n // perform bridging\n HopAMM(hopData.hopAMM).swapAndSend(\n hopData.toChainId,\n hopData.receiverAddress,\n amount,\n hopData.bonderFee,\n hopData.amountOutMin,\n hopData.deadline,\n hopData.amountOutMinDestination,\n hopData.deadlineDestination\n );\n }\n\n emit SocketBridge(\n amount,\n hopData.token,\n hopData.toChainId,\n HopIdentifier,\n msg.sender,\n hopData.receiverAddress,\n hopData.metadata\n );\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from bridgeAfterSwap since this function holds the logic for swapping tokens too.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in HopBridgeData struct\n * @param swapId routeId for the swapImpl\n * @param swapData encoded data for swap\n * @param hopData encoded data for HopData\n */\n function swapAndBridge(\n uint32 swapId,\n bytes calldata swapData,\n HopBridgeDataNoToken calldata hopData\n ) external payable {\n (bool success, bytes memory result) = socketRoute\n .getRoute(swapId)\n .delegatecall(swapData);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n (uint256 bridgeAmount, address token) = abi.decode(\n result,\n (uint256, address)\n );\n\n if (token == NATIVE_TOKEN_ADDRESS) {\n HopAMM(hopData.hopAMM).swapAndSend{value: bridgeAmount}(\n hopData.toChainId,\n hopData.receiverAddress,\n bridgeAmount,\n hopData.bonderFee,\n hopData.amountOutMin,\n hopData.deadline,\n hopData.amountOutMinDestination,\n hopData.deadlineDestination\n );\n } else {\n // perform bridging\n HopAMM(hopData.hopAMM).swapAndSend(\n hopData.toChainId,\n hopData.receiverAddress,\n bridgeAmount,\n hopData.bonderFee,\n hopData.amountOutMin,\n hopData.deadline,\n hopData.amountOutMinDestination,\n hopData.deadlineDestination\n );\n }\n\n emit SocketBridge(\n bridgeAmount,\n token,\n hopData.toChainId,\n HopIdentifier,\n msg.sender,\n hopData.receiverAddress,\n hopData.metadata\n );\n }\n\n /**\n * @notice function to handle ERC20 bridging to receipent via Hop-L2-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param receiverAddress The address receiving funds at the destination\n * @param token token being bridged\n * @param hopAMM AMM address of Hop on L2\n * @param amount The amount being bridged\n * @param toChainId The chainId of the destination chain\n * @param hopBridgeRequestData extraData for Bridging across Hop-L2\n */\n function bridgeERC20To(\n address receiverAddress,\n address token,\n address hopAMM,\n uint256 amount,\n uint256 toChainId,\n HopBridgeRequestData calldata hopBridgeRequestData\n ) external payable {\n ERC20 tokenInstance = ERC20(token);\n tokenInstance.safeTransferFrom(msg.sender, socketGateway, amount);\n\n HopAMM(hopAMM).swapAndSend(\n toChainId,\n receiverAddress,\n amount,\n hopBridgeRequestData.bonderFee,\n hopBridgeRequestData.amountOutMin,\n hopBridgeRequestData.deadline,\n hopBridgeRequestData.amountOutMinDestination,\n hopBridgeRequestData.deadlineDestination\n );\n\n emit SocketBridge(\n amount,\n token,\n toChainId,\n HopIdentifier,\n msg.sender,\n receiverAddress,\n hopBridgeRequestData.metadata\n );\n }\n\n /**\n * @notice function to handle Native bridging to receipent via Hop-L2-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param receiverAddress The address receiving funds at the destination\n * @param hopAMM AMM address of Hop on L2\n * @param amount The amount being bridged\n * @param toChainId The chainId of the destination chain\n * @param bonderFee fees passed to relayer\n * @param amountOutMin The minimum amount received after attempting to swap in the destination AMM market. 0 if no swap is intended.\n * @param deadline The deadline for swapping in the destination AMM market. 0 if no swap is intended.\n * @param amountOutMinDestination Minimum amount expected to be received or bridged to destination\n * @param deadlineDestination deadline for bridging to destination\n */\n function bridgeNativeTo(\n address receiverAddress,\n address hopAMM,\n uint256 amount,\n uint256 toChainId,\n uint256 bonderFee,\n uint256 amountOutMin,\n uint256 deadline,\n uint256 amountOutMinDestination,\n uint256 deadlineDestination,\n bytes32 metadata\n ) external payable {\n // token address might not be indication thats why passed through extraData\n // perform bridging\n HopAMM(hopAMM).swapAndSend{value: amount}(\n toChainId,\n receiverAddress,\n amount,\n bonderFee,\n amountOutMin,\n deadline,\n amountOutMinDestination,\n deadlineDestination\n );\n\n emit SocketBridge(\n amount,\n NATIVE_TOKEN_ADDRESS,\n toChainId,\n HopIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n}\n" - }, - "src/bridges/anyswap-router-v4/l2/Anyswap.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {BridgeImplBase} from \"../../BridgeImplBase.sol\";\nimport {ANYSWAP} from \"../../../static/RouteIdentifiers.sol\";\n\n/**\n * @title Anyswap-V4-Route L1 Implementation\n * @notice Route implementation with functions to bridge ERC20 via Anyswap-Bridge\n * Called via SocketGateway if the routeId in the request maps to the routeId of AnyswapImplementation\n * This is the L2 implementation, so this is used when transferring from l2.\n * Contains function to handle bridging as post-step i.e linked to a preceeding step for swap\n * RequestData is different to just bride and bridging chained with swap\n * @author Socket dot tech.\n */\ninterface AnyswapV4Router {\n function anySwapOutUnderlying(\n address token,\n address to,\n uint256 amount,\n uint256 toChainID\n ) external;\n}\n\ncontract AnyswapL2Impl is BridgeImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable AnyswapIdentifier = ANYSWAP;\n\n /// @notice Function-selector for ERC20-token bridging on Anyswap-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge ERC20 tokens\n bytes4 public immutable ANYSWAP_L2_ERC20_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeERC20To(uint256,uint256,bytes32,address,address,address)\"\n )\n );\n\n bytes4 public immutable ANYSWAP_SWAP_BRIDGE_SELECTOR =\n bytes4(\n keccak256(\n \"swapAndBridge(uint32,bytes,(uint256,address,address,bytes32))\"\n )\n );\n\n // polygon router multichain router v4\n AnyswapV4Router public immutable router;\n\n /**\n * @notice Constructor sets the router address and socketGateway address.\n * @dev anyswap v4 router is immutable. so no setter function required.\n */\n constructor(\n address _router,\n address _socketGateway,\n address _socketDeployFactory\n ) BridgeImplBase(_socketGateway, _socketDeployFactory) {\n router = AnyswapV4Router(_router);\n }\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct AnyswapBridgeDataNoToken {\n /// @notice destination ChainId\n uint256 toChainId;\n /// @notice address of receiver of bridged tokens\n address receiverAddress;\n /// @notice address of wrapperToken, WrappedVersion of the token being bridged\n address wrapperTokenAddress;\n /// @notice socket offchain created hash\n bytes32 metadata;\n }\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct AnyswapBridgeData {\n /// @notice destination ChainId\n uint256 toChainId;\n /// @notice address of receiver of bridged tokens\n address receiverAddress;\n /// @notice address of wrapperToken, WrappedVersion of the token being bridged\n address wrapperTokenAddress;\n /// @notice address of token being bridged\n address token;\n /// @notice socket offchain created hash\n bytes32 metadata;\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from swapAndBridge, this function is called when the swap has already happened at a different place.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in AnyswapBridgeData struct\n * @param amount amount of tokens being bridged. this can be ERC20 or native\n * @param bridgeData encoded data for AnyswapBridge\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable override {\n AnyswapBridgeData memory anyswapBridgeData = abi.decode(\n bridgeData,\n (AnyswapBridgeData)\n );\n ERC20(anyswapBridgeData.token).safeApprove(address(router), amount);\n router.anySwapOutUnderlying(\n anyswapBridgeData.wrapperTokenAddress,\n anyswapBridgeData.receiverAddress,\n amount,\n anyswapBridgeData.toChainId\n );\n\n emit SocketBridge(\n amount,\n anyswapBridgeData.token,\n anyswapBridgeData.toChainId,\n AnyswapIdentifier,\n msg.sender,\n anyswapBridgeData.receiverAddress,\n anyswapBridgeData.metadata\n );\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from bridgeAfterSwap since this function holds the logic for swapping tokens too.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in AnyswapBridgeData struct\n * @param swapId routeId for the swapImpl\n * @param swapData encoded data for swap\n * @param anyswapBridgeData encoded data for AnyswapBridge\n */\n function swapAndBridge(\n uint32 swapId,\n bytes calldata swapData,\n AnyswapBridgeDataNoToken calldata anyswapBridgeData\n ) external payable {\n (bool success, bytes memory result) = socketRoute\n .getRoute(swapId)\n .delegatecall(swapData);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n (uint256 bridgeAmount, address token) = abi.decode(\n result,\n (uint256, address)\n );\n\n ERC20(token).safeApprove(address(router), bridgeAmount);\n router.anySwapOutUnderlying(\n anyswapBridgeData.wrapperTokenAddress,\n anyswapBridgeData.receiverAddress,\n bridgeAmount,\n anyswapBridgeData.toChainId\n );\n\n emit SocketBridge(\n bridgeAmount,\n token,\n anyswapBridgeData.toChainId,\n AnyswapIdentifier,\n msg.sender,\n anyswapBridgeData.receiverAddress,\n anyswapBridgeData.metadata\n );\n }\n\n /**\n * @notice function to handle ERC20 bridging to receipent via Anyswap-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param amount amount being bridged\n * @param toChainId destination ChainId\n * @param receiverAddress address of receiver of bridged tokens\n * @param token address of token being bridged\n * @param wrapperTokenAddress address of wrapperToken, WrappedVersion of the token being bridged\n */\n function bridgeERC20To(\n uint256 amount,\n uint256 toChainId,\n bytes32 metadata,\n address receiverAddress,\n address token,\n address wrapperTokenAddress\n ) external payable {\n ERC20 tokenInstance = ERC20(token);\n tokenInstance.safeTransferFrom(msg.sender, socketGateway, amount);\n tokenInstance.safeApprove(address(router), amount);\n router.anySwapOutUnderlying(\n wrapperTokenAddress,\n receiverAddress,\n amount,\n toChainId\n );\n\n emit SocketBridge(\n amount,\n token,\n toChainId,\n AnyswapIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n}\n" - }, - "src/bridges/hyphen/Hyphen.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport \"./interfaces/hyphen.sol\";\nimport \"../BridgeImplBase.sol\";\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {HYPHEN} from \"../../static/RouteIdentifiers.sol\";\n\n/**\n * @title Hyphen-Route Implementation\n * @notice Route implementation with functions to bridge ERC20 and Native via Hyphen-Bridge\n * Called via SocketGateway if the routeId in the request maps to the routeId of HyphenImplementation\n * Contains function to handle bridging as post-step i.e linked to a preceeding step for swap\n * RequestData is different to just bride and bridging chained with swap\n * @author Socket dot tech.\n */\ncontract HyphenImpl is BridgeImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable HyphenIdentifier = HYPHEN;\n\n /// @notice Function-selector for ERC20-token bridging on Hyphen-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge ERC20 tokens\n bytes4 public immutable HYPHEN_ERC20_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\"bridgeERC20To(uint256,bytes32,address,address,uint256)\")\n );\n\n /// @notice Function-selector for Native bridging on Hyphen-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge Native tokens\n bytes4 public immutable HYPHEN_NATIVE_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(keccak256(\"bridgeNativeTo(uint256,bytes32,address,uint256)\"));\n\n bytes4 public immutable HYPHEN_SWAP_BRIDGE_SELECTOR =\n bytes4(\n keccak256(\"swapAndBridge(uint32,bytes,(address,uint256,bytes32))\")\n );\n\n /// @notice liquidityPoolManager - liquidityPool Manager of Hyphen used to bridge ERC20 and native\n /// @dev this is to be initialized in constructor with a valid deployed address of hyphen-liquidityPoolManager\n HyphenLiquidityPoolManager public immutable liquidityPoolManager;\n\n /// @notice socketGatewayAddress to be initialised via storage variable BridgeImplBase\n /// @dev ensure liquidityPoolManager-address are set properly for the chainId in which the contract is being deployed\n constructor(\n address _liquidityPoolManager,\n address _socketGateway,\n address _socketDeployFactory\n ) BridgeImplBase(_socketGateway, _socketDeployFactory) {\n liquidityPoolManager = HyphenLiquidityPoolManager(\n _liquidityPoolManager\n );\n }\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct HyphenData {\n /// @notice address of token being bridged\n address token;\n /// @notice address of receiver\n address receiverAddress;\n /// @notice chainId of destination\n uint256 toChainId;\n /// @notice socket offchain created hash\n bytes32 metadata;\n }\n\n struct HyphenDataNoToken {\n /// @notice address of receiver\n address receiverAddress;\n /// @notice chainId of destination\n uint256 toChainId;\n /// @notice chainId of destination\n bytes32 metadata;\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from swapAndBridge, this function is called when the swap has already happened at a different place.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in HyphenBridgeData struct\n * @param amount amount of tokens being bridged. this can be ERC20 or native\n * @param bridgeData encoded data for HyphenBridge\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable override {\n HyphenData memory hyphenData = abi.decode(bridgeData, (HyphenData));\n\n if (hyphenData.token == NATIVE_TOKEN_ADDRESS) {\n liquidityPoolManager.depositNative{value: amount}(\n hyphenData.receiverAddress,\n hyphenData.toChainId,\n \"SOCKET\"\n );\n } else {\n ERC20(hyphenData.token).safeApprove(\n address(liquidityPoolManager),\n amount\n );\n liquidityPoolManager.depositErc20(\n hyphenData.toChainId,\n hyphenData.token,\n hyphenData.receiverAddress,\n amount,\n \"SOCKET\"\n );\n }\n\n emit SocketBridge(\n amount,\n hyphenData.token,\n hyphenData.toChainId,\n HyphenIdentifier,\n msg.sender,\n hyphenData.receiverAddress,\n hyphenData.metadata\n );\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from bridgeAfterSwap since this function holds the logic for swapping tokens too.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in HyphenBridgeData struct\n * @param swapId routeId for the swapImpl\n * @param swapData encoded data for swap\n * @param hyphenData encoded data for hyphenData\n */\n function swapAndBridge(\n uint32 swapId,\n bytes calldata swapData,\n HyphenDataNoToken calldata hyphenData\n ) external payable {\n (bool success, bytes memory result) = socketRoute\n .getRoute(swapId)\n .delegatecall(swapData);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n (uint256 bridgeAmount, address token) = abi.decode(\n result,\n (uint256, address)\n );\n if (token == NATIVE_TOKEN_ADDRESS) {\n liquidityPoolManager.depositNative{value: bridgeAmount}(\n hyphenData.receiverAddress,\n hyphenData.toChainId,\n \"SOCKET\"\n );\n } else {\n ERC20(token).safeApprove(\n address(liquidityPoolManager),\n bridgeAmount\n );\n liquidityPoolManager.depositErc20(\n hyphenData.toChainId,\n token,\n hyphenData.receiverAddress,\n bridgeAmount,\n \"SOCKET\"\n );\n }\n\n emit SocketBridge(\n bridgeAmount,\n token,\n hyphenData.toChainId,\n HyphenIdentifier,\n msg.sender,\n hyphenData.receiverAddress,\n hyphenData.metadata\n );\n }\n\n /**\n * @notice function to handle ERC20 bridging to receipent via Hyphen-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param amount amount to be sent\n * @param receiverAddress address of the token to bridged to the destination chain.\n * @param token address of token being bridged\n * @param toChainId chainId of destination\n */\n function bridgeERC20To(\n uint256 amount,\n bytes32 metadata,\n address receiverAddress,\n address token,\n uint256 toChainId\n ) external payable {\n ERC20 tokenInstance = ERC20(token);\n tokenInstance.safeTransferFrom(msg.sender, socketGateway, amount);\n tokenInstance.safeApprove(address(liquidityPoolManager), amount);\n liquidityPoolManager.depositErc20(\n toChainId,\n token,\n receiverAddress,\n amount,\n \"SOCKET\"\n );\n\n emit SocketBridge(\n amount,\n token,\n toChainId,\n HyphenIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n\n /**\n * @notice function to handle Native bridging to receipent via Hyphen-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param amount amount to be sent\n * @param receiverAddress address of the token to bridged to the destination chain.\n * @param toChainId chainId of destination\n */\n function bridgeNativeTo(\n uint256 amount,\n bytes32 metadata,\n address receiverAddress,\n uint256 toChainId\n ) external payable {\n liquidityPoolManager.depositNative{value: amount}(\n receiverAddress,\n toChainId,\n \"SOCKET\"\n );\n\n emit SocketBridge(\n amount,\n NATIVE_TOKEN_ADDRESS,\n toChainId,\n HyphenIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n}\n" - }, - "src/bridges/optimism/l1/NativeOptimism.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport \"../interfaces/optimism.sol\";\nimport {BridgeImplBase} from \"../../BridgeImplBase.sol\";\nimport {UnsupportedInterfaceId} from \"../../../errors/SocketErrors.sol\";\nimport {NATIVE_OPTIMISM} from \"../../../static/RouteIdentifiers.sol\";\n\n/**\n * @title NativeOptimism-Route Implementation\n * @notice Route implementation with functions to bridge ERC20 and Native via NativeOptimism-Bridge\n * Tokens are bridged from Ethereum to Optimism Chain.\n * Called via SocketGateway if the routeId in the request maps to the routeId of NativeOptimism-Implementation\n * Contains function to handle bridging as post-step i.e linked to a preceeding step for swap\n * RequestData is different to just bride and bridging chained with swap\n * @author Socket dot tech.\n */\ncontract NativeOptimismImpl is BridgeImplBase {\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable NativeOptimismIdentifier = NATIVE_OPTIMISM;\n\n uint256 public constant DESTINATION_CHAIN_ID = 10;\n\n /// @notice Function-selector for ERC20-token bridging on Native-Optimism-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge ERC20 tokens\n bytes4\n public immutable NATIVE_OPTIMISM_ERC20_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeERC20To(address,address,address,uint32,(bytes32,bytes32),uint256,uint256,address,bytes)\"\n )\n );\n\n /// @notice Function-selector for Native bridging on Native-Optimism-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge Native balance\n bytes4\n public immutable NATIVE_OPTIMISM_NATIVE_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeNativeTo(address,address,uint32,uint256,bytes32,bytes)\"\n )\n );\n\n bytes4 public immutable NATIVE_OPTIMISM_SWAP_BRIDGE_SELECTOR =\n bytes4(\n keccak256(\n \"swapAndBridge(uint32,bytes,(uint256,bytes32,bytes32,address,address,uint32,address,bytes))\"\n )\n );\n\n /// @notice socketGatewayAddress to be initialised via storage variable BridgeImplBase\n constructor(\n address _socketGateway,\n address _socketDeployFactory\n ) BridgeImplBase(_socketGateway, _socketDeployFactory) {}\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct OptimismBridgeDataNoToken {\n // interfaceId to be set offchain which is used to select one of the 3 kinds of bridging (standard bridge / old standard / synthetic)\n uint256 interfaceId;\n // currencyKey of the token beingBridged\n bytes32 currencyKey;\n // socket offchain created hash\n bytes32 metadata;\n // address of receiver of bridged tokens\n address receiverAddress;\n /**\n * OptimismBridge that Performs the logic for deposits by informing the L2 Deposited Token\n * contract of the deposit and calling a handler to lock the L1 funds. (e.g. transferFrom)\n */\n address customBridgeAddress;\n // Gas limit required to complete the deposit on L2.\n uint32 l2Gas;\n // Address of the L1 respective L2 ERC20\n address l2Token;\n // additional data , for ll contracts this will be 0x data or empty data\n bytes data;\n }\n\n struct OptimismBridgeData {\n // interfaceId to be set offchain which is used to select one of the 3 kinds of bridging (standard bridge / old standard / synthetic)\n uint256 interfaceId;\n // currencyKey of the token beingBridged\n bytes32 currencyKey;\n // socket offchain created hash\n bytes32 metadata;\n // address of receiver of bridged tokens\n address receiverAddress;\n /**\n * OptimismBridge that Performs the logic for deposits by informing the L2 Deposited Token\n * contract of the deposit and calling a handler to lock the L1 funds. (e.g. transferFrom)\n */\n address customBridgeAddress;\n /// @notice address of token being bridged\n address token;\n // Gas limit required to complete the deposit on L2.\n uint32 l2Gas;\n // Address of the L1 respective L2 ERC20\n address l2Token;\n // additional data , for ll contracts this will be 0x data or empty data\n bytes data;\n }\n\n struct OptimismERC20Data {\n bytes32 currencyKey;\n bytes32 metadata;\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from swapAndBridge, this function is called when the swap has already happened at a different place.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in OptimismBridgeData struct\n * @param amount amount of tokens being bridged. this can be ERC20 or native\n * @param bridgeData encoded data for Optimism-Bridge\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable override {\n OptimismBridgeData memory optimismBridgeData = abi.decode(\n bridgeData,\n (OptimismBridgeData)\n );\n\n emit SocketBridge(\n amount,\n optimismBridgeData.token,\n DESTINATION_CHAIN_ID,\n NativeOptimismIdentifier,\n msg.sender,\n optimismBridgeData.receiverAddress,\n optimismBridgeData.metadata\n );\n if (optimismBridgeData.token == NATIVE_TOKEN_ADDRESS) {\n L1StandardBridge(optimismBridgeData.customBridgeAddress)\n .depositETHTo{value: amount}(\n optimismBridgeData.receiverAddress,\n optimismBridgeData.l2Gas,\n optimismBridgeData.data\n );\n } else {\n if (optimismBridgeData.interfaceId == 0) {\n revert UnsupportedInterfaceId();\n }\n\n ERC20(optimismBridgeData.token).safeApprove(\n optimismBridgeData.customBridgeAddress,\n amount\n );\n\n if (optimismBridgeData.interfaceId == 1) {\n // deposit into standard bridge\n L1StandardBridge(optimismBridgeData.customBridgeAddress)\n .depositERC20To(\n optimismBridgeData.token,\n optimismBridgeData.l2Token,\n optimismBridgeData.receiverAddress,\n amount,\n optimismBridgeData.l2Gas,\n optimismBridgeData.data\n );\n return;\n }\n\n // Deposit Using Old Standard - iOVM_L1TokenGateway(Example - SNX Token)\n if (optimismBridgeData.interfaceId == 2) {\n OldL1TokenGateway(optimismBridgeData.customBridgeAddress)\n .depositTo(optimismBridgeData.receiverAddress, amount);\n return;\n }\n\n if (optimismBridgeData.interfaceId == 3) {\n OldL1TokenGateway(optimismBridgeData.customBridgeAddress)\n .initiateSynthTransfer(\n optimismBridgeData.currencyKey,\n optimismBridgeData.receiverAddress,\n amount\n );\n return;\n }\n }\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from bridgeAfterSwap since this function holds the logic for swapping tokens too.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in OptimismBridgeData struct\n * @param swapId routeId for the swapImpl\n * @param swapData encoded data for swap\n * @param optimismBridgeData encoded data for OptimismBridgeData\n */\n function swapAndBridge(\n uint32 swapId,\n bytes calldata swapData,\n OptimismBridgeDataNoToken calldata optimismBridgeData\n ) external payable {\n (bool success, bytes memory result) = socketRoute\n .getRoute(swapId)\n .delegatecall(swapData);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n (uint256 bridgeAmount, address token) = abi.decode(\n result,\n (uint256, address)\n );\n\n emit SocketBridge(\n bridgeAmount,\n token,\n DESTINATION_CHAIN_ID,\n NativeOptimismIdentifier,\n msg.sender,\n optimismBridgeData.receiverAddress,\n optimismBridgeData.metadata\n );\n if (token == NATIVE_TOKEN_ADDRESS) {\n L1StandardBridge(optimismBridgeData.customBridgeAddress)\n .depositETHTo{value: bridgeAmount}(\n optimismBridgeData.receiverAddress,\n optimismBridgeData.l2Gas,\n optimismBridgeData.data\n );\n } else {\n if (optimismBridgeData.interfaceId == 0) {\n revert UnsupportedInterfaceId();\n }\n\n ERC20(token).safeApprove(\n optimismBridgeData.customBridgeAddress,\n bridgeAmount\n );\n\n if (optimismBridgeData.interfaceId == 1) {\n // deposit into standard bridge\n L1StandardBridge(optimismBridgeData.customBridgeAddress)\n .depositERC20To(\n token,\n optimismBridgeData.l2Token,\n optimismBridgeData.receiverAddress,\n bridgeAmount,\n optimismBridgeData.l2Gas,\n optimismBridgeData.data\n );\n return;\n }\n\n // Deposit Using Old Standard - iOVM_L1TokenGateway(Example - SNX Token)\n if (optimismBridgeData.interfaceId == 2) {\n OldL1TokenGateway(optimismBridgeData.customBridgeAddress)\n .depositTo(\n optimismBridgeData.receiverAddress,\n bridgeAmount\n );\n return;\n }\n\n if (optimismBridgeData.interfaceId == 3) {\n OldL1TokenGateway(optimismBridgeData.customBridgeAddress)\n .initiateSynthTransfer(\n optimismBridgeData.currencyKey,\n optimismBridgeData.receiverAddress,\n bridgeAmount\n );\n return;\n }\n }\n }\n\n /**\n * @notice function to handle ERC20 bridging to receipent via NativeOptimism-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param token address of token being bridged\n * @param receiverAddress address of receiver of bridged tokens\n * @param customBridgeAddress OptimismBridge that Performs the logic for deposits by informing the L2 Deposited Token\n * contract of the deposit and calling a handler to lock the L1 funds. (e.g. transferFrom)\n * @param l2Gas Gas limit required to complete the deposit on L2.\n * @param optimismData extra data needed for optimism bridge\n * @param amount amount being bridged\n * @param interfaceId interfaceId to be set offchain which is used to select one of the 3 kinds of bridging (standard bridge / old standard / synthetic)\n * @param l2Token Address of the L1 respective L2 ERC20\n * @param data additional data , for ll contracts this will be 0x data or empty data\n */\n function bridgeERC20To(\n address token,\n address receiverAddress,\n address customBridgeAddress,\n uint32 l2Gas,\n OptimismERC20Data calldata optimismData,\n uint256 amount,\n uint256 interfaceId,\n address l2Token,\n bytes calldata data\n ) external payable {\n if (interfaceId == 0) {\n revert UnsupportedInterfaceId();\n }\n\n ERC20 tokenInstance = ERC20(token);\n tokenInstance.safeTransferFrom(msg.sender, socketGateway, amount);\n tokenInstance.safeApprove(customBridgeAddress, amount);\n\n emit SocketBridge(\n amount,\n token,\n DESTINATION_CHAIN_ID,\n NativeOptimismIdentifier,\n msg.sender,\n receiverAddress,\n optimismData.metadata\n );\n if (interfaceId == 1) {\n // deposit into standard bridge\n L1StandardBridge(customBridgeAddress).depositERC20To(\n token,\n l2Token,\n receiverAddress,\n amount,\n l2Gas,\n data\n );\n return;\n }\n\n // Deposit Using Old Standard - iOVM_L1TokenGateway(Example - SNX Token)\n if (interfaceId == 2) {\n OldL1TokenGateway(customBridgeAddress).depositTo(\n receiverAddress,\n amount\n );\n return;\n }\n\n if (interfaceId == 3) {\n OldL1TokenGateway(customBridgeAddress).initiateSynthTransfer(\n optimismData.currencyKey,\n receiverAddress,\n amount\n );\n return;\n }\n }\n\n /**\n * @notice function to handle native balance bridging to receipent via NativeOptimism-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param receiverAddress address of receiver of bridged tokens\n * @param customBridgeAddress OptimismBridge that Performs the logic for deposits by informing the L2 Deposited Token\n * contract of the deposit and calling a handler to lock the L1 funds. (e.g. transferFrom)\n * @param l2Gas Gas limit required to complete the deposit on L2.\n * @param amount amount being bridged\n * @param data additional data , for ll contracts this will be 0x data or empty data\n */\n function bridgeNativeTo(\n address receiverAddress,\n address customBridgeAddress,\n uint32 l2Gas,\n uint256 amount,\n bytes32 metadata,\n bytes calldata data\n ) external payable {\n L1StandardBridge(customBridgeAddress).depositETHTo{value: amount}(\n receiverAddress,\n l2Gas,\n data\n );\n\n emit SocketBridge(\n amount,\n NATIVE_TOKEN_ADDRESS,\n DESTINATION_CHAIN_ID,\n NativeOptimismIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n}\n" - }, - "src/deployFactory/SocketDeployFactory.sol": { - "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport \"../utils/Ownable.sol\";\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {ISocketBridgeBase} from \"../interfaces/ISocketBridgeBase.sol\";\n\n/**\n * @dev In the constructor, set up the initialization code for socket\n * contracts as well as the keccak256 hash of the given initialization code.\n * that will be used to deploy any transient contracts, which will deploy any\n * socket contracts that require the use of a constructor.\n *\n * Socket contract initialization code (29 bytes):\n *\n * 0x5860208158601c335a63aaf10f428752fa158151803b80938091923cf3\n *\n * Description:\n *\n * pc|op|name | [stack] | \n *\n * ** set the first stack item to zero - used later **\n * 00 58 getpc [0] <>\n *\n * ** set second stack item to 32, length of word returned from staticcall **\n * 01 60 push1\n * 02 20 outsize [0, 32] <>\n *\n * ** set third stack item to 0, position of word returned from staticcall **\n * 03 81 dup2 [0, 32, 0] <>\n *\n * ** set fourth stack item to 4, length of selector given to staticcall **\n * 04 58 getpc [0, 32, 0, 4] <>\n *\n * ** set fifth stack item to 28, position of selector given to staticcall **\n * 05 60 push1\n * 06 1c inpos [0, 32, 0, 4, 28] <>\n *\n * ** set the sixth stack item to msg.sender, target address for staticcall **\n * 07 33 caller [0, 32, 0, 4, 28, caller] <>\n *\n * ** set the seventh stack item to msg.gas, gas to forward for staticcall **\n * 08 5a gas [0, 32, 0, 4, 28, caller, gas] <>\n *\n * ** set the eighth stack item to selector, \"what\" to store via mstore **\n * 09 63 push4\n * 10 aaf10f42 selector [0, 32, 0, 4, 28, caller, gas, 0xaaf10f42] <>\n *\n * ** set the ninth stack item to 0, \"where\" to store via mstore ***\n * 11 87 dup8 [0, 32, 0, 4, 28, caller, gas, 0xaaf10f42, 0] <>\n *\n * ** call mstore, consume 8 and 9 from the stack, place selector in memory **\n * 12 52 mstore [0, 32, 0, 4, 0, caller, gas] <0xaaf10f42>\n *\n * ** call staticcall, consume items 2 through 7, place address in memory **\n * 13 fa staticcall [0, 1 (if successful)]
\n *\n * ** flip success bit in second stack item to set to 0 **\n * 14 15 iszero [0, 0]
\n *\n * ** push a third 0 to the stack, position of address in memory **\n * 15 81 dup2 [0, 0, 0]
\n *\n * ** place address from position in memory onto third stack item **\n * 16 51 mload [0, 0, address] <>\n *\n * ** place address to fourth stack item for extcodesize to consume **\n * 17 80 dup1 [0, 0, address, address] <>\n *\n * ** get extcodesize on fourth stack item for extcodecopy **\n * 18 3b extcodesize [0, 0, address, size] <>\n *\n * ** dup and swap size for use by return at end of init code **\n * 19 80 dup1 [0, 0, address, size, size] <>\n * 20 93 swap4 [size, 0, address, size, 0] <>\n *\n * ** push code position 0 to stack and reorder stack items for extcodecopy **\n * 21 80 dup1 [size, 0, address, size, 0, 0] <>\n * 22 91 swap2 [size, 0, address, 0, 0, size] <>\n * 23 92 swap3 [size, 0, size, 0, 0, address] <>\n *\n * ** call extcodecopy, consume four items, clone runtime code to memory **\n * 24 3c extcodecopy [size, 0] \n *\n * ** return to deploy final code in memory **\n * 25 f3 return [] *deployed!*\n */\ncontract SocketDeployFactory is Ownable {\n using SafeTransferLib for ERC20;\n address public immutable disabledRouteAddress;\n\n mapping(address => address) _implementations;\n mapping(uint256 => bool) isDisabled;\n mapping(uint256 => bool) isRouteDeployed;\n mapping(address => bool) canDisableRoute;\n\n event Deployed(address _addr);\n event DisabledRoute(address _addr);\n event Destroyed(address _addr);\n error ContractAlreadyDeployed();\n error NothingToDestroy();\n error AlreadyDisabled();\n error CannotBeDisabled();\n error OnlyDisabler();\n\n constructor(address _owner, address disabledRoute) Ownable(_owner) {\n disabledRouteAddress = disabledRoute;\n canDisableRoute[_owner] = true;\n }\n\n modifier onlyDisabler() {\n if (!canDisableRoute[msg.sender]) {\n revert OnlyDisabler();\n }\n _;\n }\n\n function addDisablerAddress(address disabler) external onlyOwner {\n canDisableRoute[disabler] = true;\n }\n\n function removeDisablerAddress(address disabler) external onlyOwner {\n canDisableRoute[disabler] = false;\n }\n\n /**\n * @notice Deploys a route contract at predetermined location\n * @notice Caller must first deploy the route contract at another location and pass its address as implementation.\n * @param routeId route identifier\n * @param implementationContract address of deployed route contract. Its byte code will be copied to predetermined location.\n */\n function deploy(\n uint256 routeId,\n address implementationContract\n ) external onlyOwner returns (address) {\n // assign the initialization code for the socket contract.\n\n bytes memory initCode = (\n hex\"5860208158601c335a63aaf10f428752fa158151803b80938091923cf3\"\n );\n\n // determine the address of the socket contract.\n address routeContractAddress = _getContractAddress(routeId);\n\n if (isRouteDeployed[routeId]) {\n revert ContractAlreadyDeployed();\n }\n\n isRouteDeployed[routeId] = true;\n\n //first we deploy the code we want to deploy on a separate address\n // store the implementation to be retrieved by the socket contract.\n _implementations[routeContractAddress] = implementationContract;\n address addr;\n assembly {\n let encoded_data := add(0x20, initCode) // load initialization code.\n let encoded_size := mload(initCode) // load init code's length.\n addr := create2(0, encoded_data, encoded_size, routeId) // routeId is used as salt\n }\n require(\n addr == routeContractAddress,\n \"Failed to deploy the new socket contract.\"\n );\n emit Deployed(addr);\n return addr;\n }\n\n /**\n * @notice Destroy the route deployed at a location.\n * @param routeId route identifier to be destroyed.\n */\n function destroy(uint256 routeId) external onlyDisabler {\n // determine the address of the socket contract.\n _destroy(routeId);\n }\n\n /**\n * @notice Deploy a disabled contract at destroyed route to handle it gracefully.\n * @param routeId route identifier to be disabled.\n */\n function disableRoute(\n uint256 routeId\n ) external onlyDisabler returns (address) {\n return _disableRoute(routeId);\n }\n\n /**\n * @notice Destroy a list of routeIds\n * @param routeIds array of routeIds to be destroyed.\n */\n function multiDestroy(uint256[] calldata routeIds) external onlyDisabler {\n for (uint32 index = 0; index < routeIds.length; ) {\n _destroy(routeIds[index]);\n unchecked {\n ++index;\n }\n }\n }\n\n /**\n * @notice Deploy a disabled contract at list of routeIds.\n * @param routeIds array of routeIds to be disabled.\n */\n function multiDisableRoute(\n uint256[] calldata routeIds\n ) external onlyDisabler {\n for (uint32 index = 0; index < routeIds.length; ) {\n _disableRoute(routeIds[index]);\n unchecked {\n ++index;\n }\n }\n }\n\n /**\n * @dev External view function for calculating a socket contract address\n * given a particular routeId.\n */\n function getContractAddress(\n uint256 routeId\n ) external view returns (address) {\n // determine the address of the socket contract.\n return _getContractAddress(routeId);\n }\n\n //those two functions are getting called by the socket Contract\n function getImplementation()\n external\n view\n returns (address implementation)\n {\n return _implementations[msg.sender];\n }\n\n function _disableRoute(uint256 routeId) internal returns (address) {\n // assign the initialization code for the socket contract.\n bytes memory initCode = (\n hex\"5860208158601c335a63aaf10f428752fa158151803b80938091923cf3\"\n );\n\n // determine the address of the socket contract.\n address routeContractAddress = _getContractAddress(routeId);\n\n if (!isRouteDeployed[routeId]) {\n revert CannotBeDisabled();\n }\n\n if (isDisabled[routeId]) {\n revert AlreadyDisabled();\n }\n\n isDisabled[routeId] = true;\n\n //first we deploy the code we want to deploy on a separate address\n // store the implementation to be retrieved by the socket contract.\n _implementations[routeContractAddress] = disabledRouteAddress;\n address addr;\n assembly {\n let encoded_data := add(0x20, initCode) // load initialization code.\n let encoded_size := mload(initCode) // load init code's length.\n addr := create2(0, encoded_data, encoded_size, routeId) // routeId is used as salt.\n }\n require(\n addr == routeContractAddress,\n \"Failed to deploy the new socket contract.\"\n );\n emit Deployed(addr);\n return addr;\n }\n\n function _destroy(uint256 routeId) internal {\n // determine the address of the socket contract.\n address routeContractAddress = _getContractAddress(routeId);\n\n if (!isRouteDeployed[routeId]) {\n revert NothingToDestroy();\n }\n ISocketBridgeBase(routeContractAddress).killme();\n emit Destroyed(routeContractAddress);\n }\n\n /**\n * @dev Internal view function for calculating a socket contract address\n * given a particular routeId.\n */\n function _getContractAddress(\n uint256 routeId\n ) internal view returns (address) {\n // determine the address of the socket contract.\n\n bytes memory initCode = (\n hex\"5860208158601c335a63aaf10f428752fa158151803b80938091923cf3\"\n );\n return\n address(\n uint160( // downcast to match the address type.\n uint256( // convert to uint to truncate upper digits.\n keccak256( // compute the CREATE2 hash using 4 inputs.\n abi.encodePacked( // pack all inputs to the hash together.\n hex\"ff\", // start with 0xff to distinguish from RLP.\n address(this), // this contract will be the caller.\n routeId, // the routeId is used as salt.\n keccak256(abi.encodePacked(initCode)) // the init code hash.\n )\n )\n )\n )\n );\n }\n\n /**\n * @notice Rescues the ERC20 token to an address\n this is a restricted function to be called by only socketGatewayOwner\n * @dev as this is a restricted to socketGatewayOwner, ensure the userAddress is a known address\n * @param token address of the ERC20 token being rescued\n * @param userAddress address to which ERC20 is to be rescued\n * @param amount amount of ERC20 tokens being rescued\n */\n function rescueFunds(\n address token,\n address userAddress,\n uint256 amount\n ) external onlyOwner {\n ERC20(token).safeTransfer(userAddress, amount);\n }\n\n /**\n * @notice Rescues the native balance to an address\n this is a restricted function to be called by only socketGatewayOwner\n * @dev as this is a restricted to socketGatewayOwner, ensure the userAddress is a known address\n * @param userAddress address to which native-balance is to be rescued\n * @param amount amount of native-balance being rescued\n */\n function rescueEther(\n address payable userAddress,\n uint256 amount\n ) external onlyOwner {\n userAddress.transfer(amount);\n }\n}\n" - }, - "src/interfaces/ISocketController.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/**\n * @title ISocketController\n * @notice Interface for SocketController functions.\n * @dev functions can be added here for invocation from external contracts or off-chain\n * only restriction is that this should have functions to manage controllers\n * @author Socket dot tech.\n */\ninterface ISocketController {\n /**\n * @notice Add controller to the socketGateway\n This is a restricted function to be called by only socketGatewayOwner\n * @dev ensure controllerAddress is a verified controller implementation address\n * @param _controllerAddress The address of controller implementation contract deployed\n * @return Id of the controller added to the controllers-mapping in socketGateway storage\n */\n function addController(\n address _controllerAddress\n ) external returns (uint32);\n\n /**\n * @notice disable controller by setting ZeroAddress to the entry in controllers-mapping\n identified by controllerId as key.\n This is a restricted function to be called by only socketGatewayOwner\n * @param _controllerId The Id of controller-implementation in the controllers mapping\n */\n function disableController(uint32 _controllerId) external;\n\n /**\n * @notice Get controllerImplementation address mapped to the controllerId\n * @param _controllerId controllerId is the key in the mapping for controllers\n * @return controller-implementation address\n */\n function getController(uint32 _controllerId) external returns (address);\n}\n" - }, - "lib/solmate/src/utils/SafeTransferLib.sol": { - "content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\nimport {ERC20} from \"../tokens/ERC20.sol\";\n\n/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.\n/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)\n/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.\n/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.\nlibrary SafeTransferLib {\n /*//////////////////////////////////////////////////////////////\n ETH OPERATIONS\n //////////////////////////////////////////////////////////////*/\n\n function safeTransferETH(address to, uint256 amount) internal {\n bool success;\n\n /// @solidity memory-safe-assembly\n assembly {\n // Transfer the ETH and store if it succeeded or not.\n success := call(gas(), to, amount, 0, 0, 0, 0)\n }\n\n require(success, \"ETH_TRANSFER_FAILED\");\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC20 OPERATIONS\n //////////////////////////////////////////////////////////////*/\n\n function safeTransferFrom(\n ERC20 token,\n address from,\n address to,\n uint256 amount\n ) internal {\n bool success;\n\n /// @solidity memory-safe-assembly\n assembly {\n // Get a pointer to some free memory.\n let freeMemoryPointer := mload(0x40)\n\n // Write the abi-encoded calldata into memory, beginning with the function selector.\n mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)\n mstore(add(freeMemoryPointer, 4), from) // Append the \"from\" argument.\n mstore(add(freeMemoryPointer, 36), to) // Append the \"to\" argument.\n mstore(add(freeMemoryPointer, 68), amount) // Append the \"amount\" argument.\n\n success := and(\n // Set success to whether the call reverted, if not we check it either\n // returned exactly 1 (can't just be non-zero data), or had no return data.\n or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),\n // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.\n // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.\n // Counterintuitively, this call must be positioned second to the or() call in the\n // surrounding and() call or else returndatasize() will be zero during the computation.\n call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)\n )\n }\n\n require(success, \"TRANSFER_FROM_FAILED\");\n }\n\n function safeTransfer(\n ERC20 token,\n address to,\n uint256 amount\n ) internal {\n bool success;\n\n /// @solidity memory-safe-assembly\n assembly {\n // Get a pointer to some free memory.\n let freeMemoryPointer := mload(0x40)\n\n // Write the abi-encoded calldata into memory, beginning with the function selector.\n mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)\n mstore(add(freeMemoryPointer, 4), to) // Append the \"to\" argument.\n mstore(add(freeMemoryPointer, 36), amount) // Append the \"amount\" argument.\n\n success := and(\n // Set success to whether the call reverted, if not we check it either\n // returned exactly 1 (can't just be non-zero data), or had no return data.\n or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),\n // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.\n // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.\n // Counterintuitively, this call must be positioned second to the or() call in the\n // surrounding and() call or else returndatasize() will be zero during the computation.\n call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)\n )\n }\n\n require(success, \"TRANSFER_FAILED\");\n }\n\n function safeApprove(\n ERC20 token,\n address to,\n uint256 amount\n ) internal {\n bool success;\n\n /// @solidity memory-safe-assembly\n assembly {\n // Get a pointer to some free memory.\n let freeMemoryPointer := mload(0x40)\n\n // Write the abi-encoded calldata into memory, beginning with the function selector.\n mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)\n mstore(add(freeMemoryPointer, 4), to) // Append the \"to\" argument.\n mstore(add(freeMemoryPointer, 36), amount) // Append the \"amount\" argument.\n\n success := and(\n // Set success to whether the call reverted, if not we check it either\n // returned exactly 1 (can't just be non-zero data), or had no return data.\n or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),\n // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.\n // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.\n // Counterintuitively, this call must be positioned second to the or() call in the\n // surrounding and() call or else returndatasize() will be zero during the computation.\n call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)\n )\n }\n\n require(success, \"APPROVE_FAILED\");\n }\n}\n" - }, - "src/controllers/BaseController.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {ISocketRequest} from \"../interfaces/ISocketRequest.sol\";\nimport {ISocketRoute} from \"../interfaces/ISocketRoute.sol\";\n\n/// @title BaseController Controller\n/// @notice Base contract for all controller contracts\nabstract contract BaseController {\n /// @notice Address used to identify if it is a native token transfer or not\n address public immutable NATIVE_TOKEN_ADDRESS =\n address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);\n\n /// @notice Address used to identify if it is a Zero address\n address public immutable NULL_ADDRESS = address(0);\n\n /// @notice FunctionSelector used to delegatecall from swap to the function of bridge router implementation\n bytes4 public immutable BRIDGE_AFTER_SWAP_SELECTOR =\n bytes4(keccak256(\"bridgeAfterSwap(uint256,bytes)\"));\n\n /// @notice immutable variable to store the socketGateway address\n address public immutable socketGatewayAddress;\n\n /// @notice immutable variable with instance of SocketRoute to access route functions\n ISocketRoute public immutable socketRoute;\n\n /**\n * @notice Construct the base for all controllers.\n * @param _socketGatewayAddress Socketgateway address, an immutable variable to set.\n * @notice initialize the immutable variables of SocketRoute, SocketGateway\n */\n constructor(address _socketGatewayAddress) {\n socketGatewayAddress = _socketGatewayAddress;\n socketRoute = ISocketRoute(_socketGatewayAddress);\n }\n\n /**\n * @notice Construct the base for all BridgeImplementations.\n * @param routeId routeId mapped to the routrImplementation\n * @param data transactionData generated with arguments of bridgeRequest (offchain or by caller)\n * @return returns the bytes response of the route execution (bridging, refuel or swap executions)\n */\n function _executeRoute(\n uint32 routeId,\n bytes memory data\n ) internal returns (bytes memory) {\n (bool success, bytes memory result) = socketRoute\n .getRoute(routeId)\n .delegatecall(data);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n return result;\n }\n}\n" - }, - "src/interfaces/ISocketRoute.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/**\n * @title ISocketRoute\n * @notice Interface for routeManagement functions in SocketGateway.\n * @author Socket dot tech.\n */\ninterface ISocketRoute {\n /**\n * @notice Add route to the socketGateway\n This is a restricted function to be called by only socketGatewayOwner\n * @dev ensure routeAddress is a verified bridge or middleware implementation address\n * @param routeAddress The address of bridge or middleware implementation contract deployed\n * @return Id of the route added to the routes-mapping in socketGateway storage\n */\n function addRoute(address routeAddress) external returns (uint256);\n\n /**\n * @notice disable a route by setting ZeroAddress to the entry in routes-mapping\n identified by routeId as key.\n This is a restricted function to be called by only socketGatewayOwner\n * @param routeId The Id of route-implementation in the routes mapping\n */\n function disableRoute(uint32 routeId) external;\n\n /**\n * @notice Get routeImplementation address mapped to the routeId\n * @param routeId routeId is the key in the mapping for routes\n * @return route-implementation address\n */\n function getRoute(uint32 routeId) external view returns (address);\n}\n" - }, - "src/SocketGatewayDeployment.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\npragma experimental ABIEncoderV2;\n\nimport \"./utils/Ownable.sol\";\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {LibUtil} from \"./libraries/LibUtil.sol\";\nimport \"./libraries/LibBytes.sol\";\nimport {ISocketRoute} from \"./interfaces/ISocketRoute.sol\";\nimport {ISocketRequest} from \"./interfaces/ISocketRequest.sol\";\nimport {ISocketGateway} from \"./interfaces/ISocketGateway.sol\";\nimport {IncorrectBridgeRatios, ZeroAddressNotAllowed, ArrayLengthMismatch} from \"./errors/SocketErrors.sol\";\n\n/// @title SocketGatewayContract\n/// @notice Socketgateway is a contract with entrypoint functions for all interactions with socket liquidity layer\n/// @author Socket Team\ncontract SocketGateway is Ownable {\n using LibBytes for bytes;\n using LibBytes for bytes4;\n using SafeTransferLib for ERC20;\n\n /// @notice FunctionSelector used to delegatecall from swap to the function of bridge router implementation\n bytes4 public immutable BRIDGE_AFTER_SWAP_SELECTOR =\n bytes4(keccak256(\"bridgeAfterSwap(uint256,bytes)\"));\n\n /// @notice storage variable to keep track of total number of routes registered in socketgateway\n uint32 public routesCount = 385;\n\n /// @notice storage variable to keep track of total number of controllers registered in socketgateway\n uint32 public controllerCount;\n\n address public immutable disabledRouteAddress;\n\n uint256 public constant CENT_PERCENT = 100e18;\n\n /// @notice storage mapping for route implementation addresses\n mapping(uint32 => address) public routes;\n\n /// storage mapping for controller implemenation addresses\n mapping(uint32 => address) public controllers;\n\n // Events ------------------------------------------------------------------------------------------------------->\n\n /// @notice Event emitted when a router is added to socketgateway\n event NewRouteAdded(uint32 indexed routeId, address indexed route);\n\n /// @notice Event emitted when a route is disabled\n event RouteDisabled(uint32 indexed routeId);\n\n /// @notice Event emitted when ownership transfer is requested by socket-gateway-owner\n event OwnershipTransferRequested(\n address indexed _from,\n address indexed _to\n );\n\n /// @notice Event emitted when a controller is added to socketgateway\n event ControllerAdded(\n uint32 indexed controllerId,\n address indexed controllerAddress\n );\n\n /// @notice Event emitted when a controller is disabled\n event ControllerDisabled(uint32 indexed controllerId);\n\n constructor(address _owner, address _disabledRoute) Ownable(_owner) {\n disabledRouteAddress = _disabledRoute;\n }\n\n // Able to receive ether\n // solhint-disable-next-line no-empty-blocks\n receive() external payable {}\n\n /*******************************************\n * EXTERNAL AND PUBLIC FUNCTIONS *\n *******************************************/\n\n /**\n * @notice executes functions in the routes identified using routeId and functionSelectorData\n * @notice The caller must first approve this contract to spend amount of ERC20-Token being bridged/swapped\n * @dev ensure the data in routeData to be built using the function-selector defined as a\n * constant in the route implementation contract\n * @param routeId route identifier\n * @param routeData functionSelectorData generated using the function-selector defined in the route Implementation\n */\n function executeRoute(\n uint32 routeId,\n bytes calldata routeData\n ) external payable returns (bytes memory) {\n (bool success, bytes memory result) = addressAt(routeId).delegatecall(\n routeData\n );\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n return result;\n }\n\n /**\n * @notice swaps a token on sourceChain and split it across multiple bridge-recipients\n * @notice The caller must first approve this contract to spend amount of ERC20-Token being swapped\n * @dev ensure the swap-data and bridge-data is generated using the function-selector defined as a constant in the implementation address\n * @param swapMultiBridgeRequest request\n */\n function swapAndMultiBridge(\n ISocketRequest.SwapMultiBridgeRequest calldata swapMultiBridgeRequest\n ) external payable {\n uint256 requestLength = swapMultiBridgeRequest.bridgeRouteIds.length;\n\n if (\n requestLength != swapMultiBridgeRequest.bridgeImplDataItems.length\n ) {\n revert ArrayLengthMismatch();\n }\n uint256 ratioAggregate;\n for (uint256 index = 0; index < requestLength; ) {\n ratioAggregate += swapMultiBridgeRequest.bridgeRatios[index];\n }\n\n if (ratioAggregate != CENT_PERCENT) {\n revert IncorrectBridgeRatios();\n }\n\n (bool swapSuccess, bytes memory swapResult) = addressAt(\n swapMultiBridgeRequest.swapRouteId\n ).delegatecall(swapMultiBridgeRequest.swapImplData);\n\n if (!swapSuccess) {\n assembly {\n revert(add(swapResult, 32), mload(swapResult))\n }\n }\n\n uint256 amountReceivedFromSwap = abi.decode(swapResult, (uint256));\n\n uint256 bridgedAmount;\n\n for (uint256 index = 0; index < requestLength; ) {\n uint256 bridgingAmount;\n\n // if it is the last bridge request, bridge the remaining amount\n if (index == requestLength - 1) {\n bridgingAmount = amountReceivedFromSwap - bridgedAmount;\n } else {\n // bridging amount is the multiplication of bridgeRatio and amountReceivedFromSwap\n bridgingAmount =\n (amountReceivedFromSwap *\n swapMultiBridgeRequest.bridgeRatios[index]) /\n (CENT_PERCENT);\n }\n\n // update the bridged amount, this would be used for computation for last bridgeRequest\n bridgedAmount += bridgingAmount;\n\n bytes memory bridgeImpldata = abi.encodeWithSelector(\n BRIDGE_AFTER_SWAP_SELECTOR,\n bridgingAmount,\n swapMultiBridgeRequest.bridgeImplDataItems[index]\n );\n\n (bool bridgeSuccess, bytes memory bridgeResult) = addressAt(\n swapMultiBridgeRequest.bridgeRouteIds[index]\n ).delegatecall(bridgeImpldata);\n\n if (!bridgeSuccess) {\n assembly {\n revert(add(bridgeResult, 32), mload(bridgeResult))\n }\n }\n\n unchecked {\n ++index;\n }\n }\n }\n\n /**\n * @notice sequentially executes functions in the routes identified using routeId and functionSelectorData\n * @notice The caller must first approve this contract to spend amount of ERC20-Token being bridged/swapped\n * @dev ensure the data in each dataItem to be built using the function-selector defined as a\n * constant in the route implementation contract\n * @param routeIds a list of route identifiers\n * @param dataItems a list of functionSelectorData generated using the function-selector defined in the route Implementation\n */\n function executeRoutes(\n uint32[] calldata routeIds,\n bytes[] calldata dataItems\n ) external payable {\n uint256 routeIdslength = routeIds.length;\n if (routeIdslength != dataItems.length) revert ArrayLengthMismatch();\n for (uint256 index = 0; index < routeIdslength; ) {\n (bool success, bytes memory result) = addressAt(routeIds[index])\n .delegatecall(dataItems[index]);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n unchecked {\n ++index;\n }\n }\n }\n\n /**\n * @notice execute a controller function identified using the controllerId in the request\n * @notice The caller must first approve this contract to spend amount of ERC20-Token being bridged/swapped\n * @dev ensure the data in request to be built using the function-selector defined as a\n * constant in the controller implementation contract\n * @param socketControllerRequest socketControllerRequest with controllerId to identify the\n * controllerAddress and byteData constructed using functionSelector\n * of the function being invoked\n * @return bytes data received from the call delegated to controller\n */\n function executeController(\n ISocketGateway.SocketControllerRequest calldata socketControllerRequest\n ) external payable returns (bytes memory) {\n (bool success, bytes memory result) = controllers[\n socketControllerRequest.controllerId\n ].delegatecall(socketControllerRequest.data);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n return result;\n }\n\n /**\n * @notice sequentially executes all controller requests\n * @notice The caller must first approve this contract to spend amount of ERC20-Token being bridged/swapped\n * @dev ensure the data in each controller-request to be built using the function-selector defined as a\n * constant in the controller implementation contract\n * @param controllerRequests a list of socketControllerRequest\n * Each controllerRequest contains controllerId to identify the controllerAddress and\n * byteData constructed using functionSelector of the function being invoked\n */\n function executeControllers(\n ISocketGateway.SocketControllerRequest[] calldata controllerRequests\n ) external payable {\n for (uint32 index = 0; index < controllerRequests.length; ) {\n (bool success, bytes memory result) = controllers[\n controllerRequests[index].controllerId\n ].delegatecall(controllerRequests[index].data);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n unchecked {\n ++index;\n }\n }\n }\n\n /**************************************\n * ADMIN FUNCTIONS *\n **************************************/\n\n /**\n * @notice Add route to the socketGateway\n This is a restricted function to be called by only socketGatewayOwner\n * @dev ensure routeAddress is a verified bridge or middleware implementation address\n * @param routeAddress The address of bridge or middleware implementation contract deployed\n * @return Id of the route added to the routes-mapping in socketGateway storage\n */\n function addRoute(\n address routeAddress\n ) external onlyOwner returns (uint32) {\n uint32 routeId = routesCount;\n routes[routeId] = routeAddress;\n\n routesCount += 1;\n\n emit NewRouteAdded(routeId, routeAddress);\n\n return routeId;\n }\n\n /**\n * @notice Give Infinite or 0 approval to bridgeRoute for the tokenAddress\n This is a restricted function to be called by only socketGatewayOwner\n */\n\n function setApprovalForRouters(\n address[] memory routeAddresses,\n address[] memory tokenAddresses,\n bool isMax\n ) external onlyOwner {\n for (uint32 index = 0; index < routeAddresses.length; ) {\n ERC20(tokenAddresses[index]).approve(\n routeAddresses[index],\n isMax ? type(uint256).max : 0\n );\n unchecked {\n ++index;\n }\n }\n }\n\n /**\n * @notice Add controller to the socketGateway\n This is a restricted function to be called by only socketGatewayOwner\n * @dev ensure controllerAddress is a verified controller implementation address\n * @param controllerAddress The address of controller implementation contract deployed\n * @return Id of the controller added to the controllers-mapping in socketGateway storage\n */\n function addController(\n address controllerAddress\n ) external onlyOwner returns (uint32) {\n uint32 controllerId = controllerCount;\n\n controllers[controllerId] = controllerAddress;\n\n controllerCount += 1;\n\n emit ControllerAdded(controllerId, controllerAddress);\n\n return controllerId;\n }\n\n /**\n * @notice disable controller by setting ZeroAddress to the entry in controllers-mapping\n identified by controllerId as key.\n This is a restricted function to be called by only socketGatewayOwner\n * @param controllerId The Id of controller-implementation in the controllers mapping\n */\n function disableController(uint32 controllerId) public onlyOwner {\n controllers[controllerId] = disabledRouteAddress;\n emit ControllerDisabled(controllerId);\n }\n\n /**\n * @notice disable a route by setting ZeroAddress to the entry in routes-mapping\n identified by routeId as key.\n This is a restricted function to be called by only socketGatewayOwner\n * @param routeId The Id of route-implementation in the routes mapping\n */\n function disableRoute(uint32 routeId) external onlyOwner {\n routes[routeId] = disabledRouteAddress;\n emit RouteDisabled(routeId);\n }\n\n /*******************************************\n * RESTRICTED RESCUE FUNCTIONS *\n *******************************************/\n\n /**\n * @notice Rescues the ERC20 token to an address\n this is a restricted function to be called by only socketGatewayOwner\n * @dev as this is a restricted to socketGatewayOwner, ensure the userAddress is a known address\n * @param token address of the ERC20 token being rescued\n * @param userAddress address to which ERC20 is to be rescued\n * @param amount amount of ERC20 tokens being rescued\n */\n function rescueFunds(\n address token,\n address userAddress,\n uint256 amount\n ) external onlyOwner {\n ERC20(token).safeTransfer(userAddress, amount);\n }\n\n /**\n * @notice Rescues the native balance to an address\n this is a restricted function to be called by only socketGatewayOwner\n * @dev as this is a restricted to socketGatewayOwner, ensure the userAddress is a known address\n * @param userAddress address to which native-balance is to be rescued\n * @param amount amount of native-balance being rescued\n */\n function rescueEther(\n address payable userAddress,\n uint256 amount\n ) external onlyOwner {\n userAddress.transfer(amount);\n }\n\n /*******************************************\n * VIEW FUNCTIONS *\n *******************************************/\n\n /**\n * @notice Get routeImplementation address mapped to the routeId\n * @param routeId routeId is the key in the mapping for routes\n * @return route-implementation address\n */\n function getRoute(uint32 routeId) public view returns (address) {\n return addressAt(routeId);\n }\n\n /**\n * @notice Get controllerImplementation address mapped to the controllerId\n * @param controllerId controllerId is the key in the mapping for controllers\n * @return controller-implementation address\n */\n function getController(uint32 controllerId) public view returns (address) {\n return controllers[controllerId];\n }\n\n function addressAt(uint32 routeId) public view returns (address) {\n if (routeId < 385) {\n if (routeId < 257) {\n if (routeId < 129) {\n if (routeId < 65) {\n if (routeId < 33) {\n if (routeId < 17) {\n if (routeId < 9) {\n if (routeId < 5) {\n if (routeId < 3) {\n if (routeId == 1) {\n return\n 0x8cd6BaCDAe46B449E2e5B34e348A4eD459c84D50;\n } else {\n return\n 0x31524750Cd865fF6A3540f232754Fb974c18585C;\n }\n } else {\n if (routeId == 3) {\n return\n 0xEd9b37342BeC8f3a2D7b000732ec87498aA6EC6a;\n } else {\n return\n 0xE8704Ef6211F8988Ccbb11badC89841808d66890;\n }\n }\n } else {\n if (routeId < 7) {\n if (routeId == 5) {\n return\n 0x9aFF58C460a461578C433e11C4108D1c4cF77761;\n } else {\n return\n 0x2D1733886cFd465B0B99F1492F40847495f334C5;\n }\n } else {\n if (routeId == 7) {\n return\n 0x715497Be4D130F04B8442F0A1F7a9312D4e54FC4;\n } else {\n return\n 0x90C8a40c38E633B5B0e0d0585b9F7FA05462CaaF;\n }\n }\n }\n } else {\n if (routeId < 13) {\n if (routeId < 11) {\n if (routeId == 9) {\n return\n 0xa402b70FCfF3F4a8422B93Ef58E895021eAdE4F6;\n } else {\n return\n 0xc1B718522E15CD42C4Ac385a929fc2B51f5B892e;\n }\n } else {\n if (routeId == 11) {\n return\n 0xa97bf2f7c26C43c010c349F52f5eA5dC49B2DD38;\n } else {\n return\n 0x969423d71b62C81d2f28d707364c9Dc4a0764c53;\n }\n }\n } else {\n if (routeId < 15) {\n if (routeId == 13) {\n return\n 0xF86729934C083fbEc8C796068A1fC60701Ea1207;\n } else {\n return\n 0xD7cC2571F5823caCA26A42690D2BE7803DD5393f;\n }\n } else {\n if (routeId == 15) {\n return\n 0x7c8837a279bbbf7d8B93413763176de9F65d5bB9;\n } else {\n return\n 0x13b81C27B588C07D04458ed7dDbdbD26D1e39bcc;\n }\n }\n }\n }\n } else {\n if (routeId < 25) {\n if (routeId < 21) {\n if (routeId < 19) {\n if (routeId == 17) {\n return\n 0x52560Ac678aFA1345D15474287d16Dc1eA3F78aE;\n } else {\n return\n 0x1E31e376551459667cd7643440c1b21CE69065A0;\n }\n } else {\n if (routeId == 19) {\n return\n 0xc57D822CB3288e7b97EF8f8af0EcdcD1B783529B;\n } else {\n return\n 0x2197A1D9Af24b4d6a64Bff95B4c29Fcd3Ff28C30;\n }\n }\n } else {\n if (routeId < 23) {\n if (routeId == 21) {\n return\n 0xE3700feAa5100041Bf6b7AdBA1f72f647809Fd00;\n } else {\n return\n 0xc02E8a0Fdabf0EeFCEA025163d90B5621E2b9948;\n }\n } else {\n if (routeId == 23) {\n return\n 0xF5144235E2926cAb3c69b30113254Fa632f72d62;\n } else {\n return\n 0xBa3F92313B00A1f7Bc53b2c24EB195c8b2F57682;\n }\n }\n }\n } else {\n if (routeId < 29) {\n if (routeId < 27) {\n if (routeId == 25) {\n return\n 0x77a6856fe1fFA5bEB55A1d2ED86E27C7c482CB76;\n } else {\n return\n 0x4826Ff4e01E44b1FCEFBfb38cd96687Eb7786b44;\n }\n } else {\n if (routeId == 27) {\n return\n 0x55FF3f5493cf5e80E76DEA7E327b9Cd8440Af646;\n } else {\n return\n 0xF430Db544bE9770503BE4aa51997aA19bBd5BA4f;\n }\n }\n } else {\n if (routeId < 31) {\n if (routeId == 29) {\n return\n 0x0f166446ce1484EE3B0663E7E67DF10F5D240115;\n } else {\n return\n 0x6365095D92537f242Db5EdFDd572745E72aC33d9;\n }\n } else {\n if (routeId == 31) {\n return\n 0x5c7BC93f06ce3eAe75ADf55E10e23d2c1dE5Bc65;\n } else {\n return\n 0xe46383bAD90d7A08197ccF08972e9DCdccCE9BA4;\n }\n }\n }\n }\n }\n } else {\n if (routeId < 49) {\n if (routeId < 41) {\n if (routeId < 37) {\n if (routeId < 35) {\n if (routeId == 33) {\n return\n 0xf0f21710c071E3B728bdc4654c3c0b873aAaa308;\n } else {\n return\n 0x63Bc9ed3AcAAeB0332531C9fB03b0a2352E9Ff25;\n }\n } else {\n if (routeId == 35) {\n return\n 0xd1CE808625CB4007a1708824AE82CdB0ece57De9;\n } else {\n return\n 0x57BbB148112f4ba224841c3FE018884171004661;\n }\n }\n } else {\n if (routeId < 39) {\n if (routeId == 37) {\n return\n 0x037f7d6933036F34DFabd40Ff8e4D789069f92e3;\n } else {\n return\n 0xeF978c280915CfF3Dca4EDfa8932469e40ADA1e1;\n }\n } else {\n if (routeId == 39) {\n return\n 0x92ee9e071B13f7ecFD62B7DED404A16CBc223CD3;\n } else {\n return\n 0x94Ae539c186e41ed762271338Edf140414D1E442;\n }\n }\n }\n } else {\n if (routeId < 45) {\n if (routeId < 43) {\n if (routeId == 41) {\n return\n 0x30A64BBe4DdBD43dA2368EFd1eB2d80C10d84DAb;\n } else {\n return\n 0x3aEABf81c1Dc4c1b73d5B2a95410f126426FB596;\n }\n } else {\n if (routeId == 43) {\n return\n 0x25b08aB3D0C8ea4cC9d967b79688C6D98f3f563a;\n } else {\n return\n 0xea40cB15C9A3BBd27af6474483886F7c0c9AE406;\n }\n }\n } else {\n if (routeId < 47) {\n if (routeId == 45) {\n return\n 0x9580113Cc04e5a0a03359686304EF3A80b936Dd3;\n } else {\n return\n 0xD211c826d568957F3b66a3F4d9c5f68cCc66E619;\n }\n } else {\n if (routeId == 47) {\n return\n 0xCEE24D0635c4C56315d133b031984d4A6f509476;\n } else {\n return\n 0x3922e6B987983229798e7A20095EC372744d4D4c;\n }\n }\n }\n }\n } else {\n if (routeId < 57) {\n if (routeId < 53) {\n if (routeId < 51) {\n if (routeId == 49) {\n return\n 0x2d92D03413d296e1F31450479349757187F2a2b7;\n } else {\n return\n 0x0fe5308eE90FC78F45c89dB6053eA859097860CA;\n }\n } else {\n if (routeId == 51) {\n return\n 0x08Ba68e067C0505bAF0C1311E0cFB2B1B59b969c;\n } else {\n return\n 0x9bee5DdDF75C24897374f92A534B7A6f24e97f4a;\n }\n }\n } else {\n if (routeId < 55) {\n if (routeId == 53) {\n return\n 0x1FC5A90B232208704B930c1edf82FFC6ACc02734;\n } else {\n return\n 0x5b1B0417cb44c761C2a23ee435d011F0214b3C85;\n }\n } else {\n if (routeId == 55) {\n return\n 0x9d70cDaCA12A738C283020760f449D7816D592ec;\n } else {\n return\n 0x95a23b9CB830EcCFDDD5dF56A4ec665e3381Fa12;\n }\n }\n }\n } else {\n if (routeId < 61) {\n if (routeId < 59) {\n if (routeId == 57) {\n return\n 0x483a957Cf1251c20e096C35c8399721D1200A3Fc;\n } else {\n return\n 0xb4AD39Cb293b0Ec7FEDa743442769A7FF04987CD;\n }\n } else {\n if (routeId == 59) {\n return\n 0x4C543AD78c1590D81BAe09Fc5B6Df4132A2461d0;\n } else {\n return\n 0x471d5E5195c563902781734cfe1FF3981F8B6c86;\n }\n }\n } else {\n if (routeId < 63) {\n if (routeId == 61) {\n return\n 0x1B12a54B5E606D95B8B8D123c9Cb09221Ee37584;\n } else {\n return\n 0xE4127cC550baC433646a7D998775a84daC16c7f3;\n }\n } else {\n if (routeId == 63) {\n return\n 0xecb1b55AB12E7dd788D585c6C5cD61B5F87be836;\n } else {\n return\n 0xf91ef487C5A1579f70601b6D347e19756092eEBf;\n }\n }\n }\n }\n }\n }\n } else {\n if (routeId < 97) {\n if (routeId < 81) {\n if (routeId < 73) {\n if (routeId < 69) {\n if (routeId < 67) {\n if (routeId == 65) {\n return\n 0x34a16a7e9BADEEFD4f056310cbE0b1423Fa1b760;\n } else {\n return\n 0x60E10E80c7680f429dBbC232830BEcd3D623c4CF;\n }\n } else {\n if (routeId == 67) {\n return\n 0x66465285B8D65362A1d86CE00fE2bE949Fd6debF;\n } else {\n return\n 0x5aB231B7e1A3A74a48f67Ab7bde5Cdd4267022E0;\n }\n }\n } else {\n if (routeId < 71) {\n if (routeId == 69) {\n return\n 0x3A1C3633eE79d43366F5c67802a746aFD6b162Ba;\n } else {\n return\n 0x0C4BfCbA8dC3C811437521a80E81e41DAF479039;\n }\n } else {\n if (routeId == 71) {\n return\n 0x6caf25d2e139C5431a1FA526EAf8d73ff2e6252C;\n } else {\n return\n 0x74ad21e09FDa68638CE14A3009A79B6D16574257;\n }\n }\n }\n } else {\n if (routeId < 77) {\n if (routeId < 75) {\n if (routeId == 73) {\n return\n 0xD4923A61008894b99cc1CD3407eF9524f02aA0Ca;\n } else {\n return\n 0x6F159b5EB823BD415886b9271aA2A723a00a1987;\n }\n } else {\n if (routeId == 75) {\n return\n 0x742a8aA42E7bfB4554dE30f4Fb07FFb6f2068863;\n } else {\n return\n 0x4AE9702d3360400E47B446e76DE063ACAb930101;\n }\n }\n } else {\n if (routeId < 79) {\n if (routeId == 77) {\n return\n 0x0E19a0a44ddA7dAD854ec5Cc867d16869c4E80F4;\n } else {\n return\n 0xE021A51968f25148F726E326C88d2556c5647557;\n }\n } else {\n if (routeId == 79) {\n return\n 0x64287BDDDaeF4d94E4599a3D882bed29E6Ada4B6;\n } else {\n return\n 0xcBB57Fd2e19cc7e9D444d5b4325A2F1047d0C73f;\n }\n }\n }\n }\n } else {\n if (routeId < 89) {\n if (routeId < 85) {\n if (routeId < 83) {\n if (routeId == 81) {\n return\n 0x373DE80DF7D82cFF6D76F29581b360C56331e957;\n } else {\n return\n 0x0466356E131AD61596a51F86BAd1C03A328960D8;\n }\n } else {\n if (routeId == 83) {\n return\n 0x01726B960992f1b74311b248E2a922fC707d43A6;\n } else {\n return\n 0x2E21bdf9A4509b89795BCE7E132f248a75814CEc;\n }\n }\n } else {\n if (routeId < 87) {\n if (routeId == 85) {\n return\n 0x769512b23aEfF842379091d3B6E4B5456F631D42;\n } else {\n return\n 0xe7eD9be946a74Ec19325D39C6EEb57887ccB2B0D;\n }\n } else {\n if (routeId == 87) {\n return\n 0xc4D01Ec357c2b511d10c15e6b6974380F0E62e67;\n } else {\n return\n 0x5bC49CC9dD77bECF2fd3A3C55611e84E69AFa3AE;\n }\n }\n }\n } else {\n if (routeId < 93) {\n if (routeId < 91) {\n if (routeId == 89) {\n return\n 0x48bcD879954fA14e7DbdAeb56F79C1e9DDcb69ec;\n } else {\n return\n 0xE929bDde21b462572FcAA4de6F49B9D3246688D0;\n }\n } else {\n if (routeId == 91) {\n return\n 0x85Aae300438222f0e3A9Bc870267a5633A9438bd;\n } else {\n return\n 0x51f72E1096a81C55cd142d66d39B688C657f9Be8;\n }\n }\n } else {\n if (routeId < 95) {\n if (routeId == 93) {\n return\n 0x3A8a05BF68ac54B01E6C0f492abF97465F3d15f9;\n } else {\n return\n 0x145aA67133F0c2C36b9771e92e0B7655f0D59040;\n }\n } else {\n if (routeId == 95) {\n return\n 0xa030315d7DB11F9892758C9e7092D841e0ADC618;\n } else {\n return\n 0xdF1f8d81a3734bdDdEfaC6Ca1596E081e57c3044;\n }\n }\n }\n }\n }\n } else {\n if (routeId < 113) {\n if (routeId < 105) {\n if (routeId < 101) {\n if (routeId < 99) {\n if (routeId == 97) {\n return\n 0xFF2833123B58aa05d04D7fb99f5FB768B2b435F8;\n } else {\n return\n 0xc8f09c1fD751C570233765f71b0e280d74e6e743;\n }\n } else {\n if (routeId == 99) {\n return\n 0x3026DA6Ceca2E5A57A05153653D9212FFAaA49d8;\n } else {\n return\n 0xdE68Ee703dE0D11f67B0cE5891cB4a903de6D160;\n }\n }\n } else {\n if (routeId < 103) {\n if (routeId == 101) {\n return\n 0xE23a7730e81FB4E87A6D0bd9f63EE77ac86C3DA4;\n } else {\n return\n 0x8b1DBe04aD76a7d8bC079cACd3ED4D99B897F4a0;\n }\n } else {\n if (routeId == 103) {\n return\n 0xBB227240FA459b69C6889B2b8cb1BE76F118061f;\n } else {\n return\n 0xC062b9b3f0dB28BB8afAfcD4d075729344114ffe;\n }\n }\n }\n } else {\n if (routeId < 109) {\n if (routeId < 107) {\n if (routeId == 105) {\n return\n 0x553188Aa45f5FDB83EC4Ca485982F8fC082480D1;\n } else {\n return\n 0x0109d83D746EaCb6d4014953D9E12d6ca85e330b;\n }\n } else {\n if (routeId == 107) {\n return\n 0x45B1bEd29812F5bf6711074ACD180B2aeB783AD9;\n } else {\n return\n 0xdA06eC8c19aea31D77F60299678Cba40E743e1aD;\n }\n }\n } else {\n if (routeId < 111) {\n if (routeId == 109) {\n return\n 0x3cC5235c97d975a9b4FD4501B3446c981ea3D855;\n } else {\n return\n 0xa1827267d6Bd989Ff38580aE3d9deff6Acf19163;\n }\n } else {\n if (routeId == 111) {\n return\n 0x3663CAA0433A3D4171b3581Cf2410702840A735A;\n } else {\n return\n 0x7575D0a7614F655BA77C74a72a43bbd4fA6246a3;\n }\n }\n }\n }\n } else {\n if (routeId < 121) {\n if (routeId < 117) {\n if (routeId < 115) {\n if (routeId == 113) {\n return\n 0x2516Defc18bc07089c5dAFf5eafD7B0EF64611E2;\n } else {\n return\n 0xfec5FF08E20fbc107a97Af2D38BD0025b84ee233;\n }\n } else {\n if (routeId == 115) {\n return\n 0x0FB5763a87242B25243e23D73f55945fE787523A;\n } else {\n return\n 0xe4C00db89678dBf8391f430C578Ca857Dd98aDE1;\n }\n }\n } else {\n if (routeId < 119) {\n if (routeId == 117) {\n return\n 0x8F2A22061F9F35E64f14523dC1A5f8159e6a21B7;\n } else {\n return\n 0x18e4b838ae966917E20E9c9c5Ad359cDD38303bB;\n }\n } else {\n if (routeId == 119) {\n return\n 0x61ACb1d3Dcb3e3429832A164Cc0fC9849fb75A4a;\n } else {\n return\n 0x7681e3c8e7A41DCA55C257cc0d1Ae757f5530E65;\n }\n }\n }\n } else {\n if (routeId < 125) {\n if (routeId < 123) {\n if (routeId == 121) {\n return\n 0x806a2AB9748C3D1DB976550890E3f528B7E8Faec;\n } else {\n return\n 0xBDb8A5DD52C2c239fbC31E9d43B763B0197028FF;\n }\n } else {\n if (routeId == 123) {\n return\n 0x474EC9203706010B9978D6bD0b105D36755e4848;\n } else {\n return\n 0x8dfd0D829b303F2239212E591a0F92a32880f36E;\n }\n }\n } else {\n if (routeId < 127) {\n if (routeId == 125) {\n return\n 0xad4BcE9745860B1adD6F1Bd34a916f050E4c82C2;\n } else {\n return\n 0xBC701115b9fe14bC8CC5934cdC92517173e308C4;\n }\n } else {\n if (routeId == 127) {\n return\n 0x0D1918d786Db8546a11aDeD475C98370E06f255E;\n } else {\n return\n 0xee44f57cD6936DB55B99163f3Df367B01EdA785a;\n }\n }\n }\n }\n }\n }\n }\n } else {\n if (routeId < 193) {\n if (routeId < 161) {\n if (routeId < 145) {\n if (routeId < 137) {\n if (routeId < 133) {\n if (routeId < 131) {\n if (routeId == 129) {\n return\n 0x63044521fe5a1e488D7eD419cD0e35b7C24F2aa7;\n } else {\n return\n 0x410085E73BD85e90d97b84A68C125aDB9F91f85b;\n }\n } else {\n if (routeId == 131) {\n return\n 0x7913fe97E07C7A397Ec274Ab1d4E2622C88EC5D1;\n } else {\n return\n 0x977f9fE93c064DCf54157406DaABC3a722e8184C;\n }\n }\n } else {\n if (routeId < 135) {\n if (routeId == 133) {\n return\n 0xCD2236468722057cFbbABad2db3DEA9c20d5B01B;\n } else {\n return\n 0x17c7287A491cf5Ff81E2678cF2BfAE4333F6108c;\n }\n } else {\n if (routeId == 135) {\n return\n 0x354D9a5Dbf96c71B79a265F03B595C6Fdc04dadd;\n } else {\n return\n 0xb4e409EB8e775eeFEb0344f9eee884cc7ed21c69;\n }\n }\n }\n } else {\n if (routeId < 141) {\n if (routeId < 139) {\n if (routeId == 137) {\n return\n 0xa1a3c4670Ad69D9be4ab2D39D1231FEC2a63b519;\n } else {\n return\n 0x4589A22199870729C1be5CD62EE93BeD858113E6;\n }\n } else {\n if (routeId == 139) {\n return\n 0x8E7b864dB26Bd6C798C38d4Ba36EbA0d6602cF11;\n } else {\n return\n 0xA2D17C7260a4CB7b9854e89Fc367E80E87872a2d;\n }\n }\n } else {\n if (routeId < 143) {\n if (routeId == 141) {\n return\n 0xC7F0EDf0A1288627b0432304918A75e9084CBD46;\n } else {\n return\n 0xE4B4EF1f9A4aBFEdB371fA7a6143993B15d4df25;\n }\n } else {\n if (routeId == 143) {\n return\n 0xfe3D84A2Ef306FEBb5452441C9BDBb6521666F6A;\n } else {\n return\n 0x8A12B6C64121920110aE58F7cd67DfEc21c6a4C3;\n }\n }\n }\n }\n } else {\n if (routeId < 153) {\n if (routeId < 149) {\n if (routeId < 147) {\n if (routeId == 145) {\n return\n 0x76c4d9aFC4717a2BAac4e5f26CccF02351f7a3DA;\n } else {\n return\n 0xd4719BA550E397aeAcca1Ad2201c1ba69024FAAf;\n }\n } else {\n if (routeId == 147) {\n return\n 0x9646126Ce025224d1682C227d915a386efc0A1Fb;\n } else {\n return\n 0x4DD8Af2E3F2044842f0247920Bc4BABb636915ea;\n }\n }\n } else {\n if (routeId < 151) {\n if (routeId == 149) {\n return\n 0x8e8a327183Af0cf8C2ece9F0ed547C42A160D409;\n } else {\n return\n 0x9D49614CaE1C685C71678CA6d8CDF7584bfd0740;\n }\n } else {\n if (routeId == 151) {\n return\n 0x5a00ef257394cbc31828d48655E3d39e9c11c93d;\n } else {\n return\n 0xC9a2751b38d3dDD161A41Ca0135C5C6c09EC1d56;\n }\n }\n }\n } else {\n if (routeId < 157) {\n if (routeId < 155) {\n if (routeId == 153) {\n return\n 0x7e1c261640a525C94Ca4f8c25b48CF754DD83590;\n } else {\n return\n 0x409Fe24ba6F6BD5aF31C1aAf8059b986A3158233;\n }\n } else {\n if (routeId == 155) {\n return\n 0x704Cf5BFDADc0f55fDBb53B6ed8B582E018A72A2;\n } else {\n return\n 0x3982bF65d7d6E77E3b6661cd6F6468c247512737;\n }\n }\n } else {\n if (routeId < 159) {\n if (routeId == 157) {\n return\n 0x3982b9f26FFD67a13Ee371e2C0a9Da338BA70E7f;\n } else {\n return\n 0x6D834AB385900c1f49055D098e90264077FbC4f2;\n }\n } else {\n if (routeId == 159) {\n return\n 0x11FE5F70779A094B7166B391e1Fb73d422eF4e4d;\n } else {\n return\n 0xD347e4E47280d21F13B73D89c6d16f867D50DD13;\n }\n }\n }\n }\n }\n } else {\n if (routeId < 177) {\n if (routeId < 169) {\n if (routeId < 165) {\n if (routeId < 163) {\n if (routeId == 161) {\n return\n 0xb6035eDD53DDA28d8B69b4ae9836E40C80306CD7;\n } else {\n return\n 0x54c884e6f5C7CcfeCA990396c520C858c922b6CA;\n }\n } else {\n if (routeId == 163) {\n return\n 0x5eA93E240b083d686558Ed607BC013d88057cE46;\n } else {\n return\n 0x4C7131eE812De685cBe4e2cCb033d46ecD46612E;\n }\n }\n } else {\n if (routeId < 167) {\n if (routeId == 165) {\n return\n 0xc1a5Be9F0c33D8483801D702111068669f81fF91;\n } else {\n return\n 0x9E5fAb91455Be5E5b2C05967E73F456c8118B1Fc;\n }\n } else {\n if (routeId == 167) {\n return\n 0x3d9A05927223E0DC2F382831770405885e22F0d8;\n } else {\n return\n 0x6303A011fB6063f5B1681cb5a9938EA278dc6128;\n }\n }\n }\n } else {\n if (routeId < 173) {\n if (routeId < 171) {\n if (routeId == 169) {\n return\n 0xe9c60795c90C66797e4c8E97511eA07CdAda32bE;\n } else {\n return\n 0xD56cC98e69A1e13815818b466a8aA6163d84234A;\n }\n } else {\n if (routeId == 171) {\n return\n 0x47EbB9D36a6e40895316cD894E4860D774E2c531;\n } else {\n return\n 0xA5EB293629410065d14a7B1663A67829b0618292;\n }\n }\n } else {\n if (routeId < 175) {\n if (routeId == 173) {\n return\n 0x1b3B4C8146F939cE00899db8B3ddeF0062b7E023;\n } else {\n return\n 0x257Bbc11653625EbfB6A8587eF4f4FBe49828EB3;\n }\n } else {\n if (routeId == 175) {\n return\n 0x44cc979C01b5bB1eAC21301E73C37200dFD06F59;\n } else {\n return\n 0x2972fDF43352225D82754C0174Ff853819D1ef2A;\n }\n }\n }\n }\n } else {\n if (routeId < 185) {\n if (routeId < 181) {\n if (routeId < 179) {\n if (routeId == 177) {\n return\n 0x3e54144f032648A04D62d79f7B4b93FF3aC2333b;\n } else {\n return\n 0x444016102dB8adbE73C3B6703a1ea7F2f75A510D;\n }\n } else {\n if (routeId == 179) {\n return\n 0xac079143f98a6eb744Fde34541ebF243DF5B5dED;\n } else {\n return\n 0xAe9010767Fb112d29d35CEdfba2b372Ad7A308d3;\n }\n }\n } else {\n if (routeId < 183) {\n if (routeId == 181) {\n return\n 0xfE0BCcF9cCC2265D5fB3450743f17DfE57aE1e56;\n } else {\n return\n 0x04ED8C0545716119437a45386B1d691C63234C7D;\n }\n } else {\n if (routeId == 183) {\n return\n 0x636c14013e531A286Bc4C848da34585f0bB73d59;\n } else {\n return\n 0x2Fa67fc7ECC5cAA01C653d3BFeA98ecc5db9C42A;\n }\n }\n }\n } else {\n if (routeId < 189) {\n if (routeId < 187) {\n if (routeId == 185) {\n return\n 0x23e9a0FC180818aA872D2079a985217017E97bd9;\n } else {\n return\n 0x79A95c3Ef81b3ae64ee03A9D5f73e570495F164E;\n }\n } else {\n if (routeId == 187) {\n return\n 0xa7EA0E88F04a84ba0ad1E396cb07Fa3fDAD7dF6D;\n } else {\n return\n 0xd23cA1278a2B01a3C0Ca1a00d104b11c1Ebe6f42;\n }\n }\n } else {\n if (routeId < 191) {\n if (routeId == 189) {\n return\n 0x707bc4a9FA2E349AED5df4e9f5440C15aA9D14Bd;\n } else {\n return\n 0x7E290F2dd539Ac6CE58d8B4C2B944931a1fD3612;\n }\n } else {\n if (routeId == 191) {\n return\n 0x707AA5503088Ce06Ba450B6470A506122eA5c8eF;\n } else {\n return\n 0xFbB3f7BF680deeb149f4E7BC30eA3DDfa68F3C3f;\n }\n }\n }\n }\n }\n }\n } else {\n if (routeId < 225) {\n if (routeId < 209) {\n if (routeId < 201) {\n if (routeId < 197) {\n if (routeId < 195) {\n if (routeId == 193) {\n return\n 0xDE74aD8cCC3dbF14992f49Cf24f36855912f4934;\n } else {\n return\n 0x409BA83df7777F070b2B50a10a41DE2468d2a3B3;\n }\n } else {\n if (routeId == 195) {\n return\n 0x5CB7Be90A5DD7CfDa54e87626e254FE8C18255B4;\n } else {\n return\n 0x0A684fE12BC64fb72B59d0771a566F49BC090356;\n }\n }\n } else {\n if (routeId < 199) {\n if (routeId == 197) {\n return\n 0xDf30048d91F8FA2bCfC54952B92bFA8e161D3360;\n } else {\n return\n 0x050825Fff032a547C47061CF0696FDB0f65AEa5D;\n }\n } else {\n if (routeId == 199) {\n return\n 0xd55e671dAC1f03d366d8535073ada5DB2Aab1Ea2;\n } else {\n return\n 0x9470C704A9616c8Cd41c595Fcd2181B6fe2183C2;\n }\n }\n }\n } else {\n if (routeId < 205) {\n if (routeId < 203) {\n if (routeId == 201) {\n return\n 0x2D9ffD275181F5865d5e11CbB4ced1521C4dF9f1;\n } else {\n return\n 0x816d28Dec10ec95DF5334f884dE85cA6215918d8;\n }\n } else {\n if (routeId == 203) {\n return\n 0xd1f87267c4A43835E666dd69Df077e578A3b6299;\n } else {\n return\n 0x39E89Bde9DACbe5468C025dE371FbDa12bDeBAB1;\n }\n }\n } else {\n if (routeId < 207) {\n if (routeId == 205) {\n return\n 0x7b40A3207956ecad6686E61EfcaC48912FcD0658;\n } else {\n return\n 0x090cF10D793B1Efba9c7D76115878814B663859A;\n }\n } else {\n if (routeId == 207) {\n return\n 0x312A59c06E41327878F2063eD0e9c282C1DA3AfC;\n } else {\n return\n 0x4F1188f46236DD6B5de11Ebf2a9fF08716E7DeB6;\n }\n }\n }\n }\n } else {\n if (routeId < 217) {\n if (routeId < 213) {\n if (routeId < 211) {\n if (routeId == 209) {\n return\n 0x0A6F9a3f4fA49909bBfb4339cbE12B42F53BbBeD;\n } else {\n return\n 0x01d13d7aCaCbB955B81935c80ffF31e14BdFa71f;\n }\n } else {\n if (routeId == 211) {\n return\n 0x691a14Fa6C7360422EC56dF5876f84d4eDD7f00A;\n } else {\n return\n 0x97Aad18d886d181a9c726B3B6aE15a0A69F5aF73;\n }\n }\n } else {\n if (routeId < 215) {\n if (routeId == 213) {\n return\n 0x2917241371D2099049Fa29432DC46735baEC33b4;\n } else {\n return\n 0x5F20F20F7890c2e383E29D4147C9695A371165f5;\n }\n } else {\n if (routeId == 215) {\n return\n 0xeC0a60e639958335662C5219A320cCEbb56C6077;\n } else {\n return\n 0x96d63CF5062975C09845d17ec672E10255866053;\n }\n }\n }\n } else {\n if (routeId < 221) {\n if (routeId < 219) {\n if (routeId == 217) {\n return\n 0xFF57429e57D383939CAB50f09ABBfB63C0e6c9AD;\n } else {\n return\n 0x18E393A7c8578fb1e235C242076E50013cDdD0d7;\n }\n } else {\n if (routeId == 219) {\n return\n 0xE7E5238AF5d61f52E9B4ACC025F713d1C0216507;\n } else {\n return\n 0x428401D4d0F25A2EE1DA4d5366cB96Ded425D9bD;\n }\n }\n } else {\n if (routeId < 223) {\n if (routeId == 221) {\n return\n 0x42E5733551ff1Ee5B48Aa9fc2B61Af9b58C812E6;\n } else {\n return\n 0x64Df9c7A0551B056d860Bc2419Ca4c1EF75320bE;\n }\n } else {\n if (routeId == 223) {\n return\n 0x46006925506145611bBf0263243D8627dAf26B0F;\n } else {\n return\n 0x8D64BE884314662804eAaB884531f5C50F4d500c;\n }\n }\n }\n }\n }\n } else {\n if (routeId < 241) {\n if (routeId < 233) {\n if (routeId < 229) {\n if (routeId < 227) {\n if (routeId == 225) {\n return\n 0x157a62D92D07B5ce221A5429645a03bBaCE85373;\n } else {\n return\n 0xaF037D33e1F1F2F87309B425fe8a9d895Ef3722B;\n }\n } else {\n if (routeId == 227) {\n return\n 0x921D1154E494A2f7218a37ad7B17701f94b4B40e;\n } else {\n return\n 0xF282b4555186d8Dea51B8b3F947E1E0568d09bc4;\n }\n }\n } else {\n if (routeId < 231) {\n if (routeId == 229) {\n return\n 0xa794E2E1869765a4600b3DFd8a4ebcF16350f6B6;\n } else {\n return\n 0xFEFb048e20c5652F7940A49B1980E0125Ec4D358;\n }\n } else {\n if (routeId == 231) {\n return\n 0x220104b641971e9b25612a8F001bf48AbB23f1cF;\n } else {\n return\n 0xcB9D373Bb54A501B35dd3be5bF4Ba43cA31F7035;\n }\n }\n }\n } else {\n if (routeId < 237) {\n if (routeId < 235) {\n if (routeId == 233) {\n return\n 0x37D627F56e3FF36aC316372109ea82E03ac97DAc;\n } else {\n return\n 0x4E81355FfB4A271B4EA59ff78da2b61c7833161f;\n }\n } else {\n if (routeId == 235) {\n return\n 0xADd8D65cAF6Cc9ad73127B49E16eA7ac29d91e87;\n } else {\n return\n 0x630F9b95626487dfEAe3C97A44DB6C59cF35d996;\n }\n }\n } else {\n if (routeId < 239) {\n if (routeId == 237) {\n return\n 0x78CE2BC8238B679680A67FCB98C5A60E4ec17b2D;\n } else {\n return\n 0xA38D776028eD1310b9A6b086f67F788201762E21;\n }\n } else {\n if (routeId == 239) {\n return\n 0x7Bb5178827B76B86753Ed62a0d662c72cEcb1bD3;\n } else {\n return\n 0x4faC26f61C76eC5c3D43b43eDfAFF0736Ae0e3da;\n }\n }\n }\n }\n } else {\n if (routeId < 249) {\n if (routeId < 245) {\n if (routeId < 243) {\n if (routeId == 241) {\n return\n 0x791Bb49bfFA7129D6889FDB27744422Ac4571A85;\n } else {\n return\n 0x26766fFEbb5fa564777913A6f101dF019AB32afa;\n }\n } else {\n if (routeId == 243) {\n return\n 0x05e98E5e95b4ECBbbAf3258c3999Cc81ed8048Be;\n } else {\n return\n 0xC5c4621e52f1D6A1825A5ed4F95855401a3D9C6b;\n }\n }\n } else {\n if (routeId < 247) {\n if (routeId == 245) {\n return\n 0xfcb15f909BA7FC7Ea083503Fb4c1020203c107EB;\n } else {\n return\n 0xbD27603279d969c74f2486ad14E71080829DFd38;\n }\n } else {\n if (routeId == 247) {\n return\n 0xff2f756BcEcC1A55BFc09a30cc5F64720458cFCB;\n } else {\n return\n 0x3bfB968FEbC12F4e8420B2d016EfcE1E615f7246;\n }\n }\n }\n } else {\n if (routeId < 253) {\n if (routeId < 251) {\n if (routeId == 249) {\n return\n 0x982EE9Ffe23051A2ec945ed676D864fa8345222b;\n } else {\n return\n 0xe101899100785E74767d454FFF0131277BaD48d9;\n }\n } else {\n if (routeId == 251) {\n return\n 0x4F730C0c6b3B5B7d06ca511379f4Aa5BfB2E9525;\n } else {\n return\n 0x5499c36b365795e4e0Ef671aF6C2ce26D7c78265;\n }\n }\n } else {\n if (routeId < 255) {\n if (routeId == 253) {\n return\n 0x8AF51F7237Fc8fB2fc3E700488a94a0aC6Ad8b5a;\n } else {\n return\n 0xda8716df61213c0b143F2849785FB85928084857;\n }\n } else {\n if (routeId == 255) {\n return\n 0xF040Cf9b1ebD11Bf28e04e80740DF3DDe717e4f5;\n } else {\n return\n 0xB87ba32f759D14023C7520366B844dF7f0F036C2;\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n if (routeId < 321) {\n if (routeId < 289) {\n if (routeId < 273) {\n if (routeId < 265) {\n if (routeId < 261) {\n if (routeId < 259) {\n if (routeId == 257) {\n return\n 0x0Edde681b8478F0c3194f468EdD2dB5e75c65CDD;\n } else {\n return\n 0x59C70900Fca06eE2aCE1BDd5A8D0Af0cc3BBA720;\n }\n } else {\n if (routeId == 259) {\n return\n 0x8041F0f180D17dD07087199632c45E17AeB0BAd5;\n } else {\n return\n 0x4fB4727064BA595995DD516b63b5921Df9B93aC6;\n }\n }\n } else {\n if (routeId < 263) {\n if (routeId == 261) {\n return\n 0x86e98b594565857eD098864F560915C0dAfd6Ea1;\n } else {\n return\n 0x70f8818E8B698EFfeCd86A513a4c87c0c380Bef6;\n }\n } else {\n if (routeId == 263) {\n return\n 0x78Ed227c8A897A21Da2875a752142dd80d865158;\n } else {\n return\n 0xd02A30BB5C3a8C51d2751A029a6fcfDE2Af9fbc6;\n }\n }\n }\n } else {\n if (routeId < 269) {\n if (routeId < 267) {\n if (routeId == 265) {\n return\n 0x0F00d5c5acb24e975e2a56730609f7F40aa763b8;\n } else {\n return\n 0xC3e2091edc2D3D9D98ba09269138b617B536834A;\n }\n } else {\n if (routeId == 267) {\n return\n 0xa6FbaF7F30867C9633908998ea8C3da28920E75C;\n } else {\n return\n 0xE6dDdcD41E2bBe8122AE32Ac29B8fbAB79CD21d9;\n }\n }\n } else {\n if (routeId < 271) {\n if (routeId == 269) {\n return\n 0x537aa8c1Ef6a8Eaf039dd6e1Eb67694a48195cE4;\n } else {\n return\n 0x96ABAC485fd2D0B03CF4a10df8BD58b8dED28300;\n }\n } else {\n if (routeId == 271) {\n return\n 0xda8e7D46d04Bd4F62705Cd80355BDB6d441DafFD;\n } else {\n return\n 0xbE50018E7a5c67E2e5f5414393e971CC96F293f2;\n }\n }\n }\n }\n } else {\n if (routeId < 281) {\n if (routeId < 277) {\n if (routeId < 275) {\n if (routeId == 273) {\n return\n 0xa1b3907D6CB542a4cbe2eE441EfFAA909FAb62C3;\n } else {\n return\n 0x6d08ee8511C0237a515013aC389e7B3968Cb1753;\n }\n } else {\n if (routeId == 275) {\n return\n 0x22faa5B5Fe43eAdbB52745e35a5cdA8bD5F96bbA;\n } else {\n return\n 0x7a673eB74D79e4868D689E7852abB5f93Ec2fD4b;\n }\n }\n } else {\n if (routeId < 279) {\n if (routeId == 277) {\n return\n 0x0b8531F8AFD4190b76F3e10deCaDb84c98b4d419;\n } else {\n return\n 0x78eABC743A93583DeE403D6b84795490e652216B;\n }\n } else {\n if (routeId == 279) {\n return\n 0x3A95D907b2a7a8604B59BccA08585F58Afe0Aa64;\n } else {\n return\n 0xf4271f0C8c9Af0F06A80b8832fa820ccE64FAda8;\n }\n }\n }\n } else {\n if (routeId < 285) {\n if (routeId < 283) {\n if (routeId == 281) {\n return\n 0x74b2DF841245C3748c0d31542e1335659a25C33b;\n } else {\n return\n 0xdFC99Fd0Ad7D16f30f295a5EEFcE029E04d0fa65;\n }\n } else {\n if (routeId == 283) {\n return\n 0xE992416b6aC1144eD8148a9632973257839027F6;\n } else {\n return\n 0x54ce55ba954E981BB1fd9399054B35Ce1f2C0816;\n }\n }\n } else {\n if (routeId < 287) {\n if (routeId == 285) {\n return\n 0xD4AB52f9e7E5B315Bd7471920baD04F405Ab1c38;\n } else {\n return\n 0x3670C990994d12837e95eE127fE2f06FD3E2104B;\n }\n } else {\n if (routeId == 287) {\n return\n 0xDcf190B09C47E4f551E30BBb79969c3FdEA1e992;\n } else {\n return\n 0xa65057B967B59677237e57Ab815B209744b9bc40;\n }\n }\n }\n }\n }\n } else {\n if (routeId < 305) {\n if (routeId < 297) {\n if (routeId < 293) {\n if (routeId < 291) {\n if (routeId == 289) {\n return\n 0x6Efc86B40573e4C7F28659B13327D55ae955C483;\n } else {\n return\n 0x06BcC25CF8e0E72316F53631b3aA7134E9f73Ae0;\n }\n } else {\n if (routeId == 291) {\n return\n 0x710b6414E1D53882b1FCD3A168aD5Ccd435fc6D0;\n } else {\n return\n 0x5Ebb2C3d78c4e9818074559e7BaE7FCc99781DC1;\n }\n }\n } else {\n if (routeId < 295) {\n if (routeId == 293) {\n return\n 0xAf0a409c3AEe0bD08015cfb29D89E90b6e89A88F;\n } else {\n return\n 0x522559d8b99773C693B80cE06DF559036295Ce44;\n }\n } else {\n if (routeId == 295) {\n return\n 0xB65290A5Bae838aaa7825c9ECEC68041841a1B64;\n } else {\n return\n 0x801b8F2068edd5Bcb659E6BDa0c425909043C420;\n }\n }\n }\n } else {\n if (routeId < 301) {\n if (routeId < 299) {\n if (routeId == 297) {\n return\n 0x29b5F00515d093627E0B7bd0b5c8E84F6b4cDb87;\n } else {\n return\n 0x652839Ae74683cbF9f1293F1019D938F87464D3E;\n }\n } else {\n if (routeId == 299) {\n return\n 0x5Bc95dCebDDE9B79F2b6DC76121BC7936eF8D666;\n } else {\n return\n 0x90db359CEA62E53051158Ab5F99811C0a07Fe686;\n }\n }\n } else {\n if (routeId < 303) {\n if (routeId == 301) {\n return\n 0x2c3625EedadbDcDbB5330eb0d17b3C39ff269807;\n } else {\n return\n 0xC3f0324471b5c9d415acD625b8d8694a4e48e001;\n }\n } else {\n if (routeId == 303) {\n return\n 0x8C60e7E05fa0FfB6F720233736f245134685799d;\n } else {\n return\n 0x98fAF2c09aa4EBb995ad0B56152993E7291a500e;\n }\n }\n }\n }\n } else {\n if (routeId < 313) {\n if (routeId < 309) {\n if (routeId < 307) {\n if (routeId == 305) {\n return\n 0x802c1063a861414dFAEc16bacb81429FC0d40D6e;\n } else {\n return\n 0x11C4AeFCC0dC156f64195f6513CB1Fb3Be0Ae056;\n }\n } else {\n if (routeId == 307) {\n return\n 0xEff1F3258214E31B6B4F640b4389d55715C3Be2B;\n } else {\n return\n 0x47e379Abe8DDFEA4289aBa01235EFF7E93758fd7;\n }\n }\n } else {\n if (routeId < 311) {\n if (routeId == 309) {\n return\n 0x3CC26384c3eA31dDc8D9789e8872CeA6F20cD3ff;\n } else {\n return\n 0xEdd9EFa6c69108FAA4611097d643E20Ba0Ed1634;\n }\n } else {\n if (routeId == 311) {\n return\n 0xCb93525CA5f3D371F74F3D112bC19526740717B8;\n } else {\n return\n 0x7071E0124EB4438137e60dF1b8DD8Af1BfB362cF;\n }\n }\n }\n } else {\n if (routeId < 317) {\n if (routeId < 315) {\n if (routeId == 313) {\n return\n 0x4691096EB0b78C8F4b4A8091E5B66b18e1835c10;\n } else {\n return\n 0x8d953c9b2d1C2137CF95992079f3A77fCd793272;\n }\n } else {\n if (routeId == 315) {\n return\n 0xbdCc2A3Bf6e3Ba49ff86595e6b2b8D70d8368c92;\n } else {\n return\n 0x95E6948aB38c61b2D294E8Bd896BCc4cCC0713cf;\n }\n }\n } else {\n if (routeId < 319) {\n if (routeId == 317) {\n return\n 0x607b27C881fFEE4Cb95B1c5862FaE7224ccd0b4A;\n } else {\n return\n 0x09D28aFA166e566A2Ee1cB834ea8e78C7E627eD2;\n }\n } else {\n if (routeId == 319) {\n return\n 0x9c01449b38bDF0B263818401044Fb1401B29fDfA;\n } else {\n return\n 0x1F7723599bbB658c051F8A39bE2688388d22ceD6;\n }\n }\n }\n }\n }\n }\n } else {\n if (routeId < 353) {\n if (routeId < 337) {\n if (routeId < 329) {\n if (routeId < 325) {\n if (routeId < 323) {\n if (routeId == 321) {\n return\n 0x52B71603f7b8A5d15B4482e965a0619aa3210194;\n } else {\n return\n 0x01c0f072CB210406653752FecFA70B42dA9173a2;\n }\n } else {\n if (routeId == 323) {\n return\n 0x3021142f021E943e57fc1886cAF58D06147D09A6;\n } else {\n return\n 0xe6f2AF38e76AB09Db59225d97d3E770942D3D842;\n }\n }\n } else {\n if (routeId < 327) {\n if (routeId == 325) {\n return\n 0x06a25554e5135F08b9e2eD1DEC1fc3CEd52e0B48;\n } else {\n return\n 0x71d75e670EE3511C8290C705E0620126B710BF8D;\n }\n } else {\n if (routeId == 327) {\n return\n 0x8b9cE142b80FeA7c932952EC533694b1DF9B3c54;\n } else {\n return\n 0xd7Be24f32f39231116B3fDc483C2A12E1521f73B;\n }\n }\n }\n } else {\n if (routeId < 333) {\n if (routeId < 331) {\n if (routeId == 329) {\n return\n 0xb40cafBC4797d4Ff64087E087F6D2e661f954CbE;\n } else {\n return\n 0xBdDCe7771EfEe81893e838f62204A4c76D72757e;\n }\n } else {\n if (routeId == 331) {\n return\n 0x5d3D299EA7Fd4F39AcDb336E26631Dfee41F9287;\n } else {\n return\n 0x6BfEE09E1Fc0684e0826A9A0dC1352a14B136FAC;\n }\n }\n } else {\n if (routeId < 335) {\n if (routeId == 333) {\n return\n 0xd0001bB8E2Cb661436093f96458a4358B5156E3c;\n } else {\n return\n 0x1867c6485CfD1eD448988368A22bfB17a7747293;\n }\n } else {\n if (routeId == 335) {\n return\n 0x8997EF9F95dF24aB67703AB6C262aABfeEBE33bD;\n } else {\n return\n 0x1e39E9E601922deD91BCFc8F78836302133465e2;\n }\n }\n }\n }\n } else {\n if (routeId < 345) {\n if (routeId < 341) {\n if (routeId < 339) {\n if (routeId == 337) {\n return\n 0x8A8ec6CeacFf502a782216774E5AF3421562C6ff;\n } else {\n return\n 0x3B8FC561df5415c8DC01e97Ee6E38435A8F9C40A;\n }\n } else {\n if (routeId == 339) {\n return\n 0xD5d5f5B37E67c43ceA663aEDADFFc3a93a2065B0;\n } else {\n return\n 0xCC8F55EC43B4f25013CE1946FBB740c43Be5B96D;\n }\n }\n } else {\n if (routeId < 343) {\n if (routeId == 341) {\n return\n 0x18f586E816eEeDbb57B8011239150367561B58Fb;\n } else {\n return\n 0xd0CD802B19c1a52501cb2f07d656e3Cd7B0Ce124;\n }\n } else {\n if (routeId == 343) {\n return\n 0xe0AeD899b39C6e4f2d83e4913a1e9e0cf6368abE;\n } else {\n return\n 0x0606e1b6c0f1A398C38825DCcc4678a7Cbc2737c;\n }\n }\n }\n } else {\n if (routeId < 349) {\n if (routeId < 347) {\n if (routeId == 345) {\n return\n 0x2d188e85b27d18EF80f16686EA1593ABF7Ed2A63;\n } else {\n return\n 0x64412292fA4A135a3300E24366E99ff59Db2eAc1;\n }\n } else {\n if (routeId == 347) {\n return\n 0x38b74c173f3733E8b90aAEf0e98B89791266149F;\n } else {\n return\n 0x36DAA49A79aaEF4E7a217A11530D3cCD84414124;\n }\n }\n } else {\n if (routeId < 351) {\n if (routeId == 349) {\n return\n 0x10f088FE2C88F90270E4449c46c8B1b232511d58;\n } else {\n return\n 0x4FeDbd25B58586838ABD17D10272697dF1dC3087;\n }\n } else {\n if (routeId == 351) {\n return\n 0x685278209248CB058E5cEe93e37f274A80Faf6eb;\n } else {\n return\n 0xDd9F8F1eeC3955f78168e2Fb2d1e808fa8A8f15b;\n }\n }\n }\n }\n }\n } else {\n if (routeId < 369) {\n if (routeId < 361) {\n if (routeId < 357) {\n if (routeId < 355) {\n if (routeId == 353) {\n return\n 0x7392aEeFD5825aaC28817031dEEBbFaAA20983D9;\n } else {\n return\n 0x0Cc182555E00767D6FB8AD161A10d0C04C476d91;\n }\n } else {\n if (routeId == 355) {\n return\n 0x90E52837d56715c79FD592E8D58bFD20365798b2;\n } else {\n return\n 0x6F4451DE14049B6770ad5BF4013118529e68A40C;\n }\n }\n } else {\n if (routeId < 359) {\n if (routeId == 357) {\n return\n 0x89B97ef2aFAb9ed9c7f0FDb095d02E6840b52d9c;\n } else {\n return\n 0x92A5cC5C42d94d3e23aeB1214fFf43Db2B97759E;\n }\n } else {\n if (routeId == 359) {\n return\n 0x63ddc52F135A1dcBA831EAaC11C63849F018b739;\n } else {\n return\n 0x692A691533B571C2c54C1D7F8043A204b3d8120E;\n }\n }\n }\n } else {\n if (routeId < 365) {\n if (routeId < 363) {\n if (routeId == 361) {\n return\n 0x97c7492CF083969F61C6f302d45c8270391b921c;\n } else {\n return\n 0xDeFD2B8643553dAd19548eB14fd94A57F4B9e543;\n }\n } else {\n if (routeId == 363) {\n return\n 0x30645C04205cA3f670B67b02F971B088930ACB8C;\n } else {\n return\n 0xA6f80ed2d607Cd67aEB4109B64A0BEcc4D7d03CF;\n }\n }\n } else {\n if (routeId < 367) {\n if (routeId == 365) {\n return\n 0xBbbbC6c276eB3F7E674f2D39301509236001c42f;\n } else {\n return\n 0xC20E77d349FB40CE88eB01824e2873ad9f681f3C;\n }\n } else {\n if (routeId == 367) {\n return\n 0x5fCfD9a962De19294467C358C1FA55082285960b;\n } else {\n return\n 0x4D87BD6a0E4E5cc6332923cb3E85fC71b287F58A;\n }\n }\n }\n }\n } else {\n if (routeId < 377) {\n if (routeId < 373) {\n if (routeId < 371) {\n if (routeId == 369) {\n return\n 0x3AA5B757cd6Dde98214E56D57Dde7fcF0F7aB04E;\n } else {\n return\n 0xe28eFCE7192e11a2297f44059113C1fD6967b2d4;\n }\n } else {\n if (routeId == 371) {\n return\n 0x3251cAE10a1Cf246e0808D76ACC26F7B5edA0eE5;\n } else {\n return\n 0xbA2091cc9357Cf4c4F25D64F30d1b4Ba3A5a174B;\n }\n }\n } else {\n if (routeId < 375) {\n if (routeId == 373) {\n return\n 0x49c8e1Da9693692096F63C82D11b52d738566d55;\n } else {\n return\n 0xA0731615aB5FFF451031E9551367A4F7dB27b39c;\n }\n } else {\n if (routeId == 375) {\n return\n 0xFb214541888671AE1403CecC1D59763a12fc1609;\n } else {\n return\n 0x1D6bCB17642E2336405df73dF22F07688cAec020;\n }\n }\n }\n } else {\n if (routeId < 381) {\n if (routeId < 379) {\n if (routeId == 377) {\n return\n 0xfC9c0C7bfe187120fF7f4E21446161794A617a9e;\n } else {\n return\n 0xBa5bF37678EeE2dAB17AEf9D898153258252250E;\n }\n } else {\n if (routeId == 379) {\n return\n 0x7c55690bd2C9961576A32c02f8EB29ed36415Ec7;\n } else {\n return\n 0xcA40073E868E8Bc611aEc8Fe741D17E68Fe422f6;\n }\n }\n } else {\n if (routeId < 383) {\n if (routeId == 381) {\n return\n 0x31641bAFb87E9A58f78835050a7BE56921986339;\n } else {\n return\n 0xA54766424f6dA74b45EbCc5Bf0Bd1D74D2CCcaAB;\n }\n } else {\n if (routeId == 383) {\n return\n 0xc7bBa57F8C179EDDBaa62117ddA360e28f3F8252;\n } else {\n return\n 0x5e663ED97ea77d393B8858C90d0683bF180E0ffd;\n }\n }\n }\n }\n }\n }\n }\n }\n }\n\n if (routes[routeId] == address(0)) revert ZeroAddressNotAllowed();\n return routes[routeId];\n }\n\n /// @notice fallback function to handle swap, bridge execution\n /// @dev ensure routeId is converted to bytes4 and sent as msg.sig in the transaction\n fallback() external payable {\n address routeAddress = addressAt(uint32(msg.sig));\n\n bytes memory result;\n\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 4, sub(calldatasize(), 4))\n // execute function call using the facet\n result := delegatecall(\n gas(),\n routeAddress,\n 0,\n sub(calldatasize(), 4),\n 0,\n 0\n )\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n}\n" - }, - "src/bridges/hop/interfaces/IHopL1Bridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/**\n * @title L1Bridge Hop Interface\n * @notice L1 Hop Bridge, Used to transfer from L1 to L2s.\n */\ninterface IHopL1Bridge {\n /**\n * @notice `amountOutMin` and `deadline` should be 0 when no swap is intended at the destination.\n * @notice `amount` is the total amount the user wants to send including the relayer fee\n * @dev Send tokens to a supported layer-2 to mint hToken and optionally swap the hToken in the\n * AMM at the destination.\n * @param chainId The chainId of the destination chain\n * @param recipient The address receiving funds at the destination\n * @param amount The amount being sent\n * @param amountOutMin The minimum amount received after attempting to swap in the destination\n * AMM market. 0 if no swap is intended.\n * @param deadline The deadline for swapping in the destination AMM market. 0 if no\n * swap is intended.\n * @param relayer The address of the relayer at the destination.\n * @param relayerFee The amount distributed to the relayer at the destination. This is subtracted from the `amount`.\n */\n function sendToL2(\n uint256 chainId,\n address recipient,\n uint256 amount,\n uint256 amountOutMin,\n uint256 deadline,\n address relayer,\n uint256 relayerFee\n ) external payable;\n}\n" - }, - "src/bridges/refuel/interfaces/refuel.sol": { - "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity >=0.8.0;\n\n/// @notice interface with functions to interact with Refuel contract\ninterface IRefuel {\n /**\n * @notice function to deposit nativeToken to Destination-address on destinationChain\n * @param destinationChainId chainId of the Destination chain\n * @param _to recipient address\n */\n function depositNativeToken(\n uint256 destinationChainId,\n address _to\n ) external payable;\n}\n" - }, - "src/bridges/stargate/interfaces/stargate.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity >=0.8.0;\n\n/**\n * @title IBridgeStargate Interface Contract.\n * @notice Interface used by Stargate-L1 and L2 Router implementations\n * @dev router and routerETH addresses will be distinct for L1 and L2\n */\ninterface IBridgeStargate {\n // @notice Struct to hold the additional-data for bridging ERC20 token\n struct lzTxObj {\n // gas limit to bridge the token in Stargate to destinationChain\n uint256 dstGasForCall;\n // destination nativeAmount, this is always set as 0\n uint256 dstNativeAmount;\n // destination nativeAddress, this is always set as 0x\n bytes dstNativeAddr;\n }\n\n /// @notice function in stargate bridge which is used to bridge ERC20 tokens to recipient on destinationChain\n function swap(\n uint16 _dstChainId,\n uint256 _srcPoolId,\n uint256 _dstPoolId,\n address payable _refundAddress,\n uint256 _amountLD,\n uint256 _minAmountLD,\n lzTxObj memory _lzTxParams,\n bytes calldata _to,\n bytes calldata _payload\n ) external payable;\n\n /// @notice function in stargate bridge which is used to bridge native tokens to recipient on destinationChain\n function swapETH(\n uint16 _dstChainId, // destination Stargate chainId\n address payable _refundAddress, // refund additional messageFee to this address\n bytes calldata _toAddress, // the receiver of the destination ETH\n uint256 _amountLD, // the amount, in Local Decimals, to be swapped\n uint256 _minAmountLD // the minimum amount accepted out on destination\n ) external payable;\n}\n" - }, - "src/controllers/FeesTakerController.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {BaseController} from \"./BaseController.sol\";\nimport {ISocketRequest} from \"../interfaces/ISocketRequest.sol\";\n\n/**\n * @title FeesTaker-Controller Implementation\n * @notice Controller with composed actions to deduct-fees followed by Refuel, Swap and Bridge\n * to be executed Sequentially and this is atomic\n * @author Socket dot tech.\n */\ncontract FeesTakerController is BaseController {\n using SafeTransferLib for ERC20;\n\n /// @notice event emitted upon fee-deduction to fees-taker address\n event SocketFeesDeducted(\n uint256 fees,\n address feesToken,\n address feesTaker\n );\n\n /// @notice Function-selector to invoke deduct-fees and swap token\n /// @dev This function selector is to be used while building transaction-data\n bytes4 public immutable FEES_TAKER_SWAP_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\"takeFeesAndSwap((address,address,uint256,uint32,bytes))\")\n );\n\n /// @notice Function-selector to invoke deduct-fees and bridge token\n /// @dev This function selector is to be used while building transaction-data\n bytes4 public immutable FEES_TAKER_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"takeFeesAndBridge((address,address,uint256,uint32,bytes))\"\n )\n );\n\n /// @notice Function-selector to invoke deduct-fees and bridge multiple tokens\n /// @dev This function selector is to be used while building transaction-data\n bytes4 public immutable FEES_TAKER_MULTI_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"takeFeesAndMultiBridge((address,address,uint256,uint32[],bytes[]))\"\n )\n );\n\n /// @notice Function-selector to invoke deduct-fees followed by swapping of a token and bridging the swapped bridge\n /// @dev This function selector is to be used while building transaction-data\n bytes4 public immutable FEES_TAKER_SWAP_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"takeFeeAndSwapAndBridge((address,address,uint256,uint32,bytes,uint32,bytes))\"\n )\n );\n\n /// @notice Function-selector to invoke deduct-fees refuel\n /// @notice followed by swapping of a token and bridging the swapped bridge\n /// @dev This function selector is to be used while building transaction-data\n bytes4 public immutable FEES_TAKER_REFUEL_SWAP_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"takeFeeAndRefuelAndSwapAndBridge((address,address,uint256,uint32,bytes,uint32,bytes,uint32,bytes))\"\n )\n );\n\n /// @notice socketGatewayAddress to be initialised via storage variable BaseController\n constructor(\n address _socketGatewayAddress\n ) BaseController(_socketGatewayAddress) {}\n\n /**\n * @notice function to deduct-fees to fees-taker address on source-chain and swap token\n * @dev ensure correct function selector is used to generate transaction-data for bridgeRequest\n * @param ftsRequest feesTakerSwapRequest object generated either off-chain or the calling contract using\n * the function-selector FEES_TAKER_SWAP_FUNCTION_SELECTOR\n * @return output bytes from the swap operation (last operation in the composed actions)\n */\n function takeFeesAndSwap(\n ISocketRequest.FeesTakerSwapRequest calldata ftsRequest\n ) external payable returns (bytes memory) {\n if (ftsRequest.feesToken == NATIVE_TOKEN_ADDRESS) {\n //transfer the native amount to the feeTakerAddress\n payable(ftsRequest.feesTakerAddress).transfer(\n ftsRequest.feesAmount\n );\n } else {\n //transfer feesAmount to feesTakerAddress\n ERC20(ftsRequest.feesToken).safeTransferFrom(\n msg.sender,\n ftsRequest.feesTakerAddress,\n ftsRequest.feesAmount\n );\n }\n\n emit SocketFeesDeducted(\n ftsRequest.feesAmount,\n ftsRequest.feesTakerAddress,\n ftsRequest.feesToken\n );\n\n //call bridge function (executeRoute for the swapRequestData)\n return _executeRoute(ftsRequest.routeId, ftsRequest.swapRequestData);\n }\n\n /**\n * @notice function to deduct-fees to fees-taker address on source-chain and bridge amount to destinationChain\n * @dev ensure correct function selector is used to generate transaction-data for bridgeRequest\n * @param ftbRequest feesTakerBridgeRequest object generated either off-chain or the calling contract using\n * the function-selector FEES_TAKER_BRIDGE_FUNCTION_SELECTOR\n * @return output bytes from the bridge operation (last operation in the composed actions)\n */\n function takeFeesAndBridge(\n ISocketRequest.FeesTakerBridgeRequest calldata ftbRequest\n ) external payable returns (bytes memory) {\n if (ftbRequest.feesToken == NATIVE_TOKEN_ADDRESS) {\n //transfer the native amount to the feeTakerAddress\n payable(ftbRequest.feesTakerAddress).transfer(\n ftbRequest.feesAmount\n );\n } else {\n //transfer feesAmount to feesTakerAddress\n ERC20(ftbRequest.feesToken).safeTransferFrom(\n msg.sender,\n ftbRequest.feesTakerAddress,\n ftbRequest.feesAmount\n );\n }\n\n emit SocketFeesDeducted(\n ftbRequest.feesAmount,\n ftbRequest.feesTakerAddress,\n ftbRequest.feesToken\n );\n\n //call bridge function (executeRoute for the bridgeData)\n return _executeRoute(ftbRequest.routeId, ftbRequest.bridgeRequestData);\n }\n\n /**\n * @notice function to deduct-fees to fees-taker address on source-chain and bridge amount to destinationChain\n * @notice multiple bridge-requests are to be generated and sequence and number of routeIds should match with the bridgeData array\n * @dev ensure correct function selector is used to generate transaction-data for bridgeRequest\n * @param ftmbRequest feesTakerMultiBridgeRequest object generated either off-chain or the calling contract using\n * the function-selector FEES_TAKER_MULTI_BRIDGE_FUNCTION_SELECTOR\n */\n function takeFeesAndMultiBridge(\n ISocketRequest.FeesTakerMultiBridgeRequest calldata ftmbRequest\n ) external payable {\n if (ftmbRequest.feesToken == NATIVE_TOKEN_ADDRESS) {\n //transfer the native amount to the feeTakerAddress\n payable(ftmbRequest.feesTakerAddress).transfer(\n ftmbRequest.feesAmount\n );\n } else {\n //transfer feesAmount to feesTakerAddress\n ERC20(ftmbRequest.feesToken).safeTransferFrom(\n msg.sender,\n ftmbRequest.feesTakerAddress,\n ftmbRequest.feesAmount\n );\n }\n\n emit SocketFeesDeducted(\n ftmbRequest.feesAmount,\n ftmbRequest.feesTakerAddress,\n ftmbRequest.feesToken\n );\n\n // multiple bridge-requests are to be generated and sequence and number of routeIds should match with the bridgeData array\n for (\n uint256 index = 0;\n index < ftmbRequest.bridgeRouteIds.length;\n ++index\n ) {\n //call bridge function (executeRoute for the bridgeData)\n _executeRoute(\n ftmbRequest.bridgeRouteIds[index],\n ftmbRequest.bridgeRequestDataItems[index]\n );\n }\n }\n\n /**\n * @notice function to deduct-fees to fees-taker address on source-chain followed by swap the amount on sourceChain followed by\n * bridging the swapped amount to destinationChain\n * @dev while generating implData for swap and bridgeRequests, ensure correct function selector is used\n * bridge action corresponds to the bridgeAfterSwap function of the bridgeImplementation\n * @param fsbRequest feesTakerSwapBridgeRequest object generated either off-chain or the calling contract using\n * the function-selector FEES_TAKER_SWAP_BRIDGE_FUNCTION_SELECTOR\n */\n function takeFeeAndSwapAndBridge(\n ISocketRequest.FeesTakerSwapBridgeRequest calldata fsbRequest\n ) external payable returns (bytes memory) {\n if (fsbRequest.feesToken == NATIVE_TOKEN_ADDRESS) {\n //transfer the native amount to the feeTakerAddress\n payable(fsbRequest.feesTakerAddress).transfer(\n fsbRequest.feesAmount\n );\n } else {\n //transfer feesAmount to feesTakerAddress\n ERC20(fsbRequest.feesToken).safeTransferFrom(\n msg.sender,\n fsbRequest.feesTakerAddress,\n fsbRequest.feesAmount\n );\n }\n\n emit SocketFeesDeducted(\n fsbRequest.feesAmount,\n fsbRequest.feesTakerAddress,\n fsbRequest.feesToken\n );\n\n // execute swap operation\n bytes memory swapResponseData = _executeRoute(\n fsbRequest.swapRouteId,\n fsbRequest.swapData\n );\n\n uint256 swapAmount = abi.decode(swapResponseData, (uint256));\n\n // swapped amount is to be bridged to the recipient on destinationChain\n bytes memory bridgeImpldata = abi.encodeWithSelector(\n BRIDGE_AFTER_SWAP_SELECTOR,\n swapAmount,\n fsbRequest.bridgeData\n );\n\n // execute bridge operation and return the byte-data from response of bridge operation\n return _executeRoute(fsbRequest.bridgeRouteId, bridgeImpldata);\n }\n\n /**\n * @notice function to deduct-fees to fees-taker address on source-chain followed by refuel followed by\n * swap the amount on sourceChain followed by bridging the swapped amount to destinationChain\n * @dev while generating implData for refuel, swap and bridge Requests, ensure correct function selector is used\n * bridge action corresponds to the bridgeAfterSwap function of the bridgeImplementation\n * @param frsbRequest feesTakerRefuelSwapBridgeRequest object generated either off-chain or the calling contract using\n * the function-selector FEES_TAKER_REFUEL_SWAP_BRIDGE_FUNCTION_SELECTOR\n */\n function takeFeeAndRefuelAndSwapAndBridge(\n ISocketRequest.FeesTakerRefuelSwapBridgeRequest calldata frsbRequest\n ) external payable returns (bytes memory) {\n if (frsbRequest.feesToken == NATIVE_TOKEN_ADDRESS) {\n //transfer the native amount to the feeTakerAddress\n payable(frsbRequest.feesTakerAddress).transfer(\n frsbRequest.feesAmount\n );\n } else {\n //transfer feesAmount to feesTakerAddress\n ERC20(frsbRequest.feesToken).safeTransferFrom(\n msg.sender,\n frsbRequest.feesTakerAddress,\n frsbRequest.feesAmount\n );\n }\n\n emit SocketFeesDeducted(\n frsbRequest.feesAmount,\n frsbRequest.feesTakerAddress,\n frsbRequest.feesToken\n );\n\n // refuel is also done via bridge execution via refuelRouteImplementation identified by refuelRouteId\n _executeRoute(frsbRequest.refuelRouteId, frsbRequest.refuelData);\n\n // execute swap operation\n bytes memory swapResponseData = _executeRoute(\n frsbRequest.swapRouteId,\n frsbRequest.swapData\n );\n\n uint256 swapAmount = abi.decode(swapResponseData, (uint256));\n\n // swapped amount is to be bridged to the recipient on destinationChain\n bytes memory bridgeImpldata = abi.encodeWithSelector(\n BRIDGE_AFTER_SWAP_SELECTOR,\n swapAmount,\n frsbRequest.bridgeData\n );\n\n // execute bridge operation and return the byte-data from response of bridge operation\n return _executeRoute(frsbRequest.bridgeRouteId, bridgeImpldata);\n }\n}\n" - }, - "src/errors/SocketErrors.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nerror CelerRefundNotReady();\nerror OnlySocketDeployer();\nerror OnlySocketGatewayOwner();\nerror OnlySocketGateway();\nerror OnlyOwner();\nerror OnlyNominee();\nerror TransferIdExists();\nerror TransferIdDoesnotExist();\nerror Address0Provided();\nerror SwapFailed();\nerror UnsupportedInterfaceId();\nerror InvalidCelerRefund();\nerror CelerAlreadyRefunded();\nerror IncorrectBridgeRatios();\nerror ZeroAddressNotAllowed();\nerror ArrayLengthMismatch();\n" - }, - "src/bridges/hop/l1/HopImplL1.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\nimport \"../interfaces/IHopL1Bridge.sol\";\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {BridgeImplBase} from \"../../BridgeImplBase.sol\";\nimport {HOP} from \"../../../static/RouteIdentifiers.sol\";\n\n/**\n * @title Hop-L1 Route Implementation\n * @notice Route implementation with functions to bridge ERC20 and Native via Hop-Bridge from L1 to Supported L2s\n * Called via SocketGateway if the routeId in the request maps to the routeId of HopImplementation\n * Contains function to handle bridging as post-step i.e linked to a preceeding step for swap\n * RequestData is different to just bride and bridging chained with swap\n * @author Socket dot tech.\n */\ncontract HopImplL1 is BridgeImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable HopIdentifier = HOP;\n\n /// @notice Function-selector for ERC20-token bridging on Hop-L1-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge ERC20 tokens\n bytes4 public immutable HOP_L1_ERC20_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeERC20To(address,address,address,address,uint256,uint256,uint256,uint256,(uint256,bytes32))\"\n )\n );\n\n /// @notice Function-selector for Native bridging on Hop-L1-Route\n /// @dev This function selector is to be used while building transaction-data to bridge Native tokens\n bytes4 public immutable HOP_L1_NATIVE_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeNativeTo(address,address,address,uint256,uint256,uint256,uint256,uint256,bytes32)\"\n )\n );\n\n bytes4 public immutable HOP_L1_SWAP_BRIDGE_SELECTOR =\n bytes4(\n keccak256(\n \"swapAndBridge(uint32,bytes,(address,address,address,uint256,uint256,uint256,uint256,bytes32))\"\n )\n );\n\n /// @notice socketGatewayAddress to be initialised via storage variable BridgeImplBase\n constructor(\n address _socketGateway,\n address _socketDeployFactory\n ) BridgeImplBase(_socketGateway, _socketDeployFactory) {}\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct HopDataNoToken {\n // The address receiving funds at the destination\n address receiverAddress;\n // address of the Hop-L1-Bridge to handle bridging the tokens\n address l1bridgeAddr;\n // relayerFee The amount distributed to the relayer at the destination. This is subtracted from the `_amount`.\n address relayer;\n // The chainId of the destination chain\n uint256 toChainId;\n // The minimum amount received after attempting to swap in the destination AMM market. 0 if no swap is intended.\n uint256 amountOutMin;\n // The amount distributed to the relayer at the destination. This is subtracted from the `amount`.\n uint256 relayerFee;\n // The deadline for swapping in the destination AMM market. 0 if no swap is intended.\n uint256 deadline;\n // socket offchain created hash\n bytes32 metadata;\n }\n\n struct HopData {\n /// @notice address of token being bridged\n address token;\n // The address receiving funds at the destination\n address receiverAddress;\n // address of the Hop-L1-Bridge to handle bridging the tokens\n address l1bridgeAddr;\n // relayerFee The amount distributed to the relayer at the destination. This is subtracted from the `_amount`.\n address relayer;\n // The chainId of the destination chain\n uint256 toChainId;\n // The minimum amount received after attempting to swap in the destination AMM market. 0 if no swap is intended.\n uint256 amountOutMin;\n // The amount distributed to the relayer at the destination. This is subtracted from the `amount`.\n uint256 relayerFee;\n // The deadline for swapping in the destination AMM market. 0 if no swap is intended.\n uint256 deadline;\n // socket offchain created hash\n bytes32 metadata;\n }\n\n struct HopERC20Data {\n uint256 deadline;\n bytes32 metadata;\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from swapAndBridge, this function is called when the swap has already happened at a different place.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in HopBridgeData struct\n * @param amount amount of tokens being bridged. this can be ERC20 or native\n * @param bridgeData encoded data for Hop-L1-Bridge\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable override {\n HopData memory hopData = abi.decode(bridgeData, (HopData));\n\n if (hopData.token == NATIVE_TOKEN_ADDRESS) {\n IHopL1Bridge(hopData.l1bridgeAddr).sendToL2{value: amount}(\n hopData.toChainId,\n hopData.receiverAddress,\n amount,\n hopData.amountOutMin,\n hopData.deadline,\n hopData.relayer,\n hopData.relayerFee\n );\n } else {\n ERC20(hopData.token).safeApprove(hopData.l1bridgeAddr, amount);\n\n // perform bridging\n IHopL1Bridge(hopData.l1bridgeAddr).sendToL2(\n hopData.toChainId,\n hopData.receiverAddress,\n amount,\n hopData.amountOutMin,\n hopData.deadline,\n hopData.relayer,\n hopData.relayerFee\n );\n }\n\n emit SocketBridge(\n amount,\n hopData.token,\n hopData.toChainId,\n HopIdentifier,\n msg.sender,\n hopData.receiverAddress,\n hopData.metadata\n );\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from bridgeAfterSwap since this function holds the logic for swapping tokens too.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in HopBridgeData struct\n * @param swapId routeId for the swapImpl\n * @param swapData encoded data for swap\n * @param hopData encoded data for HopData\n */\n function swapAndBridge(\n uint32 swapId,\n bytes calldata swapData,\n HopDataNoToken calldata hopData\n ) external payable {\n (bool success, bytes memory result) = socketRoute\n .getRoute(swapId)\n .delegatecall(swapData);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n (uint256 bridgeAmount, address token) = abi.decode(\n result,\n (uint256, address)\n );\n\n if (token == NATIVE_TOKEN_ADDRESS) {\n IHopL1Bridge(hopData.l1bridgeAddr).sendToL2{value: bridgeAmount}(\n hopData.toChainId,\n hopData.receiverAddress,\n bridgeAmount,\n hopData.amountOutMin,\n hopData.deadline,\n hopData.relayer,\n hopData.relayerFee\n );\n } else {\n ERC20(token).safeApprove(hopData.l1bridgeAddr, bridgeAmount);\n\n // perform bridging\n IHopL1Bridge(hopData.l1bridgeAddr).sendToL2(\n hopData.toChainId,\n hopData.receiverAddress,\n bridgeAmount,\n hopData.amountOutMin,\n hopData.deadline,\n hopData.relayer,\n hopData.relayerFee\n );\n }\n\n emit SocketBridge(\n bridgeAmount,\n token,\n hopData.toChainId,\n HopIdentifier,\n msg.sender,\n hopData.receiverAddress,\n hopData.metadata\n );\n }\n\n /**\n * @notice function to handle ERC20 bridging to receipent via Hop-L1-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param receiverAddress The address receiving funds at the destination\n * @param token token being bridged\n * @param l1bridgeAddr address of the Hop-L1-Bridge to handle bridging the tokens\n * @param relayer The amount distributed to the relayer at the destination. This is subtracted from the `_amount`.\n * @param toChainId The chainId of the destination chain\n * @param amount The amount being sent\n * @param amountOutMin The minimum amount received after attempting to swap in the destination AMM market. 0 if no swap is intended.\n * @param relayerFee The amount distributed to the relayer at the destination. This is subtracted from the `amount`.\n * @param hopData extra data needed to build the tx\n */\n function bridgeERC20To(\n address receiverAddress,\n address token,\n address l1bridgeAddr,\n address relayer,\n uint256 toChainId,\n uint256 amount,\n uint256 amountOutMin,\n uint256 relayerFee,\n HopERC20Data calldata hopData\n ) external payable {\n ERC20 tokenInstance = ERC20(token);\n tokenInstance.safeTransferFrom(msg.sender, socketGateway, amount);\n tokenInstance.safeApprove(l1bridgeAddr, amount);\n\n // perform bridging\n IHopL1Bridge(l1bridgeAddr).sendToL2(\n toChainId,\n receiverAddress,\n amount,\n amountOutMin,\n hopData.deadline,\n relayer,\n relayerFee\n );\n\n emit SocketBridge(\n amount,\n token,\n toChainId,\n HopIdentifier,\n msg.sender,\n receiverAddress,\n hopData.metadata\n );\n }\n\n /**\n * @notice function to handle Native bridging to receipent via Hop-L1-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param receiverAddress The address receiving funds at the destination\n * @param l1bridgeAddr address of the Hop-L1-Bridge to handle bridging the tokens\n * @param relayer The amount distributed to the relayer at the destination. This is subtracted from the `_amount`.\n * @param toChainId The chainId of the destination chain\n * @param amount The amount being sent\n * @param amountOutMin The minimum amount received after attempting to swap in the destination AMM market. 0 if no swap is intended.\n * @param relayerFee The amount distributed to the relayer at the destination. This is subtracted from the `amount`.\n * @param deadline The deadline for swapping in the destination AMM market. 0 if no swap is intended.\n */\n function bridgeNativeTo(\n address receiverAddress,\n address l1bridgeAddr,\n address relayer,\n uint256 toChainId,\n uint256 amount,\n uint256 amountOutMin,\n uint256 relayerFee,\n uint256 deadline,\n bytes32 metadata\n ) external payable {\n IHopL1Bridge(l1bridgeAddr).sendToL2{value: amount}(\n toChainId,\n receiverAddress,\n amount,\n amountOutMin,\n deadline,\n relayer,\n relayerFee\n );\n\n emit SocketBridge(\n amount,\n NATIVE_TOKEN_ADDRESS,\n toChainId,\n HopIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n}\n" - }, - "src/static/RouteIdentifiers.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\nbytes32 constant ACROSS = keccak256(\"Across\");\n\nbytes32 constant ANYSWAP = keccak256(\"Anyswap\");\n\nbytes32 constant CBRIDGE = keccak256(\"CBridge\");\n\nbytes32 constant HOP = keccak256(\"Hop\");\n\nbytes32 constant HYPHEN = keccak256(\"Hyphen\");\n\nbytes32 constant NATIVE_OPTIMISM = keccak256(\"NativeOptimism\");\n\nbytes32 constant NATIVE_ARBITRUM = keccak256(\"NativeArbitrum\");\n\nbytes32 constant NATIVE_POLYGON = keccak256(\"NativePolygon\");\n\nbytes32 constant REFUEL = keccak256(\"Refuel\");\n\nbytes32 constant STARGATE = keccak256(\"Stargate\");\n\nbytes32 constant ONEINCH = keccak256(\"OneInch\");\n\nbytes32 constant ZEROX = keccak256(\"Zerox\");\n\nbytes32 constant RAINBOW = keccak256(\"Rainbow\");\n" - }, - "src/SocketGateway.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\npragma experimental ABIEncoderV2;\n\nimport \"./utils/Ownable.sol\";\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {LibUtil} from \"./libraries/LibUtil.sol\";\nimport \"./libraries/LibBytes.sol\";\nimport {ISocketRoute} from \"./interfaces/ISocketRoute.sol\";\nimport {ISocketRequest} from \"./interfaces/ISocketRequest.sol\";\nimport {ISocketGateway} from \"./interfaces/ISocketGateway.sol\";\nimport {IncorrectBridgeRatios, ZeroAddressNotAllowed, ArrayLengthMismatch} from \"./errors/SocketErrors.sol\";\n\n/// @title SocketGatewayContract\n/// @notice Socketgateway is a contract with entrypoint functions for all interactions with socket liquidity layer\n/// @author Socket Team\ncontract SocketGatewayTemplate is Ownable {\n using LibBytes for bytes;\n using LibBytes for bytes4;\n using SafeTransferLib for ERC20;\n\n /// @notice FunctionSelector used to delegatecall from swap to the function of bridge router implementation\n bytes4 public immutable BRIDGE_AFTER_SWAP_SELECTOR =\n bytes4(keccak256(\"bridgeAfterSwap(uint256,bytes)\"));\n\n /// @notice storage variable to keep track of total number of routes registered in socketgateway\n uint32 public routesCount = 385;\n\n /// @notice storage variable to keep track of total number of controllers registered in socketgateway\n uint32 public controllerCount;\n\n address public immutable disabledRouteAddress;\n\n uint256 public constant CENT_PERCENT = 100e18;\n\n /// @notice storage mapping for route implementation addresses\n mapping(uint32 => address) public routes;\n\n /// storage mapping for controller implemenation addresses\n mapping(uint32 => address) public controllers;\n\n // Events ------------------------------------------------------------------------------------------------------->\n\n /// @notice Event emitted when a router is added to socketgateway\n event NewRouteAdded(uint32 indexed routeId, address indexed route);\n\n /// @notice Event emitted when a route is disabled\n event RouteDisabled(uint32 indexed routeId);\n\n /// @notice Event emitted when ownership transfer is requested by socket-gateway-owner\n event OwnershipTransferRequested(\n address indexed _from,\n address indexed _to\n );\n\n /// @notice Event emitted when a controller is added to socketgateway\n event ControllerAdded(\n uint32 indexed controllerId,\n address indexed controllerAddress\n );\n\n /// @notice Event emitted when a controller is disabled\n event ControllerDisabled(uint32 indexed controllerId);\n\n constructor(address _owner, address _disabledRoute) Ownable(_owner) {\n disabledRouteAddress = _disabledRoute;\n }\n\n // Able to receive ether\n // solhint-disable-next-line no-empty-blocks\n receive() external payable {}\n\n /*******************************************\n * EXTERNAL AND PUBLIC FUNCTIONS *\n *******************************************/\n\n /**\n * @notice executes functions in the routes identified using routeId and functionSelectorData\n * @notice The caller must first approve this contract to spend amount of ERC20-Token being bridged/swapped\n * @dev ensure the data in routeData to be built using the function-selector defined as a\n * constant in the route implementation contract\n * @param routeId route identifier\n * @param routeData functionSelectorData generated using the function-selector defined in the route Implementation\n */\n function executeRoute(\n uint32 routeId,\n bytes calldata routeData\n ) external payable returns (bytes memory) {\n (bool success, bytes memory result) = addressAt(routeId).delegatecall(\n routeData\n );\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n return result;\n }\n\n /**\n * @notice swaps a token on sourceChain and split it across multiple bridge-recipients\n * @notice The caller must first approve this contract to spend amount of ERC20-Token being swapped\n * @dev ensure the swap-data and bridge-data is generated using the function-selector defined as a constant in the implementation address\n * @param swapMultiBridgeRequest request\n */\n function swapAndMultiBridge(\n ISocketRequest.SwapMultiBridgeRequest calldata swapMultiBridgeRequest\n ) external payable {\n uint256 requestLength = swapMultiBridgeRequest.bridgeRouteIds.length;\n\n if (\n requestLength != swapMultiBridgeRequest.bridgeImplDataItems.length\n ) {\n revert ArrayLengthMismatch();\n }\n uint256 ratioAggregate;\n for (uint256 index = 0; index < requestLength; ) {\n ratioAggregate += swapMultiBridgeRequest.bridgeRatios[index];\n }\n\n if (ratioAggregate != CENT_PERCENT) {\n revert IncorrectBridgeRatios();\n }\n\n (bool swapSuccess, bytes memory swapResult) = addressAt(\n swapMultiBridgeRequest.swapRouteId\n ).delegatecall(swapMultiBridgeRequest.swapImplData);\n\n if (!swapSuccess) {\n assembly {\n revert(add(swapResult, 32), mload(swapResult))\n }\n }\n\n uint256 amountReceivedFromSwap = abi.decode(swapResult, (uint256));\n\n uint256 bridgedAmount;\n\n for (uint256 index = 0; index < requestLength; ) {\n uint256 bridgingAmount;\n\n // if it is the last bridge request, bridge the remaining amount\n if (index == requestLength - 1) {\n bridgingAmount = amountReceivedFromSwap - bridgedAmount;\n } else {\n // bridging amount is the multiplication of bridgeRatio and amountReceivedFromSwap\n bridgingAmount =\n (amountReceivedFromSwap *\n swapMultiBridgeRequest.bridgeRatios[index]) /\n (CENT_PERCENT);\n }\n\n // update the bridged amount, this would be used for computation for last bridgeRequest\n bridgedAmount += bridgingAmount;\n\n bytes memory bridgeImpldata = abi.encodeWithSelector(\n BRIDGE_AFTER_SWAP_SELECTOR,\n bridgingAmount,\n swapMultiBridgeRequest.bridgeImplDataItems[index]\n );\n\n (bool bridgeSuccess, bytes memory bridgeResult) = addressAt(\n swapMultiBridgeRequest.bridgeRouteIds[index]\n ).delegatecall(bridgeImpldata);\n\n if (!bridgeSuccess) {\n assembly {\n revert(add(bridgeResult, 32), mload(bridgeResult))\n }\n }\n\n unchecked {\n ++index;\n }\n }\n }\n\n /**\n * @notice sequentially executes functions in the routes identified using routeId and functionSelectorData\n * @notice The caller must first approve this contract to spend amount of ERC20-Token being bridged/swapped\n * @dev ensure the data in each dataItem to be built using the function-selector defined as a\n * constant in the route implementation contract\n * @param routeIds a list of route identifiers\n * @param dataItems a list of functionSelectorData generated using the function-selector defined in the route Implementation\n */\n function executeRoutes(\n uint32[] calldata routeIds,\n bytes[] calldata dataItems\n ) external payable {\n uint256 routeIdslength = routeIds.length;\n if (routeIdslength != dataItems.length) revert ArrayLengthMismatch();\n for (uint256 index = 0; index < routeIdslength; ) {\n (bool success, bytes memory result) = addressAt(routeIds[index])\n .delegatecall(dataItems[index]);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n unchecked {\n ++index;\n }\n }\n }\n\n /**\n * @notice execute a controller function identified using the controllerId in the request\n * @notice The caller must first approve this contract to spend amount of ERC20-Token being bridged/swapped\n * @dev ensure the data in request to be built using the function-selector defined as a\n * constant in the controller implementation contract\n * @param socketControllerRequest socketControllerRequest with controllerId to identify the\n * controllerAddress and byteData constructed using functionSelector\n * of the function being invoked\n * @return bytes data received from the call delegated to controller\n */\n function executeController(\n ISocketGateway.SocketControllerRequest calldata socketControllerRequest\n ) external payable returns (bytes memory) {\n (bool success, bytes memory result) = controllers[\n socketControllerRequest.controllerId\n ].delegatecall(socketControllerRequest.data);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n return result;\n }\n\n /**\n * @notice sequentially executes all controller requests\n * @notice The caller must first approve this contract to spend amount of ERC20-Token being bridged/swapped\n * @dev ensure the data in each controller-request to be built using the function-selector defined as a\n * constant in the controller implementation contract\n * @param controllerRequests a list of socketControllerRequest\n * Each controllerRequest contains controllerId to identify the controllerAddress and\n * byteData constructed using functionSelector of the function being invoked\n */\n function executeControllers(\n ISocketGateway.SocketControllerRequest[] calldata controllerRequests\n ) external payable {\n for (uint32 index = 0; index < controllerRequests.length; ) {\n (bool success, bytes memory result) = controllers[\n controllerRequests[index].controllerId\n ].delegatecall(controllerRequests[index].data);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n unchecked {\n ++index;\n }\n }\n }\n\n /**************************************\n * ADMIN FUNCTIONS *\n **************************************/\n\n /**\n * @notice Add route to the socketGateway\n This is a restricted function to be called by only socketGatewayOwner\n * @dev ensure routeAddress is a verified bridge or middleware implementation address\n * @param routeAddress The address of bridge or middleware implementation contract deployed\n * @return Id of the route added to the routes-mapping in socketGateway storage\n */\n function addRoute(\n address routeAddress\n ) external onlyOwner returns (uint32) {\n uint32 routeId = routesCount;\n routes[routeId] = routeAddress;\n\n routesCount += 1;\n\n emit NewRouteAdded(routeId, routeAddress);\n\n return routeId;\n }\n\n /**\n * @notice Give Infinite or 0 approval to bridgeRoute for the tokenAddress\n This is a restricted function to be called by only socketGatewayOwner\n */\n\n function setApprovalForRouters(\n address[] memory routeAddresses,\n address[] memory tokenAddresses,\n bool isMax\n ) external onlyOwner {\n for (uint32 index = 0; index < routeAddresses.length; ) {\n ERC20(tokenAddresses[index]).approve(\n routeAddresses[index],\n isMax ? type(uint256).max : 0\n );\n unchecked {\n ++index;\n }\n }\n }\n\n /**\n * @notice Add controller to the socketGateway\n This is a restricted function to be called by only socketGatewayOwner\n * @dev ensure controllerAddress is a verified controller implementation address\n * @param controllerAddress The address of controller implementation contract deployed\n * @return Id of the controller added to the controllers-mapping in socketGateway storage\n */\n function addController(\n address controllerAddress\n ) external onlyOwner returns (uint32) {\n uint32 controllerId = controllerCount;\n\n controllers[controllerId] = controllerAddress;\n\n controllerCount += 1;\n\n emit ControllerAdded(controllerId, controllerAddress);\n\n return controllerId;\n }\n\n /**\n * @notice disable controller by setting ZeroAddress to the entry in controllers-mapping\n identified by controllerId as key.\n This is a restricted function to be called by only socketGatewayOwner\n * @param controllerId The Id of controller-implementation in the controllers mapping\n */\n function disableController(uint32 controllerId) public onlyOwner {\n controllers[controllerId] = disabledRouteAddress;\n emit ControllerDisabled(controllerId);\n }\n\n /**\n * @notice disable a route by setting ZeroAddress to the entry in routes-mapping\n identified by routeId as key.\n This is a restricted function to be called by only socketGatewayOwner\n * @param routeId The Id of route-implementation in the routes mapping\n */\n function disableRoute(uint32 routeId) external onlyOwner {\n routes[routeId] = disabledRouteAddress;\n emit RouteDisabled(routeId);\n }\n\n /*******************************************\n * RESTRICTED RESCUE FUNCTIONS *\n *******************************************/\n\n /**\n * @notice Rescues the ERC20 token to an address\n this is a restricted function to be called by only socketGatewayOwner\n * @dev as this is a restricted to socketGatewayOwner, ensure the userAddress is a known address\n * @param token address of the ERC20 token being rescued\n * @param userAddress address to which ERC20 is to be rescued\n * @param amount amount of ERC20 tokens being rescued\n */\n function rescueFunds(\n address token,\n address userAddress,\n uint256 amount\n ) external onlyOwner {\n ERC20(token).safeTransfer(userAddress, amount);\n }\n\n /**\n * @notice Rescues the native balance to an address\n this is a restricted function to be called by only socketGatewayOwner\n * @dev as this is a restricted to socketGatewayOwner, ensure the userAddress is a known address\n * @param userAddress address to which native-balance is to be rescued\n * @param amount amount of native-balance being rescued\n */\n function rescueEther(\n address payable userAddress,\n uint256 amount\n ) external onlyOwner {\n userAddress.transfer(amount);\n }\n\n /*******************************************\n * VIEW FUNCTIONS *\n *******************************************/\n\n /**\n * @notice Get routeImplementation address mapped to the routeId\n * @param routeId routeId is the key in the mapping for routes\n * @return route-implementation address\n */\n function getRoute(uint32 routeId) public view returns (address) {\n return addressAt(routeId);\n }\n\n /**\n * @notice Get controllerImplementation address mapped to the controllerId\n * @param controllerId controllerId is the key in the mapping for controllers\n * @return controller-implementation address\n */\n function getController(uint32 controllerId) public view returns (address) {\n return controllers[controllerId];\n }\n\n function addressAt(uint32 routeId) public view returns (address) {\n if (routeId < 385) {\n if (routeId < 257) {\n if (routeId < 129) {\n if (routeId < 65) {\n if (routeId < 33) {\n if (routeId < 17) {\n if (routeId < 9) {\n if (routeId < 5) {\n if (routeId < 3) {\n if (routeId == 1) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 3) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 7) {\n if (routeId == 5) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 7) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 13) {\n if (routeId < 11) {\n if (routeId == 9) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 11) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 15) {\n if (routeId == 13) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 15) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n } else {\n if (routeId < 25) {\n if (routeId < 21) {\n if (routeId < 19) {\n if (routeId == 17) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 19) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 23) {\n if (routeId == 21) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 23) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 29) {\n if (routeId < 27) {\n if (routeId == 25) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 27) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 31) {\n if (routeId == 29) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 31) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n }\n } else {\n if (routeId < 49) {\n if (routeId < 41) {\n if (routeId < 37) {\n if (routeId < 35) {\n if (routeId == 33) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 35) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 39) {\n if (routeId == 37) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 39) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 45) {\n if (routeId < 43) {\n if (routeId == 41) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 43) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 47) {\n if (routeId == 45) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 47) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n } else {\n if (routeId < 57) {\n if (routeId < 53) {\n if (routeId < 51) {\n if (routeId == 49) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 51) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 55) {\n if (routeId == 53) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 55) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 61) {\n if (routeId < 59) {\n if (routeId == 57) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 59) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 63) {\n if (routeId == 61) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 63) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n }\n }\n } else {\n if (routeId < 97) {\n if (routeId < 81) {\n if (routeId < 73) {\n if (routeId < 69) {\n if (routeId < 67) {\n if (routeId == 65) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 67) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 71) {\n if (routeId == 69) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 71) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 77) {\n if (routeId < 75) {\n if (routeId == 73) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 75) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 79) {\n if (routeId == 77) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 79) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n } else {\n if (routeId < 89) {\n if (routeId < 85) {\n if (routeId < 83) {\n if (routeId == 81) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 83) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 87) {\n if (routeId == 85) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 87) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 93) {\n if (routeId < 91) {\n if (routeId == 89) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 91) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 95) {\n if (routeId == 93) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 95) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n }\n } else {\n if (routeId < 113) {\n if (routeId < 105) {\n if (routeId < 101) {\n if (routeId < 99) {\n if (routeId == 97) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 99) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 103) {\n if (routeId == 101) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 103) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 109) {\n if (routeId < 107) {\n if (routeId == 105) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 107) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 111) {\n if (routeId == 109) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 111) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n } else {\n if (routeId < 121) {\n if (routeId < 117) {\n if (routeId < 115) {\n if (routeId == 113) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 115) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 119) {\n if (routeId == 117) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 119) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 125) {\n if (routeId < 123) {\n if (routeId == 121) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 123) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 127) {\n if (routeId == 125) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 127) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n }\n }\n }\n } else {\n if (routeId < 193) {\n if (routeId < 161) {\n if (routeId < 145) {\n if (routeId < 137) {\n if (routeId < 133) {\n if (routeId < 131) {\n if (routeId == 129) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 131) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 135) {\n if (routeId == 133) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 135) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 141) {\n if (routeId < 139) {\n if (routeId == 137) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 139) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 143) {\n if (routeId == 141) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 143) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n } else {\n if (routeId < 153) {\n if (routeId < 149) {\n if (routeId < 147) {\n if (routeId == 145) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 147) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 151) {\n if (routeId == 149) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 151) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 157) {\n if (routeId < 155) {\n if (routeId == 153) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 155) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 159) {\n if (routeId == 157) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 159) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n }\n } else {\n if (routeId < 177) {\n if (routeId < 169) {\n if (routeId < 165) {\n if (routeId < 163) {\n if (routeId == 161) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 163) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 167) {\n if (routeId == 165) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 167) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 173) {\n if (routeId < 171) {\n if (routeId == 169) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 171) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 175) {\n if (routeId == 173) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 175) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n } else {\n if (routeId < 185) {\n if (routeId < 181) {\n if (routeId < 179) {\n if (routeId == 177) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 179) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 183) {\n if (routeId == 181) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 183) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 189) {\n if (routeId < 187) {\n if (routeId == 185) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 187) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 191) {\n if (routeId == 189) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 191) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n }\n }\n } else {\n if (routeId < 225) {\n if (routeId < 209) {\n if (routeId < 201) {\n if (routeId < 197) {\n if (routeId < 195) {\n if (routeId == 193) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 195) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 199) {\n if (routeId == 197) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 199) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 205) {\n if (routeId < 203) {\n if (routeId == 201) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 203) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 207) {\n if (routeId == 205) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 207) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n } else {\n if (routeId < 217) {\n if (routeId < 213) {\n if (routeId < 211) {\n if (routeId == 209) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 211) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 215) {\n if (routeId == 213) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 215) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 221) {\n if (routeId < 219) {\n if (routeId == 217) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 219) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 223) {\n if (routeId == 221) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 223) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n }\n } else {\n if (routeId < 241) {\n if (routeId < 233) {\n if (routeId < 229) {\n if (routeId < 227) {\n if (routeId == 225) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 227) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 231) {\n if (routeId == 229) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 231) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 237) {\n if (routeId < 235) {\n if (routeId == 233) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 235) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 239) {\n if (routeId == 237) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 239) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n } else {\n if (routeId < 249) {\n if (routeId < 245) {\n if (routeId < 243) {\n if (routeId == 241) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 243) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 247) {\n if (routeId == 245) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 247) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 253) {\n if (routeId < 251) {\n if (routeId == 249) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 251) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 255) {\n if (routeId == 253) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 255) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n if (routeId < 321) {\n if (routeId < 289) {\n if (routeId < 273) {\n if (routeId < 265) {\n if (routeId < 261) {\n if (routeId < 259) {\n if (routeId == 257) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 259) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 263) {\n if (routeId == 261) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 263) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 269) {\n if (routeId < 267) {\n if (routeId == 265) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 267) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 271) {\n if (routeId == 269) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 271) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n } else {\n if (routeId < 281) {\n if (routeId < 277) {\n if (routeId < 275) {\n if (routeId == 273) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 275) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 279) {\n if (routeId == 277) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 279) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 285) {\n if (routeId < 283) {\n if (routeId == 281) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 283) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 287) {\n if (routeId == 285) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 287) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n }\n } else {\n if (routeId < 305) {\n if (routeId < 297) {\n if (routeId < 293) {\n if (routeId < 291) {\n if (routeId == 289) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 291) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 295) {\n if (routeId == 293) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 295) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 301) {\n if (routeId < 299) {\n if (routeId == 297) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 299) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 303) {\n if (routeId == 301) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 303) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n } else {\n if (routeId < 313) {\n if (routeId < 309) {\n if (routeId < 307) {\n if (routeId == 305) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 307) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 311) {\n if (routeId == 309) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 311) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 317) {\n if (routeId < 315) {\n if (routeId == 313) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 315) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 319) {\n if (routeId == 317) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 319) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n }\n }\n } else {\n if (routeId < 353) {\n if (routeId < 337) {\n if (routeId < 329) {\n if (routeId < 325) {\n if (routeId < 323) {\n if (routeId == 321) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 323) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 327) {\n if (routeId == 325) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 327) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 333) {\n if (routeId < 331) {\n if (routeId == 329) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 331) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 335) {\n if (routeId == 333) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 335) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n } else {\n if (routeId < 345) {\n if (routeId < 341) {\n if (routeId < 339) {\n if (routeId == 337) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 339) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 343) {\n if (routeId == 341) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 343) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 349) {\n if (routeId < 347) {\n if (routeId == 345) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 347) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 351) {\n if (routeId == 349) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 351) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n }\n } else {\n if (routeId < 369) {\n if (routeId < 361) {\n if (routeId < 357) {\n if (routeId < 355) {\n if (routeId == 353) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 355) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 359) {\n if (routeId == 357) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 359) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 365) {\n if (routeId < 363) {\n if (routeId == 361) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 363) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 367) {\n if (routeId == 365) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 367) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n } else {\n if (routeId < 377) {\n if (routeId < 373) {\n if (routeId < 371) {\n if (routeId == 369) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 371) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 375) {\n if (routeId == 373) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 375) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 381) {\n if (routeId < 379) {\n if (routeId == 377) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 379) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 383) {\n if (routeId == 381) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 383) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n }\n }\n }\n }\n }\n\n if (routes[routeId] == address(0)) revert ZeroAddressNotAllowed();\n return routes[routeId];\n }\n\n /// @notice fallback function to handle swap, bridge execution\n /// @dev ensure routeId is converted to bytes4 and sent as msg.sig in the transaction\n fallback() external payable {\n address routeAddress = addressAt(uint32(msg.sig));\n\n bytes memory result;\n\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 4, sub(calldatasize(), 4))\n // execute function call using the facet\n result := delegatecall(\n gas(),\n routeAddress,\n 0,\n sub(calldatasize(), 4),\n 0,\n 0\n )\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n}\n" - }, - "src/swap/rainbow/Rainbow.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport \"../SwapImplBase.sol\";\nimport {Address0Provided, SwapFailed} from \"../../errors/SocketErrors.sol\";\nimport {RAINBOW} from \"../../static/RouteIdentifiers.sol\";\n\n/**\n * @title Rainbow-Swap-Route Implementation\n * @notice Route implementation with functions to swap tokens via Rainbow-Swap\n * Called via SocketGateway if the routeId in the request maps to the routeId of RainbowImplementation\n * @author Socket dot tech.\n */\ncontract RainbowSwapImpl is SwapImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable RainbowIdentifier = RAINBOW;\n\n /// @notice unique name to identify the router, used to emit event upon successful bridging\n bytes32 public immutable NAME = keccak256(\"Rainbow-Router\");\n\n /// @notice address of rainbow-swap-aggregator to swap the tokens on Chain\n address payable public immutable rainbowSwapAggregator;\n\n /// @notice socketGatewayAddress to be initialised via storage variable SwapImplBase\n /// @notice rainbow swap aggregator contract is payable to allow ethereum swaps\n /// @dev ensure _rainbowSwapAggregator are set properly for the chainId in which the contract is being deployed\n constructor(\n address _rainbowSwapAggregator,\n address _socketGateway,\n address _socketDeployFactory\n ) SwapImplBase(_socketGateway, _socketDeployFactory) {\n rainbowSwapAggregator = payable(_rainbowSwapAggregator);\n }\n\n receive() external payable {}\n\n fallback() external payable {}\n\n /**\n * @notice function to swap tokens on the chain and transfer to receiver address\n * @notice This method is payable because the caller is doing token transfer and swap operation\n * @param fromToken address of token being Swapped\n * @param toToken address of token that recipient will receive after swap\n * @param amount amount of fromToken being swapped\n * @param receiverAddress recipient-address\n * @param swapExtraData additional Data to perform Swap via Rainbow-Aggregator\n * @return swapped amount (in toToken Address)\n */\n function performAction(\n address fromToken,\n address toToken,\n uint256 amount,\n address receiverAddress,\n bytes calldata swapExtraData\n ) external payable override returns (uint256) {\n if (fromToken == address(0)) {\n revert Address0Provided();\n }\n\n bytes memory swapCallData = abi.decode(swapExtraData, (bytes));\n\n uint256 _initialBalanceTokenOut;\n uint256 _finalBalanceTokenOut;\n\n ERC20 toTokenERC20 = ERC20(toToken);\n if (toToken != NATIVE_TOKEN_ADDRESS) {\n _initialBalanceTokenOut = toTokenERC20.balanceOf(socketGateway);\n } else {\n _initialBalanceTokenOut = address(this).balance;\n }\n\n if (fromToken != NATIVE_TOKEN_ADDRESS) {\n ERC20 token = ERC20(fromToken);\n token.safeTransferFrom(msg.sender, socketGateway, amount);\n token.safeApprove(rainbowSwapAggregator, amount);\n\n // solhint-disable-next-line\n (bool success, ) = rainbowSwapAggregator.call(swapCallData);\n\n if (!success) {\n revert SwapFailed();\n }\n\n token.safeApprove(rainbowSwapAggregator, 0);\n } else {\n (bool success, ) = rainbowSwapAggregator.call{value: amount}(\n swapCallData\n );\n if (!success) {\n revert SwapFailed();\n }\n }\n\n if (toToken != NATIVE_TOKEN_ADDRESS) {\n _finalBalanceTokenOut = toTokenERC20.balanceOf(socketGateway);\n } else {\n _finalBalanceTokenOut = address(this).balance;\n }\n\n uint256 returnAmount = _finalBalanceTokenOut - _initialBalanceTokenOut;\n\n if (toToken == NATIVE_TOKEN_ADDRESS) {\n payable(receiverAddress).transfer(returnAmount);\n } else {\n toTokenERC20.transfer(receiverAddress, returnAmount);\n }\n\n emit SocketSwapTokens(\n fromToken,\n toToken,\n returnAmount,\n amount,\n RainbowIdentifier,\n receiverAddress\n );\n\n return returnAmount;\n }\n\n /**\n * @notice function to swapWithIn SocketGateway - swaps tokens on the chain to socketGateway as recipient\n * @param fromToken token to be swapped\n * @param toToken token to which fromToken has to be swapped\n * @param amount amount of fromToken being swapped\n * @param swapExtraData encoded value of properties in the swapData Struct\n * @return swapped amount (in toToken Address)\n */\n function performActionWithIn(\n address fromToken,\n address toToken,\n uint256 amount,\n bytes calldata swapExtraData\n ) external payable override returns (uint256, address) {\n if (fromToken == address(0)) {\n revert Address0Provided();\n }\n\n bytes memory swapCallData = abi.decode(swapExtraData, (bytes));\n\n uint256 _initialBalanceTokenOut;\n uint256 _finalBalanceTokenOut;\n\n ERC20 toTokenERC20 = ERC20(toToken);\n if (toToken != NATIVE_TOKEN_ADDRESS) {\n _initialBalanceTokenOut = toTokenERC20.balanceOf(socketGateway);\n } else {\n _initialBalanceTokenOut = address(this).balance;\n }\n\n if (fromToken != NATIVE_TOKEN_ADDRESS) {\n ERC20 token = ERC20(fromToken);\n token.safeTransferFrom(msg.sender, socketGateway, amount);\n token.safeApprove(rainbowSwapAggregator, amount);\n\n // solhint-disable-next-line\n (bool success, ) = rainbowSwapAggregator.call(swapCallData);\n\n if (!success) {\n revert SwapFailed();\n }\n\n token.safeApprove(rainbowSwapAggregator, 0);\n } else {\n (bool success, ) = rainbowSwapAggregator.call{value: amount}(\n swapCallData\n );\n if (!success) {\n revert SwapFailed();\n }\n }\n\n if (toToken != NATIVE_TOKEN_ADDRESS) {\n _finalBalanceTokenOut = toTokenERC20.balanceOf(socketGateway);\n } else {\n _finalBalanceTokenOut = address(this).balance;\n }\n\n uint256 returnAmount = _finalBalanceTokenOut - _initialBalanceTokenOut;\n\n emit SocketSwapTokens(\n fromToken,\n toToken,\n returnAmount,\n amount,\n RainbowIdentifier,\n socketGateway\n );\n\n return (returnAmount, toToken);\n }\n}\n" - }, - "src/interfaces/ISocketBridgeBase.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface ISocketBridgeBase {\n function killme() external;\n}\n" - }, - "src/interfaces/ISocketRequest.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/**\n * @title ISocketRoute\n * @notice Interface with Request DataStructures to invoke controller functions.\n * @author Socket dot tech.\n */\ninterface ISocketRequest {\n struct SwapMultiBridgeRequest {\n uint32 swapRouteId;\n bytes swapImplData;\n uint32[] bridgeRouteIds;\n bytes[] bridgeImplDataItems;\n uint256[] bridgeRatios;\n bytes[] eventDataItems;\n }\n\n // Datastructure for Refuel-Swap-Bridge function\n struct RefuelSwapBridgeRequest {\n uint32 refuelRouteId;\n bytes refuelData;\n uint32 swapRouteId;\n bytes swapData;\n uint32 bridgeRouteId;\n bytes bridgeData;\n }\n\n // Datastructure for DeductFees-Swap function\n struct FeesTakerSwapRequest {\n address feesTakerAddress;\n address feesToken;\n uint256 feesAmount;\n uint32 routeId;\n bytes swapRequestData;\n }\n\n // Datastructure for DeductFees-Bridge function\n struct FeesTakerBridgeRequest {\n address feesTakerAddress;\n address feesToken;\n uint256 feesAmount;\n uint32 routeId;\n bytes bridgeRequestData;\n }\n\n // Datastructure for DeductFees-MultiBridge function\n struct FeesTakerMultiBridgeRequest {\n address feesTakerAddress;\n address feesToken;\n uint256 feesAmount;\n uint32[] bridgeRouteIds;\n bytes[] bridgeRequestDataItems;\n }\n\n // Datastructure for DeductFees-Swap-Bridge function\n struct FeesTakerSwapBridgeRequest {\n address feesTakerAddress;\n address feesToken;\n uint256 feesAmount;\n uint32 swapRouteId;\n bytes swapData;\n uint32 bridgeRouteId;\n bytes bridgeData;\n }\n\n // Datastructure for DeductFees-Refuel-Swap-Bridge function\n struct FeesTakerRefuelSwapBridgeRequest {\n address feesTakerAddress;\n address feesToken;\n uint256 feesAmount;\n uint32 refuelRouteId;\n bytes refuelData;\n uint32 swapRouteId;\n bytes swapData;\n uint32 bridgeRouteId;\n bytes bridgeData;\n }\n}\n" - }, - "src/utils/Ownable.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.4;\n\nimport {OnlyOwner, OnlyNominee} from \"../errors/SocketErrors.sol\";\n\nabstract contract Ownable {\n address private _owner;\n address private _nominee;\n\n event OwnerNominated(address indexed nominee);\n event OwnerClaimed(address indexed claimer);\n\n constructor(address owner_) {\n _claimOwner(owner_);\n }\n\n modifier onlyOwner() {\n if (msg.sender != _owner) {\n revert OnlyOwner();\n }\n _;\n }\n\n function owner() public view returns (address) {\n return _owner;\n }\n\n function nominee() public view returns (address) {\n return _nominee;\n }\n\n function nominateOwner(address nominee_) external {\n if (msg.sender != _owner) {\n revert OnlyOwner();\n }\n _nominee = nominee_;\n emit OwnerNominated(_nominee);\n }\n\n function claimOwner() external {\n if (msg.sender != _nominee) {\n revert OnlyNominee();\n }\n _claimOwner(msg.sender);\n }\n\n function _claimOwner(address claimer_) internal {\n _owner = claimer_;\n _nominee = address(0);\n emit OwnerClaimed(claimer_);\n }\n}\n" - }, - "lib/solmate/src/tokens/ERC20.sol": { - "content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.\n/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)\n/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)\n/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.\nabstract contract ERC20 {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event Transfer(address indexed from, address indexed to, uint256 amount);\n\n event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n /*//////////////////////////////////////////////////////////////\n METADATA STORAGE\n //////////////////////////////////////////////////////////////*/\n\n string public name;\n\n string public symbol;\n\n uint8 public immutable decimals;\n\n /*//////////////////////////////////////////////////////////////\n ERC20 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 public totalSupply;\n\n mapping(address => uint256) public balanceOf;\n\n mapping(address => mapping(address => uint256)) public allowance;\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 internal immutable INITIAL_CHAIN_ID;\n\n bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;\n\n mapping(address => uint256) public nonces;\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(\n string memory _name,\n string memory _symbol,\n uint8 _decimals\n ) {\n name = _name;\n symbol = _symbol;\n decimals = _decimals;\n\n INITIAL_CHAIN_ID = block.chainid;\n INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC20 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 amount) public virtual returns (bool) {\n allowance[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n\n return true;\n }\n\n function transfer(address to, uint256 amount) public virtual returns (bool) {\n balanceOf[msg.sender] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(msg.sender, to, amount);\n\n return true;\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual returns (bool) {\n uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.\n\n if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;\n\n balanceOf[from] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n return true;\n }\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual {\n require(deadline >= block.timestamp, \"PERMIT_DEADLINE_EXPIRED\");\n\n // Unchecked because the only math done is incrementing\n // the owner's nonce which cannot realistically overflow.\n unchecked {\n address recoveredAddress = ecrecover(\n keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR(),\n keccak256(\n abi.encode(\n keccak256(\n \"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\"\n ),\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n )\n ),\n v,\n r,\n s\n );\n\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"INVALID_SIGNER\");\n\n allowance[recoveredAddress][spender] = value;\n }\n\n emit Approval(owner, spender, value);\n }\n\n function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\n return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();\n }\n\n function computeDomainSeparator() internal view virtual returns (bytes32) {\n return\n keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name)),\n keccak256(\"1\"),\n block.chainid,\n address(this)\n )\n );\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL MINT/BURN LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _mint(address to, uint256 amount) internal virtual {\n totalSupply += amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(address(0), to, amount);\n }\n\n function _burn(address from, uint256 amount) internal virtual {\n balanceOf[from] -= amount;\n\n // Cannot underflow because a user's balance\n // will never be larger than the total supply.\n unchecked {\n totalSupply -= amount;\n }\n\n emit Transfer(from, address(0), amount);\n }\n}\n" - }, - "src/controllers/RefuelSwapAndBridgeController.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {ISocketRequest} from \"../interfaces/ISocketRequest.sol\";\nimport {ISocketRoute} from \"../interfaces/ISocketRoute.sol\";\nimport {BaseController} from \"./BaseController.sol\";\n\n/**\n * @title RefuelSwapAndBridge Controller Implementation\n * @notice Controller with composed actions for Refuel,Swap and Bridge to be executed Sequentially and this is atomic\n * @author Socket dot tech.\n */\ncontract RefuelSwapAndBridgeController is BaseController {\n /// @notice Function-selector to invoke refuel-swap-bridge function\n /// @dev This function selector is to be used while buidling transaction-data\n bytes4 public immutable REFUEL_SWAP_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"refuelAndSwapAndBridge((uint32,bytes,uint32,bytes,uint32,bytes))\"\n )\n );\n\n /// @notice socketGatewayAddress to be initialised via storage variable BaseController\n constructor(\n address _socketGatewayAddress\n ) BaseController(_socketGatewayAddress) {}\n\n /**\n * @notice function to handle refuel followed by Swap and Bridge actions\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param rsbRequest Request with data to execute refuel followed by swap and bridge\n * @return output data from bridging operation\n */\n function refuelAndSwapAndBridge(\n ISocketRequest.RefuelSwapBridgeRequest calldata rsbRequest\n ) public payable returns (bytes memory) {\n _executeRoute(rsbRequest.refuelRouteId, rsbRequest.refuelData);\n\n // refuel is also a bridging activity via refuel-route-implementation\n bytes memory swapResponseData = _executeRoute(\n rsbRequest.swapRouteId,\n rsbRequest.swapData\n );\n\n uint256 swapAmount = abi.decode(swapResponseData, (uint256));\n\n //sequence of arguments for implData: amount, token, data\n // Bridging the swapAmount received in the preceeding step\n bytes memory bridgeImpldata = abi.encodeWithSelector(\n BRIDGE_AFTER_SWAP_SELECTOR,\n swapAmount,\n rsbRequest.bridgeData\n );\n\n return _executeRoute(rsbRequest.bridgeRouteId, bridgeImpldata);\n }\n}\n" - }, - "src/interfaces/ISocketGateway.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/**\n * @title ISocketGateway\n * @notice Interface for SocketGateway functions.\n * @dev functions can be added here for invocation from external contracts or off-chain\n * @author Socket dot tech.\n */\ninterface ISocketGateway {\n /**\n * @notice Request-struct for controllerRequests\n * @dev ensure the value for data is generated using the function-selectors defined in the controllerImplementation contracts\n */\n struct SocketControllerRequest {\n // controllerId is the id mapped to the controllerAddress\n uint32 controllerId;\n // transactionImplData generated off-chain or by caller using function-selector of the controllerContract\n bytes data;\n }\n\n // @notice view to get owner-address\n function owner() external view returns (address);\n}\n" - }, - "src/libraries/Pb.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity ^0.8.4;\n\n// runtime proto sol library\nlibrary Pb {\n enum WireType {\n Varint,\n Fixed64,\n LengthDelim,\n StartGroup,\n EndGroup,\n Fixed32\n }\n\n struct Buffer {\n uint256 idx; // the start index of next read. when idx=b.length, we're done\n bytes b; // hold serialized proto msg, readonly\n }\n\n // create a new in-memory Buffer object from raw msg bytes\n function fromBytes(\n bytes memory raw\n ) internal pure returns (Buffer memory buf) {\n buf.b = raw;\n buf.idx = 0;\n }\n\n // whether there are unread bytes\n function hasMore(Buffer memory buf) internal pure returns (bool) {\n return buf.idx < buf.b.length;\n }\n\n // decode current field number and wiretype\n function decKey(\n Buffer memory buf\n ) internal pure returns (uint256 tag, WireType wiretype) {\n uint256 v = decVarint(buf);\n tag = v / 8;\n wiretype = WireType(v & 7);\n }\n\n // read varint from current buf idx, move buf.idx to next read, return the int value\n function decVarint(Buffer memory buf) internal pure returns (uint256 v) {\n bytes10 tmp; // proto int is at most 10 bytes (7 bits can be used per byte)\n bytes memory bb = buf.b; // get buf.b mem addr to use in assembly\n v = buf.idx; // use v to save one additional uint variable\n assembly {\n tmp := mload(add(add(bb, 32), v)) // load 10 bytes from buf.b[buf.idx] to tmp\n }\n uint256 b; // store current byte content\n v = 0; // reset to 0 for return value\n for (uint256 i = 0; i < 10; i++) {\n assembly {\n b := byte(i, tmp) // don't use tmp[i] because it does bound check and costs extra\n }\n v |= (b & 0x7F) << (i * 7);\n if (b & 0x80 == 0) {\n buf.idx += i + 1;\n return v;\n }\n }\n revert(); // i=10, invalid varint stream\n }\n\n // read length delimited field and return bytes\n function decBytes(\n Buffer memory buf\n ) internal pure returns (bytes memory b) {\n uint256 len = decVarint(buf);\n uint256 end = buf.idx + len;\n require(end <= buf.b.length); // avoid overflow\n b = new bytes(len);\n bytes memory bufB = buf.b; // get buf.b mem addr to use in assembly\n uint256 bStart;\n uint256 bufBStart = buf.idx;\n assembly {\n bStart := add(b, 32)\n bufBStart := add(add(bufB, 32), bufBStart)\n }\n for (uint256 i = 0; i < len; i += 32) {\n assembly {\n mstore(add(bStart, i), mload(add(bufBStart, i)))\n }\n }\n buf.idx = end;\n }\n\n // move idx pass current value field, to beginning of next tag or msg end\n function skipValue(Buffer memory buf, WireType wire) internal pure {\n if (wire == WireType.Varint) {\n decVarint(buf);\n } else if (wire == WireType.LengthDelim) {\n uint256 len = decVarint(buf);\n buf.idx += len; // skip len bytes value data\n require(buf.idx <= buf.b.length); // avoid overflow\n } else {\n revert();\n } // unsupported wiretype\n }\n\n function _uint256(bytes memory b) internal pure returns (uint256 v) {\n require(b.length <= 32); // b's length must be smaller than or equal to 32\n assembly {\n v := mload(add(b, 32))\n } // load all 32bytes to v\n v = v >> (8 * (32 - b.length)); // only first b.length is valid\n }\n\n function _address(bytes memory b) internal pure returns (address v) {\n v = _addressPayable(b);\n }\n\n function _addressPayable(\n bytes memory b\n ) internal pure returns (address payable v) {\n require(b.length == 20);\n //load 32bytes then shift right 12 bytes\n assembly {\n v := div(mload(add(b, 32)), 0x1000000000000000000000000)\n }\n }\n\n function _bytes32(bytes memory b) internal pure returns (bytes32 v) {\n require(b.length == 32);\n assembly {\n v := mload(add(b, 32))\n }\n }\n}\n" - }, - "src/bridges/BridgeImplBase.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {ISocketGateway} from \"../interfaces/ISocketGateway.sol\";\nimport {ISocketRoute} from \"../interfaces/ISocketRoute.sol\";\nimport {OnlySocketGatewayOwner, OnlySocketDeployer} from \"../errors/SocketErrors.sol\";\n\n/**\n * @title Abstract Implementation Contract.\n * @notice All Bridge Implementation will follow this interface.\n */\nabstract contract BridgeImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n /// @notice Address used to identify if it is a native token transfer or not\n address public immutable NATIVE_TOKEN_ADDRESS =\n address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);\n\n /// @notice immutable variable to store the socketGateway address\n address public immutable socketGateway;\n\n /// @notice immutable variable to store the socketGateway address\n address public immutable socketDeployFactory;\n\n /// @notice immutable variable with instance of SocketRoute to access route functions\n ISocketRoute public immutable socketRoute;\n\n /// @notice FunctionSelector used to delegatecall from swap to the function of bridge router implementation\n bytes4 public immutable BRIDGE_AFTER_SWAP_SELECTOR =\n bytes4(keccak256(\"bridgeAfterSwap(uint256,bytes)\"));\n\n /****************************************\n * EVENTS *\n ****************************************/\n\n event SocketBridge(\n uint256 amount,\n address token,\n uint256 toChainId,\n bytes32 bridgeName,\n address sender,\n address receiver,\n bytes32 metadata\n );\n\n /**\n * @notice Construct the base for all BridgeImplementations.\n * @param _socketGateway Socketgateway address, an immutable variable to set.\n * @param _socketDeployFactory Socket Deploy Factory address, an immutable variable to set.\n */\n constructor(address _socketGateway, address _socketDeployFactory) {\n socketGateway = _socketGateway;\n socketDeployFactory = _socketDeployFactory;\n socketRoute = ISocketRoute(_socketGateway);\n }\n\n /****************************************\n * MODIFIERS *\n ****************************************/\n\n /// @notice Implementing contract needs to make use of the modifier where restricted access is to be used\n modifier isSocketGatewayOwner() {\n if (msg.sender != ISocketGateway(socketGateway).owner()) {\n revert OnlySocketGatewayOwner();\n }\n _;\n }\n\n /// @notice Implementing contract needs to make use of the modifier where restricted access is to be used\n modifier isSocketDeployFactory() {\n if (msg.sender != socketDeployFactory) {\n revert OnlySocketDeployer();\n }\n _;\n }\n\n /****************************************\n * RESTRICTED FUNCTIONS *\n ****************************************/\n\n /**\n * @notice function to rescue the ERC20 tokens in the bridge Implementation contract\n * @notice this is a function restricted to Owner of SocketGateway only\n * @param token address of ERC20 token being rescued\n * @param userAddress receipient address to which ERC20 tokens will be rescued to\n * @param amount amount of ERC20 tokens being rescued\n */\n function rescueFunds(\n address token,\n address userAddress,\n uint256 amount\n ) external isSocketGatewayOwner {\n ERC20(token).safeTransfer(userAddress, amount);\n }\n\n /**\n * @notice function to rescue the native-balance in the bridge Implementation contract\n * @notice this is a function restricted to Owner of SocketGateway only\n * @param userAddress receipient address to which native-balance will be rescued to\n * @param amount amount of native balance tokens being rescued\n */\n function rescueEther(\n address payable userAddress,\n uint256 amount\n ) external isSocketGatewayOwner {\n userAddress.transfer(amount);\n }\n\n function killme() external isSocketDeployFactory {\n selfdestruct(payable(msg.sender));\n }\n\n /******************************\n * VIRTUAL FUNCTIONS *\n *****************************/\n\n /**\n * @notice function to bridge which is succeeding the swap function\n * @notice this function is to be used only when bridging as a succeeding step\n * @notice All bridge implementation contracts must implement this function\n * @notice bridge-implementations will have a bridge specific struct with properties used in bridging\n * @param bridgeData encoded value of properties in the bridgeData Struct\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable virtual;\n}\n" - }, - "src/bridges/cbridge/CelerImpl.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport \"../../libraries/Pb.sol\";\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport \"./interfaces/cbridge.sol\";\nimport \"./interfaces/ICelerStorageWrapper.sol\";\nimport {TransferIdExists, InvalidCelerRefund, CelerAlreadyRefunded, CelerRefundNotReady} from \"../../errors/SocketErrors.sol\";\nimport {BridgeImplBase} from \"../BridgeImplBase.sol\";\nimport {CBRIDGE} from \"../../static/RouteIdentifiers.sol\";\n\n/**\n * @title Celer-Route Implementation\n * @notice Route implementation with functions to bridge ERC20 and Native via Celer-Bridge\n * Called via SocketGateway if the routeId in the request maps to the routeId of CelerImplementation\n * Contains function to handle bridging as post-step i.e linked to a preceeding step for swap\n * RequestData is different to just bride and bridging chained with swap\n * @author Socket dot tech.\n */\ncontract CelerImpl is BridgeImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable CBridgeIdentifier = CBRIDGE;\n\n /// @notice Utility to perform operation on Buffer\n using Pb for Pb.Buffer;\n\n /// @notice Function-selector for ERC20-token bridging on Celer-Route\n /// @dev This function selector is to be used while building transaction-data to bridge ERC20 tokens\n bytes4 public immutable CELER_ERC20_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeERC20To(address,address,uint256,bytes32,uint64,uint64,uint32)\"\n )\n );\n\n /// @notice Function-selector for Native bridging on Celer-Route\n /// @dev This function selector is to be used while building transaction-data to bridge Native tokens\n bytes4 public immutable CELER_NATIVE_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeNativeTo(address,uint256,bytes32,uint64,uint64,uint32)\"\n )\n );\n\n bytes4 public immutable CELER_SWAP_BRIDGE_SELECTOR =\n bytes4(\n keccak256(\n \"swapAndBridge(uint32,bytes,(address,uint64,uint32,uint64,bytes32))\"\n )\n );\n\n /// @notice router Contract instance used to deposit ERC20 and Native on to Celer-Bridge\n /// @dev contract instance is to be initialized in the constructor using the routerAddress passed as constructor argument\n ICBridge public immutable router;\n\n /// @notice celerStorageWrapper Contract instance used to store the transferId generated during ERC20 and Native bridge on to Celer-Bridge\n /// @dev contract instance is to be initialized in the constructor using the celerStorageWrapperAddress passed as constructor argument\n ICelerStorageWrapper public immutable celerStorageWrapper;\n\n /// @notice WETH token address\n address public immutable weth;\n\n /// @notice chainId used during generation of transferId generated while bridging ERC20 and Native on to Celer-Bridge\n /// @dev this is to be initialised in the constructor\n uint64 public immutable chainId;\n\n struct WithdrawMsg {\n uint64 chainid; // tag: 1\n uint64 seqnum; // tag: 2\n address receiver; // tag: 3\n address token; // tag: 4\n uint256 amount; // tag: 5\n bytes32 refid; // tag: 6\n }\n\n /// @notice socketGatewayAddress to be initialised via storage variable BridgeImplBase\n /// @dev ensure routerAddress, weth-address, celerStorageWrapperAddress are set properly for the chainId in which the contract is being deployed\n constructor(\n address _routerAddress,\n address _weth,\n address _celerStorageWrapperAddress,\n address _socketGateway,\n address _socketDeployFactory\n ) BridgeImplBase(_socketGateway, _socketDeployFactory) {\n router = ICBridge(_routerAddress);\n celerStorageWrapper = ICelerStorageWrapper(_celerStorageWrapperAddress);\n weth = _weth;\n chainId = uint64(block.chainid);\n }\n\n // Function to receive Ether. msg.data must be empty\n receive() external payable {}\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct CelerBridgeDataNoToken {\n address receiverAddress;\n uint64 toChainId;\n uint32 maxSlippage;\n uint64 nonce;\n bytes32 metadata;\n }\n\n struct CelerBridgeData {\n address token;\n address receiverAddress;\n uint64 toChainId;\n uint32 maxSlippage;\n uint64 nonce;\n bytes32 metadata;\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from swapAndBridge, this function is called when the swap has already happened at a different place.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in CelerBridgeData struct\n * @param amount amount of tokens being bridged. this can be ERC20 or native\n * @param bridgeData encoded data for CelerBridge\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable override {\n CelerBridgeData memory celerBridgeData = abi.decode(\n bridgeData,\n (CelerBridgeData)\n );\n\n if (celerBridgeData.token == NATIVE_TOKEN_ADDRESS) {\n // transferId is generated using the request-params and nonce of the account\n // transferId should be unique for each request and this is used while handling refund from celerBridge\n bytes32 transferId = keccak256(\n abi.encodePacked(\n address(this),\n celerBridgeData.receiverAddress,\n weth,\n amount,\n celerBridgeData.toChainId,\n celerBridgeData.nonce,\n chainId\n )\n );\n\n // transferId is stored in CelerStorageWrapper with in a mapping where key is transferId and value is the msg-sender\n celerStorageWrapper.setAddressForTransferId(transferId, msg.sender);\n\n router.sendNative{value: amount}(\n celerBridgeData.receiverAddress,\n amount,\n celerBridgeData.toChainId,\n celerBridgeData.nonce,\n celerBridgeData.maxSlippage\n );\n } else {\n // transferId is generated using the request-params and nonce of the account\n // transferId should be unique for each request and this is used while handling refund from celerBridge\n bytes32 transferId = keccak256(\n abi.encodePacked(\n address(this),\n celerBridgeData.receiverAddress,\n celerBridgeData.token,\n amount,\n celerBridgeData.toChainId,\n celerBridgeData.nonce,\n chainId\n )\n );\n\n // transferId is stored in CelerStorageWrapper with in a mapping where key is transferId and value is the msg-sender\n celerStorageWrapper.setAddressForTransferId(transferId, msg.sender);\n router.send(\n celerBridgeData.receiverAddress,\n celerBridgeData.token,\n amount,\n celerBridgeData.toChainId,\n celerBridgeData.nonce,\n celerBridgeData.maxSlippage\n );\n }\n\n emit SocketBridge(\n amount,\n celerBridgeData.token,\n celerBridgeData.toChainId,\n CBridgeIdentifier,\n msg.sender,\n celerBridgeData.receiverAddress,\n celerBridgeData.metadata\n );\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from bridgeAfterSwap since this function holds the logic for swapping tokens too.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in CelerBridgeData struct\n * @param swapId routeId for the swapImpl\n * @param swapData encoded data for swap\n * @param celerBridgeData encoded data for CelerBridgeData\n */\n function swapAndBridge(\n uint32 swapId,\n bytes calldata swapData,\n CelerBridgeDataNoToken calldata celerBridgeData\n ) external payable {\n (bool success, bytes memory result) = socketRoute\n .getRoute(swapId)\n .delegatecall(swapData);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n (uint256 bridgeAmount, address token) = abi.decode(\n result,\n (uint256, address)\n );\n\n if (token == NATIVE_TOKEN_ADDRESS) {\n // transferId is generated using the request-params and nonce of the account\n // transferId should be unique for each request and this is used while handling refund from celerBridge\n bytes32 transferId = keccak256(\n abi.encodePacked(\n address(this),\n celerBridgeData.receiverAddress,\n weth,\n bridgeAmount,\n celerBridgeData.toChainId,\n celerBridgeData.nonce,\n chainId\n )\n );\n\n // transferId is stored in CelerStorageWrapper with in a mapping where key is transferId and value is the msg-sender\n celerStorageWrapper.setAddressForTransferId(transferId, msg.sender);\n\n router.sendNative{value: bridgeAmount}(\n celerBridgeData.receiverAddress,\n bridgeAmount,\n celerBridgeData.toChainId,\n celerBridgeData.nonce,\n celerBridgeData.maxSlippage\n );\n } else {\n // transferId is generated using the request-params and nonce of the account\n // transferId should be unique for each request and this is used while handling refund from celerBridge\n bytes32 transferId = keccak256(\n abi.encodePacked(\n address(this),\n celerBridgeData.receiverAddress,\n token,\n bridgeAmount,\n celerBridgeData.toChainId,\n celerBridgeData.nonce,\n chainId\n )\n );\n\n // transferId is stored in CelerStorageWrapper with in a mapping where key is transferId and value is the msg-sender\n celerStorageWrapper.setAddressForTransferId(transferId, msg.sender);\n router.send(\n celerBridgeData.receiverAddress,\n token,\n bridgeAmount,\n celerBridgeData.toChainId,\n celerBridgeData.nonce,\n celerBridgeData.maxSlippage\n );\n }\n\n emit SocketBridge(\n bridgeAmount,\n token,\n celerBridgeData.toChainId,\n CBridgeIdentifier,\n msg.sender,\n celerBridgeData.receiverAddress,\n celerBridgeData.metadata\n );\n }\n\n /**\n * @notice function to handle ERC20 bridging to receipent via Celer-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param receiverAddress address of recipient\n * @param token address of token being bridged\n * @param amount amount of token for bridging\n * @param toChainId destination ChainId\n * @param nonce nonce of the sender-account address\n * @param maxSlippage maximum Slippage for the bridging\n */\n function bridgeERC20To(\n address receiverAddress,\n address token,\n uint256 amount,\n bytes32 metadata,\n uint64 toChainId,\n uint64 nonce,\n uint32 maxSlippage\n ) external payable {\n /// @notice transferId is generated using the request-params and nonce of the account\n /// @notice transferId should be unique for each request and this is used while handling refund from celerBridge\n bytes32 transferId = keccak256(\n abi.encodePacked(\n address(this),\n receiverAddress,\n token,\n amount,\n toChainId,\n nonce,\n chainId\n )\n );\n\n /// @notice stored in the CelerStorageWrapper contract\n celerStorageWrapper.setAddressForTransferId(transferId, msg.sender);\n\n ERC20 tokenInstance = ERC20(token);\n tokenInstance.safeTransferFrom(msg.sender, socketGateway, amount);\n router.send(\n receiverAddress,\n token,\n amount,\n toChainId,\n nonce,\n maxSlippage\n );\n\n emit SocketBridge(\n amount,\n token,\n toChainId,\n CBridgeIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n\n /**\n * @notice function to handle Native bridging to receipent via Celer-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param receiverAddress address of recipient\n * @param amount amount of token for bridging\n * @param toChainId destination ChainId\n * @param nonce nonce of the sender-account address\n * @param maxSlippage maximum Slippage for the bridging\n */\n function bridgeNativeTo(\n address receiverAddress,\n uint256 amount,\n bytes32 metadata,\n uint64 toChainId,\n uint64 nonce,\n uint32 maxSlippage\n ) external payable {\n bytes32 transferId = keccak256(\n abi.encodePacked(\n address(this),\n receiverAddress,\n weth,\n amount,\n toChainId,\n nonce,\n chainId\n )\n );\n\n celerStorageWrapper.setAddressForTransferId(transferId, msg.sender);\n\n router.sendNative{value: amount}(\n receiverAddress,\n amount,\n toChainId,\n nonce,\n maxSlippage\n );\n\n emit SocketBridge(\n amount,\n NATIVE_TOKEN_ADDRESS,\n toChainId,\n CBridgeIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n\n /**\n * @notice function to handle refund from CelerBridge-Router\n * @param _request request data generated offchain using the celer-SDK\n * @param _sigs generated offchain using the celer-SDK\n * @param _signers generated offchain using the celer-SDK\n * @param _powers generated offchain using the celer-SDK\n */\n function refundCelerUser(\n bytes calldata _request,\n bytes[] calldata _sigs,\n address[] calldata _signers,\n uint256[] calldata _powers\n ) external payable {\n WithdrawMsg memory request = decWithdrawMsg(_request);\n bytes32 transferId = keccak256(\n abi.encodePacked(\n request.chainid,\n request.seqnum,\n request.receiver,\n request.token,\n request.amount\n )\n );\n uint256 _initialNativeBalance = address(this).balance;\n uint256 _initialTokenBalance = ERC20(request.token).balanceOf(\n address(this)\n );\n if (!router.withdraws(transferId)) {\n router.withdraw(_request, _sigs, _signers, _powers);\n }\n\n if (request.receiver != socketGateway) {\n revert InvalidCelerRefund();\n }\n\n address _receiver = celerStorageWrapper.getAddressFromTransferId(\n request.refid\n );\n celerStorageWrapper.deleteTransferId(request.refid);\n\n if (_receiver == address(0)) {\n revert CelerAlreadyRefunded();\n }\n\n uint256 _nativeBalanceAfter = address(this).balance;\n uint256 _tokenBalanceAfter = ERC20(request.token).balanceOf(\n address(this)\n );\n if (_nativeBalanceAfter > _initialNativeBalance) {\n if ((_nativeBalanceAfter - _initialNativeBalance) != request.amount)\n revert CelerRefundNotReady();\n payable(_receiver).transfer(request.amount);\n return;\n }\n\n if (_tokenBalanceAfter > _initialTokenBalance) {\n if ((_tokenBalanceAfter - _initialTokenBalance) != request.amount)\n revert CelerRefundNotReady();\n ERC20(request.token).safeTransfer(_receiver, request.amount);\n return;\n }\n\n revert CelerRefundNotReady();\n }\n\n function decWithdrawMsg(\n bytes memory raw\n ) internal pure returns (WithdrawMsg memory m) {\n Pb.Buffer memory buf = Pb.fromBytes(raw);\n\n uint256 tag;\n Pb.WireType wire;\n while (buf.hasMore()) {\n (tag, wire) = buf.decKey();\n if (false) {}\n // solidity has no switch/case\n else if (tag == 1) {\n m.chainid = uint64(buf.decVarint());\n } else if (tag == 2) {\n m.seqnum = uint64(buf.decVarint());\n } else if (tag == 3) {\n m.receiver = Pb._address(buf.decBytes());\n } else if (tag == 4) {\n m.token = Pb._address(buf.decBytes());\n } else if (tag == 5) {\n m.amount = Pb._uint256(buf.decBytes());\n } else if (tag == 6) {\n m.refid = Pb._bytes32(buf.decBytes());\n } else {\n buf.skipValue(wire);\n } // skip value of unknown tag\n }\n } // end decoder WithdrawMsg\n}\n" - }, - "src/libraries/LibBytes.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n// Functions taken out from https://github.com/GNSPS/solidity-bytes-utils/blob/master/contracts/BytesLib.sol\nlibrary LibBytes {\n // solhint-disable no-inline-assembly\n\n // LibBytes specific errors\n error SliceOverflow();\n error SliceOutOfBounds();\n error AddressOutOfBounds();\n error UintOutOfBounds();\n\n // -------------------------\n\n function concat(\n bytes memory _preBytes,\n bytes memory _postBytes\n ) internal pure returns (bytes memory) {\n bytes memory tempBytes;\n\n assembly {\n // Get a location of some free memory and store it in tempBytes as\n // Solidity does for memory variables.\n tempBytes := mload(0x40)\n\n // Store the length of the first bytes array at the beginning of\n // the memory for tempBytes.\n let length := mload(_preBytes)\n mstore(tempBytes, length)\n\n // Maintain a memory counter for the current write location in the\n // temp bytes array by adding the 32 bytes for the array length to\n // the starting location.\n let mc := add(tempBytes, 0x20)\n // Stop copying when the memory counter reaches the length of the\n // first bytes array.\n let end := add(mc, length)\n\n for {\n // Initialize a copy counter to the start of the _preBytes data,\n // 32 bytes into its memory.\n let cc := add(_preBytes, 0x20)\n } lt(mc, end) {\n // Increase both counters by 32 bytes each iteration.\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n // Write the _preBytes data into the tempBytes memory 32 bytes\n // at a time.\n mstore(mc, mload(cc))\n }\n\n // Add the length of _postBytes to the current length of tempBytes\n // and store it as the new length in the first 32 bytes of the\n // tempBytes memory.\n length := mload(_postBytes)\n mstore(tempBytes, add(length, mload(tempBytes)))\n\n // Move the memory counter back from a multiple of 0x20 to the\n // actual end of the _preBytes data.\n mc := end\n // Stop copying when the memory counter reaches the new combined\n // length of the arrays.\n end := add(mc, length)\n\n for {\n let cc := add(_postBytes, 0x20)\n } lt(mc, end) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n mstore(mc, mload(cc))\n }\n\n // Update the free-memory pointer by padding our last write location\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\n // next 32 byte block, then round down to the nearest multiple of\n // 32. If the sum of the length of the two arrays is zero then add\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\n mstore(\n 0x40,\n and(\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\n not(31) // Round down to the nearest 32 bytes.\n )\n )\n }\n\n return tempBytes;\n }\n\n function slice(\n bytes memory _bytes,\n uint256 _start,\n uint256 _length\n ) internal pure returns (bytes memory) {\n if (_length + 31 < _length) {\n revert SliceOverflow();\n }\n if (_bytes.length < _start + _length) {\n revert SliceOutOfBounds();\n }\n\n bytes memory tempBytes;\n\n assembly {\n switch iszero(_length)\n case 0 {\n // Get a location of some free memory and store it in tempBytes as\n // Solidity does for memory variables.\n tempBytes := mload(0x40)\n\n // The first word of the slice result is potentially a partial\n // word read from the original array. To read it, we calculate\n // the length of that partial word and start copying that many\n // bytes into the array. The first word we copy will start with\n // data we don't care about, but the last `lengthmod` bytes will\n // land at the beginning of the contents of the new array. When\n // we're done copying, we overwrite the full first word with\n // the actual length of the slice.\n let lengthmod := and(_length, 31)\n\n // The multiplication in the next line is necessary\n // because when slicing multiples of 32 bytes (lengthmod == 0)\n // the following copy loop was copying the origin's length\n // and then ending prematurely not copying everything it should.\n let mc := add(\n add(tempBytes, lengthmod),\n mul(0x20, iszero(lengthmod))\n )\n let end := add(mc, _length)\n\n for {\n // The multiplication in the next line has the same exact purpose\n // as the one above.\n let cc := add(\n add(\n add(_bytes, lengthmod),\n mul(0x20, iszero(lengthmod))\n ),\n _start\n )\n } lt(mc, end) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n mstore(mc, mload(cc))\n }\n\n mstore(tempBytes, _length)\n\n //update free-memory pointer\n //allocating the array padded to 32 bytes like the compiler does now\n mstore(0x40, and(add(mc, 31), not(31)))\n }\n //if we want a zero-length slice let's just return a zero-length array\n default {\n tempBytes := mload(0x40)\n //zero out the 32 bytes slice we are about to return\n //we need to do it because Solidity does not garbage collect\n mstore(tempBytes, 0)\n\n mstore(0x40, add(tempBytes, 0x20))\n }\n }\n\n return tempBytes;\n }\n}\n" - }, - "src/bridges/hyphen/interfaces/hyphen.sol": { - "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity >=0.8.0;\n\n/**\n * @title HyphenLiquidityPoolManager\n * @notice interface with functions to bridge ERC20 and Native via Hyphen-Bridge\n * @author Socket dot tech.\n */\ninterface HyphenLiquidityPoolManager {\n /**\n * @dev Function used to deposit tokens into pool to initiate a cross chain token transfer.\n * @param toChainId Chain id where funds needs to be transfered\n * @param tokenAddress ERC20 Token address that needs to be transfered\n * @param receiver Address on toChainId where tokens needs to be transfered\n * @param amount Amount of token being transfered\n */\n function depositErc20(\n uint256 toChainId,\n address tokenAddress,\n address receiver,\n uint256 amount,\n string calldata tag\n ) external;\n\n /**\n * @dev Function used to deposit native token into pool to initiate a cross chain token transfer.\n * @param receiver Address on toChainId where tokens needs to be transfered\n * @param toChainId Chain id where funds needs to be transfered\n */\n function depositNative(\n address receiver,\n uint256 toChainId,\n string calldata tag\n ) external payable;\n}\n" - }, - "src/swap/SwapImplBase.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {ISocketGateway} from \"../interfaces/ISocketGateway.sol\";\nimport {OnlySocketGatewayOwner, OnlySocketDeployer} from \"../errors/SocketErrors.sol\";\n\n/**\n * @title Abstract Implementation Contract.\n * @notice All Swap Implementation will follow this interface.\n * @author Socket dot tech.\n */\nabstract contract SwapImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n /// @notice Address used to identify if it is a native token transfer or not\n address public immutable NATIVE_TOKEN_ADDRESS =\n address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);\n\n /// @notice immutable variable to store the socketGateway address\n address public immutable socketGateway;\n\n /// @notice immutable variable to store the socketGateway address\n address public immutable socketDeployFactory;\n\n /// @notice FunctionSelector used to delegatecall to the performAction function of swap-router-implementation\n bytes4 public immutable SWAP_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\"performAction(address,address,uint256,address,bytes)\")\n );\n\n /// @notice FunctionSelector used to delegatecall to the performActionWithIn function of swap-router-implementation\n bytes4 public immutable SWAP_WITHIN_FUNCTION_SELECTOR =\n bytes4(keccak256(\"performActionWithIn(address,address,uint256,bytes)\"));\n\n /****************************************\n * EVENTS *\n ****************************************/\n\n event SocketSwapTokens(\n address fromToken,\n address toToken,\n uint256 buyAmount,\n uint256 sellAmount,\n bytes32 routeName,\n address receiver\n );\n\n /**\n * @notice Construct the base for all SwapImplementations.\n * @param _socketGateway Socketgateway address, an immutable variable to set.\n */\n constructor(address _socketGateway, address _socketDeployFactory) {\n socketGateway = _socketGateway;\n socketDeployFactory = _socketDeployFactory;\n }\n\n /****************************************\n * MODIFIERS *\n ****************************************/\n\n /// @notice Implementing contract needs to make use of the modifier where restricted access is to be used\n modifier isSocketGatewayOwner() {\n if (msg.sender != ISocketGateway(socketGateway).owner()) {\n revert OnlySocketGatewayOwner();\n }\n _;\n }\n\n /// @notice Implementing contract needs to make use of the modifier where restricted access is to be used\n modifier isSocketDeployFactory() {\n if (msg.sender != socketDeployFactory) {\n revert OnlySocketDeployer();\n }\n _;\n }\n\n /****************************************\n * RESTRICTED FUNCTIONS *\n ****************************************/\n\n /**\n * @notice function to rescue the ERC20 tokens in the Swap-Implementation contract\n * @notice this is a function restricted to Owner of SocketGateway only\n * @param token address of ERC20 token being rescued\n * @param userAddress receipient address to which ERC20 tokens will be rescued to\n * @param amount amount of ERC20 tokens being rescued\n */\n function rescueFunds(\n address token,\n address userAddress,\n uint256 amount\n ) external isSocketGatewayOwner {\n ERC20(token).safeTransfer(userAddress, amount);\n }\n\n /**\n * @notice function to rescue the native-balance in the Swap-Implementation contract\n * @notice this is a function restricted to Owner of SocketGateway only\n * @param userAddress receipient address to which native-balance will be rescued to\n * @param amount amount of native balance tokens being rescued\n */\n function rescueEther(\n address payable userAddress,\n uint256 amount\n ) external isSocketGatewayOwner {\n userAddress.transfer(amount);\n }\n\n function killme() external isSocketDeployFactory {\n selfdestruct(payable(msg.sender));\n }\n\n /******************************\n * VIRTUAL FUNCTIONS *\n *****************************/\n\n /**\n * @notice function to swap tokens on the chain\n * All swap implementation contracts must implement this function\n * @param fromToken token to be swapped\n * @param toToken token to which fromToken has to be swapped\n * @param amount amount of fromToken being swapped\n * @param receiverAddress recipient address of toToken\n * @param data encoded value of properties in the swapData Struct\n */\n function performAction(\n address fromToken,\n address toToken,\n uint256 amount,\n address receiverAddress,\n bytes memory data\n ) external payable virtual returns (uint256);\n\n /**\n * @notice function to swapWith - swaps tokens on the chain to socketGateway as recipient\n * All swap implementation contracts must implement this function\n * @param fromToken token to be swapped\n * @param toToken token to which fromToken has to be swapped\n * @param amount amount of fromToken being swapped\n * @param swapExtraData encoded value of properties in the swapData Struct\n */\n function performActionWithIn(\n address fromToken,\n address toToken,\n uint256 amount,\n bytes memory swapExtraData\n ) external payable virtual returns (uint256, address);\n}\n" - }, - "src/swap/zerox/ZeroXSwapImpl.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport \"../SwapImplBase.sol\";\nimport {Address0Provided, SwapFailed} from \"../../errors/SocketErrors.sol\";\nimport {ZEROX} from \"../../static/RouteIdentifiers.sol\";\n\n/**\n * @title ZeroX-Swap-Route Implementation\n * @notice Route implementation with functions to swap tokens via ZeroX-Swap\n * Called via SocketGateway if the routeId in the request maps to the routeId of ZeroX-Swap-Implementation\n * @author Socket dot tech.\n */\ncontract ZeroXSwapImpl is SwapImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable ZeroXIdentifier = ZEROX;\n\n /// @notice unique name to identify the router, used to emit event upon successful bridging\n bytes32 public immutable NAME = keccak256(\"Zerox-Router\");\n\n /// @notice address of ZeroX-Exchange-Proxy to swap the tokens on Chain\n address payable public immutable zeroXExchangeProxy;\n\n /// @notice socketGatewayAddress to be initialised via storage variable SwapImplBase\n /// @notice ZeroXExchangeProxy contract is payable to allow ethereum swaps\n /// @dev ensure _zeroXExchangeProxy are set properly for the chainId in which the contract is being deployed\n constructor(\n address _zeroXExchangeProxy,\n address _socketGateway,\n address _socketDeployFactory\n ) SwapImplBase(_socketGateway, _socketDeployFactory) {\n zeroXExchangeProxy = payable(_zeroXExchangeProxy);\n }\n\n receive() external payable {}\n\n fallback() external payable {}\n\n /**\n * @notice function to swap tokens on the chain and transfer to receiver address\n * @dev This is called only when there is a request for a swap.\n * @param fromToken token to be swapped\n * @param toToken token to which fromToken is to be swapped\n * @param amount amount to be swapped\n * @param receiverAddress address of toToken recipient\n * @param swapExtraData data required for zeroX Exchange to get the swap done\n */\n function performAction(\n address fromToken,\n address toToken,\n uint256 amount,\n address receiverAddress,\n bytes calldata swapExtraData\n ) external payable override returns (uint256) {\n if (fromToken == address(0)) {\n revert Address0Provided();\n }\n\n bytes memory swapCallData = abi.decode(swapExtraData, (bytes));\n\n uint256 _initialBalanceTokenOut;\n uint256 _finalBalanceTokenOut;\n\n ERC20 erc20ToToken = ERC20(toToken);\n if (toToken != NATIVE_TOKEN_ADDRESS) {\n _initialBalanceTokenOut = erc20ToToken.balanceOf(address(this));\n } else {\n _initialBalanceTokenOut = address(this).balance;\n }\n\n if (fromToken != NATIVE_TOKEN_ADDRESS) {\n ERC20 token = ERC20(fromToken);\n token.safeTransferFrom(msg.sender, address(this), amount);\n token.safeApprove(zeroXExchangeProxy, amount);\n\n // solhint-disable-next-line\n (bool success, ) = zeroXExchangeProxy.call(swapCallData);\n\n if (!success) {\n revert SwapFailed();\n }\n\n token.safeApprove(zeroXExchangeProxy, 0);\n } else {\n (bool success, ) = zeroXExchangeProxy.call{value: amount}(\n swapCallData\n );\n if (!success) {\n revert SwapFailed();\n }\n }\n\n if (toToken != NATIVE_TOKEN_ADDRESS) {\n _finalBalanceTokenOut = erc20ToToken.balanceOf(address(this));\n } else {\n _finalBalanceTokenOut = address(this).balance;\n }\n\n uint256 returnAmount = _finalBalanceTokenOut - _initialBalanceTokenOut;\n\n if (toToken == NATIVE_TOKEN_ADDRESS) {\n payable(receiverAddress).transfer(returnAmount);\n } else {\n erc20ToToken.transfer(receiverAddress, returnAmount);\n }\n\n emit SocketSwapTokens(\n fromToken,\n toToken,\n returnAmount,\n amount,\n ZeroXIdentifier,\n receiverAddress\n );\n\n return returnAmount;\n }\n\n /**\n * @notice function to swapWithIn SocketGateway - swaps tokens on the chain to socketGateway as recipient\n * @param fromToken token to be swapped\n * @param toToken token to which fromToken has to be swapped\n * @param amount amount of fromToken being swapped\n * @param swapExtraData encoded value of properties in the swapData Struct\n * @return swapped amount (in toToken Address)\n */\n function performActionWithIn(\n address fromToken,\n address toToken,\n uint256 amount,\n bytes calldata swapExtraData\n ) external payable override returns (uint256, address) {\n if (fromToken == address(0)) {\n revert Address0Provided();\n }\n\n bytes memory swapCallData = abi.decode(swapExtraData, (bytes));\n\n uint256 _initialBalanceTokenOut;\n uint256 _finalBalanceTokenOut;\n\n ERC20 erc20ToToken = ERC20(toToken);\n if (toToken != NATIVE_TOKEN_ADDRESS) {\n _initialBalanceTokenOut = erc20ToToken.balanceOf(address(this));\n } else {\n _initialBalanceTokenOut = address(this).balance;\n }\n\n if (fromToken != NATIVE_TOKEN_ADDRESS) {\n ERC20 token = ERC20(fromToken);\n token.safeTransferFrom(msg.sender, address(this), amount);\n token.safeApprove(zeroXExchangeProxy, amount);\n\n // solhint-disable-next-line\n (bool success, ) = zeroXExchangeProxy.call(swapCallData);\n\n if (!success) {\n revert SwapFailed();\n }\n\n token.safeApprove(zeroXExchangeProxy, 0);\n } else {\n (bool success, ) = zeroXExchangeProxy.call{value: amount}(\n swapCallData\n );\n if (!success) {\n revert SwapFailed();\n }\n }\n\n if (toToken != NATIVE_TOKEN_ADDRESS) {\n _finalBalanceTokenOut = erc20ToToken.balanceOf(address(this));\n } else {\n _finalBalanceTokenOut = address(this).balance;\n }\n\n uint256 returnAmount = _finalBalanceTokenOut - _initialBalanceTokenOut;\n\n emit SocketSwapTokens(\n fromToken,\n toToken,\n returnAmount,\n amount,\n ZeroXIdentifier,\n socketGateway\n );\n\n return (returnAmount, toToken);\n }\n}\n" - }, - "src/bridges/cbridge/interfaces/cbridge.sol": { - "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity >=0.8.0;\n\ninterface ICBridge {\n function send(\n address _receiver,\n address _token,\n uint256 _amount,\n uint64 _dstChinId,\n uint64 _nonce,\n uint32 _maxSlippage\n ) external;\n\n function sendNative(\n address _receiver,\n uint256 _amount,\n uint64 _dstChinId,\n uint64 _nonce,\n uint32 _maxSlippage\n ) external payable;\n\n function withdraws(bytes32 withdrawId) external view returns (bool);\n\n function withdraw(\n bytes calldata _wdmsg,\n bytes[] calldata _sigs,\n address[] calldata _signers,\n uint256[] calldata _powers\n ) external;\n}\n" - }, - "src/bridges/stargate/l2/Stargate.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport \"../interfaces/stargate.sol\";\nimport \"../../../errors/SocketErrors.sol\";\nimport {BridgeImplBase} from \"../../BridgeImplBase.sol\";\nimport {STARGATE} from \"../../../static/RouteIdentifiers.sol\";\n\n/**\n * @title Stargate-L2-Route Implementation\n * @notice Route implementation with functions to bridge ERC20 and Native via Stargate-L2-Bridge\n * Called via SocketGateway if the routeId in the request maps to the routeId of Stargate-L2-Implementation\n * Contains function to handle bridging as post-step i.e linked to a preceeding step for swap\n * RequestData is different to just bride and bridging chained with swap\n * @author Socket dot tech.\n */\ncontract StargateImplL2 is BridgeImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable StargateIdentifier = STARGATE;\n\n /// @notice Function-selector for ERC20-token bridging on Stargate-L2-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge ERC20 tokens\n bytes4\n public immutable STARGATE_L2_ERC20_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeERC20To(address,address,address,uint256,uint256,uint256,(uint256,uint256,uint256,uint256,bytes32,bytes,uint16))\"\n )\n );\n\n bytes4 public immutable STARGATE_L1_SWAP_BRIDGE_SELECTOR =\n bytes4(\n keccak256(\n \"swapAndBridge(uint32,bytes,(address,address,uint16,uint256,uint256,uint256,uint256,uint256,uint256,bytes32,bytes))\"\n )\n );\n\n /// @notice Function-selector for Native bridging on Stargate-L2-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge Native tokens\n bytes4\n public immutable STARGATE_L2_NATIVE_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeNativeTo(address,address,uint16,uint256,uint256,uint256,bytes32)\"\n )\n );\n\n /// @notice Stargate Router to bridge ERC20 tokens\n IBridgeStargate public immutable router;\n\n /// @notice Stargate Router to bridge native tokens\n IBridgeStargate public immutable routerETH;\n\n /// @notice socketGatewayAddress to be initialised via storage variable BridgeImplBase\n /// @dev ensure router, routerEth are set properly for the chainId in which the contract is being deployed\n constructor(\n address _router,\n address _routerEth,\n address _socketGateway,\n address _socketDeployFactory\n ) BridgeImplBase(_socketGateway, _socketDeployFactory) {\n router = IBridgeStargate(_router);\n routerETH = IBridgeStargate(_routerEth);\n }\n\n /// @notice Struct to be used as a input parameter for Bridging tokens via Stargate-L2-route\n /// @dev while building transactionData,values should be set in this sequence of properties in this struct\n struct StargateBridgeExtraData {\n uint256 srcPoolId;\n uint256 dstPoolId;\n uint256 destinationGasLimit;\n uint256 minReceivedAmt;\n bytes32 metadata;\n bytes destinationPayload;\n uint16 stargateDstChainId; // stargate defines chain id in its way\n }\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct StargateBridgeDataNoToken {\n address receiverAddress;\n address senderAddress;\n uint16 stargateDstChainId; // stargate defines chain id in its way\n uint256 value;\n // a unique identifier that is uses to dedup transfers\n // this value is the a timestamp sent from frontend, but in theory can be any unique number\n uint256 srcPoolId;\n uint256 dstPoolId;\n uint256 minReceivedAmt; // defines the slippage, the min qty you would accept on the destination\n uint256 optionalValue;\n uint256 destinationGasLimit;\n bytes32 metadata;\n bytes destinationPayload;\n }\n\n struct StargateBridgeData {\n address token;\n address receiverAddress;\n address senderAddress;\n uint16 stargateDstChainId; // stargate defines chain id in its way\n uint256 value;\n // a unique identifier that is uses to dedup transfers\n // this value is the a timestamp sent from frontend, but in theory can be any unique number\n uint256 srcPoolId;\n uint256 dstPoolId;\n uint256 minReceivedAmt; // defines the slippage, the min qty you would accept on the destination\n uint256 optionalValue;\n uint256 destinationGasLimit;\n bytes32 metadata;\n bytes destinationPayload;\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from swapAndBridge, this function is called when the swap has already happened at a different place.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in Stargate-BridgeData struct\n * @param amount amount of tokens being bridged. this can be ERC20 or native\n * @param bridgeData encoded data for Stargate-L1-Bridge\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable override {\n StargateBridgeData memory stargateBridgeData = abi.decode(\n bridgeData,\n (StargateBridgeData)\n );\n\n if (stargateBridgeData.token == NATIVE_TOKEN_ADDRESS) {\n // perform bridging\n routerETH.swapETH{value: amount + stargateBridgeData.optionalValue}(\n stargateBridgeData.stargateDstChainId,\n payable(stargateBridgeData.senderAddress),\n abi.encodePacked(stargateBridgeData.receiverAddress),\n amount,\n stargateBridgeData.minReceivedAmt\n );\n } else {\n ERC20(stargateBridgeData.token).safeApprove(\n address(router),\n amount\n );\n {\n router.swap{value: stargateBridgeData.value}(\n stargateBridgeData.stargateDstChainId,\n stargateBridgeData.srcPoolId,\n stargateBridgeData.dstPoolId,\n payable(stargateBridgeData.senderAddress), // default to refund to main contract\n amount,\n stargateBridgeData.minReceivedAmt,\n IBridgeStargate.lzTxObj(\n stargateBridgeData.destinationGasLimit,\n 0, // zero amount since this is a ERC20 bridging\n \"0x\" //empty data since this is for only ERC20\n ),\n abi.encodePacked(stargateBridgeData.receiverAddress),\n stargateBridgeData.destinationPayload\n );\n }\n }\n\n emit SocketBridge(\n amount,\n stargateBridgeData.token,\n stargateBridgeData.stargateDstChainId,\n StargateIdentifier,\n msg.sender,\n stargateBridgeData.receiverAddress,\n stargateBridgeData.metadata\n );\n }\n\n /**\n * @notice function to bridge tokens after swapping.\n * @notice this is different from bridgeAfterSwap since this function holds the logic for swapping tokens too.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in Stargate-BridgeData struct\n * @param swapId routeId for the swapImpl\n * @param swapData encoded data for swap\n * @param stargateBridgeData encoded data for StargateBridgeData\n */\n function swapAndBridge(\n uint32 swapId,\n bytes calldata swapData,\n StargateBridgeDataNoToken calldata stargateBridgeData\n ) external payable {\n (bool success, bytes memory result) = socketRoute\n .getRoute(swapId)\n .delegatecall(swapData);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n (uint256 bridgeAmount, address token) = abi.decode(\n result,\n (uint256, address)\n );\n\n if (token == NATIVE_TOKEN_ADDRESS) {\n routerETH.swapETH{\n value: bridgeAmount + stargateBridgeData.optionalValue\n }(\n stargateBridgeData.stargateDstChainId,\n payable(stargateBridgeData.senderAddress),\n abi.encodePacked(stargateBridgeData.receiverAddress),\n bridgeAmount,\n stargateBridgeData.minReceivedAmt\n );\n } else {\n ERC20(token).safeApprove(address(router), bridgeAmount);\n {\n router.swap{value: stargateBridgeData.value}(\n stargateBridgeData.stargateDstChainId,\n stargateBridgeData.srcPoolId,\n stargateBridgeData.dstPoolId,\n payable(stargateBridgeData.senderAddress), // default to refund to main contract\n bridgeAmount,\n stargateBridgeData.minReceivedAmt,\n IBridgeStargate.lzTxObj(\n stargateBridgeData.destinationGasLimit,\n 0,\n \"0x\"\n ),\n abi.encodePacked(stargateBridgeData.receiverAddress),\n stargateBridgeData.destinationPayload\n );\n }\n }\n\n emit SocketBridge(\n bridgeAmount,\n token,\n stargateBridgeData.stargateDstChainId,\n StargateIdentifier,\n msg.sender,\n stargateBridgeData.receiverAddress,\n stargateBridgeData.metadata\n );\n }\n\n /**\n * @notice function to handle ERC20 bridging to receipent via Stargate-L1-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param token address of token being bridged\n * @param senderAddress address of sender\n * @param receiverAddress address of recipient\n * @param amount amount of token being bridge\n * @param value value\n * @param optionalValue optionalValue\n * @param stargateBridgeExtraData stargate bridge extradata\n */\n function bridgeERC20To(\n address token,\n address senderAddress,\n address receiverAddress,\n uint256 amount,\n uint256 value,\n uint256 optionalValue,\n StargateBridgeExtraData calldata stargateBridgeExtraData\n ) external payable {\n // token address might not be indication thats why passed through extraData\n if (token == NATIVE_TOKEN_ADDRESS) {\n // perform bridging\n routerETH.swapETH{value: amount + optionalValue}(\n stargateBridgeExtraData.stargateDstChainId,\n payable(senderAddress),\n abi.encodePacked(receiverAddress),\n amount,\n stargateBridgeExtraData.minReceivedAmt\n );\n } else {\n ERC20 tokenInstance = ERC20(token);\n tokenInstance.safeTransferFrom(msg.sender, socketGateway, amount);\n tokenInstance.safeApprove(address(router), amount);\n {\n router.swap{value: value}(\n stargateBridgeExtraData.stargateDstChainId,\n stargateBridgeExtraData.srcPoolId,\n stargateBridgeExtraData.dstPoolId,\n payable(senderAddress), // default to refund to main contract\n amount,\n stargateBridgeExtraData.minReceivedAmt,\n IBridgeStargate.lzTxObj(\n stargateBridgeExtraData.destinationGasLimit,\n 0, // zero amount since this is a ERC20 bridging\n \"0x\" //empty data since this is for only ERC20\n ),\n abi.encodePacked(receiverAddress),\n stargateBridgeExtraData.destinationPayload\n );\n }\n }\n\n emit SocketBridge(\n amount,\n token,\n stargateBridgeExtraData.stargateDstChainId,\n StargateIdentifier,\n msg.sender,\n receiverAddress,\n stargateBridgeExtraData.metadata\n );\n }\n\n function bridgeNativeTo(\n address receiverAddress,\n address senderAddress,\n uint16 stargateDstChainId,\n uint256 amount,\n uint256 minReceivedAmt,\n uint256 optionalValue,\n bytes32 metadata\n ) external payable {\n // perform bridging\n routerETH.swapETH{value: amount + optionalValue}(\n stargateDstChainId,\n payable(senderAddress),\n abi.encodePacked(receiverAddress),\n amount,\n minReceivedAmt\n );\n\n emit SocketBridge(\n amount,\n NATIVE_TOKEN_ADDRESS,\n stargateDstChainId,\n StargateIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n}\n" - } - }, - "settings": { - "optimizer": { - "enabled": true, - "runs": 1000000 - }, - "outputSelection": { - "*": { - "*": [ - "evm.bytecode", - "evm.deployedBytecode", - "devdoc", - "userdoc", - "metadata", - "abi" - ] - } - }, - "metadata": { - "useLiteralContent": true - }, - "libraries": {} - } - }, - "ABI": "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_disabledRoute\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayLengthMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectBridgeRatios\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyNominee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"controllerId\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"controllerAddress\",\"type\":\"address\"}],\"name\":\"ControllerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"controllerId\",\"type\":\"uint32\"}],\"name\":\"ControllerDisabled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"routeId\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"route\",\"type\":\"address\"}],\"name\":\"NewRouteAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"claimer\",\"type\":\"address\"}],\"name\":\"OwnerClaimed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"nominee\",\"type\":\"address\"}],\"name\":\"OwnerNominated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"routeId\",\"type\":\"uint32\"}],\"name\":\"RouteDisabled\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"BRIDGE_AFTER_SWAP_SELECTOR\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"CENT_PERCENT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"controllerAddress\",\"type\":\"address\"}],\"name\":\"addController\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"routeAddress\",\"type\":\"address\"}],\"name\":\"addRoute\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"routeId\",\"type\":\"uint32\"}],\"name\":\"addressAt\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"controllerCount\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"name\":\"controllers\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"controllerId\",\"type\":\"uint32\"}],\"name\":\"disableController\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"routeId\",\"type\":\"uint32\"}],\"name\":\"disableRoute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"disabledRouteAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"controllerId\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"struct ISocketGateway.SocketControllerRequest\",\"name\":\"socketControllerRequest\",\"type\":\"tuple\"}],\"name\":\"executeController\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"controllerId\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"struct ISocketGateway.SocketControllerRequest[]\",\"name\":\"controllerRequests\",\"type\":\"tuple[]\"}],\"name\":\"executeControllers\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"routeId\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"routeData\",\"type\":\"bytes\"}],\"name\":\"executeRoute\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"routeIds\",\"type\":\"uint32[]\"},{\"internalType\":\"bytes[]\",\"name\":\"dataItems\",\"type\":\"bytes[]\"}],\"name\":\"executeRoutes\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"controllerId\",\"type\":\"uint32\"}],\"name\":\"getController\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"routeId\",\"type\":\"uint32\"}],\"name\":\"getRoute\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"nominee_\",\"type\":\"address\"}],\"name\":\"nominateOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nominee\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"userAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"rescueEther\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"userAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"rescueFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"name\":\"routes\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"routesCount\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"routeAddresses\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"tokenAddresses\",\"type\":\"address[]\"},{\"internalType\":\"bool\",\"name\":\"isMax\",\"type\":\"bool\"}],\"name\":\"setApprovalForRouters\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"swapRouteId\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"swapImplData\",\"type\":\"bytes\"},{\"internalType\":\"uint32[]\",\"name\":\"bridgeRouteIds\",\"type\":\"uint32[]\"},{\"internalType\":\"bytes[]\",\"name\":\"bridgeImplDataItems\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256[]\",\"name\":\"bridgeRatios\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"eventDataItems\",\"type\":\"bytes[]\"}],\"internalType\":\"struct ISocketRequest.SwapMultiBridgeRequest\",\"name\":\"swapMultiBridgeRequest\",\"type\":\"tuple\"}],\"name\":\"swapAndMultiBridge\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", - "ContractName": "SocketGateway", - "CompilerVersion": "v0.8.7+commit.e28d00a7", - "OptimizationUsed": 1, - "Runs": 1000000, - "ConstructorArguments": "0x000000000000000000000000e8dd38e673a93ccfc2e3d7053efccb5c93f493650000000000000000000000000f34a522ff82151c90679b73211955068fd854f1", - "EVMVersion": "Default", - "Library": "", - "LicenseType": "", - "Proxy": 1, - "Implementation": "0xa3c4e32af0da5efaddb20cc9fb26159f55c8c42f", - "SwarmSource": "" - } -] \ No newline at end of file +[{"SourceCode":{"language":"Solidity","sources":{"src/bridges/hop/interfaces/amm.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/**\n * @title HopAMM\n * @notice Interface to handle the token bridging to L2 chains.\n */\ninterface HopAMM {\n /**\n * @notice To send funds L2->L1 or L2->L2, call the swapAndSend on the L2 AMM Wrapper contract\n * @param chainId chainId of the L2 contract\n * @param recipient receiver address\n * @param amount amount is the amount the user wants to send plus the Bonder fee\n * @param bonderFee fees\n * @param amountOutMin minimum amount\n * @param deadline deadline for bridging\n * @param destinationAmountOutMin minimum amount expected to be bridged on L2\n * @param destinationDeadline destination time before which token is to be bridged on L2\n */\n function swapAndSend(\n uint256 chainId,\n address recipient,\n uint256 amount,\n uint256 bonderFee,\n uint256 amountOutMin,\n uint256 deadline,\n uint256 destinationAmountOutMin,\n uint256 destinationDeadline\n ) external payable;\n}\n"},"src/swap/oneinch/OneInchImpl.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport \"../SwapImplBase.sol\";\nimport {SwapFailed} from \"../../errors/SocketErrors.sol\";\nimport {ONEINCH} from \"../../static/RouteIdentifiers.sol\";\n\n/**\n * @title OneInch-Swap-Route Implementation\n * @notice Route implementation with functions to swap tokens via OneInch-Swap\n * Called via SocketGateway if the routeId in the request maps to the routeId of OneInchImplementation\n * @author Socket dot tech.\n */\ncontract OneInchImpl is SwapImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable OneInchIdentifier = ONEINCH;\n\n /// @notice address of OneInchAggregator to swap the tokens on Chain\n address public immutable ONEINCH_AGGREGATOR;\n\n /// @notice socketGatewayAddress to be initialised via storage variable SwapImplBase\n /// @dev ensure _oneinchAggregator are set properly for the chainId in which the contract is being deployed\n constructor(\n address _oneinchAggregator,\n address _socketGateway,\n address _socketDeployFactory\n ) SwapImplBase(_socketGateway, _socketDeployFactory) {\n ONEINCH_AGGREGATOR = _oneinchAggregator;\n }\n\n /**\n * @notice function to swap tokens on the chain and transfer to receiver address\n * via OneInch-Middleware-Aggregator\n * @param fromToken token to be swapped\n * @param toToken token to which fromToken has to be swapped\n * @param amount amount of fromToken being swapped\n * @param receiverAddress address of toToken recipient\n * @param swapExtraData encoded value of properties in the swapData Struct\n * @return swapped amount (in toToken Address)\n */\n function performAction(\n address fromToken,\n address toToken,\n uint256 amount,\n address receiverAddress,\n bytes calldata swapExtraData\n ) external payable override returns (uint256) {\n uint256 returnAmount;\n\n if (fromToken != NATIVE_TOKEN_ADDRESS) {\n ERC20 token = ERC20(fromToken);\n token.safeTransferFrom(msg.sender, socketGateway, amount);\n token.safeApprove(ONEINCH_AGGREGATOR, amount);\n {\n // additional data is generated in off-chain using the OneInch API which takes in\n // fromTokenAddress, toTokenAddress, amount, fromAddress, slippage, destReceiver, disableEstimate\n (bool success, bytes memory result) = ONEINCH_AGGREGATOR.call(\n swapExtraData\n );\n token.safeApprove(ONEINCH_AGGREGATOR, 0);\n\n if (!success) {\n revert SwapFailed();\n }\n\n returnAmount = abi.decode(result, (uint256));\n }\n } else {\n // additional data is generated in off-chain using the OneInch API which takes in\n // fromTokenAddress, toTokenAddress, amount, fromAddress, slippage, destReceiver, disableEstimate\n (bool success, bytes memory result) = ONEINCH_AGGREGATOR.call{\n value: amount\n }(swapExtraData);\n if (!success) {\n revert SwapFailed();\n }\n returnAmount = abi.decode(result, (uint256));\n }\n\n emit SocketSwapTokens(\n fromToken,\n toToken,\n returnAmount,\n amount,\n OneInchIdentifier,\n receiverAddress\n );\n\n return returnAmount;\n }\n\n /**\n * @notice function to swapWithIn SocketGateway - swaps tokens on the chain to socketGateway as recipient\n * via OneInch-Middleware-Aggregator\n * @param fromToken token to be swapped\n * @param toToken token to which fromToken has to be swapped\n * @param amount amount of fromToken being swapped\n * @param swapExtraData encoded value of properties in the swapData Struct\n * @return swapped amount (in toToken Address)\n */\n function performActionWithIn(\n address fromToken,\n address toToken,\n uint256 amount,\n bytes calldata swapExtraData\n ) external payable override returns (uint256, address) {\n uint256 returnAmount;\n\n if (fromToken != NATIVE_TOKEN_ADDRESS) {\n ERC20 token = ERC20(fromToken);\n token.safeTransferFrom(msg.sender, socketGateway, amount);\n token.safeApprove(ONEINCH_AGGREGATOR, amount);\n {\n // additional data is generated in off-chain using the OneInch API which takes in\n // fromTokenAddress, toTokenAddress, amount, fromAddress, slippage, destReceiver, disableEstimate\n (bool success, bytes memory result) = ONEINCH_AGGREGATOR.call(\n swapExtraData\n );\n token.safeApprove(ONEINCH_AGGREGATOR, 0);\n\n if (!success) {\n revert SwapFailed();\n }\n\n returnAmount = abi.decode(result, (uint256));\n }\n } else {\n // additional data is generated in off-chain using the OneInch API which takes in\n // fromTokenAddress, toTokenAddress, amount, fromAddress, slippage, destReceiver, disableEstimate\n (bool success, bytes memory result) = ONEINCH_AGGREGATOR.call{\n value: amount\n }(swapExtraData);\n if (!success) {\n revert SwapFailed();\n }\n returnAmount = abi.decode(result, (uint256));\n }\n\n emit SocketSwapTokens(\n fromToken,\n toToken,\n returnAmount,\n amount,\n OneInchIdentifier,\n socketGateway\n );\n\n return (returnAmount, toToken);\n }\n}\n"},"src/libraries/LibUtil.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport \"./LibBytes.sol\";\n\n/// @title LibUtil library\n/// @notice library with helper functions to operate on bytes-data and addresses\n/// @author socket dot tech\nlibrary LibUtil {\n /// @notice LibBytes library to handle operations on bytes\n using LibBytes for bytes;\n\n /// @notice function to extract revertMessage from bytes data\n /// @dev use the revertMessage and then further revert with a custom revert and message\n /// @param _res bytes data received from the transaction call\n function getRevertMsg(\n bytes memory _res\n ) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_res.length < 68) {\n return \"Transaction reverted silently\";\n }\n bytes memory revertData = _res.slice(4, _res.length - 4); // Remove the selector which is the first 4 bytes\n return abi.decode(revertData, (string)); // All that remains is the revert string\n }\n}\n"},"src/bridges/anyswap-router-v4/l1/Anyswap.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {BridgeImplBase} from \"../../BridgeImplBase.sol\";\nimport {ANYSWAP} from \"../../../static/RouteIdentifiers.sol\";\n\n/**\n * @title Anyswap-V4-Route L1 Implementation\n * @notice Route implementation with functions to bridge ERC20 via Anyswap-Bridge\n * Called via SocketGateway if the routeId in the request maps to the routeId of AnyswapImplementation\n * This is the L1 implementation, so this is used when transferring from l1 to supported l1s or L1.\n * Contains function to handle bridging as post-step i.e linked to a preceeding step for swap\n * RequestData is different to just bride and bridging chained with swap\n * @author Socket dot tech.\n */\n\n/// @notice Interface to interact with AnyswapV4-Router Implementation\ninterface AnyswapV4Router {\n function anySwapOutUnderlying(\n address token,\n address to,\n uint256 amount,\n uint256 toChainID\n ) external;\n}\n\ncontract AnyswapImplL1 is BridgeImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable AnyswapIdentifier = ANYSWAP;\n\n /// @notice Function-selector for ERC20-token bridging on Anyswap-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge ERC20 tokens\n bytes4 public immutable ANYSWAP_L1_ERC20_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeERC20To(uint256,uint256,bytes32,address,address,address)\"\n )\n );\n\n bytes4 public immutable ANYSWAP_SWAP_BRIDGE_SELECTOR =\n bytes4(\n keccak256(\n \"swapAndBridge(uint32,bytes,(uint256,address,address,bytes32))\"\n )\n );\n\n /// @notice AnSwapV4Router Contract instance used to deposit ERC20 on to Anyswap-Bridge\n /// @dev contract instance is to be initialized in the constructor using the router-address passed as constructor argument\n AnyswapV4Router public immutable router;\n\n /**\n * @notice Constructor sets the router address and socketGateway address.\n * @dev anyswap 4 router is immutable. so no setter function required.\n */\n constructor(\n address _router,\n address _socketGateway,\n address _socketDeployFactory\n ) BridgeImplBase(_socketGateway, _socketDeployFactory) {\n router = AnyswapV4Router(_router);\n }\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct AnyswapBridgeDataNoToken {\n /// @notice destination ChainId\n uint256 toChainId;\n /// @notice address of receiver of bridged tokens\n address receiverAddress;\n /// @notice address of wrapperToken, WrappedVersion of the token being bridged\n address wrapperTokenAddress;\n /// @notice socket offchain created hash\n bytes32 metadata;\n }\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct AnyswapBridgeData {\n /// @notice destination ChainId\n uint256 toChainId;\n /// @notice address of receiver of bridged tokens\n address receiverAddress;\n /// @notice address of wrapperToken, WrappedVersion of the token being bridged\n address wrapperTokenAddress;\n /// @notice address of token being bridged\n address token;\n /// @notice socket offchain created hash\n bytes32 metadata;\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from swapAndBridge, this function is called when the swap has already happened at a different place.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in AnyswapBridgeData struct\n * @param amount amount of tokens being bridged. this can be ERC20 or native\n * @param bridgeData encoded data for AnyswapBridge\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable override {\n AnyswapBridgeData memory anyswapBridgeData = abi.decode(\n bridgeData,\n (AnyswapBridgeData)\n );\n ERC20(anyswapBridgeData.token).safeApprove(address(router), amount);\n router.anySwapOutUnderlying(\n anyswapBridgeData.wrapperTokenAddress,\n anyswapBridgeData.receiverAddress,\n amount,\n anyswapBridgeData.toChainId\n );\n\n emit SocketBridge(\n amount,\n anyswapBridgeData.token,\n anyswapBridgeData.toChainId,\n AnyswapIdentifier,\n msg.sender,\n anyswapBridgeData.receiverAddress,\n anyswapBridgeData.metadata\n );\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from bridgeAfterSwap since this function holds the logic for swapping tokens too.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in AnyswapBridgeData struct\n * @param swapId routeId for the swapImpl\n * @param swapData encoded data for swap\n * @param anyswapBridgeData encoded data for AnyswapBridge\n */\n function swapAndBridge(\n uint32 swapId,\n bytes calldata swapData,\n AnyswapBridgeDataNoToken calldata anyswapBridgeData\n ) external payable {\n (bool success, bytes memory result) = socketRoute\n .getRoute(swapId)\n .delegatecall(swapData);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n (uint256 bridgeAmount, address token) = abi.decode(\n result,\n (uint256, address)\n );\n\n ERC20(token).safeApprove(address(router), bridgeAmount);\n router.anySwapOutUnderlying(\n anyswapBridgeData.wrapperTokenAddress,\n anyswapBridgeData.receiverAddress,\n bridgeAmount,\n anyswapBridgeData.toChainId\n );\n\n emit SocketBridge(\n bridgeAmount,\n token,\n anyswapBridgeData.toChainId,\n AnyswapIdentifier,\n msg.sender,\n anyswapBridgeData.receiverAddress,\n anyswapBridgeData.metadata\n );\n }\n\n /**\n * @notice function to handle ERC20 bridging to receipent via Anyswap-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param amount amount being bridged\n * @param toChainId destination ChainId\n * @param receiverAddress address of receiver of bridged tokens\n * @param token address of token being bridged\n * @param wrapperTokenAddress address of wrapperToken, WrappedVersion of the token being bridged\n */\n function bridgeERC20To(\n uint256 amount,\n uint256 toChainId,\n bytes32 metadata,\n address receiverAddress,\n address token,\n address wrapperTokenAddress\n ) external payable {\n ERC20 tokenInstance = ERC20(token);\n tokenInstance.safeTransferFrom(msg.sender, socketGateway, amount);\n tokenInstance.safeApprove(address(router), amount);\n router.anySwapOutUnderlying(\n wrapperTokenAddress,\n receiverAddress,\n amount,\n toChainId\n );\n\n emit SocketBridge(\n amount,\n token,\n toChainId,\n AnyswapIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n}\n"},"src/bridges/cbridge/CelerStorageWrapper.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity >=0.8.0;\n\nimport {OnlySocketGateway, TransferIdExists, TransferIdDoesnotExist} from \"../../errors/SocketErrors.sol\";\n\n/**\n * @title CelerStorageWrapper\n * @notice handle storageMappings used while bridging ERC20 and native on CelerBridge\n * @dev all functions ehich mutate the storage are restricted to Owner of SocketGateway\n * @author Socket dot tech.\n */\ncontract CelerStorageWrapper {\n /// @notice Socketgateway-address to be set in the constructor of CelerStorageWrapper\n address public immutable socketGateway;\n\n /// @notice mapping to store the transferId generated during bridging on Celer to message-sender\n mapping(bytes32 => address) private transferIdMapping;\n\n /// @notice socketGatewayAddress to be initialised via storage variable BridgeImplBase\n constructor(address _socketGateway) {\n socketGateway = _socketGateway;\n }\n\n /**\n * @notice function to store the transferId and message-sender of a bridging activity\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in CelerBridgeData struct\n * @param transferId transferId generated during the bridging of ERC20 or native on CelerBridge\n * @param transferIdAddress message sender who is making the bridging on CelerBridge\n */\n function setAddressForTransferId(\n bytes32 transferId,\n address transferIdAddress\n ) external {\n if (msg.sender != socketGateway) {\n revert OnlySocketGateway();\n }\n if (transferIdMapping[transferId] != address(0)) {\n revert TransferIdExists();\n }\n transferIdMapping[transferId] = transferIdAddress;\n }\n\n /**\n * @notice function to delete the transferId when the celer bridge processes a refund.\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in CelerBridgeData struct\n * @param transferId transferId generated during the bridging of ERC20 or native on CelerBridge\n */\n function deleteTransferId(bytes32 transferId) external {\n if (msg.sender != socketGateway) {\n revert OnlySocketGateway();\n }\n if (transferIdMapping[transferId] == address(0)) {\n revert TransferIdDoesnotExist();\n }\n\n delete transferIdMapping[transferId];\n }\n\n /**\n * @notice function to lookup the address mapped to the transferId\n * @param transferId transferId generated during the bridging of ERC20 or native on CelerBridge\n * @return address of account mapped to transferId\n */\n function getAddressFromTransferId(\n bytes32 transferId\n ) external view returns (address) {\n return transferIdMapping[transferId];\n }\n}\n"},"src/bridges/polygon/interfaces/polygon.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/**\n * @title RootChain Manager Interface for Polygon Bridge.\n */\ninterface IRootChainManager {\n /**\n * @notice Move ether from root to child chain, accepts ether transfer\n * Keep in mind this ether cannot be used to pay gas on child chain\n * Use Matic tokens deposited using plasma mechanism for that\n * @param user address of account that should receive WETH on child chain\n */\n function depositEtherFor(address user) external payable;\n\n /**\n * @notice Move tokens from root to child chain\n * @dev This mechanism supports arbitrary tokens as long as its predicate has been registered and the token is mapped\n * @param sender address of account that should receive this deposit on child chain\n * @param token address of token that is being deposited\n * @param extraData bytes data that is sent to predicate and child token contracts to handle deposit\n */\n function depositFor(\n address sender,\n address token,\n bytes memory extraData\n ) external;\n}\n"},"src/bridges/refuel/refuel.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport \"./interfaces/refuel.sol\";\nimport \"../BridgeImplBase.sol\";\nimport {REFUEL} from \"../../static/RouteIdentifiers.sol\";\n\n/**\n * @title Refuel-Route Implementation\n * @notice Route implementation with functions to bridge Native via Refuel-Bridge\n * Called via SocketGateway if the routeId in the request maps to the routeId of RefuelImplementation\n * @author Socket dot tech.\n */\ncontract RefuelBridgeImpl is BridgeImplBase {\n bytes32 public immutable RefuelIdentifier = REFUEL;\n\n /// @notice refuelBridge-Contract address used to deposit Native on Refuel-Bridge\n address public immutable refuelBridge;\n\n /// @notice Function-selector for Native bridging via Refuel-Bridge\n /// @dev This function selector is to be used while buidling transaction-data to bridge Native tokens\n bytes4 public immutable REFUEL_NATIVE_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(keccak256(\"bridgeNativeTo(uint256,address,uint256,bytes32)\"));\n\n bytes4 public immutable REFUEL_NATIVE_SWAP_BRIDGE_SELECTOR =\n bytes4(\n keccak256(\"swapAndBridge(uint32,address,uint256,bytes32,bytes)\")\n );\n\n /// @notice socketGatewayAddress to be initialised via storage variable BridgeImplBase\n /// @dev ensure _refuelBridge are set properly for the chainId in which the contract is being deployed\n constructor(\n address _refuelBridge,\n address _socketGateway,\n address _socketDeployFactory\n ) BridgeImplBase(_socketGateway, _socketDeployFactory) {\n refuelBridge = _refuelBridge;\n }\n\n // Function to receive Ether. msg.data must be empty\n receive() external payable {}\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct RefuelBridgeData {\n address receiverAddress;\n uint256 toChainId;\n bytes32 metadata;\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from swapAndBridge, this function is called when the swap has already happened at a different place.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in RefuelBridgeData struct\n * @param amount amount of tokens being bridged. this must be only native\n * @param bridgeData encoded data for RefuelBridge\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable override {\n RefuelBridgeData memory refuelBridgeData = abi.decode(\n bridgeData,\n (RefuelBridgeData)\n );\n IRefuel(refuelBridge).depositNativeToken{value: amount}(\n refuelBridgeData.toChainId,\n refuelBridgeData.receiverAddress\n );\n\n emit SocketBridge(\n amount,\n NATIVE_TOKEN_ADDRESS,\n refuelBridgeData.toChainId,\n RefuelIdentifier,\n msg.sender,\n refuelBridgeData.receiverAddress,\n refuelBridgeData.metadata\n );\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from bridgeAfterSwap since this function holds the logic for swapping tokens too.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in RefuelBridgeData struct\n * @param swapId routeId for the swapImpl\n * @param receiverAddress receiverAddress\n * @param toChainId toChainId\n * @param swapData encoded data for swap\n */\n function swapAndBridge(\n uint32 swapId,\n address receiverAddress,\n uint256 toChainId,\n bytes32 metadata,\n bytes calldata swapData\n ) external payable {\n (bool success, bytes memory result) = socketRoute\n .getRoute(swapId)\n .delegatecall(swapData);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n (uint256 bridgeAmount, ) = abi.decode(result, (uint256, address));\n IRefuel(refuelBridge).depositNativeToken{value: bridgeAmount}(\n toChainId,\n receiverAddress\n );\n\n emit SocketBridge(\n bridgeAmount,\n NATIVE_TOKEN_ADDRESS,\n toChainId,\n RefuelIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n\n /**\n * @notice function to handle Native bridging to receipent via Refuel-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param amount amount of native being refuelled to destination chain\n * @param receiverAddress recipient address of the refuelled native\n * @param toChainId destinationChainId\n */\n function bridgeNativeTo(\n uint256 amount,\n address receiverAddress,\n uint256 toChainId,\n bytes32 metadata\n ) external payable {\n IRefuel(refuelBridge).depositNativeToken{value: amount}(\n toChainId,\n receiverAddress\n );\n\n emit SocketBridge(\n amount,\n NATIVE_TOKEN_ADDRESS,\n toChainId,\n RefuelIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n}\n"},"src/bridges/across/interfaces/across.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice interface with functions to interact with SpokePool contract of Across-Bridge\ninterface SpokePool {\n /**************************************\n * DEPOSITOR FUNCTIONS *\n **************************************/\n\n /**\n * @notice Called by user to bridge funds from origin to destination chain. Depositor will effectively lock\n * tokens in this contract and receive a destination token on the destination chain. The origin => destination\n * token mapping is stored on the L1 HubPool.\n * @notice The caller must first approve this contract to spend amount of originToken.\n * @notice The originToken => destinationChainId must be enabled.\n * @notice This method is payable because the caller is able to deposit native token if the originToken is\n * wrappedNativeToken and this function will handle wrapping the native token to wrappedNativeToken.\n * @param recipient Address to receive funds at on destination chain.\n * @param originToken Token to lock into this contract to initiate deposit.\n * @param amount Amount of tokens to deposit. Will be amount of tokens to receive less fees.\n * @param destinationChainId Denotes network where user will receive funds from SpokePool by a relayer.\n * @param relayerFeePct % of deposit amount taken out to incentivize a fast relayer.\n * @param quoteTimestamp Timestamp used by relayers to compute this deposit's realizedLPFeePct which is paid\n * to LP pool on HubPool.\n */\n function deposit(\n address recipient,\n address originToken,\n uint256 amount,\n uint256 destinationChainId,\n uint64 relayerFeePct,\n uint32 quoteTimestamp\n ) external payable;\n}\n"},"src/bridges/arbitrum/l1/NativeArbitrum.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {L1GatewayRouter} from \"../interfaces/arbitrum.sol\";\nimport {BridgeImplBase} from \"../../BridgeImplBase.sol\";\nimport {NATIVE_ARBITRUM} from \"../../../static/RouteIdentifiers.sol\";\n\n/**\n * @title Native Arbitrum-Route Implementation\n * @notice Route implementation with functions to bridge ERC20 via NativeArbitrum-Bridge\n * @notice Called via SocketGateway if the routeId in the request maps to the routeId of NativeArbitrum-Implementation\n * @notice This is used when transferring from ethereum chain to arbitrum via their native bridge.\n * @notice Contains function to handle bridging as post-step i.e linked to a preceeding step for swap\n * @notice RequestData is different to just bride and bridging chained with swap\n * @author Socket dot tech.\n */\ncontract NativeArbitrumImpl is BridgeImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable NativeArbitrumIdentifier = NATIVE_ARBITRUM;\n\n uint256 public constant DESTINATION_CHAIN_ID = 42161;\n\n /// @notice Function-selector for ERC20-token bridging on NativeArbitrum\n /// @dev This function selector is to be used while buidling transaction-data to bridge ERC20 tokens\n bytes4\n public immutable NATIVE_ARBITRUM_ERC20_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeERC20To(uint256,uint256,uint256,uint256,bytes32,address,address,address,bytes)\"\n )\n );\n\n bytes4 public immutable NATIVE_ARBITRUM_SWAP_BRIDGE_SELECTOR =\n bytes4(\n keccak256(\n \"swapAndBridge(uint32,bytes,(uint256,uint256,uint256,address,address,bytes32,bytes))\"\n )\n );\n\n /// @notice router address of NativeArbitrum Bridge\n /// @notice GatewayRouter looks up ERC20Token's gateway, and finding that it's Standard ERC20 gateway (the L1ERC20Gateway contract).\n address public immutable router;\n\n /// @notice socketGatewayAddress to be initialised via storage variable BridgeImplBase\n /// @dev ensure router-address are set properly for the chainId in which the contract is being deployed\n constructor(\n address _router,\n address _socketGateway,\n address _socketDeployFactory\n ) BridgeImplBase(_socketGateway, _socketDeployFactory) {\n router = _router;\n }\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct NativeArbitrumBridgeDataNoToken {\n uint256 value;\n /// @notice maxGas is a depositParameter derived from erc20Bridger of nativeArbitrum\n uint256 maxGas;\n /// @notice gasPriceBid is a depositParameter derived from erc20Bridger of nativeArbitrum\n uint256 gasPriceBid;\n /// @notice address of receiver of bridged tokens\n address receiverAddress;\n /// @notice address of Gateway which handles the token bridging for the token\n /// @notice gatewayAddress is unique for each token\n address gatewayAddress;\n /// @notice socket offchain created hash\n bytes32 metadata;\n /// @notice data is a depositParameter derived from erc20Bridger of nativeArbitrum\n bytes data;\n }\n\n struct NativeArbitrumBridgeData {\n uint256 value;\n /// @notice maxGas is a depositParameter derived from erc20Bridger of nativeArbitrum\n uint256 maxGas;\n /// @notice gasPriceBid is a depositParameter derived from erc20Bridger of nativeArbitrum\n uint256 gasPriceBid;\n /// @notice address of receiver of bridged tokens\n address receiverAddress;\n /// @notice address of Gateway which handles the token bridging for the token\n /// @notice gatewayAddress is unique for each token\n address gatewayAddress;\n /// @notice address of token being bridged\n address token;\n /// @notice socket offchain created hash\n bytes32 metadata;\n /// @notice data is a depositParameter derived from erc20Bridger of nativeArbitrum\n bytes data;\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from swapAndBridge, this function is called when the swap has already happened at a different place.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in NativeArbitrumBridgeData struct\n * @param amount amount of tokens being bridged. this can be ERC20 or native\n * @param bridgeData encoded data for NativeArbitrumBridge\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable override {\n NativeArbitrumBridgeData memory nativeArbitrumBridgeData = abi.decode(\n bridgeData,\n (NativeArbitrumBridgeData)\n );\n ERC20(nativeArbitrumBridgeData.token).safeApprove(\n nativeArbitrumBridgeData.gatewayAddress,\n amount\n );\n\n L1GatewayRouter(router).outboundTransfer{\n value: nativeArbitrumBridgeData.value\n }(\n nativeArbitrumBridgeData.token,\n nativeArbitrumBridgeData.receiverAddress,\n amount,\n nativeArbitrumBridgeData.maxGas,\n nativeArbitrumBridgeData.gasPriceBid,\n nativeArbitrumBridgeData.data\n );\n\n emit SocketBridge(\n amount,\n nativeArbitrumBridgeData.token,\n DESTINATION_CHAIN_ID,\n NativeArbitrumIdentifier,\n msg.sender,\n nativeArbitrumBridgeData.receiverAddress,\n nativeArbitrumBridgeData.metadata\n );\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from bridgeAfterSwap since this function holds the logic for swapping tokens too.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in NativeArbitrumBridgeData struct\n * @param swapId routeId for the swapImpl\n * @param swapData encoded data for swap\n * @param nativeArbitrumBridgeData encoded data for NativeArbitrumBridge\n */\n function swapAndBridge(\n uint32 swapId,\n bytes calldata swapData,\n NativeArbitrumBridgeDataNoToken calldata nativeArbitrumBridgeData\n ) external payable {\n (bool success, bytes memory result) = socketRoute\n .getRoute(swapId)\n .delegatecall(swapData);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n (uint256 bridgeAmount, address token) = abi.decode(\n result,\n (uint256, address)\n );\n ERC20(token).safeApprove(\n nativeArbitrumBridgeData.gatewayAddress,\n bridgeAmount\n );\n\n L1GatewayRouter(router).outboundTransfer{\n value: nativeArbitrumBridgeData.value\n }(\n token,\n nativeArbitrumBridgeData.receiverAddress,\n bridgeAmount,\n nativeArbitrumBridgeData.maxGas,\n nativeArbitrumBridgeData.gasPriceBid,\n nativeArbitrumBridgeData.data\n );\n\n emit SocketBridge(\n bridgeAmount,\n token,\n DESTINATION_CHAIN_ID,\n NativeArbitrumIdentifier,\n msg.sender,\n nativeArbitrumBridgeData.receiverAddress,\n nativeArbitrumBridgeData.metadata\n );\n }\n\n /**\n * @notice function to handle ERC20 bridging to receipent via NativeArbitrum-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param amount amount being bridged\n * @param value value\n * @param maxGas maxGas is a depositParameter derived from erc20Bridger of nativeArbitrum\n * @param gasPriceBid gasPriceBid is a depositParameter derived from erc20Bridger of nativeArbitrum\n * @param receiverAddress address of receiver of bridged tokens\n * @param token address of token being bridged\n * @param gatewayAddress address of Gateway which handles the token bridging for the token, gatewayAddress is unique for each token\n * @param data data is a depositParameter derived from erc20Bridger of nativeArbitrum\n */\n function bridgeERC20To(\n uint256 amount,\n uint256 value,\n uint256 maxGas,\n uint256 gasPriceBid,\n bytes32 metadata,\n address receiverAddress,\n address token,\n address gatewayAddress,\n bytes memory data\n ) external payable {\n ERC20 tokenInstance = ERC20(token);\n tokenInstance.safeTransferFrom(msg.sender, socketGateway, amount);\n tokenInstance.safeApprove(gatewayAddress, amount);\n\n L1GatewayRouter(router).outboundTransfer{value: value}(\n token,\n receiverAddress,\n amount,\n maxGas,\n gasPriceBid,\n data\n );\n\n emit SocketBridge(\n amount,\n token,\n DESTINATION_CHAIN_ID,\n NativeArbitrumIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n}\n"},"src/bridges/across/Across.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport \"./interfaces/across.sol\";\nimport \"../BridgeImplBase.sol\";\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {ACROSS} from \"../../static/RouteIdentifiers.sol\";\n\n/**\n * @title Across-Route Implementation\n * @notice Route implementation with functions to bridge ERC20 and Native via Across-Bridge\n * Called via SocketGateway if the routeId in the request maps to the routeId of AcrossImplementation\n * Contains function to handle bridging as post-step i.e linked to a preceeding step for swap\n * RequestData is different to just bride and bridging chained with swap\n * @author Socket dot tech.\n */\ncontract AcrossImpl is BridgeImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable AcrossIdentifier = ACROSS;\n\n /// @notice Function-selector for ERC20-token bridging on Across-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge ERC20 tokens\n bytes4 public immutable ACROSS_ERC20_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeERC20To(uint256,uint256,bytes32,address,address,uint32,uint64)\"\n )\n );\n\n /// @notice Function-selector for Native bridging on Across-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge Native tokens\n bytes4 public immutable ACROSS_NATIVE_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeNativeTo(uint256,uint256,bytes32,address,uint32,uint64)\"\n )\n );\n\n bytes4 public immutable ACROSS_SWAP_BRIDGE_SELECTOR =\n bytes4(\n keccak256(\n \"swapAndBridge(uint32,bytes,(uint256,address,uint32,uint64,bytes32))\"\n )\n );\n\n /// @notice spokePool Contract instance used to deposit ERC20 and Native on to Across-Bridge\n /// @dev contract instance is to be initialized in the constructor using the spokePoolAddress passed as constructor argument\n SpokePool public immutable spokePool;\n address public immutable spokePoolAddress;\n\n /// @notice address of WETH token to be initialised in constructor\n address public immutable WETH;\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct AcrossBridgeDataNoToken {\n uint256 toChainId;\n address receiverAddress;\n uint32 quoteTimestamp;\n uint64 relayerFeePct;\n bytes32 metadata;\n }\n\n struct AcrossBridgeData {\n uint256 toChainId;\n address receiverAddress;\n address token;\n uint32 quoteTimestamp;\n uint64 relayerFeePct;\n bytes32 metadata;\n }\n\n /// @notice socketGatewayAddress to be initialised via storage variable BridgeImplBase\n /// @dev ensure spokepool, weth-address are set properly for the chainId in which the contract is being deployed\n constructor(\n address _spokePool,\n address _wethAddress,\n address _socketGateway,\n address _socketDeployFactory\n ) BridgeImplBase(_socketGateway, _socketDeployFactory) {\n spokePool = SpokePool(_spokePool);\n spokePoolAddress = _spokePool;\n WETH = _wethAddress;\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from swapAndBridge, this function is called when the swap has already happened at a different place.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in AcrossBridgeData struct\n * @param amount amount of tokens being bridged. this can be ERC20 or native\n * @param bridgeData encoded data for AcrossBridge\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable override {\n AcrossBridgeData memory acrossBridgeData = abi.decode(\n bridgeData,\n (AcrossBridgeData)\n );\n\n if (acrossBridgeData.token == NATIVE_TOKEN_ADDRESS) {\n spokePool.deposit{value: amount}(\n acrossBridgeData.receiverAddress,\n WETH,\n amount,\n acrossBridgeData.toChainId,\n acrossBridgeData.relayerFeePct,\n acrossBridgeData.quoteTimestamp\n );\n } else {\n spokePool.deposit(\n acrossBridgeData.receiverAddress,\n acrossBridgeData.token,\n amount,\n acrossBridgeData.toChainId,\n acrossBridgeData.relayerFeePct,\n acrossBridgeData.quoteTimestamp\n );\n }\n\n emit SocketBridge(\n amount,\n acrossBridgeData.token,\n acrossBridgeData.toChainId,\n AcrossIdentifier,\n msg.sender,\n acrossBridgeData.receiverAddress,\n acrossBridgeData.metadata\n );\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from bridgeAfterSwap since this function holds the logic for swapping tokens too.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in AcrossBridgeData struct\n * @param swapId routeId for the swapImpl\n * @param swapData encoded data for swap\n * @param acrossBridgeData encoded data for AcrossBridge\n */\n function swapAndBridge(\n uint32 swapId,\n bytes calldata swapData,\n AcrossBridgeDataNoToken calldata acrossBridgeData\n ) external payable {\n (bool success, bytes memory result) = socketRoute\n .getRoute(swapId)\n .delegatecall(swapData);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n (uint256 bridgeAmount, address token) = abi.decode(\n result,\n (uint256, address)\n );\n if (token == NATIVE_TOKEN_ADDRESS) {\n spokePool.deposit{value: bridgeAmount}(\n acrossBridgeData.receiverAddress,\n WETH,\n bridgeAmount,\n acrossBridgeData.toChainId,\n acrossBridgeData.relayerFeePct,\n acrossBridgeData.quoteTimestamp\n );\n } else {\n spokePool.deposit(\n acrossBridgeData.receiverAddress,\n token,\n bridgeAmount,\n acrossBridgeData.toChainId,\n acrossBridgeData.relayerFeePct,\n acrossBridgeData.quoteTimestamp\n );\n }\n\n emit SocketBridge(\n bridgeAmount,\n token,\n acrossBridgeData.toChainId,\n AcrossIdentifier,\n msg.sender,\n acrossBridgeData.receiverAddress,\n acrossBridgeData.metadata\n );\n }\n\n /**\n * @notice function to handle ERC20 bridging to receipent via Across-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param amount amount being bridged\n * @param toChainId destination ChainId\n * @param receiverAddress address of receiver of bridged tokens\n * @param token address of token being bridged\n * @param quoteTimestamp timestamp for quote and this is to be used by Across-Bridge contract\n * @param relayerFeePct feePct that will be relayed by the Bridge to the relayer\n */\n function bridgeERC20To(\n uint256 amount,\n uint256 toChainId,\n bytes32 metadata,\n address receiverAddress,\n address token,\n uint32 quoteTimestamp,\n uint64 relayerFeePct\n ) external payable {\n ERC20 tokenInstance = ERC20(token);\n tokenInstance.safeTransferFrom(msg.sender, socketGateway, amount);\n spokePool.deposit(\n receiverAddress,\n address(token),\n amount,\n toChainId,\n relayerFeePct,\n quoteTimestamp\n );\n\n emit SocketBridge(\n amount,\n token,\n toChainId,\n AcrossIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n\n /**\n * @notice function to handle Native bridging to receipent via Across-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param amount amount being bridged\n * @param toChainId destination ChainId\n * @param receiverAddress address of receiver of bridged tokens\n * @param quoteTimestamp timestamp for quote and this is to be used by Across-Bridge contract\n * @param relayerFeePct feePct that will be relayed by the Bridge to the relayer\n */\n function bridgeNativeTo(\n uint256 amount,\n uint256 toChainId,\n bytes32 metadata,\n address receiverAddress,\n uint32 quoteTimestamp,\n uint64 relayerFeePct\n ) external payable {\n spokePool.deposit{value: amount}(\n receiverAddress,\n WETH,\n amount,\n toChainId,\n relayerFeePct,\n quoteTimestamp\n );\n\n emit SocketBridge(\n amount,\n NATIVE_TOKEN_ADDRESS,\n toChainId,\n AcrossIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n}\n"},"src/bridges/cbridge/interfaces/ICelerStorageWrapper.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity >=0.8.0;\n\n/**\n * @title Celer-StorageWrapper interface\n * @notice Interface to handle storageMappings used while bridging ERC20 and native on CelerBridge\n * @dev all functions ehich mutate the storage are restricted to Owner of SocketGateway\n * @author Socket dot tech.\n */\ninterface ICelerStorageWrapper {\n /**\n * @notice function to store the transferId and message-sender of a bridging activity\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in CelerBridgeData struct\n * @param transferId transferId generated during the bridging of ERC20 or native on CelerBridge\n * @param transferIdAddress message sender who is making the bridging on CelerBridge\n */\n function setAddressForTransferId(\n bytes32 transferId,\n address transferIdAddress\n ) external;\n\n /**\n * @notice function to store the transferId and message-sender of a bridging activity\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in CelerBridgeData struct\n * @param transferId transferId generated during the bridging of ERC20 or native on CelerBridge\n */\n function deleteTransferId(bytes32 transferId) external;\n\n /**\n * @notice function to lookup the address mapped to the transferId\n * @param transferId transferId generated during the bridging of ERC20 or native on CelerBridge\n * @return address of account mapped to transferId\n */\n function getAddressFromTransferId(\n bytes32 transferId\n ) external view returns (address);\n}\n"},"src/bridges/optimism/interfaces/optimism.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity >=0.8.0;\n\ninterface L1StandardBridge {\n /**\n * @dev Performs the logic for deposits by storing the ETH and informing the L2 ETH Gateway of\n * the deposit.\n * @param _to Account to give the deposit to on L2.\n * @param _l2Gas Gas limit required to complete the deposit on L2.\n * @param _data Optional data to forward to L2. This data is provided\n * solely as a convenience for external contracts. Aside from enforcing a maximum\n * length, these contracts provide no guarantees about its content.\n */\n function depositETHTo(\n address _to,\n uint32 _l2Gas,\n bytes calldata _data\n ) external payable;\n\n /**\n * @dev deposit an amount of ERC20 to a recipient's balance on L2.\n * @param _l1Token Address of the L1 ERC20 we are depositing\n * @param _l2Token Address of the L1 respective L2 ERC20\n * @param _to L2 address to credit the withdrawal to.\n * @param _amount Amount of the ERC20 to deposit.\n * @param _l2Gas Gas limit required to complete the deposit on L2.\n * @param _data Optional data to forward to L2. This data is provided\n * solely as a convenience for external contracts. Aside from enforcing a maximum\n * length, these contracts provide no guarantees about its content.\n */\n function depositERC20To(\n address _l1Token,\n address _l2Token,\n address _to,\n uint256 _amount,\n uint32 _l2Gas,\n bytes calldata _data\n ) external;\n}\n\ninterface OldL1TokenGateway {\n /**\n * @dev Transfer SNX to L2 First, moves the SNX into the deposit escrow\n *\n * @param _to Account to give the deposit to on L2\n * @param _amount Amount of the ERC20 to deposit.\n */\n function depositTo(address _to, uint256 _amount) external;\n\n /**\n * @dev Transfer SNX to L2 First, moves the SNX into the deposit escrow\n *\n * @param currencyKey currencyKey for the SynthToken\n * @param destination Account to give the deposit to on L2\n * @param amount Amount of the ERC20 to deposit.\n */\n function initiateSynthTransfer(\n bytes32 currencyKey,\n address destination,\n uint256 amount\n ) external;\n}\n"},"src/bridges/arbitrum/interfaces/arbitrum.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\n\n/*\n * Copyright 2021, Offchain Labs, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npragma solidity >=0.8.0;\n\n/**\n * @title L1gatewayRouter for native-arbitrum\n */\ninterface L1GatewayRouter {\n /**\n * @notice outbound function to bridge ERC20 via NativeArbitrum-Bridge\n * @param _token address of token being bridged via GatewayRouter\n * @param _to recipient of the token on arbitrum chain\n * @param _amount amount of ERC20 token being bridged\n * @param _maxGas a depositParameter for bridging the token\n * @param _gasPriceBid a depositParameter for bridging the token\n * @param _data a depositParameter for bridging the token\n * @return calldata returns the output of transactioncall made on gatewayRouter\n */\n function outboundTransfer(\n address _token,\n address _to,\n uint256 _amount,\n uint256 _maxGas,\n uint256 _gasPriceBid,\n bytes calldata _data\n ) external payable returns (bytes calldata);\n}\n"},"src/deployFactory/DisabledSocketRoute.sol":{"content":"//SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {ISocketGateway} from \"../interfaces/ISocketGateway.sol\";\nimport {OnlySocketGatewayOwner} from \"../errors/SocketErrors.sol\";\n\ncontract DisabledSocketRoute {\n using SafeTransferLib for ERC20;\n\n /// @notice immutable variable to store the socketGateway address\n address public immutable socketGateway;\n error RouteDisabled();\n\n /**\n * @notice Construct the base for all BridgeImplementations.\n * @param _socketGateway Socketgateway address, an immutable variable to set.\n */\n constructor(address _socketGateway) {\n socketGateway = _socketGateway;\n }\n\n /// @notice Implementing contract needs to make use of the modifier where restricted access is to be used\n modifier isSocketGatewayOwner() {\n if (msg.sender != ISocketGateway(socketGateway).owner()) {\n revert OnlySocketGatewayOwner();\n }\n _;\n }\n\n /**\n * @notice function to rescue the ERC20 tokens in the bridge Implementation contract\n * @notice this is a function restricted to Owner of SocketGateway only\n * @param token address of ERC20 token being rescued\n * @param userAddress receipient address to which ERC20 tokens will be rescued to\n * @param amount amount of ERC20 tokens being rescued\n */\n function rescueFunds(\n address token,\n address userAddress,\n uint256 amount\n ) external isSocketGatewayOwner {\n ERC20(token).safeTransfer(userAddress, amount);\n }\n\n /**\n * @notice function to rescue the native-balance in the bridge Implementation contract\n * @notice this is a function restricted to Owner of SocketGateway only\n * @param userAddress receipient address to which native-balance will be rescued to\n * @param amount amount of native balance tokens being rescued\n */\n function rescueEther(\n address payable userAddress,\n uint256 amount\n ) external isSocketGatewayOwner {\n userAddress.transfer(amount);\n }\n\n /**\n * @notice Handle route function calls gracefully.\n */\n fallback() external payable {\n revert RouteDisabled();\n }\n\n /**\n * @notice Support receiving ether to handle refunds etc.\n */\n receive() external payable {}\n}\n"},"src/bridges/polygon/NativePolygon.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport \"./interfaces/polygon.sol\";\nimport {BridgeImplBase} from \"../BridgeImplBase.sol\";\nimport {NATIVE_POLYGON} from \"../../static/RouteIdentifiers.sol\";\n\n/**\n * @title NativePolygon-Route Implementation\n * @notice This is the L1 implementation, so this is used when transferring from ethereum to polygon via their native bridge.\n * @author Socket dot tech.\n */\ncontract NativePolygonImpl is BridgeImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable NativePolyonIdentifier = NATIVE_POLYGON;\n\n /// @notice destination-chain-Id for this router is always arbitrum\n uint256 public constant DESTINATION_CHAIN_ID = 137;\n\n /// @notice Function-selector for ERC20-token bridging on NativePolygon-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge ERC20 tokens\n bytes4\n public immutable NATIVE_POLYGON_ERC20_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(keccak256(\"bridgeERC20To(uint256,bytes32,address,address)\"));\n\n /// @notice Function-selector for Native bridging on NativePolygon-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge Native tokens\n bytes4\n public immutable NATIVE_POLYGON_NATIVE_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(keccak256(\"bridgeNativeTo(uint256,bytes32,address)\"));\n\n bytes4 public immutable NATIVE_POLYGON_SWAP_BRIDGE_SELECTOR =\n bytes4(keccak256(\"swapAndBridge(uint32,address,bytes32,bytes)\"));\n\n /// @notice root chain manager proxy on the ethereum chain\n /// @dev to be initialised in the constructor\n IRootChainManager public immutable rootChainManagerProxy;\n\n /// @notice ERC20 Predicate proxy on the ethereum chain\n /// @dev to be initialised in the constructor\n address public immutable erc20PredicateProxy;\n\n /**\n * // @notice We set all the required addresses in the constructor while deploying the contract.\n * // These will be constant addresses.\n * // @dev Please use the Proxy addresses and not the implementation addresses while setting these\n * // @param _rootChainManagerProxy address of the root chain manager proxy on the ethereum chain\n * // @param _erc20PredicateProxy address of the ERC20 Predicate proxy on the ethereum chain.\n * // @param _socketGateway address of the socketGateway contract that calls this contract\n */\n constructor(\n address _rootChainManagerProxy,\n address _erc20PredicateProxy,\n address _socketGateway,\n address _socketDeployFactory\n ) BridgeImplBase(_socketGateway, _socketDeployFactory) {\n rootChainManagerProxy = IRootChainManager(_rootChainManagerProxy);\n erc20PredicateProxy = _erc20PredicateProxy;\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from swapAndBridge, this function is called when the swap has already happened at a different place.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in NativePolygon-BridgeData struct\n * @param amount amount of tokens being bridged. this can be ERC20 or native\n * @param bridgeData encoded data for NativePolygon-Bridge\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable override {\n (address token, address receiverAddress, bytes32 metadata) = abi.decode(\n bridgeData,\n (address, address, bytes32)\n );\n\n if (token == NATIVE_TOKEN_ADDRESS) {\n IRootChainManager(rootChainManagerProxy).depositEtherFor{\n value: amount\n }(receiverAddress);\n } else {\n ERC20(token).safeApprove(erc20PredicateProxy, amount);\n\n // deposit into rootchain manager\n IRootChainManager(rootChainManagerProxy).depositFor(\n receiverAddress,\n token,\n abi.encodePacked(amount)\n );\n }\n\n emit SocketBridge(\n amount,\n token,\n DESTINATION_CHAIN_ID,\n NativePolyonIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from bridgeAfterSwap since this function holds the logic for swapping tokens too.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in NativePolygon-BridgeData struct\n * @param swapId routeId for the swapImpl\n * @param receiverAddress address of the receiver\n * @param swapData encoded data for swap\n */\n function swapAndBridge(\n uint32 swapId,\n address receiverAddress,\n bytes32 metadata,\n bytes calldata swapData\n ) external payable {\n (bool success, bytes memory result) = socketRoute\n .getRoute(swapId)\n .delegatecall(swapData);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n (uint256 bridgeAmount, address token) = abi.decode(\n result,\n (uint256, address)\n );\n\n if (token == NATIVE_TOKEN_ADDRESS) {\n IRootChainManager(rootChainManagerProxy).depositEtherFor{\n value: bridgeAmount\n }(receiverAddress);\n } else {\n ERC20(token).safeApprove(erc20PredicateProxy, bridgeAmount);\n\n // deposit into rootchain manager\n IRootChainManager(rootChainManagerProxy).depositFor(\n receiverAddress,\n token,\n abi.encodePacked(bridgeAmount)\n );\n }\n\n emit SocketBridge(\n bridgeAmount,\n token,\n DESTINATION_CHAIN_ID,\n NativePolyonIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n\n /**\n * @notice function to handle ERC20 bridging to receipent via NativePolygon-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param amount amount of tokens being bridged\n * @param receiverAddress recipient address\n * @param token address of token being bridged\n */\n function bridgeERC20To(\n uint256 amount,\n bytes32 metadata,\n address receiverAddress,\n address token\n ) external payable {\n ERC20 tokenInstance = ERC20(token);\n\n // set allowance for erc20 predicate\n tokenInstance.safeTransferFrom(msg.sender, socketGateway, amount);\n tokenInstance.safeApprove(erc20PredicateProxy, amount);\n\n // deposit into rootchain manager\n rootChainManagerProxy.depositFor(\n receiverAddress,\n token,\n abi.encodePacked(amount)\n );\n\n emit SocketBridge(\n amount,\n token,\n DESTINATION_CHAIN_ID,\n NativePolyonIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n\n /**\n * @notice function to handle Native bridging to receipent via NativePolygon-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param amount amount of tokens being bridged\n * @param receiverAddress recipient address\n */\n function bridgeNativeTo(\n uint256 amount,\n bytes32 metadata,\n address receiverAddress\n ) external payable {\n rootChainManagerProxy.depositEtherFor{value: amount}(receiverAddress);\n\n emit SocketBridge(\n amount,\n NATIVE_TOKEN_ADDRESS,\n DESTINATION_CHAIN_ID,\n NativePolyonIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n}\n"},"src/bridges/stargate/l1/Stargate.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport \"../interfaces/stargate.sol\";\nimport {BridgeImplBase} from \"../../BridgeImplBase.sol\";\nimport {STARGATE} from \"../../../static/RouteIdentifiers.sol\";\n\n/**\n * @title Stargate-L1-Route Implementation\n * @notice Route implementation with functions to bridge ERC20 and Native via Stargate-L1-Bridge\n * Called via SocketGateway if the routeId in the request maps to the routeId of Stargate-L1-Implementation\n * Contains function to handle bridging as post-step i.e linked to a preceeding step for swap\n * RequestData is different to just bride and bridging chained with swap\n * @author Socket dot tech.\n */\ncontract StargateImplL1 is BridgeImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable StargateIdentifier = STARGATE;\n\n /// @notice Function-selector for ERC20-token bridging on Stargate-L1-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge ERC20 tokens\n bytes4\n public immutable STARGATE_L1_ERC20_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeERC20To(address,address,address,uint256,uint256,(uint256,uint256,uint256,uint256,bytes32,bytes,uint16))\"\n )\n );\n\n /// @notice Function-selector for Native bridging on Stargate-L1-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge Native tokens\n bytes4\n public immutable STARGATE_L1_NATIVE_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeNativeTo(address,address,uint16,uint256,uint256,uint256,bytes32)\"\n )\n );\n\n bytes4 public immutable STARGATE_L1_SWAP_BRIDGE_SELECTOR =\n bytes4(\n keccak256(\n \"swapAndBridge(uint32,bytes,(address,address,uint16,uint256,uint256,uint256,uint256,uint256,uint256,bytes32,bytes))\"\n )\n );\n\n /// @notice Stargate Router to bridge ERC20 tokens\n IBridgeStargate public immutable router;\n\n /// @notice Stargate Router to bridge native tokens\n IBridgeStargate public immutable routerETH;\n\n /// @notice socketGatewayAddress to be initialised via storage variable BridgeImplBase\n /// @dev ensure router, routerEth are set properly for the chainId in which the contract is being deployed\n constructor(\n address _router,\n address _routerEth,\n address _socketGateway,\n address _socketDeployFactory\n ) BridgeImplBase(_socketGateway, _socketDeployFactory) {\n router = IBridgeStargate(_router);\n routerETH = IBridgeStargate(_routerEth);\n }\n\n struct StargateBridgeExtraData {\n uint256 srcPoolId;\n uint256 dstPoolId;\n uint256 destinationGasLimit;\n uint256 minReceivedAmt;\n bytes32 metadata;\n bytes destinationPayload;\n uint16 stargateDstChainId; // stargate defines chain id in its way\n }\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct StargateBridgeDataNoToken {\n address receiverAddress;\n address senderAddress;\n uint16 stargateDstChainId; // stargate defines chain id in its way\n uint256 value;\n // a unique identifier that is uses to dedup transfers\n // this value is the a timestamp sent from frontend, but in theory can be any unique number\n uint256 srcPoolId;\n uint256 dstPoolId;\n uint256 minReceivedAmt; // defines the slippage, the min qty you would accept on the destination\n uint256 optionalValue;\n uint256 destinationGasLimit;\n bytes32 metadata;\n bytes destinationPayload;\n }\n\n struct StargateBridgeData {\n address token;\n address receiverAddress;\n address senderAddress;\n uint16 stargateDstChainId; // stargate defines chain id in its way\n uint256 value;\n // a unique identifier that is uses to dedup transfers\n // this value is the a timestamp sent from frontend, but in theory can be any unique number\n uint256 srcPoolId;\n uint256 dstPoolId;\n uint256 minReceivedAmt; // defines the slippage, the min qty you would accept on the destination\n uint256 optionalValue;\n uint256 destinationGasLimit;\n bytes32 metadata;\n bytes destinationPayload;\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from swapAndBridge, this function is called when the swap has already happened at a different place.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in Stargate-BridgeData struct\n * @param amount amount of tokens being bridged. this can be ERC20 or native\n * @param bridgeData encoded data for Stargate-L1-Bridge\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable override {\n StargateBridgeData memory stargateBridgeData = abi.decode(\n bridgeData,\n (StargateBridgeData)\n );\n\n if (stargateBridgeData.token == NATIVE_TOKEN_ADDRESS) {\n // perform bridging\n routerETH.swapETH{value: amount + stargateBridgeData.optionalValue}(\n stargateBridgeData.stargateDstChainId,\n payable(stargateBridgeData.senderAddress),\n abi.encodePacked(stargateBridgeData.receiverAddress),\n amount,\n stargateBridgeData.minReceivedAmt\n );\n } else {\n ERC20(stargateBridgeData.token).safeApprove(\n address(router),\n amount\n );\n {\n router.swap{value: stargateBridgeData.value}(\n stargateBridgeData.stargateDstChainId,\n stargateBridgeData.srcPoolId,\n stargateBridgeData.dstPoolId,\n payable(stargateBridgeData.senderAddress), // default to refund to main contract\n amount,\n stargateBridgeData.minReceivedAmt,\n IBridgeStargate.lzTxObj(\n stargateBridgeData.destinationGasLimit,\n 0, // zero amount since this is a ERC20 bridging\n \"0x\" //empty data since this is for only ERC20\n ),\n abi.encodePacked(stargateBridgeData.receiverAddress),\n stargateBridgeData.destinationPayload\n );\n }\n }\n\n emit SocketBridge(\n amount,\n stargateBridgeData.token,\n stargateBridgeData.stargateDstChainId,\n StargateIdentifier,\n msg.sender,\n stargateBridgeData.receiverAddress,\n stargateBridgeData.metadata\n );\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from bridgeAfterSwap since this function holds the logic for swapping tokens too.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in Stargate-BridgeData struct\n * @param swapId routeId for the swapImpl\n * @param swapData encoded data for swap\n * @param stargateBridgeData encoded data for StargateBridgeData\n */\n function swapAndBridge(\n uint32 swapId,\n bytes calldata swapData,\n StargateBridgeDataNoToken calldata stargateBridgeData\n ) external payable {\n (bool success, bytes memory result) = socketRoute\n .getRoute(swapId)\n .delegatecall(swapData);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n (uint256 bridgeAmount, address token) = abi.decode(\n result,\n (uint256, address)\n );\n\n if (token == NATIVE_TOKEN_ADDRESS) {\n // perform bridging\n routerETH.swapETH{\n value: bridgeAmount + stargateBridgeData.optionalValue\n }(\n stargateBridgeData.stargateDstChainId,\n payable(stargateBridgeData.senderAddress),\n abi.encodePacked(stargateBridgeData.receiverAddress),\n bridgeAmount,\n stargateBridgeData.minReceivedAmt\n );\n } else {\n ERC20(token).safeApprove(address(router), bridgeAmount);\n {\n router.swap{value: stargateBridgeData.value}(\n stargateBridgeData.stargateDstChainId,\n stargateBridgeData.srcPoolId,\n stargateBridgeData.dstPoolId,\n payable(stargateBridgeData.senderAddress), // default to refund to main contract\n bridgeAmount,\n stargateBridgeData.minReceivedAmt,\n IBridgeStargate.lzTxObj(\n stargateBridgeData.destinationGasLimit,\n 0, // zero amount since this is a ERC20 bridging\n \"0x\" //empty data since this is for only ERC20\n ),\n abi.encodePacked(stargateBridgeData.receiverAddress),\n stargateBridgeData.destinationPayload\n );\n }\n }\n\n emit SocketBridge(\n bridgeAmount,\n token,\n stargateBridgeData.stargateDstChainId,\n StargateIdentifier,\n msg.sender,\n stargateBridgeData.receiverAddress,\n stargateBridgeData.metadata\n );\n }\n\n /**\n * @notice function to handle ERC20 bridging to receipent via Stargate-L1-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param token address of token being bridged\n * @param senderAddress address of sender\n * @param receiverAddress address of recipient\n * @param amount amount of token being bridge\n * @param value value\n * @param stargateBridgeExtraData stargate bridge extradata\n */\n function bridgeERC20To(\n address token,\n address senderAddress,\n address receiverAddress,\n uint256 amount,\n uint256 value,\n StargateBridgeExtraData calldata stargateBridgeExtraData\n ) external payable {\n ERC20 tokenInstance = ERC20(token);\n tokenInstance.safeTransferFrom(msg.sender, socketGateway, amount);\n tokenInstance.safeApprove(address(router), amount);\n {\n router.swap{value: value}(\n stargateBridgeExtraData.stargateDstChainId,\n stargateBridgeExtraData.srcPoolId,\n stargateBridgeExtraData.dstPoolId,\n payable(senderAddress), // default to refund to main contract\n amount,\n stargateBridgeExtraData.minReceivedAmt,\n IBridgeStargate.lzTxObj(\n stargateBridgeExtraData.destinationGasLimit,\n 0, // zero amount since this is a ERC20 bridging\n \"0x\" //empty data since this is for only ERC20\n ),\n abi.encodePacked(receiverAddress),\n stargateBridgeExtraData.destinationPayload\n );\n }\n\n emit SocketBridge(\n amount,\n token,\n stargateBridgeExtraData.stargateDstChainId,\n StargateIdentifier,\n msg.sender,\n receiverAddress,\n stargateBridgeExtraData.metadata\n );\n }\n\n /**\n * @notice function to handle Native bridging to receipent via Stargate-L1-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param receiverAddress address of receipient\n * @param senderAddress address of sender\n * @param stargateDstChainId stargate defines chain id in its way\n * @param amount amount of token being bridge\n * @param minReceivedAmt defines the slippage, the min qty you would accept on the destination\n * @param optionalValue optionalValue Native amount\n */\n function bridgeNativeTo(\n address receiverAddress,\n address senderAddress,\n uint16 stargateDstChainId,\n uint256 amount,\n uint256 minReceivedAmt,\n uint256 optionalValue,\n bytes32 metadata\n ) external payable {\n // perform bridging\n routerETH.swapETH{value: amount + optionalValue}(\n stargateDstChainId,\n payable(senderAddress),\n abi.encodePacked(receiverAddress),\n amount,\n minReceivedAmt\n );\n\n emit SocketBridge(\n amount,\n NATIVE_TOKEN_ADDRESS,\n stargateDstChainId,\n StargateIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n}\n"},"src/bridges/hop/l2/HopImplL2.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport \"../interfaces/amm.sol\";\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {BridgeImplBase} from \"../../BridgeImplBase.sol\";\nimport {HOP} from \"../../../static/RouteIdentifiers.sol\";\n\n/**\n * @title Hop-L2 Route Implementation\n * @notice This is the L2 implementation, so this is used when transferring from l2 to supported l2s\n * Called via SocketGateway if the routeId in the request maps to the routeId of HopL2-Implementation\n * Contains function to handle bridging as post-step i.e linked to a preceeding step for swap\n * RequestData is different to just bride and bridging chained with swap\n * @author Socket dot tech.\n */\ncontract HopImplL2 is BridgeImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable HopIdentifier = HOP;\n\n /// @notice Function-selector for ERC20-token bridging on Hop-L2-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge ERC20 tokens\n bytes4 public immutable HOP_L2_ERC20_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeERC20To(address,address,address,uint256,uint256,(uint256,uint256,uint256,uint256,uint256,bytes32))\"\n )\n );\n\n /// @notice Function-selector for Native bridging on Hop-L2-Route\n /// @dev This function selector is to be used while building transaction-data to bridge Native tokens\n bytes4 public immutable HOP_L2_NATIVE_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeNativeTo(address,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,bytes32)\"\n )\n );\n\n bytes4 public immutable HOP_L2_SWAP_BRIDGE_SELECTOR =\n bytes4(\n keccak256(\n \"swapAndBridge(uint32,bytes,(address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes32))\"\n )\n );\n\n /// @notice socketGatewayAddress to be initialised via storage variable BridgeImplBase\n constructor(\n address _socketGateway,\n address _socketDeployFactory\n ) BridgeImplBase(_socketGateway, _socketDeployFactory) {}\n\n /// @notice Struct to be used as a input parameter for Bridging tokens via Hop-L2-route\n /// @dev while building transactionData,values should be set in this sequence of properties in this struct\n struct HopBridgeRequestData {\n // fees passed to relayer\n uint256 bonderFee;\n // The minimum amount received after attempting to swap in the destination AMM market. 0 if no swap is intended.\n uint256 amountOutMin;\n // The deadline for swapping in the destination AMM market. 0 if no swap is intended.\n uint256 deadline;\n // Minimum amount expected to be received or bridged to destination\n uint256 amountOutMinDestination;\n // deadline for bridging to destination\n uint256 deadlineDestination;\n // socket offchain created hash\n bytes32 metadata;\n }\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct HopBridgeDataNoToken {\n // The address receiving funds at the destination\n address receiverAddress;\n // AMM address of Hop on L2\n address hopAMM;\n // The chainId of the destination chain\n uint256 toChainId;\n // fees passed to relayer\n uint256 bonderFee;\n // The minimum amount received after attempting to swap in the destination AMM market. 0 if no swap is intended.\n uint256 amountOutMin;\n // The deadline for swapping in the destination AMM market. 0 if no swap is intended.\n uint256 deadline;\n // Minimum amount expected to be received or bridged to destination\n uint256 amountOutMinDestination;\n // deadline for bridging to destination\n uint256 deadlineDestination;\n // socket offchain created hash\n bytes32 metadata;\n }\n\n struct HopBridgeData {\n /// @notice address of token being bridged\n address token;\n // The address receiving funds at the destination\n address receiverAddress;\n // AMM address of Hop on L2\n address hopAMM;\n // The chainId of the destination chain\n uint256 toChainId;\n // fees passed to relayer\n uint256 bonderFee;\n // The minimum amount received after attempting to swap in the destination AMM market. 0 if no swap is intended.\n uint256 amountOutMin;\n // The deadline for swapping in the destination AMM market. 0 if no swap is intended.\n uint256 deadline;\n // Minimum amount expected to be received or bridged to destination\n uint256 amountOutMinDestination;\n // deadline for bridging to destination\n uint256 deadlineDestination;\n // socket offchain created hash\n bytes32 metadata;\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from swapAndBridge, this function is called when the swap has already happened at a different place.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in HopBridgeData struct\n * @param amount amount of tokens being bridged. this can be ERC20 or native\n * @param bridgeData encoded data for Hop-L2-Bridge\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable override {\n HopBridgeData memory hopData = abi.decode(bridgeData, (HopBridgeData));\n\n if (hopData.token == NATIVE_TOKEN_ADDRESS) {\n HopAMM(hopData.hopAMM).swapAndSend{value: amount}(\n hopData.toChainId,\n hopData.receiverAddress,\n amount,\n hopData.bonderFee,\n hopData.amountOutMin,\n hopData.deadline,\n hopData.amountOutMinDestination,\n hopData.deadlineDestination\n );\n } else {\n // perform bridging\n HopAMM(hopData.hopAMM).swapAndSend(\n hopData.toChainId,\n hopData.receiverAddress,\n amount,\n hopData.bonderFee,\n hopData.amountOutMin,\n hopData.deadline,\n hopData.amountOutMinDestination,\n hopData.deadlineDestination\n );\n }\n\n emit SocketBridge(\n amount,\n hopData.token,\n hopData.toChainId,\n HopIdentifier,\n msg.sender,\n hopData.receiverAddress,\n hopData.metadata\n );\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from bridgeAfterSwap since this function holds the logic for swapping tokens too.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in HopBridgeData struct\n * @param swapId routeId for the swapImpl\n * @param swapData encoded data for swap\n * @param hopData encoded data for HopData\n */\n function swapAndBridge(\n uint32 swapId,\n bytes calldata swapData,\n HopBridgeDataNoToken calldata hopData\n ) external payable {\n (bool success, bytes memory result) = socketRoute\n .getRoute(swapId)\n .delegatecall(swapData);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n (uint256 bridgeAmount, address token) = abi.decode(\n result,\n (uint256, address)\n );\n\n if (token == NATIVE_TOKEN_ADDRESS) {\n HopAMM(hopData.hopAMM).swapAndSend{value: bridgeAmount}(\n hopData.toChainId,\n hopData.receiverAddress,\n bridgeAmount,\n hopData.bonderFee,\n hopData.amountOutMin,\n hopData.deadline,\n hopData.amountOutMinDestination,\n hopData.deadlineDestination\n );\n } else {\n // perform bridging\n HopAMM(hopData.hopAMM).swapAndSend(\n hopData.toChainId,\n hopData.receiverAddress,\n bridgeAmount,\n hopData.bonderFee,\n hopData.amountOutMin,\n hopData.deadline,\n hopData.amountOutMinDestination,\n hopData.deadlineDestination\n );\n }\n\n emit SocketBridge(\n bridgeAmount,\n token,\n hopData.toChainId,\n HopIdentifier,\n msg.sender,\n hopData.receiverAddress,\n hopData.metadata\n );\n }\n\n /**\n * @notice function to handle ERC20 bridging to receipent via Hop-L2-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param receiverAddress The address receiving funds at the destination\n * @param token token being bridged\n * @param hopAMM AMM address of Hop on L2\n * @param amount The amount being bridged\n * @param toChainId The chainId of the destination chain\n * @param hopBridgeRequestData extraData for Bridging across Hop-L2\n */\n function bridgeERC20To(\n address receiverAddress,\n address token,\n address hopAMM,\n uint256 amount,\n uint256 toChainId,\n HopBridgeRequestData calldata hopBridgeRequestData\n ) external payable {\n ERC20 tokenInstance = ERC20(token);\n tokenInstance.safeTransferFrom(msg.sender, socketGateway, amount);\n\n HopAMM(hopAMM).swapAndSend(\n toChainId,\n receiverAddress,\n amount,\n hopBridgeRequestData.bonderFee,\n hopBridgeRequestData.amountOutMin,\n hopBridgeRequestData.deadline,\n hopBridgeRequestData.amountOutMinDestination,\n hopBridgeRequestData.deadlineDestination\n );\n\n emit SocketBridge(\n amount,\n token,\n toChainId,\n HopIdentifier,\n msg.sender,\n receiverAddress,\n hopBridgeRequestData.metadata\n );\n }\n\n /**\n * @notice function to handle Native bridging to receipent via Hop-L2-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param receiverAddress The address receiving funds at the destination\n * @param hopAMM AMM address of Hop on L2\n * @param amount The amount being bridged\n * @param toChainId The chainId of the destination chain\n * @param bonderFee fees passed to relayer\n * @param amountOutMin The minimum amount received after attempting to swap in the destination AMM market. 0 if no swap is intended.\n * @param deadline The deadline for swapping in the destination AMM market. 0 if no swap is intended.\n * @param amountOutMinDestination Minimum amount expected to be received or bridged to destination\n * @param deadlineDestination deadline for bridging to destination\n */\n function bridgeNativeTo(\n address receiverAddress,\n address hopAMM,\n uint256 amount,\n uint256 toChainId,\n uint256 bonderFee,\n uint256 amountOutMin,\n uint256 deadline,\n uint256 amountOutMinDestination,\n uint256 deadlineDestination,\n bytes32 metadata\n ) external payable {\n // token address might not be indication thats why passed through extraData\n // perform bridging\n HopAMM(hopAMM).swapAndSend{value: amount}(\n toChainId,\n receiverAddress,\n amount,\n bonderFee,\n amountOutMin,\n deadline,\n amountOutMinDestination,\n deadlineDestination\n );\n\n emit SocketBridge(\n amount,\n NATIVE_TOKEN_ADDRESS,\n toChainId,\n HopIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n}\n"},"src/bridges/anyswap-router-v4/l2/Anyswap.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {BridgeImplBase} from \"../../BridgeImplBase.sol\";\nimport {ANYSWAP} from \"../../../static/RouteIdentifiers.sol\";\n\n/**\n * @title Anyswap-V4-Route L1 Implementation\n * @notice Route implementation with functions to bridge ERC20 via Anyswap-Bridge\n * Called via SocketGateway if the routeId in the request maps to the routeId of AnyswapImplementation\n * This is the L2 implementation, so this is used when transferring from l2.\n * Contains function to handle bridging as post-step i.e linked to a preceeding step for swap\n * RequestData is different to just bride and bridging chained with swap\n * @author Socket dot tech.\n */\ninterface AnyswapV4Router {\n function anySwapOutUnderlying(\n address token,\n address to,\n uint256 amount,\n uint256 toChainID\n ) external;\n}\n\ncontract AnyswapL2Impl is BridgeImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable AnyswapIdentifier = ANYSWAP;\n\n /// @notice Function-selector for ERC20-token bridging on Anyswap-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge ERC20 tokens\n bytes4 public immutable ANYSWAP_L2_ERC20_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeERC20To(uint256,uint256,bytes32,address,address,address)\"\n )\n );\n\n bytes4 public immutable ANYSWAP_SWAP_BRIDGE_SELECTOR =\n bytes4(\n keccak256(\n \"swapAndBridge(uint32,bytes,(uint256,address,address,bytes32))\"\n )\n );\n\n // polygon router multichain router v4\n AnyswapV4Router public immutable router;\n\n /**\n * @notice Constructor sets the router address and socketGateway address.\n * @dev anyswap v4 router is immutable. so no setter function required.\n */\n constructor(\n address _router,\n address _socketGateway,\n address _socketDeployFactory\n ) BridgeImplBase(_socketGateway, _socketDeployFactory) {\n router = AnyswapV4Router(_router);\n }\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct AnyswapBridgeDataNoToken {\n /// @notice destination ChainId\n uint256 toChainId;\n /// @notice address of receiver of bridged tokens\n address receiverAddress;\n /// @notice address of wrapperToken, WrappedVersion of the token being bridged\n address wrapperTokenAddress;\n /// @notice socket offchain created hash\n bytes32 metadata;\n }\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct AnyswapBridgeData {\n /// @notice destination ChainId\n uint256 toChainId;\n /// @notice address of receiver of bridged tokens\n address receiverAddress;\n /// @notice address of wrapperToken, WrappedVersion of the token being bridged\n address wrapperTokenAddress;\n /// @notice address of token being bridged\n address token;\n /// @notice socket offchain created hash\n bytes32 metadata;\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from swapAndBridge, this function is called when the swap has already happened at a different place.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in AnyswapBridgeData struct\n * @param amount amount of tokens being bridged. this can be ERC20 or native\n * @param bridgeData encoded data for AnyswapBridge\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable override {\n AnyswapBridgeData memory anyswapBridgeData = abi.decode(\n bridgeData,\n (AnyswapBridgeData)\n );\n ERC20(anyswapBridgeData.token).safeApprove(address(router), amount);\n router.anySwapOutUnderlying(\n anyswapBridgeData.wrapperTokenAddress,\n anyswapBridgeData.receiverAddress,\n amount,\n anyswapBridgeData.toChainId\n );\n\n emit SocketBridge(\n amount,\n anyswapBridgeData.token,\n anyswapBridgeData.toChainId,\n AnyswapIdentifier,\n msg.sender,\n anyswapBridgeData.receiverAddress,\n anyswapBridgeData.metadata\n );\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from bridgeAfterSwap since this function holds the logic for swapping tokens too.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in AnyswapBridgeData struct\n * @param swapId routeId for the swapImpl\n * @param swapData encoded data for swap\n * @param anyswapBridgeData encoded data for AnyswapBridge\n */\n function swapAndBridge(\n uint32 swapId,\n bytes calldata swapData,\n AnyswapBridgeDataNoToken calldata anyswapBridgeData\n ) external payable {\n (bool success, bytes memory result) = socketRoute\n .getRoute(swapId)\n .delegatecall(swapData);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n (uint256 bridgeAmount, address token) = abi.decode(\n result,\n (uint256, address)\n );\n\n ERC20(token).safeApprove(address(router), bridgeAmount);\n router.anySwapOutUnderlying(\n anyswapBridgeData.wrapperTokenAddress,\n anyswapBridgeData.receiverAddress,\n bridgeAmount,\n anyswapBridgeData.toChainId\n );\n\n emit SocketBridge(\n bridgeAmount,\n token,\n anyswapBridgeData.toChainId,\n AnyswapIdentifier,\n msg.sender,\n anyswapBridgeData.receiverAddress,\n anyswapBridgeData.metadata\n );\n }\n\n /**\n * @notice function to handle ERC20 bridging to receipent via Anyswap-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param amount amount being bridged\n * @param toChainId destination ChainId\n * @param receiverAddress address of receiver of bridged tokens\n * @param token address of token being bridged\n * @param wrapperTokenAddress address of wrapperToken, WrappedVersion of the token being bridged\n */\n function bridgeERC20To(\n uint256 amount,\n uint256 toChainId,\n bytes32 metadata,\n address receiverAddress,\n address token,\n address wrapperTokenAddress\n ) external payable {\n ERC20 tokenInstance = ERC20(token);\n tokenInstance.safeTransferFrom(msg.sender, socketGateway, amount);\n tokenInstance.safeApprove(address(router), amount);\n router.anySwapOutUnderlying(\n wrapperTokenAddress,\n receiverAddress,\n amount,\n toChainId\n );\n\n emit SocketBridge(\n amount,\n token,\n toChainId,\n AnyswapIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n}\n"},"src/bridges/hyphen/Hyphen.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport \"./interfaces/hyphen.sol\";\nimport \"../BridgeImplBase.sol\";\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {HYPHEN} from \"../../static/RouteIdentifiers.sol\";\n\n/**\n * @title Hyphen-Route Implementation\n * @notice Route implementation with functions to bridge ERC20 and Native via Hyphen-Bridge\n * Called via SocketGateway if the routeId in the request maps to the routeId of HyphenImplementation\n * Contains function to handle bridging as post-step i.e linked to a preceeding step for swap\n * RequestData is different to just bride and bridging chained with swap\n * @author Socket dot tech.\n */\ncontract HyphenImpl is BridgeImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable HyphenIdentifier = HYPHEN;\n\n /// @notice Function-selector for ERC20-token bridging on Hyphen-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge ERC20 tokens\n bytes4 public immutable HYPHEN_ERC20_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\"bridgeERC20To(uint256,bytes32,address,address,uint256)\")\n );\n\n /// @notice Function-selector for Native bridging on Hyphen-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge Native tokens\n bytes4 public immutable HYPHEN_NATIVE_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(keccak256(\"bridgeNativeTo(uint256,bytes32,address,uint256)\"));\n\n bytes4 public immutable HYPHEN_SWAP_BRIDGE_SELECTOR =\n bytes4(\n keccak256(\"swapAndBridge(uint32,bytes,(address,uint256,bytes32))\")\n );\n\n /// @notice liquidityPoolManager - liquidityPool Manager of Hyphen used to bridge ERC20 and native\n /// @dev this is to be initialized in constructor with a valid deployed address of hyphen-liquidityPoolManager\n HyphenLiquidityPoolManager public immutable liquidityPoolManager;\n\n /// @notice socketGatewayAddress to be initialised via storage variable BridgeImplBase\n /// @dev ensure liquidityPoolManager-address are set properly for the chainId in which the contract is being deployed\n constructor(\n address _liquidityPoolManager,\n address _socketGateway,\n address _socketDeployFactory\n ) BridgeImplBase(_socketGateway, _socketDeployFactory) {\n liquidityPoolManager = HyphenLiquidityPoolManager(\n _liquidityPoolManager\n );\n }\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct HyphenData {\n /// @notice address of token being bridged\n address token;\n /// @notice address of receiver\n address receiverAddress;\n /// @notice chainId of destination\n uint256 toChainId;\n /// @notice socket offchain created hash\n bytes32 metadata;\n }\n\n struct HyphenDataNoToken {\n /// @notice address of receiver\n address receiverAddress;\n /// @notice chainId of destination\n uint256 toChainId;\n /// @notice chainId of destination\n bytes32 metadata;\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from swapAndBridge, this function is called when the swap has already happened at a different place.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in HyphenBridgeData struct\n * @param amount amount of tokens being bridged. this can be ERC20 or native\n * @param bridgeData encoded data for HyphenBridge\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable override {\n HyphenData memory hyphenData = abi.decode(bridgeData, (HyphenData));\n\n if (hyphenData.token == NATIVE_TOKEN_ADDRESS) {\n liquidityPoolManager.depositNative{value: amount}(\n hyphenData.receiverAddress,\n hyphenData.toChainId,\n \"SOCKET\"\n );\n } else {\n ERC20(hyphenData.token).safeApprove(\n address(liquidityPoolManager),\n amount\n );\n liquidityPoolManager.depositErc20(\n hyphenData.toChainId,\n hyphenData.token,\n hyphenData.receiverAddress,\n amount,\n \"SOCKET\"\n );\n }\n\n emit SocketBridge(\n amount,\n hyphenData.token,\n hyphenData.toChainId,\n HyphenIdentifier,\n msg.sender,\n hyphenData.receiverAddress,\n hyphenData.metadata\n );\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from bridgeAfterSwap since this function holds the logic for swapping tokens too.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in HyphenBridgeData struct\n * @param swapId routeId for the swapImpl\n * @param swapData encoded data for swap\n * @param hyphenData encoded data for hyphenData\n */\n function swapAndBridge(\n uint32 swapId,\n bytes calldata swapData,\n HyphenDataNoToken calldata hyphenData\n ) external payable {\n (bool success, bytes memory result) = socketRoute\n .getRoute(swapId)\n .delegatecall(swapData);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n (uint256 bridgeAmount, address token) = abi.decode(\n result,\n (uint256, address)\n );\n if (token == NATIVE_TOKEN_ADDRESS) {\n liquidityPoolManager.depositNative{value: bridgeAmount}(\n hyphenData.receiverAddress,\n hyphenData.toChainId,\n \"SOCKET\"\n );\n } else {\n ERC20(token).safeApprove(\n address(liquidityPoolManager),\n bridgeAmount\n );\n liquidityPoolManager.depositErc20(\n hyphenData.toChainId,\n token,\n hyphenData.receiverAddress,\n bridgeAmount,\n \"SOCKET\"\n );\n }\n\n emit SocketBridge(\n bridgeAmount,\n token,\n hyphenData.toChainId,\n HyphenIdentifier,\n msg.sender,\n hyphenData.receiverAddress,\n hyphenData.metadata\n );\n }\n\n /**\n * @notice function to handle ERC20 bridging to receipent via Hyphen-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param amount amount to be sent\n * @param receiverAddress address of the token to bridged to the destination chain.\n * @param token address of token being bridged\n * @param toChainId chainId of destination\n */\n function bridgeERC20To(\n uint256 amount,\n bytes32 metadata,\n address receiverAddress,\n address token,\n uint256 toChainId\n ) external payable {\n ERC20 tokenInstance = ERC20(token);\n tokenInstance.safeTransferFrom(msg.sender, socketGateway, amount);\n tokenInstance.safeApprove(address(liquidityPoolManager), amount);\n liquidityPoolManager.depositErc20(\n toChainId,\n token,\n receiverAddress,\n amount,\n \"SOCKET\"\n );\n\n emit SocketBridge(\n amount,\n token,\n toChainId,\n HyphenIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n\n /**\n * @notice function to handle Native bridging to receipent via Hyphen-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param amount amount to be sent\n * @param receiverAddress address of the token to bridged to the destination chain.\n * @param toChainId chainId of destination\n */\n function bridgeNativeTo(\n uint256 amount,\n bytes32 metadata,\n address receiverAddress,\n uint256 toChainId\n ) external payable {\n liquidityPoolManager.depositNative{value: amount}(\n receiverAddress,\n toChainId,\n \"SOCKET\"\n );\n\n emit SocketBridge(\n amount,\n NATIVE_TOKEN_ADDRESS,\n toChainId,\n HyphenIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n}\n"},"src/bridges/optimism/l1/NativeOptimism.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport \"../interfaces/optimism.sol\";\nimport {BridgeImplBase} from \"../../BridgeImplBase.sol\";\nimport {UnsupportedInterfaceId} from \"../../../errors/SocketErrors.sol\";\nimport {NATIVE_OPTIMISM} from \"../../../static/RouteIdentifiers.sol\";\n\n/**\n * @title NativeOptimism-Route Implementation\n * @notice Route implementation with functions to bridge ERC20 and Native via NativeOptimism-Bridge\n * Tokens are bridged from Ethereum to Optimism Chain.\n * Called via SocketGateway if the routeId in the request maps to the routeId of NativeOptimism-Implementation\n * Contains function to handle bridging as post-step i.e linked to a preceeding step for swap\n * RequestData is different to just bride and bridging chained with swap\n * @author Socket dot tech.\n */\ncontract NativeOptimismImpl is BridgeImplBase {\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable NativeOptimismIdentifier = NATIVE_OPTIMISM;\n\n uint256 public constant DESTINATION_CHAIN_ID = 10;\n\n /// @notice Function-selector for ERC20-token bridging on Native-Optimism-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge ERC20 tokens\n bytes4\n public immutable NATIVE_OPTIMISM_ERC20_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeERC20To(address,address,address,uint32,(bytes32,bytes32),uint256,uint256,address,bytes)\"\n )\n );\n\n /// @notice Function-selector for Native bridging on Native-Optimism-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge Native balance\n bytes4\n public immutable NATIVE_OPTIMISM_NATIVE_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeNativeTo(address,address,uint32,uint256,bytes32,bytes)\"\n )\n );\n\n bytes4 public immutable NATIVE_OPTIMISM_SWAP_BRIDGE_SELECTOR =\n bytes4(\n keccak256(\n \"swapAndBridge(uint32,bytes,(uint256,bytes32,bytes32,address,address,uint32,address,bytes))\"\n )\n );\n\n /// @notice socketGatewayAddress to be initialised via storage variable BridgeImplBase\n constructor(\n address _socketGateway,\n address _socketDeployFactory\n ) BridgeImplBase(_socketGateway, _socketDeployFactory) {}\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct OptimismBridgeDataNoToken {\n // interfaceId to be set offchain which is used to select one of the 3 kinds of bridging (standard bridge / old standard / synthetic)\n uint256 interfaceId;\n // currencyKey of the token beingBridged\n bytes32 currencyKey;\n // socket offchain created hash\n bytes32 metadata;\n // address of receiver of bridged tokens\n address receiverAddress;\n /**\n * OptimismBridge that Performs the logic for deposits by informing the L2 Deposited Token\n * contract of the deposit and calling a handler to lock the L1 funds. (e.g. transferFrom)\n */\n address customBridgeAddress;\n // Gas limit required to complete the deposit on L2.\n uint32 l2Gas;\n // Address of the L1 respective L2 ERC20\n address l2Token;\n // additional data , for ll contracts this will be 0x data or empty data\n bytes data;\n }\n\n struct OptimismBridgeData {\n // interfaceId to be set offchain which is used to select one of the 3 kinds of bridging (standard bridge / old standard / synthetic)\n uint256 interfaceId;\n // currencyKey of the token beingBridged\n bytes32 currencyKey;\n // socket offchain created hash\n bytes32 metadata;\n // address of receiver of bridged tokens\n address receiverAddress;\n /**\n * OptimismBridge that Performs the logic for deposits by informing the L2 Deposited Token\n * contract of the deposit and calling a handler to lock the L1 funds. (e.g. transferFrom)\n */\n address customBridgeAddress;\n /// @notice address of token being bridged\n address token;\n // Gas limit required to complete the deposit on L2.\n uint32 l2Gas;\n // Address of the L1 respective L2 ERC20\n address l2Token;\n // additional data , for ll contracts this will be 0x data or empty data\n bytes data;\n }\n\n struct OptimismERC20Data {\n bytes32 currencyKey;\n bytes32 metadata;\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from swapAndBridge, this function is called when the swap has already happened at a different place.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in OptimismBridgeData struct\n * @param amount amount of tokens being bridged. this can be ERC20 or native\n * @param bridgeData encoded data for Optimism-Bridge\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable override {\n OptimismBridgeData memory optimismBridgeData = abi.decode(\n bridgeData,\n (OptimismBridgeData)\n );\n\n emit SocketBridge(\n amount,\n optimismBridgeData.token,\n DESTINATION_CHAIN_ID,\n NativeOptimismIdentifier,\n msg.sender,\n optimismBridgeData.receiverAddress,\n optimismBridgeData.metadata\n );\n if (optimismBridgeData.token == NATIVE_TOKEN_ADDRESS) {\n L1StandardBridge(optimismBridgeData.customBridgeAddress)\n .depositETHTo{value: amount}(\n optimismBridgeData.receiverAddress,\n optimismBridgeData.l2Gas,\n optimismBridgeData.data\n );\n } else {\n if (optimismBridgeData.interfaceId == 0) {\n revert UnsupportedInterfaceId();\n }\n\n ERC20(optimismBridgeData.token).safeApprove(\n optimismBridgeData.customBridgeAddress,\n amount\n );\n\n if (optimismBridgeData.interfaceId == 1) {\n // deposit into standard bridge\n L1StandardBridge(optimismBridgeData.customBridgeAddress)\n .depositERC20To(\n optimismBridgeData.token,\n optimismBridgeData.l2Token,\n optimismBridgeData.receiverAddress,\n amount,\n optimismBridgeData.l2Gas,\n optimismBridgeData.data\n );\n return;\n }\n\n // Deposit Using Old Standard - iOVM_L1TokenGateway(Example - SNX Token)\n if (optimismBridgeData.interfaceId == 2) {\n OldL1TokenGateway(optimismBridgeData.customBridgeAddress)\n .depositTo(optimismBridgeData.receiverAddress, amount);\n return;\n }\n\n if (optimismBridgeData.interfaceId == 3) {\n OldL1TokenGateway(optimismBridgeData.customBridgeAddress)\n .initiateSynthTransfer(\n optimismBridgeData.currencyKey,\n optimismBridgeData.receiverAddress,\n amount\n );\n return;\n }\n }\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from bridgeAfterSwap since this function holds the logic for swapping tokens too.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in OptimismBridgeData struct\n * @param swapId routeId for the swapImpl\n * @param swapData encoded data for swap\n * @param optimismBridgeData encoded data for OptimismBridgeData\n */\n function swapAndBridge(\n uint32 swapId,\n bytes calldata swapData,\n OptimismBridgeDataNoToken calldata optimismBridgeData\n ) external payable {\n (bool success, bytes memory result) = socketRoute\n .getRoute(swapId)\n .delegatecall(swapData);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n (uint256 bridgeAmount, address token) = abi.decode(\n result,\n (uint256, address)\n );\n\n emit SocketBridge(\n bridgeAmount,\n token,\n DESTINATION_CHAIN_ID,\n NativeOptimismIdentifier,\n msg.sender,\n optimismBridgeData.receiverAddress,\n optimismBridgeData.metadata\n );\n if (token == NATIVE_TOKEN_ADDRESS) {\n L1StandardBridge(optimismBridgeData.customBridgeAddress)\n .depositETHTo{value: bridgeAmount}(\n optimismBridgeData.receiverAddress,\n optimismBridgeData.l2Gas,\n optimismBridgeData.data\n );\n } else {\n if (optimismBridgeData.interfaceId == 0) {\n revert UnsupportedInterfaceId();\n }\n\n ERC20(token).safeApprove(\n optimismBridgeData.customBridgeAddress,\n bridgeAmount\n );\n\n if (optimismBridgeData.interfaceId == 1) {\n // deposit into standard bridge\n L1StandardBridge(optimismBridgeData.customBridgeAddress)\n .depositERC20To(\n token,\n optimismBridgeData.l2Token,\n optimismBridgeData.receiverAddress,\n bridgeAmount,\n optimismBridgeData.l2Gas,\n optimismBridgeData.data\n );\n return;\n }\n\n // Deposit Using Old Standard - iOVM_L1TokenGateway(Example - SNX Token)\n if (optimismBridgeData.interfaceId == 2) {\n OldL1TokenGateway(optimismBridgeData.customBridgeAddress)\n .depositTo(\n optimismBridgeData.receiverAddress,\n bridgeAmount\n );\n return;\n }\n\n if (optimismBridgeData.interfaceId == 3) {\n OldL1TokenGateway(optimismBridgeData.customBridgeAddress)\n .initiateSynthTransfer(\n optimismBridgeData.currencyKey,\n optimismBridgeData.receiverAddress,\n bridgeAmount\n );\n return;\n }\n }\n }\n\n /**\n * @notice function to handle ERC20 bridging to receipent via NativeOptimism-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param token address of token being bridged\n * @param receiverAddress address of receiver of bridged tokens\n * @param customBridgeAddress OptimismBridge that Performs the logic for deposits by informing the L2 Deposited Token\n * contract of the deposit and calling a handler to lock the L1 funds. (e.g. transferFrom)\n * @param l2Gas Gas limit required to complete the deposit on L2.\n * @param optimismData extra data needed for optimism bridge\n * @param amount amount being bridged\n * @param interfaceId interfaceId to be set offchain which is used to select one of the 3 kinds of bridging (standard bridge / old standard / synthetic)\n * @param l2Token Address of the L1 respective L2 ERC20\n * @param data additional data , for ll contracts this will be 0x data or empty data\n */\n function bridgeERC20To(\n address token,\n address receiverAddress,\n address customBridgeAddress,\n uint32 l2Gas,\n OptimismERC20Data calldata optimismData,\n uint256 amount,\n uint256 interfaceId,\n address l2Token,\n bytes calldata data\n ) external payable {\n if (interfaceId == 0) {\n revert UnsupportedInterfaceId();\n }\n\n ERC20 tokenInstance = ERC20(token);\n tokenInstance.safeTransferFrom(msg.sender, socketGateway, amount);\n tokenInstance.safeApprove(customBridgeAddress, amount);\n\n emit SocketBridge(\n amount,\n token,\n DESTINATION_CHAIN_ID,\n NativeOptimismIdentifier,\n msg.sender,\n receiverAddress,\n optimismData.metadata\n );\n if (interfaceId == 1) {\n // deposit into standard bridge\n L1StandardBridge(customBridgeAddress).depositERC20To(\n token,\n l2Token,\n receiverAddress,\n amount,\n l2Gas,\n data\n );\n return;\n }\n\n // Deposit Using Old Standard - iOVM_L1TokenGateway(Example - SNX Token)\n if (interfaceId == 2) {\n OldL1TokenGateway(customBridgeAddress).depositTo(\n receiverAddress,\n amount\n );\n return;\n }\n\n if (interfaceId == 3) {\n OldL1TokenGateway(customBridgeAddress).initiateSynthTransfer(\n optimismData.currencyKey,\n receiverAddress,\n amount\n );\n return;\n }\n }\n\n /**\n * @notice function to handle native balance bridging to receipent via NativeOptimism-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param receiverAddress address of receiver of bridged tokens\n * @param customBridgeAddress OptimismBridge that Performs the logic for deposits by informing the L2 Deposited Token\n * contract of the deposit and calling a handler to lock the L1 funds. (e.g. transferFrom)\n * @param l2Gas Gas limit required to complete the deposit on L2.\n * @param amount amount being bridged\n * @param data additional data , for ll contracts this will be 0x data or empty data\n */\n function bridgeNativeTo(\n address receiverAddress,\n address customBridgeAddress,\n uint32 l2Gas,\n uint256 amount,\n bytes32 metadata,\n bytes calldata data\n ) external payable {\n L1StandardBridge(customBridgeAddress).depositETHTo{value: amount}(\n receiverAddress,\n l2Gas,\n data\n );\n\n emit SocketBridge(\n amount,\n NATIVE_TOKEN_ADDRESS,\n DESTINATION_CHAIN_ID,\n NativeOptimismIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n}\n"},"src/deployFactory/SocketDeployFactory.sol":{"content":"//SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport \"../utils/Ownable.sol\";\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {ISocketBridgeBase} from \"../interfaces/ISocketBridgeBase.sol\";\n\n/**\n * @dev In the constructor, set up the initialization code for socket\n * contracts as well as the keccak256 hash of the given initialization code.\n * that will be used to deploy any transient contracts, which will deploy any\n * socket contracts that require the use of a constructor.\n *\n * Socket contract initialization code (29 bytes):\n *\n * 0x5860208158601c335a63aaf10f428752fa158151803b80938091923cf3\n *\n * Description:\n *\n * pc|op|name | [stack] | \n *\n * ** set the first stack item to zero - used later **\n * 00 58 getpc [0] <>\n *\n * ** set second stack item to 32, length of word returned from staticcall **\n * 01 60 push1\n * 02 20 outsize [0, 32] <>\n *\n * ** set third stack item to 0, position of word returned from staticcall **\n * 03 81 dup2 [0, 32, 0] <>\n *\n * ** set fourth stack item to 4, length of selector given to staticcall **\n * 04 58 getpc [0, 32, 0, 4] <>\n *\n * ** set fifth stack item to 28, position of selector given to staticcall **\n * 05 60 push1\n * 06 1c inpos [0, 32, 0, 4, 28] <>\n *\n * ** set the sixth stack item to msg.sender, target address for staticcall **\n * 07 33 caller [0, 32, 0, 4, 28, caller] <>\n *\n * ** set the seventh stack item to msg.gas, gas to forward for staticcall **\n * 08 5a gas [0, 32, 0, 4, 28, caller, gas] <>\n *\n * ** set the eighth stack item to selector, \"what\" to store via mstore **\n * 09 63 push4\n * 10 aaf10f42 selector [0, 32, 0, 4, 28, caller, gas, 0xaaf10f42] <>\n *\n * ** set the ninth stack item to 0, \"where\" to store via mstore ***\n * 11 87 dup8 [0, 32, 0, 4, 28, caller, gas, 0xaaf10f42, 0] <>\n *\n * ** call mstore, consume 8 and 9 from the stack, place selector in memory **\n * 12 52 mstore [0, 32, 0, 4, 0, caller, gas] <0xaaf10f42>\n *\n * ** call staticcall, consume items 2 through 7, place address in memory **\n * 13 fa staticcall [0, 1 (if successful)]
\n *\n * ** flip success bit in second stack item to set to 0 **\n * 14 15 iszero [0, 0]
\n *\n * ** push a third 0 to the stack, position of address in memory **\n * 15 81 dup2 [0, 0, 0]
\n *\n * ** place address from position in memory onto third stack item **\n * 16 51 mload [0, 0, address] <>\n *\n * ** place address to fourth stack item for extcodesize to consume **\n * 17 80 dup1 [0, 0, address, address] <>\n *\n * ** get extcodesize on fourth stack item for extcodecopy **\n * 18 3b extcodesize [0, 0, address, size] <>\n *\n * ** dup and swap size for use by return at end of init code **\n * 19 80 dup1 [0, 0, address, size, size] <>\n * 20 93 swap4 [size, 0, address, size, 0] <>\n *\n * ** push code position 0 to stack and reorder stack items for extcodecopy **\n * 21 80 dup1 [size, 0, address, size, 0, 0] <>\n * 22 91 swap2 [size, 0, address, 0, 0, size] <>\n * 23 92 swap3 [size, 0, size, 0, 0, address] <>\n *\n * ** call extcodecopy, consume four items, clone runtime code to memory **\n * 24 3c extcodecopy [size, 0] \n *\n * ** return to deploy final code in memory **\n * 25 f3 return [] *deployed!*\n */\ncontract SocketDeployFactory is Ownable {\n using SafeTransferLib for ERC20;\n address public immutable disabledRouteAddress;\n\n mapping(address => address) _implementations;\n mapping(uint256 => bool) isDisabled;\n mapping(uint256 => bool) isRouteDeployed;\n mapping(address => bool) canDisableRoute;\n\n event Deployed(address _addr);\n event DisabledRoute(address _addr);\n event Destroyed(address _addr);\n error ContractAlreadyDeployed();\n error NothingToDestroy();\n error AlreadyDisabled();\n error CannotBeDisabled();\n error OnlyDisabler();\n\n constructor(address _owner, address disabledRoute) Ownable(_owner) {\n disabledRouteAddress = disabledRoute;\n canDisableRoute[_owner] = true;\n }\n\n modifier onlyDisabler() {\n if (!canDisableRoute[msg.sender]) {\n revert OnlyDisabler();\n }\n _;\n }\n\n function addDisablerAddress(address disabler) external onlyOwner {\n canDisableRoute[disabler] = true;\n }\n\n function removeDisablerAddress(address disabler) external onlyOwner {\n canDisableRoute[disabler] = false;\n }\n\n /**\n * @notice Deploys a route contract at predetermined location\n * @notice Caller must first deploy the route contract at another location and pass its address as implementation.\n * @param routeId route identifier\n * @param implementationContract address of deployed route contract. Its byte code will be copied to predetermined location.\n */\n function deploy(\n uint256 routeId,\n address implementationContract\n ) external onlyOwner returns (address) {\n // assign the initialization code for the socket contract.\n\n bytes memory initCode = (\n hex\"5860208158601c335a63aaf10f428752fa158151803b80938091923cf3\"\n );\n\n // determine the address of the socket contract.\n address routeContractAddress = _getContractAddress(routeId);\n\n if (isRouteDeployed[routeId]) {\n revert ContractAlreadyDeployed();\n }\n\n isRouteDeployed[routeId] = true;\n\n //first we deploy the code we want to deploy on a separate address\n // store the implementation to be retrieved by the socket contract.\n _implementations[routeContractAddress] = implementationContract;\n address addr;\n assembly {\n let encoded_data := add(0x20, initCode) // load initialization code.\n let encoded_size := mload(initCode) // load init code's length.\n addr := create2(0, encoded_data, encoded_size, routeId) // routeId is used as salt\n }\n require(\n addr == routeContractAddress,\n \"Failed to deploy the new socket contract.\"\n );\n emit Deployed(addr);\n return addr;\n }\n\n /**\n * @notice Destroy the route deployed at a location.\n * @param routeId route identifier to be destroyed.\n */\n function destroy(uint256 routeId) external onlyDisabler {\n // determine the address of the socket contract.\n _destroy(routeId);\n }\n\n /**\n * @notice Deploy a disabled contract at destroyed route to handle it gracefully.\n * @param routeId route identifier to be disabled.\n */\n function disableRoute(\n uint256 routeId\n ) external onlyDisabler returns (address) {\n return _disableRoute(routeId);\n }\n\n /**\n * @notice Destroy a list of routeIds\n * @param routeIds array of routeIds to be destroyed.\n */\n function multiDestroy(uint256[] calldata routeIds) external onlyDisabler {\n for (uint32 index = 0; index < routeIds.length; ) {\n _destroy(routeIds[index]);\n unchecked {\n ++index;\n }\n }\n }\n\n /**\n * @notice Deploy a disabled contract at list of routeIds.\n * @param routeIds array of routeIds to be disabled.\n */\n function multiDisableRoute(\n uint256[] calldata routeIds\n ) external onlyDisabler {\n for (uint32 index = 0; index < routeIds.length; ) {\n _disableRoute(routeIds[index]);\n unchecked {\n ++index;\n }\n }\n }\n\n /**\n * @dev External view function for calculating a socket contract address\n * given a particular routeId.\n */\n function getContractAddress(\n uint256 routeId\n ) external view returns (address) {\n // determine the address of the socket contract.\n return _getContractAddress(routeId);\n }\n\n //those two functions are getting called by the socket Contract\n function getImplementation()\n external\n view\n returns (address implementation)\n {\n return _implementations[msg.sender];\n }\n\n function _disableRoute(uint256 routeId) internal returns (address) {\n // assign the initialization code for the socket contract.\n bytes memory initCode = (\n hex\"5860208158601c335a63aaf10f428752fa158151803b80938091923cf3\"\n );\n\n // determine the address of the socket contract.\n address routeContractAddress = _getContractAddress(routeId);\n\n if (!isRouteDeployed[routeId]) {\n revert CannotBeDisabled();\n }\n\n if (isDisabled[routeId]) {\n revert AlreadyDisabled();\n }\n\n isDisabled[routeId] = true;\n\n //first we deploy the code we want to deploy on a separate address\n // store the implementation to be retrieved by the socket contract.\n _implementations[routeContractAddress] = disabledRouteAddress;\n address addr;\n assembly {\n let encoded_data := add(0x20, initCode) // load initialization code.\n let encoded_size := mload(initCode) // load init code's length.\n addr := create2(0, encoded_data, encoded_size, routeId) // routeId is used as salt.\n }\n require(\n addr == routeContractAddress,\n \"Failed to deploy the new socket contract.\"\n );\n emit Deployed(addr);\n return addr;\n }\n\n function _destroy(uint256 routeId) internal {\n // determine the address of the socket contract.\n address routeContractAddress = _getContractAddress(routeId);\n\n if (!isRouteDeployed[routeId]) {\n revert NothingToDestroy();\n }\n ISocketBridgeBase(routeContractAddress).killme();\n emit Destroyed(routeContractAddress);\n }\n\n /**\n * @dev Internal view function for calculating a socket contract address\n * given a particular routeId.\n */\n function _getContractAddress(\n uint256 routeId\n ) internal view returns (address) {\n // determine the address of the socket contract.\n\n bytes memory initCode = (\n hex\"5860208158601c335a63aaf10f428752fa158151803b80938091923cf3\"\n );\n return\n address(\n uint160( // downcast to match the address type.\n uint256( // convert to uint to truncate upper digits.\n keccak256( // compute the CREATE2 hash using 4 inputs.\n abi.encodePacked( // pack all inputs to the hash together.\n hex\"ff\", // start with 0xff to distinguish from RLP.\n address(this), // this contract will be the caller.\n routeId, // the routeId is used as salt.\n keccak256(abi.encodePacked(initCode)) // the init code hash.\n )\n )\n )\n )\n );\n }\n\n /**\n * @notice Rescues the ERC20 token to an address\n this is a restricted function to be called by only socketGatewayOwner\n * @dev as this is a restricted to socketGatewayOwner, ensure the userAddress is a known address\n * @param token address of the ERC20 token being rescued\n * @param userAddress address to which ERC20 is to be rescued\n * @param amount amount of ERC20 tokens being rescued\n */\n function rescueFunds(\n address token,\n address userAddress,\n uint256 amount\n ) external onlyOwner {\n ERC20(token).safeTransfer(userAddress, amount);\n }\n\n /**\n * @notice Rescues the native balance to an address\n this is a restricted function to be called by only socketGatewayOwner\n * @dev as this is a restricted to socketGatewayOwner, ensure the userAddress is a known address\n * @param userAddress address to which native-balance is to be rescued\n * @param amount amount of native-balance being rescued\n */\n function rescueEther(\n address payable userAddress,\n uint256 amount\n ) external onlyOwner {\n userAddress.transfer(amount);\n }\n}\n"},"src/interfaces/ISocketController.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/**\n * @title ISocketController\n * @notice Interface for SocketController functions.\n * @dev functions can be added here for invocation from external contracts or off-chain\n * only restriction is that this should have functions to manage controllers\n * @author Socket dot tech.\n */\ninterface ISocketController {\n /**\n * @notice Add controller to the socketGateway\n This is a restricted function to be called by only socketGatewayOwner\n * @dev ensure controllerAddress is a verified controller implementation address\n * @param _controllerAddress The address of controller implementation contract deployed\n * @return Id of the controller added to the controllers-mapping in socketGateway storage\n */\n function addController(\n address _controllerAddress\n ) external returns (uint32);\n\n /**\n * @notice disable controller by setting ZeroAddress to the entry in controllers-mapping\n identified by controllerId as key.\n This is a restricted function to be called by only socketGatewayOwner\n * @param _controllerId The Id of controller-implementation in the controllers mapping\n */\n function disableController(uint32 _controllerId) external;\n\n /**\n * @notice Get controllerImplementation address mapped to the controllerId\n * @param _controllerId controllerId is the key in the mapping for controllers\n * @return controller-implementation address\n */\n function getController(uint32 _controllerId) external returns (address);\n}\n"},"lib/solmate/src/utils/SafeTransferLib.sol":{"content":"// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\nimport {ERC20} from \"../tokens/ERC20.sol\";\n\n/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.\n/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)\n/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.\n/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.\nlibrary SafeTransferLib {\n /*//////////////////////////////////////////////////////////////\n ETH OPERATIONS\n //////////////////////////////////////////////////////////////*/\n\n function safeTransferETH(address to, uint256 amount) internal {\n bool success;\n\n /// @solidity memory-safe-assembly\n assembly {\n // Transfer the ETH and store if it succeeded or not.\n success := call(gas(), to, amount, 0, 0, 0, 0)\n }\n\n require(success, \"ETH_TRANSFER_FAILED\");\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC20 OPERATIONS\n //////////////////////////////////////////////////////////////*/\n\n function safeTransferFrom(\n ERC20 token,\n address from,\n address to,\n uint256 amount\n ) internal {\n bool success;\n\n /// @solidity memory-safe-assembly\n assembly {\n // Get a pointer to some free memory.\n let freeMemoryPointer := mload(0x40)\n\n // Write the abi-encoded calldata into memory, beginning with the function selector.\n mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)\n mstore(add(freeMemoryPointer, 4), from) // Append the \"from\" argument.\n mstore(add(freeMemoryPointer, 36), to) // Append the \"to\" argument.\n mstore(add(freeMemoryPointer, 68), amount) // Append the \"amount\" argument.\n\n success := and(\n // Set success to whether the call reverted, if not we check it either\n // returned exactly 1 (can't just be non-zero data), or had no return data.\n or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),\n // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.\n // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.\n // Counterintuitively, this call must be positioned second to the or() call in the\n // surrounding and() call or else returndatasize() will be zero during the computation.\n call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)\n )\n }\n\n require(success, \"TRANSFER_FROM_FAILED\");\n }\n\n function safeTransfer(\n ERC20 token,\n address to,\n uint256 amount\n ) internal {\n bool success;\n\n /// @solidity memory-safe-assembly\n assembly {\n // Get a pointer to some free memory.\n let freeMemoryPointer := mload(0x40)\n\n // Write the abi-encoded calldata into memory, beginning with the function selector.\n mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)\n mstore(add(freeMemoryPointer, 4), to) // Append the \"to\" argument.\n mstore(add(freeMemoryPointer, 36), amount) // Append the \"amount\" argument.\n\n success := and(\n // Set success to whether the call reverted, if not we check it either\n // returned exactly 1 (can't just be non-zero data), or had no return data.\n or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),\n // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.\n // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.\n // Counterintuitively, this call must be positioned second to the or() call in the\n // surrounding and() call or else returndatasize() will be zero during the computation.\n call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)\n )\n }\n\n require(success, \"TRANSFER_FAILED\");\n }\n\n function safeApprove(\n ERC20 token,\n address to,\n uint256 amount\n ) internal {\n bool success;\n\n /// @solidity memory-safe-assembly\n assembly {\n // Get a pointer to some free memory.\n let freeMemoryPointer := mload(0x40)\n\n // Write the abi-encoded calldata into memory, beginning with the function selector.\n mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)\n mstore(add(freeMemoryPointer, 4), to) // Append the \"to\" argument.\n mstore(add(freeMemoryPointer, 36), amount) // Append the \"amount\" argument.\n\n success := and(\n // Set success to whether the call reverted, if not we check it either\n // returned exactly 1 (can't just be non-zero data), or had no return data.\n or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),\n // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.\n // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.\n // Counterintuitively, this call must be positioned second to the or() call in the\n // surrounding and() call or else returndatasize() will be zero during the computation.\n call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)\n )\n }\n\n require(success, \"APPROVE_FAILED\");\n }\n}\n"},"src/controllers/BaseController.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {ISocketRequest} from \"../interfaces/ISocketRequest.sol\";\nimport {ISocketRoute} from \"../interfaces/ISocketRoute.sol\";\n\n/// @title BaseController Controller\n/// @notice Base contract for all controller contracts\nabstract contract BaseController {\n /// @notice Address used to identify if it is a native token transfer or not\n address public immutable NATIVE_TOKEN_ADDRESS =\n address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);\n\n /// @notice Address used to identify if it is a Zero address\n address public immutable NULL_ADDRESS = address(0);\n\n /// @notice FunctionSelector used to delegatecall from swap to the function of bridge router implementation\n bytes4 public immutable BRIDGE_AFTER_SWAP_SELECTOR =\n bytes4(keccak256(\"bridgeAfterSwap(uint256,bytes)\"));\n\n /// @notice immutable variable to store the socketGateway address\n address public immutable socketGatewayAddress;\n\n /// @notice immutable variable with instance of SocketRoute to access route functions\n ISocketRoute public immutable socketRoute;\n\n /**\n * @notice Construct the base for all controllers.\n * @param _socketGatewayAddress Socketgateway address, an immutable variable to set.\n * @notice initialize the immutable variables of SocketRoute, SocketGateway\n */\n constructor(address _socketGatewayAddress) {\n socketGatewayAddress = _socketGatewayAddress;\n socketRoute = ISocketRoute(_socketGatewayAddress);\n }\n\n /**\n * @notice Construct the base for all BridgeImplementations.\n * @param routeId routeId mapped to the routrImplementation\n * @param data transactionData generated with arguments of bridgeRequest (offchain or by caller)\n * @return returns the bytes response of the route execution (bridging, refuel or swap executions)\n */\n function _executeRoute(\n uint32 routeId,\n bytes memory data\n ) internal returns (bytes memory) {\n (bool success, bytes memory result) = socketRoute\n .getRoute(routeId)\n .delegatecall(data);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n return result;\n }\n}\n"},"src/interfaces/ISocketRoute.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/**\n * @title ISocketRoute\n * @notice Interface for routeManagement functions in SocketGateway.\n * @author Socket dot tech.\n */\ninterface ISocketRoute {\n /**\n * @notice Add route to the socketGateway\n This is a restricted function to be called by only socketGatewayOwner\n * @dev ensure routeAddress is a verified bridge or middleware implementation address\n * @param routeAddress The address of bridge or middleware implementation contract deployed\n * @return Id of the route added to the routes-mapping in socketGateway storage\n */\n function addRoute(address routeAddress) external returns (uint256);\n\n /**\n * @notice disable a route by setting ZeroAddress to the entry in routes-mapping\n identified by routeId as key.\n This is a restricted function to be called by only socketGatewayOwner\n * @param routeId The Id of route-implementation in the routes mapping\n */\n function disableRoute(uint32 routeId) external;\n\n /**\n * @notice Get routeImplementation address mapped to the routeId\n * @param routeId routeId is the key in the mapping for routes\n * @return route-implementation address\n */\n function getRoute(uint32 routeId) external view returns (address);\n}\n"},"src/SocketGatewayDeployment.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\npragma experimental ABIEncoderV2;\n\nimport \"./utils/Ownable.sol\";\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {LibUtil} from \"./libraries/LibUtil.sol\";\nimport \"./libraries/LibBytes.sol\";\nimport {ISocketRoute} from \"./interfaces/ISocketRoute.sol\";\nimport {ISocketRequest} from \"./interfaces/ISocketRequest.sol\";\nimport {ISocketGateway} from \"./interfaces/ISocketGateway.sol\";\nimport {IncorrectBridgeRatios, ZeroAddressNotAllowed, ArrayLengthMismatch} from \"./errors/SocketErrors.sol\";\n\n/// @title SocketGatewayContract\n/// @notice Socketgateway is a contract with entrypoint functions for all interactions with socket liquidity layer\n/// @author Socket Team\ncontract SocketGateway is Ownable {\n using LibBytes for bytes;\n using LibBytes for bytes4;\n using SafeTransferLib for ERC20;\n\n /// @notice FunctionSelector used to delegatecall from swap to the function of bridge router implementation\n bytes4 public immutable BRIDGE_AFTER_SWAP_SELECTOR =\n bytes4(keccak256(\"bridgeAfterSwap(uint256,bytes)\"));\n\n /// @notice storage variable to keep track of total number of routes registered in socketgateway\n uint32 public routesCount = 385;\n\n /// @notice storage variable to keep track of total number of controllers registered in socketgateway\n uint32 public controllerCount;\n\n address public immutable disabledRouteAddress;\n\n uint256 public constant CENT_PERCENT = 100e18;\n\n /// @notice storage mapping for route implementation addresses\n mapping(uint32 => address) public routes;\n\n /// storage mapping for controller implemenation addresses\n mapping(uint32 => address) public controllers;\n\n // Events ------------------------------------------------------------------------------------------------------->\n\n /// @notice Event emitted when a router is added to socketgateway\n event NewRouteAdded(uint32 indexed routeId, address indexed route);\n\n /// @notice Event emitted when a route is disabled\n event RouteDisabled(uint32 indexed routeId);\n\n /// @notice Event emitted when ownership transfer is requested by socket-gateway-owner\n event OwnershipTransferRequested(\n address indexed _from,\n address indexed _to\n );\n\n /// @notice Event emitted when a controller is added to socketgateway\n event ControllerAdded(\n uint32 indexed controllerId,\n address indexed controllerAddress\n );\n\n /// @notice Event emitted when a controller is disabled\n event ControllerDisabled(uint32 indexed controllerId);\n\n constructor(address _owner, address _disabledRoute) Ownable(_owner) {\n disabledRouteAddress = _disabledRoute;\n }\n\n // Able to receive ether\n // solhint-disable-next-line no-empty-blocks\n receive() external payable {}\n\n /*******************************************\n * EXTERNAL AND PUBLIC FUNCTIONS *\n *******************************************/\n\n /**\n * @notice executes functions in the routes identified using routeId and functionSelectorData\n * @notice The caller must first approve this contract to spend amount of ERC20-Token being bridged/swapped\n * @dev ensure the data in routeData to be built using the function-selector defined as a\n * constant in the route implementation contract\n * @param routeId route identifier\n * @param routeData functionSelectorData generated using the function-selector defined in the route Implementation\n */\n function executeRoute(\n uint32 routeId,\n bytes calldata routeData\n ) external payable returns (bytes memory) {\n (bool success, bytes memory result) = addressAt(routeId).delegatecall(\n routeData\n );\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n return result;\n }\n\n /**\n * @notice swaps a token on sourceChain and split it across multiple bridge-recipients\n * @notice The caller must first approve this contract to spend amount of ERC20-Token being swapped\n * @dev ensure the swap-data and bridge-data is generated using the function-selector defined as a constant in the implementation address\n * @param swapMultiBridgeRequest request\n */\n function swapAndMultiBridge(\n ISocketRequest.SwapMultiBridgeRequest calldata swapMultiBridgeRequest\n ) external payable {\n uint256 requestLength = swapMultiBridgeRequest.bridgeRouteIds.length;\n\n if (\n requestLength != swapMultiBridgeRequest.bridgeImplDataItems.length\n ) {\n revert ArrayLengthMismatch();\n }\n uint256 ratioAggregate;\n for (uint256 index = 0; index < requestLength; ) {\n ratioAggregate += swapMultiBridgeRequest.bridgeRatios[index];\n }\n\n if (ratioAggregate != CENT_PERCENT) {\n revert IncorrectBridgeRatios();\n }\n\n (bool swapSuccess, bytes memory swapResult) = addressAt(\n swapMultiBridgeRequest.swapRouteId\n ).delegatecall(swapMultiBridgeRequest.swapImplData);\n\n if (!swapSuccess) {\n assembly {\n revert(add(swapResult, 32), mload(swapResult))\n }\n }\n\n uint256 amountReceivedFromSwap = abi.decode(swapResult, (uint256));\n\n uint256 bridgedAmount;\n\n for (uint256 index = 0; index < requestLength; ) {\n uint256 bridgingAmount;\n\n // if it is the last bridge request, bridge the remaining amount\n if (index == requestLength - 1) {\n bridgingAmount = amountReceivedFromSwap - bridgedAmount;\n } else {\n // bridging amount is the multiplication of bridgeRatio and amountReceivedFromSwap\n bridgingAmount =\n (amountReceivedFromSwap *\n swapMultiBridgeRequest.bridgeRatios[index]) /\n (CENT_PERCENT);\n }\n\n // update the bridged amount, this would be used for computation for last bridgeRequest\n bridgedAmount += bridgingAmount;\n\n bytes memory bridgeImpldata = abi.encodeWithSelector(\n BRIDGE_AFTER_SWAP_SELECTOR,\n bridgingAmount,\n swapMultiBridgeRequest.bridgeImplDataItems[index]\n );\n\n (bool bridgeSuccess, bytes memory bridgeResult) = addressAt(\n swapMultiBridgeRequest.bridgeRouteIds[index]\n ).delegatecall(bridgeImpldata);\n\n if (!bridgeSuccess) {\n assembly {\n revert(add(bridgeResult, 32), mload(bridgeResult))\n }\n }\n\n unchecked {\n ++index;\n }\n }\n }\n\n /**\n * @notice sequentially executes functions in the routes identified using routeId and functionSelectorData\n * @notice The caller must first approve this contract to spend amount of ERC20-Token being bridged/swapped\n * @dev ensure the data in each dataItem to be built using the function-selector defined as a\n * constant in the route implementation contract\n * @param routeIds a list of route identifiers\n * @param dataItems a list of functionSelectorData generated using the function-selector defined in the route Implementation\n */\n function executeRoutes(\n uint32[] calldata routeIds,\n bytes[] calldata dataItems\n ) external payable {\n uint256 routeIdslength = routeIds.length;\n if (routeIdslength != dataItems.length) revert ArrayLengthMismatch();\n for (uint256 index = 0; index < routeIdslength; ) {\n (bool success, bytes memory result) = addressAt(routeIds[index])\n .delegatecall(dataItems[index]);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n unchecked {\n ++index;\n }\n }\n }\n\n /**\n * @notice execute a controller function identified using the controllerId in the request\n * @notice The caller must first approve this contract to spend amount of ERC20-Token being bridged/swapped\n * @dev ensure the data in request to be built using the function-selector defined as a\n * constant in the controller implementation contract\n * @param socketControllerRequest socketControllerRequest with controllerId to identify the\n * controllerAddress and byteData constructed using functionSelector\n * of the function being invoked\n * @return bytes data received from the call delegated to controller\n */\n function executeController(\n ISocketGateway.SocketControllerRequest calldata socketControllerRequest\n ) external payable returns (bytes memory) {\n (bool success, bytes memory result) = controllers[\n socketControllerRequest.controllerId\n ].delegatecall(socketControllerRequest.data);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n return result;\n }\n\n /**\n * @notice sequentially executes all controller requests\n * @notice The caller must first approve this contract to spend amount of ERC20-Token being bridged/swapped\n * @dev ensure the data in each controller-request to be built using the function-selector defined as a\n * constant in the controller implementation contract\n * @param controllerRequests a list of socketControllerRequest\n * Each controllerRequest contains controllerId to identify the controllerAddress and\n * byteData constructed using functionSelector of the function being invoked\n */\n function executeControllers(\n ISocketGateway.SocketControllerRequest[] calldata controllerRequests\n ) external payable {\n for (uint32 index = 0; index < controllerRequests.length; ) {\n (bool success, bytes memory result) = controllers[\n controllerRequests[index].controllerId\n ].delegatecall(controllerRequests[index].data);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n unchecked {\n ++index;\n }\n }\n }\n\n /**************************************\n * ADMIN FUNCTIONS *\n **************************************/\n\n /**\n * @notice Add route to the socketGateway\n This is a restricted function to be called by only socketGatewayOwner\n * @dev ensure routeAddress is a verified bridge or middleware implementation address\n * @param routeAddress The address of bridge or middleware implementation contract deployed\n * @return Id of the route added to the routes-mapping in socketGateway storage\n */\n function addRoute(\n address routeAddress\n ) external onlyOwner returns (uint32) {\n uint32 routeId = routesCount;\n routes[routeId] = routeAddress;\n\n routesCount += 1;\n\n emit NewRouteAdded(routeId, routeAddress);\n\n return routeId;\n }\n\n /**\n * @notice Give Infinite or 0 approval to bridgeRoute for the tokenAddress\n This is a restricted function to be called by only socketGatewayOwner\n */\n\n function setApprovalForRouters(\n address[] memory routeAddresses,\n address[] memory tokenAddresses,\n bool isMax\n ) external onlyOwner {\n for (uint32 index = 0; index < routeAddresses.length; ) {\n ERC20(tokenAddresses[index]).approve(\n routeAddresses[index],\n isMax ? type(uint256).max : 0\n );\n unchecked {\n ++index;\n }\n }\n }\n\n /**\n * @notice Add controller to the socketGateway\n This is a restricted function to be called by only socketGatewayOwner\n * @dev ensure controllerAddress is a verified controller implementation address\n * @param controllerAddress The address of controller implementation contract deployed\n * @return Id of the controller added to the controllers-mapping in socketGateway storage\n */\n function addController(\n address controllerAddress\n ) external onlyOwner returns (uint32) {\n uint32 controllerId = controllerCount;\n\n controllers[controllerId] = controllerAddress;\n\n controllerCount += 1;\n\n emit ControllerAdded(controllerId, controllerAddress);\n\n return controllerId;\n }\n\n /**\n * @notice disable controller by setting ZeroAddress to the entry in controllers-mapping\n identified by controllerId as key.\n This is a restricted function to be called by only socketGatewayOwner\n * @param controllerId The Id of controller-implementation in the controllers mapping\n */\n function disableController(uint32 controllerId) public onlyOwner {\n controllers[controllerId] = disabledRouteAddress;\n emit ControllerDisabled(controllerId);\n }\n\n /**\n * @notice disable a route by setting ZeroAddress to the entry in routes-mapping\n identified by routeId as key.\n This is a restricted function to be called by only socketGatewayOwner\n * @param routeId The Id of route-implementation in the routes mapping\n */\n function disableRoute(uint32 routeId) external onlyOwner {\n routes[routeId] = disabledRouteAddress;\n emit RouteDisabled(routeId);\n }\n\n /*******************************************\n * RESTRICTED RESCUE FUNCTIONS *\n *******************************************/\n\n /**\n * @notice Rescues the ERC20 token to an address\n this is a restricted function to be called by only socketGatewayOwner\n * @dev as this is a restricted to socketGatewayOwner, ensure the userAddress is a known address\n * @param token address of the ERC20 token being rescued\n * @param userAddress address to which ERC20 is to be rescued\n * @param amount amount of ERC20 tokens being rescued\n */\n function rescueFunds(\n address token,\n address userAddress,\n uint256 amount\n ) external onlyOwner {\n ERC20(token).safeTransfer(userAddress, amount);\n }\n\n /**\n * @notice Rescues the native balance to an address\n this is a restricted function to be called by only socketGatewayOwner\n * @dev as this is a restricted to socketGatewayOwner, ensure the userAddress is a known address\n * @param userAddress address to which native-balance is to be rescued\n * @param amount amount of native-balance being rescued\n */\n function rescueEther(\n address payable userAddress,\n uint256 amount\n ) external onlyOwner {\n userAddress.transfer(amount);\n }\n\n /*******************************************\n * VIEW FUNCTIONS *\n *******************************************/\n\n /**\n * @notice Get routeImplementation address mapped to the routeId\n * @param routeId routeId is the key in the mapping for routes\n * @return route-implementation address\n */\n function getRoute(uint32 routeId) public view returns (address) {\n return addressAt(routeId);\n }\n\n /**\n * @notice Get controllerImplementation address mapped to the controllerId\n * @param controllerId controllerId is the key in the mapping for controllers\n * @return controller-implementation address\n */\n function getController(uint32 controllerId) public view returns (address) {\n return controllers[controllerId];\n }\n\n function addressAt(uint32 routeId) public view returns (address) {\n if (routeId < 385) {\n if (routeId < 257) {\n if (routeId < 129) {\n if (routeId < 65) {\n if (routeId < 33) {\n if (routeId < 17) {\n if (routeId < 9) {\n if (routeId < 5) {\n if (routeId < 3) {\n if (routeId == 1) {\n return\n 0x8cd6BaCDAe46B449E2e5B34e348A4eD459c84D50;\n } else {\n return\n 0x31524750Cd865fF6A3540f232754Fb974c18585C;\n }\n } else {\n if (routeId == 3) {\n return\n 0xEd9b37342BeC8f3a2D7b000732ec87498aA6EC6a;\n } else {\n return\n 0xE8704Ef6211F8988Ccbb11badC89841808d66890;\n }\n }\n } else {\n if (routeId < 7) {\n if (routeId == 5) {\n return\n 0x9aFF58C460a461578C433e11C4108D1c4cF77761;\n } else {\n return\n 0x2D1733886cFd465B0B99F1492F40847495f334C5;\n }\n } else {\n if (routeId == 7) {\n return\n 0x715497Be4D130F04B8442F0A1F7a9312D4e54FC4;\n } else {\n return\n 0x90C8a40c38E633B5B0e0d0585b9F7FA05462CaaF;\n }\n }\n }\n } else {\n if (routeId < 13) {\n if (routeId < 11) {\n if (routeId == 9) {\n return\n 0xa402b70FCfF3F4a8422B93Ef58E895021eAdE4F6;\n } else {\n return\n 0xc1B718522E15CD42C4Ac385a929fc2B51f5B892e;\n }\n } else {\n if (routeId == 11) {\n return\n 0xa97bf2f7c26C43c010c349F52f5eA5dC49B2DD38;\n } else {\n return\n 0x969423d71b62C81d2f28d707364c9Dc4a0764c53;\n }\n }\n } else {\n if (routeId < 15) {\n if (routeId == 13) {\n return\n 0xF86729934C083fbEc8C796068A1fC60701Ea1207;\n } else {\n return\n 0xD7cC2571F5823caCA26A42690D2BE7803DD5393f;\n }\n } else {\n if (routeId == 15) {\n return\n 0x7c8837a279bbbf7d8B93413763176de9F65d5bB9;\n } else {\n return\n 0x13b81C27B588C07D04458ed7dDbdbD26D1e39bcc;\n }\n }\n }\n }\n } else {\n if (routeId < 25) {\n if (routeId < 21) {\n if (routeId < 19) {\n if (routeId == 17) {\n return\n 0x52560Ac678aFA1345D15474287d16Dc1eA3F78aE;\n } else {\n return\n 0x1E31e376551459667cd7643440c1b21CE69065A0;\n }\n } else {\n if (routeId == 19) {\n return\n 0xc57D822CB3288e7b97EF8f8af0EcdcD1B783529B;\n } else {\n return\n 0x2197A1D9Af24b4d6a64Bff95B4c29Fcd3Ff28C30;\n }\n }\n } else {\n if (routeId < 23) {\n if (routeId == 21) {\n return\n 0xE3700feAa5100041Bf6b7AdBA1f72f647809Fd00;\n } else {\n return\n 0xc02E8a0Fdabf0EeFCEA025163d90B5621E2b9948;\n }\n } else {\n if (routeId == 23) {\n return\n 0xF5144235E2926cAb3c69b30113254Fa632f72d62;\n } else {\n return\n 0xBa3F92313B00A1f7Bc53b2c24EB195c8b2F57682;\n }\n }\n }\n } else {\n if (routeId < 29) {\n if (routeId < 27) {\n if (routeId == 25) {\n return\n 0x77a6856fe1fFA5bEB55A1d2ED86E27C7c482CB76;\n } else {\n return\n 0x4826Ff4e01E44b1FCEFBfb38cd96687Eb7786b44;\n }\n } else {\n if (routeId == 27) {\n return\n 0x55FF3f5493cf5e80E76DEA7E327b9Cd8440Af646;\n } else {\n return\n 0xF430Db544bE9770503BE4aa51997aA19bBd5BA4f;\n }\n }\n } else {\n if (routeId < 31) {\n if (routeId == 29) {\n return\n 0x0f166446ce1484EE3B0663E7E67DF10F5D240115;\n } else {\n return\n 0x6365095D92537f242Db5EdFDd572745E72aC33d9;\n }\n } else {\n if (routeId == 31) {\n return\n 0x5c7BC93f06ce3eAe75ADf55E10e23d2c1dE5Bc65;\n } else {\n return\n 0xe46383bAD90d7A08197ccF08972e9DCdccCE9BA4;\n }\n }\n }\n }\n }\n } else {\n if (routeId < 49) {\n if (routeId < 41) {\n if (routeId < 37) {\n if (routeId < 35) {\n if (routeId == 33) {\n return\n 0xf0f21710c071E3B728bdc4654c3c0b873aAaa308;\n } else {\n return\n 0x63Bc9ed3AcAAeB0332531C9fB03b0a2352E9Ff25;\n }\n } else {\n if (routeId == 35) {\n return\n 0xd1CE808625CB4007a1708824AE82CdB0ece57De9;\n } else {\n return\n 0x57BbB148112f4ba224841c3FE018884171004661;\n }\n }\n } else {\n if (routeId < 39) {\n if (routeId == 37) {\n return\n 0x037f7d6933036F34DFabd40Ff8e4D789069f92e3;\n } else {\n return\n 0xeF978c280915CfF3Dca4EDfa8932469e40ADA1e1;\n }\n } else {\n if (routeId == 39) {\n return\n 0x92ee9e071B13f7ecFD62B7DED404A16CBc223CD3;\n } else {\n return\n 0x94Ae539c186e41ed762271338Edf140414D1E442;\n }\n }\n }\n } else {\n if (routeId < 45) {\n if (routeId < 43) {\n if (routeId == 41) {\n return\n 0x30A64BBe4DdBD43dA2368EFd1eB2d80C10d84DAb;\n } else {\n return\n 0x3aEABf81c1Dc4c1b73d5B2a95410f126426FB596;\n }\n } else {\n if (routeId == 43) {\n return\n 0x25b08aB3D0C8ea4cC9d967b79688C6D98f3f563a;\n } else {\n return\n 0xea40cB15C9A3BBd27af6474483886F7c0c9AE406;\n }\n }\n } else {\n if (routeId < 47) {\n if (routeId == 45) {\n return\n 0x9580113Cc04e5a0a03359686304EF3A80b936Dd3;\n } else {\n return\n 0xD211c826d568957F3b66a3F4d9c5f68cCc66E619;\n }\n } else {\n if (routeId == 47) {\n return\n 0xCEE24D0635c4C56315d133b031984d4A6f509476;\n } else {\n return\n 0x3922e6B987983229798e7A20095EC372744d4D4c;\n }\n }\n }\n }\n } else {\n if (routeId < 57) {\n if (routeId < 53) {\n if (routeId < 51) {\n if (routeId == 49) {\n return\n 0x2d92D03413d296e1F31450479349757187F2a2b7;\n } else {\n return\n 0x0fe5308eE90FC78F45c89dB6053eA859097860CA;\n }\n } else {\n if (routeId == 51) {\n return\n 0x08Ba68e067C0505bAF0C1311E0cFB2B1B59b969c;\n } else {\n return\n 0x9bee5DdDF75C24897374f92A534B7A6f24e97f4a;\n }\n }\n } else {\n if (routeId < 55) {\n if (routeId == 53) {\n return\n 0x1FC5A90B232208704B930c1edf82FFC6ACc02734;\n } else {\n return\n 0x5b1B0417cb44c761C2a23ee435d011F0214b3C85;\n }\n } else {\n if (routeId == 55) {\n return\n 0x9d70cDaCA12A738C283020760f449D7816D592ec;\n } else {\n return\n 0x95a23b9CB830EcCFDDD5dF56A4ec665e3381Fa12;\n }\n }\n }\n } else {\n if (routeId < 61) {\n if (routeId < 59) {\n if (routeId == 57) {\n return\n 0x483a957Cf1251c20e096C35c8399721D1200A3Fc;\n } else {\n return\n 0xb4AD39Cb293b0Ec7FEDa743442769A7FF04987CD;\n }\n } else {\n if (routeId == 59) {\n return\n 0x4C543AD78c1590D81BAe09Fc5B6Df4132A2461d0;\n } else {\n return\n 0x471d5E5195c563902781734cfe1FF3981F8B6c86;\n }\n }\n } else {\n if (routeId < 63) {\n if (routeId == 61) {\n return\n 0x1B12a54B5E606D95B8B8D123c9Cb09221Ee37584;\n } else {\n return\n 0xE4127cC550baC433646a7D998775a84daC16c7f3;\n }\n } else {\n if (routeId == 63) {\n return\n 0xecb1b55AB12E7dd788D585c6C5cD61B5F87be836;\n } else {\n return\n 0xf91ef487C5A1579f70601b6D347e19756092eEBf;\n }\n }\n }\n }\n }\n }\n } else {\n if (routeId < 97) {\n if (routeId < 81) {\n if (routeId < 73) {\n if (routeId < 69) {\n if (routeId < 67) {\n if (routeId == 65) {\n return\n 0x34a16a7e9BADEEFD4f056310cbE0b1423Fa1b760;\n } else {\n return\n 0x60E10E80c7680f429dBbC232830BEcd3D623c4CF;\n }\n } else {\n if (routeId == 67) {\n return\n 0x66465285B8D65362A1d86CE00fE2bE949Fd6debF;\n } else {\n return\n 0x5aB231B7e1A3A74a48f67Ab7bde5Cdd4267022E0;\n }\n }\n } else {\n if (routeId < 71) {\n if (routeId == 69) {\n return\n 0x3A1C3633eE79d43366F5c67802a746aFD6b162Ba;\n } else {\n return\n 0x0C4BfCbA8dC3C811437521a80E81e41DAF479039;\n }\n } else {\n if (routeId == 71) {\n return\n 0x6caf25d2e139C5431a1FA526EAf8d73ff2e6252C;\n } else {\n return\n 0x74ad21e09FDa68638CE14A3009A79B6D16574257;\n }\n }\n }\n } else {\n if (routeId < 77) {\n if (routeId < 75) {\n if (routeId == 73) {\n return\n 0xD4923A61008894b99cc1CD3407eF9524f02aA0Ca;\n } else {\n return\n 0x6F159b5EB823BD415886b9271aA2A723a00a1987;\n }\n } else {\n if (routeId == 75) {\n return\n 0x742a8aA42E7bfB4554dE30f4Fb07FFb6f2068863;\n } else {\n return\n 0x4AE9702d3360400E47B446e76DE063ACAb930101;\n }\n }\n } else {\n if (routeId < 79) {\n if (routeId == 77) {\n return\n 0x0E19a0a44ddA7dAD854ec5Cc867d16869c4E80F4;\n } else {\n return\n 0xE021A51968f25148F726E326C88d2556c5647557;\n }\n } else {\n if (routeId == 79) {\n return\n 0x64287BDDDaeF4d94E4599a3D882bed29E6Ada4B6;\n } else {\n return\n 0xcBB57Fd2e19cc7e9D444d5b4325A2F1047d0C73f;\n }\n }\n }\n }\n } else {\n if (routeId < 89) {\n if (routeId < 85) {\n if (routeId < 83) {\n if (routeId == 81) {\n return\n 0x373DE80DF7D82cFF6D76F29581b360C56331e957;\n } else {\n return\n 0x0466356E131AD61596a51F86BAd1C03A328960D8;\n }\n } else {\n if (routeId == 83) {\n return\n 0x01726B960992f1b74311b248E2a922fC707d43A6;\n } else {\n return\n 0x2E21bdf9A4509b89795BCE7E132f248a75814CEc;\n }\n }\n } else {\n if (routeId < 87) {\n if (routeId == 85) {\n return\n 0x769512b23aEfF842379091d3B6E4B5456F631D42;\n } else {\n return\n 0xe7eD9be946a74Ec19325D39C6EEb57887ccB2B0D;\n }\n } else {\n if (routeId == 87) {\n return\n 0xc4D01Ec357c2b511d10c15e6b6974380F0E62e67;\n } else {\n return\n 0x5bC49CC9dD77bECF2fd3A3C55611e84E69AFa3AE;\n }\n }\n }\n } else {\n if (routeId < 93) {\n if (routeId < 91) {\n if (routeId == 89) {\n return\n 0x48bcD879954fA14e7DbdAeb56F79C1e9DDcb69ec;\n } else {\n return\n 0xE929bDde21b462572FcAA4de6F49B9D3246688D0;\n }\n } else {\n if (routeId == 91) {\n return\n 0x85Aae300438222f0e3A9Bc870267a5633A9438bd;\n } else {\n return\n 0x51f72E1096a81C55cd142d66d39B688C657f9Be8;\n }\n }\n } else {\n if (routeId < 95) {\n if (routeId == 93) {\n return\n 0x3A8a05BF68ac54B01E6C0f492abF97465F3d15f9;\n } else {\n return\n 0x145aA67133F0c2C36b9771e92e0B7655f0D59040;\n }\n } else {\n if (routeId == 95) {\n return\n 0xa030315d7DB11F9892758C9e7092D841e0ADC618;\n } else {\n return\n 0xdF1f8d81a3734bdDdEfaC6Ca1596E081e57c3044;\n }\n }\n }\n }\n }\n } else {\n if (routeId < 113) {\n if (routeId < 105) {\n if (routeId < 101) {\n if (routeId < 99) {\n if (routeId == 97) {\n return\n 0xFF2833123B58aa05d04D7fb99f5FB768B2b435F8;\n } else {\n return\n 0xc8f09c1fD751C570233765f71b0e280d74e6e743;\n }\n } else {\n if (routeId == 99) {\n return\n 0x3026DA6Ceca2E5A57A05153653D9212FFAaA49d8;\n } else {\n return\n 0xdE68Ee703dE0D11f67B0cE5891cB4a903de6D160;\n }\n }\n } else {\n if (routeId < 103) {\n if (routeId == 101) {\n return\n 0xE23a7730e81FB4E87A6D0bd9f63EE77ac86C3DA4;\n } else {\n return\n 0x8b1DBe04aD76a7d8bC079cACd3ED4D99B897F4a0;\n }\n } else {\n if (routeId == 103) {\n return\n 0xBB227240FA459b69C6889B2b8cb1BE76F118061f;\n } else {\n return\n 0xC062b9b3f0dB28BB8afAfcD4d075729344114ffe;\n }\n }\n }\n } else {\n if (routeId < 109) {\n if (routeId < 107) {\n if (routeId == 105) {\n return\n 0x553188Aa45f5FDB83EC4Ca485982F8fC082480D1;\n } else {\n return\n 0x0109d83D746EaCb6d4014953D9E12d6ca85e330b;\n }\n } else {\n if (routeId == 107) {\n return\n 0x45B1bEd29812F5bf6711074ACD180B2aeB783AD9;\n } else {\n return\n 0xdA06eC8c19aea31D77F60299678Cba40E743e1aD;\n }\n }\n } else {\n if (routeId < 111) {\n if (routeId == 109) {\n return\n 0x3cC5235c97d975a9b4FD4501B3446c981ea3D855;\n } else {\n return\n 0xa1827267d6Bd989Ff38580aE3d9deff6Acf19163;\n }\n } else {\n if (routeId == 111) {\n return\n 0x3663CAA0433A3D4171b3581Cf2410702840A735A;\n } else {\n return\n 0x7575D0a7614F655BA77C74a72a43bbd4fA6246a3;\n }\n }\n }\n }\n } else {\n if (routeId < 121) {\n if (routeId < 117) {\n if (routeId < 115) {\n if (routeId == 113) {\n return\n 0x2516Defc18bc07089c5dAFf5eafD7B0EF64611E2;\n } else {\n return\n 0xfec5FF08E20fbc107a97Af2D38BD0025b84ee233;\n }\n } else {\n if (routeId == 115) {\n return\n 0x0FB5763a87242B25243e23D73f55945fE787523A;\n } else {\n return\n 0xe4C00db89678dBf8391f430C578Ca857Dd98aDE1;\n }\n }\n } else {\n if (routeId < 119) {\n if (routeId == 117) {\n return\n 0x8F2A22061F9F35E64f14523dC1A5f8159e6a21B7;\n } else {\n return\n 0x18e4b838ae966917E20E9c9c5Ad359cDD38303bB;\n }\n } else {\n if (routeId == 119) {\n return\n 0x61ACb1d3Dcb3e3429832A164Cc0fC9849fb75A4a;\n } else {\n return\n 0x7681e3c8e7A41DCA55C257cc0d1Ae757f5530E65;\n }\n }\n }\n } else {\n if (routeId < 125) {\n if (routeId < 123) {\n if (routeId == 121) {\n return\n 0x806a2AB9748C3D1DB976550890E3f528B7E8Faec;\n } else {\n return\n 0xBDb8A5DD52C2c239fbC31E9d43B763B0197028FF;\n }\n } else {\n if (routeId == 123) {\n return\n 0x474EC9203706010B9978D6bD0b105D36755e4848;\n } else {\n return\n 0x8dfd0D829b303F2239212E591a0F92a32880f36E;\n }\n }\n } else {\n if (routeId < 127) {\n if (routeId == 125) {\n return\n 0xad4BcE9745860B1adD6F1Bd34a916f050E4c82C2;\n } else {\n return\n 0xBC701115b9fe14bC8CC5934cdC92517173e308C4;\n }\n } else {\n if (routeId == 127) {\n return\n 0x0D1918d786Db8546a11aDeD475C98370E06f255E;\n } else {\n return\n 0xee44f57cD6936DB55B99163f3Df367B01EdA785a;\n }\n }\n }\n }\n }\n }\n }\n } else {\n if (routeId < 193) {\n if (routeId < 161) {\n if (routeId < 145) {\n if (routeId < 137) {\n if (routeId < 133) {\n if (routeId < 131) {\n if (routeId == 129) {\n return\n 0x63044521fe5a1e488D7eD419cD0e35b7C24F2aa7;\n } else {\n return\n 0x410085E73BD85e90d97b84A68C125aDB9F91f85b;\n }\n } else {\n if (routeId == 131) {\n return\n 0x7913fe97E07C7A397Ec274Ab1d4E2622C88EC5D1;\n } else {\n return\n 0x977f9fE93c064DCf54157406DaABC3a722e8184C;\n }\n }\n } else {\n if (routeId < 135) {\n if (routeId == 133) {\n return\n 0xCD2236468722057cFbbABad2db3DEA9c20d5B01B;\n } else {\n return\n 0x17c7287A491cf5Ff81E2678cF2BfAE4333F6108c;\n }\n } else {\n if (routeId == 135) {\n return\n 0x354D9a5Dbf96c71B79a265F03B595C6Fdc04dadd;\n } else {\n return\n 0xb4e409EB8e775eeFEb0344f9eee884cc7ed21c69;\n }\n }\n }\n } else {\n if (routeId < 141) {\n if (routeId < 139) {\n if (routeId == 137) {\n return\n 0xa1a3c4670Ad69D9be4ab2D39D1231FEC2a63b519;\n } else {\n return\n 0x4589A22199870729C1be5CD62EE93BeD858113E6;\n }\n } else {\n if (routeId == 139) {\n return\n 0x8E7b864dB26Bd6C798C38d4Ba36EbA0d6602cF11;\n } else {\n return\n 0xA2D17C7260a4CB7b9854e89Fc367E80E87872a2d;\n }\n }\n } else {\n if (routeId < 143) {\n if (routeId == 141) {\n return\n 0xC7F0EDf0A1288627b0432304918A75e9084CBD46;\n } else {\n return\n 0xE4B4EF1f9A4aBFEdB371fA7a6143993B15d4df25;\n }\n } else {\n if (routeId == 143) {\n return\n 0xfe3D84A2Ef306FEBb5452441C9BDBb6521666F6A;\n } else {\n return\n 0x8A12B6C64121920110aE58F7cd67DfEc21c6a4C3;\n }\n }\n }\n }\n } else {\n if (routeId < 153) {\n if (routeId < 149) {\n if (routeId < 147) {\n if (routeId == 145) {\n return\n 0x76c4d9aFC4717a2BAac4e5f26CccF02351f7a3DA;\n } else {\n return\n 0xd4719BA550E397aeAcca1Ad2201c1ba69024FAAf;\n }\n } else {\n if (routeId == 147) {\n return\n 0x9646126Ce025224d1682C227d915a386efc0A1Fb;\n } else {\n return\n 0x4DD8Af2E3F2044842f0247920Bc4BABb636915ea;\n }\n }\n } else {\n if (routeId < 151) {\n if (routeId == 149) {\n return\n 0x8e8a327183Af0cf8C2ece9F0ed547C42A160D409;\n } else {\n return\n 0x9D49614CaE1C685C71678CA6d8CDF7584bfd0740;\n }\n } else {\n if (routeId == 151) {\n return\n 0x5a00ef257394cbc31828d48655E3d39e9c11c93d;\n } else {\n return\n 0xC9a2751b38d3dDD161A41Ca0135C5C6c09EC1d56;\n }\n }\n }\n } else {\n if (routeId < 157) {\n if (routeId < 155) {\n if (routeId == 153) {\n return\n 0x7e1c261640a525C94Ca4f8c25b48CF754DD83590;\n } else {\n return\n 0x409Fe24ba6F6BD5aF31C1aAf8059b986A3158233;\n }\n } else {\n if (routeId == 155) {\n return\n 0x704Cf5BFDADc0f55fDBb53B6ed8B582E018A72A2;\n } else {\n return\n 0x3982bF65d7d6E77E3b6661cd6F6468c247512737;\n }\n }\n } else {\n if (routeId < 159) {\n if (routeId == 157) {\n return\n 0x3982b9f26FFD67a13Ee371e2C0a9Da338BA70E7f;\n } else {\n return\n 0x6D834AB385900c1f49055D098e90264077FbC4f2;\n }\n } else {\n if (routeId == 159) {\n return\n 0x11FE5F70779A094B7166B391e1Fb73d422eF4e4d;\n } else {\n return\n 0xD347e4E47280d21F13B73D89c6d16f867D50DD13;\n }\n }\n }\n }\n }\n } else {\n if (routeId < 177) {\n if (routeId < 169) {\n if (routeId < 165) {\n if (routeId < 163) {\n if (routeId == 161) {\n return\n 0xb6035eDD53DDA28d8B69b4ae9836E40C80306CD7;\n } else {\n return\n 0x54c884e6f5C7CcfeCA990396c520C858c922b6CA;\n }\n } else {\n if (routeId == 163) {\n return\n 0x5eA93E240b083d686558Ed607BC013d88057cE46;\n } else {\n return\n 0x4C7131eE812De685cBe4e2cCb033d46ecD46612E;\n }\n }\n } else {\n if (routeId < 167) {\n if (routeId == 165) {\n return\n 0xc1a5Be9F0c33D8483801D702111068669f81fF91;\n } else {\n return\n 0x9E5fAb91455Be5E5b2C05967E73F456c8118B1Fc;\n }\n } else {\n if (routeId == 167) {\n return\n 0x3d9A05927223E0DC2F382831770405885e22F0d8;\n } else {\n return\n 0x6303A011fB6063f5B1681cb5a9938EA278dc6128;\n }\n }\n }\n } else {\n if (routeId < 173) {\n if (routeId < 171) {\n if (routeId == 169) {\n return\n 0xe9c60795c90C66797e4c8E97511eA07CdAda32bE;\n } else {\n return\n 0xD56cC98e69A1e13815818b466a8aA6163d84234A;\n }\n } else {\n if (routeId == 171) {\n return\n 0x47EbB9D36a6e40895316cD894E4860D774E2c531;\n } else {\n return\n 0xA5EB293629410065d14a7B1663A67829b0618292;\n }\n }\n } else {\n if (routeId < 175) {\n if (routeId == 173) {\n return\n 0x1b3B4C8146F939cE00899db8B3ddeF0062b7E023;\n } else {\n return\n 0x257Bbc11653625EbfB6A8587eF4f4FBe49828EB3;\n }\n } else {\n if (routeId == 175) {\n return\n 0x44cc979C01b5bB1eAC21301E73C37200dFD06F59;\n } else {\n return\n 0x2972fDF43352225D82754C0174Ff853819D1ef2A;\n }\n }\n }\n }\n } else {\n if (routeId < 185) {\n if (routeId < 181) {\n if (routeId < 179) {\n if (routeId == 177) {\n return\n 0x3e54144f032648A04D62d79f7B4b93FF3aC2333b;\n } else {\n return\n 0x444016102dB8adbE73C3B6703a1ea7F2f75A510D;\n }\n } else {\n if (routeId == 179) {\n return\n 0xac079143f98a6eb744Fde34541ebF243DF5B5dED;\n } else {\n return\n 0xAe9010767Fb112d29d35CEdfba2b372Ad7A308d3;\n }\n }\n } else {\n if (routeId < 183) {\n if (routeId == 181) {\n return\n 0xfE0BCcF9cCC2265D5fB3450743f17DfE57aE1e56;\n } else {\n return\n 0x04ED8C0545716119437a45386B1d691C63234C7D;\n }\n } else {\n if (routeId == 183) {\n return\n 0x636c14013e531A286Bc4C848da34585f0bB73d59;\n } else {\n return\n 0x2Fa67fc7ECC5cAA01C653d3BFeA98ecc5db9C42A;\n }\n }\n }\n } else {\n if (routeId < 189) {\n if (routeId < 187) {\n if (routeId == 185) {\n return\n 0x23e9a0FC180818aA872D2079a985217017E97bd9;\n } else {\n return\n 0x79A95c3Ef81b3ae64ee03A9D5f73e570495F164E;\n }\n } else {\n if (routeId == 187) {\n return\n 0xa7EA0E88F04a84ba0ad1E396cb07Fa3fDAD7dF6D;\n } else {\n return\n 0xd23cA1278a2B01a3C0Ca1a00d104b11c1Ebe6f42;\n }\n }\n } else {\n if (routeId < 191) {\n if (routeId == 189) {\n return\n 0x707bc4a9FA2E349AED5df4e9f5440C15aA9D14Bd;\n } else {\n return\n 0x7E290F2dd539Ac6CE58d8B4C2B944931a1fD3612;\n }\n } else {\n if (routeId == 191) {\n return\n 0x707AA5503088Ce06Ba450B6470A506122eA5c8eF;\n } else {\n return\n 0xFbB3f7BF680deeb149f4E7BC30eA3DDfa68F3C3f;\n }\n }\n }\n }\n }\n }\n } else {\n if (routeId < 225) {\n if (routeId < 209) {\n if (routeId < 201) {\n if (routeId < 197) {\n if (routeId < 195) {\n if (routeId == 193) {\n return\n 0xDE74aD8cCC3dbF14992f49Cf24f36855912f4934;\n } else {\n return\n 0x409BA83df7777F070b2B50a10a41DE2468d2a3B3;\n }\n } else {\n if (routeId == 195) {\n return\n 0x5CB7Be90A5DD7CfDa54e87626e254FE8C18255B4;\n } else {\n return\n 0x0A684fE12BC64fb72B59d0771a566F49BC090356;\n }\n }\n } else {\n if (routeId < 199) {\n if (routeId == 197) {\n return\n 0xDf30048d91F8FA2bCfC54952B92bFA8e161D3360;\n } else {\n return\n 0x050825Fff032a547C47061CF0696FDB0f65AEa5D;\n }\n } else {\n if (routeId == 199) {\n return\n 0xd55e671dAC1f03d366d8535073ada5DB2Aab1Ea2;\n } else {\n return\n 0x9470C704A9616c8Cd41c595Fcd2181B6fe2183C2;\n }\n }\n }\n } else {\n if (routeId < 205) {\n if (routeId < 203) {\n if (routeId == 201) {\n return\n 0x2D9ffD275181F5865d5e11CbB4ced1521C4dF9f1;\n } else {\n return\n 0x816d28Dec10ec95DF5334f884dE85cA6215918d8;\n }\n } else {\n if (routeId == 203) {\n return\n 0xd1f87267c4A43835E666dd69Df077e578A3b6299;\n } else {\n return\n 0x39E89Bde9DACbe5468C025dE371FbDa12bDeBAB1;\n }\n }\n } else {\n if (routeId < 207) {\n if (routeId == 205) {\n return\n 0x7b40A3207956ecad6686E61EfcaC48912FcD0658;\n } else {\n return\n 0x090cF10D793B1Efba9c7D76115878814B663859A;\n }\n } else {\n if (routeId == 207) {\n return\n 0x312A59c06E41327878F2063eD0e9c282C1DA3AfC;\n } else {\n return\n 0x4F1188f46236DD6B5de11Ebf2a9fF08716E7DeB6;\n }\n }\n }\n }\n } else {\n if (routeId < 217) {\n if (routeId < 213) {\n if (routeId < 211) {\n if (routeId == 209) {\n return\n 0x0A6F9a3f4fA49909bBfb4339cbE12B42F53BbBeD;\n } else {\n return\n 0x01d13d7aCaCbB955B81935c80ffF31e14BdFa71f;\n }\n } else {\n if (routeId == 211) {\n return\n 0x691a14Fa6C7360422EC56dF5876f84d4eDD7f00A;\n } else {\n return\n 0x97Aad18d886d181a9c726B3B6aE15a0A69F5aF73;\n }\n }\n } else {\n if (routeId < 215) {\n if (routeId == 213) {\n return\n 0x2917241371D2099049Fa29432DC46735baEC33b4;\n } else {\n return\n 0x5F20F20F7890c2e383E29D4147C9695A371165f5;\n }\n } else {\n if (routeId == 215) {\n return\n 0xeC0a60e639958335662C5219A320cCEbb56C6077;\n } else {\n return\n 0x96d63CF5062975C09845d17ec672E10255866053;\n }\n }\n }\n } else {\n if (routeId < 221) {\n if (routeId < 219) {\n if (routeId == 217) {\n return\n 0xFF57429e57D383939CAB50f09ABBfB63C0e6c9AD;\n } else {\n return\n 0x18E393A7c8578fb1e235C242076E50013cDdD0d7;\n }\n } else {\n if (routeId == 219) {\n return\n 0xE7E5238AF5d61f52E9B4ACC025F713d1C0216507;\n } else {\n return\n 0x428401D4d0F25A2EE1DA4d5366cB96Ded425D9bD;\n }\n }\n } else {\n if (routeId < 223) {\n if (routeId == 221) {\n return\n 0x42E5733551ff1Ee5B48Aa9fc2B61Af9b58C812E6;\n } else {\n return\n 0x64Df9c7A0551B056d860Bc2419Ca4c1EF75320bE;\n }\n } else {\n if (routeId == 223) {\n return\n 0x46006925506145611bBf0263243D8627dAf26B0F;\n } else {\n return\n 0x8D64BE884314662804eAaB884531f5C50F4d500c;\n }\n }\n }\n }\n }\n } else {\n if (routeId < 241) {\n if (routeId < 233) {\n if (routeId < 229) {\n if (routeId < 227) {\n if (routeId == 225) {\n return\n 0x157a62D92D07B5ce221A5429645a03bBaCE85373;\n } else {\n return\n 0xaF037D33e1F1F2F87309B425fe8a9d895Ef3722B;\n }\n } else {\n if (routeId == 227) {\n return\n 0x921D1154E494A2f7218a37ad7B17701f94b4B40e;\n } else {\n return\n 0xF282b4555186d8Dea51B8b3F947E1E0568d09bc4;\n }\n }\n } else {\n if (routeId < 231) {\n if (routeId == 229) {\n return\n 0xa794E2E1869765a4600b3DFd8a4ebcF16350f6B6;\n } else {\n return\n 0xFEFb048e20c5652F7940A49B1980E0125Ec4D358;\n }\n } else {\n if (routeId == 231) {\n return\n 0x220104b641971e9b25612a8F001bf48AbB23f1cF;\n } else {\n return\n 0xcB9D373Bb54A501B35dd3be5bF4Ba43cA31F7035;\n }\n }\n }\n } else {\n if (routeId < 237) {\n if (routeId < 235) {\n if (routeId == 233) {\n return\n 0x37D627F56e3FF36aC316372109ea82E03ac97DAc;\n } else {\n return\n 0x4E81355FfB4A271B4EA59ff78da2b61c7833161f;\n }\n } else {\n if (routeId == 235) {\n return\n 0xADd8D65cAF6Cc9ad73127B49E16eA7ac29d91e87;\n } else {\n return\n 0x630F9b95626487dfEAe3C97A44DB6C59cF35d996;\n }\n }\n } else {\n if (routeId < 239) {\n if (routeId == 237) {\n return\n 0x78CE2BC8238B679680A67FCB98C5A60E4ec17b2D;\n } else {\n return\n 0xA38D776028eD1310b9A6b086f67F788201762E21;\n }\n } else {\n if (routeId == 239) {\n return\n 0x7Bb5178827B76B86753Ed62a0d662c72cEcb1bD3;\n } else {\n return\n 0x4faC26f61C76eC5c3D43b43eDfAFF0736Ae0e3da;\n }\n }\n }\n }\n } else {\n if (routeId < 249) {\n if (routeId < 245) {\n if (routeId < 243) {\n if (routeId == 241) {\n return\n 0x791Bb49bfFA7129D6889FDB27744422Ac4571A85;\n } else {\n return\n 0x26766fFEbb5fa564777913A6f101dF019AB32afa;\n }\n } else {\n if (routeId == 243) {\n return\n 0x05e98E5e95b4ECBbbAf3258c3999Cc81ed8048Be;\n } else {\n return\n 0xC5c4621e52f1D6A1825A5ed4F95855401a3D9C6b;\n }\n }\n } else {\n if (routeId < 247) {\n if (routeId == 245) {\n return\n 0xfcb15f909BA7FC7Ea083503Fb4c1020203c107EB;\n } else {\n return\n 0xbD27603279d969c74f2486ad14E71080829DFd38;\n }\n } else {\n if (routeId == 247) {\n return\n 0xff2f756BcEcC1A55BFc09a30cc5F64720458cFCB;\n } else {\n return\n 0x3bfB968FEbC12F4e8420B2d016EfcE1E615f7246;\n }\n }\n }\n } else {\n if (routeId < 253) {\n if (routeId < 251) {\n if (routeId == 249) {\n return\n 0x982EE9Ffe23051A2ec945ed676D864fa8345222b;\n } else {\n return\n 0xe101899100785E74767d454FFF0131277BaD48d9;\n }\n } else {\n if (routeId == 251) {\n return\n 0x4F730C0c6b3B5B7d06ca511379f4Aa5BfB2E9525;\n } else {\n return\n 0x5499c36b365795e4e0Ef671aF6C2ce26D7c78265;\n }\n }\n } else {\n if (routeId < 255) {\n if (routeId == 253) {\n return\n 0x8AF51F7237Fc8fB2fc3E700488a94a0aC6Ad8b5a;\n } else {\n return\n 0xda8716df61213c0b143F2849785FB85928084857;\n }\n } else {\n if (routeId == 255) {\n return\n 0xF040Cf9b1ebD11Bf28e04e80740DF3DDe717e4f5;\n } else {\n return\n 0xB87ba32f759D14023C7520366B844dF7f0F036C2;\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n if (routeId < 321) {\n if (routeId < 289) {\n if (routeId < 273) {\n if (routeId < 265) {\n if (routeId < 261) {\n if (routeId < 259) {\n if (routeId == 257) {\n return\n 0x0Edde681b8478F0c3194f468EdD2dB5e75c65CDD;\n } else {\n return\n 0x59C70900Fca06eE2aCE1BDd5A8D0Af0cc3BBA720;\n }\n } else {\n if (routeId == 259) {\n return\n 0x8041F0f180D17dD07087199632c45E17AeB0BAd5;\n } else {\n return\n 0x4fB4727064BA595995DD516b63b5921Df9B93aC6;\n }\n }\n } else {\n if (routeId < 263) {\n if (routeId == 261) {\n return\n 0x86e98b594565857eD098864F560915C0dAfd6Ea1;\n } else {\n return\n 0x70f8818E8B698EFfeCd86A513a4c87c0c380Bef6;\n }\n } else {\n if (routeId == 263) {\n return\n 0x78Ed227c8A897A21Da2875a752142dd80d865158;\n } else {\n return\n 0xd02A30BB5C3a8C51d2751A029a6fcfDE2Af9fbc6;\n }\n }\n }\n } else {\n if (routeId < 269) {\n if (routeId < 267) {\n if (routeId == 265) {\n return\n 0x0F00d5c5acb24e975e2a56730609f7F40aa763b8;\n } else {\n return\n 0xC3e2091edc2D3D9D98ba09269138b617B536834A;\n }\n } else {\n if (routeId == 267) {\n return\n 0xa6FbaF7F30867C9633908998ea8C3da28920E75C;\n } else {\n return\n 0xE6dDdcD41E2bBe8122AE32Ac29B8fbAB79CD21d9;\n }\n }\n } else {\n if (routeId < 271) {\n if (routeId == 269) {\n return\n 0x537aa8c1Ef6a8Eaf039dd6e1Eb67694a48195cE4;\n } else {\n return\n 0x96ABAC485fd2D0B03CF4a10df8BD58b8dED28300;\n }\n } else {\n if (routeId == 271) {\n return\n 0xda8e7D46d04Bd4F62705Cd80355BDB6d441DafFD;\n } else {\n return\n 0xbE50018E7a5c67E2e5f5414393e971CC96F293f2;\n }\n }\n }\n }\n } else {\n if (routeId < 281) {\n if (routeId < 277) {\n if (routeId < 275) {\n if (routeId == 273) {\n return\n 0xa1b3907D6CB542a4cbe2eE441EfFAA909FAb62C3;\n } else {\n return\n 0x6d08ee8511C0237a515013aC389e7B3968Cb1753;\n }\n } else {\n if (routeId == 275) {\n return\n 0x22faa5B5Fe43eAdbB52745e35a5cdA8bD5F96bbA;\n } else {\n return\n 0x7a673eB74D79e4868D689E7852abB5f93Ec2fD4b;\n }\n }\n } else {\n if (routeId < 279) {\n if (routeId == 277) {\n return\n 0x0b8531F8AFD4190b76F3e10deCaDb84c98b4d419;\n } else {\n return\n 0x78eABC743A93583DeE403D6b84795490e652216B;\n }\n } else {\n if (routeId == 279) {\n return\n 0x3A95D907b2a7a8604B59BccA08585F58Afe0Aa64;\n } else {\n return\n 0xf4271f0C8c9Af0F06A80b8832fa820ccE64FAda8;\n }\n }\n }\n } else {\n if (routeId < 285) {\n if (routeId < 283) {\n if (routeId == 281) {\n return\n 0x74b2DF841245C3748c0d31542e1335659a25C33b;\n } else {\n return\n 0xdFC99Fd0Ad7D16f30f295a5EEFcE029E04d0fa65;\n }\n } else {\n if (routeId == 283) {\n return\n 0xE992416b6aC1144eD8148a9632973257839027F6;\n } else {\n return\n 0x54ce55ba954E981BB1fd9399054B35Ce1f2C0816;\n }\n }\n } else {\n if (routeId < 287) {\n if (routeId == 285) {\n return\n 0xD4AB52f9e7E5B315Bd7471920baD04F405Ab1c38;\n } else {\n return\n 0x3670C990994d12837e95eE127fE2f06FD3E2104B;\n }\n } else {\n if (routeId == 287) {\n return\n 0xDcf190B09C47E4f551E30BBb79969c3FdEA1e992;\n } else {\n return\n 0xa65057B967B59677237e57Ab815B209744b9bc40;\n }\n }\n }\n }\n }\n } else {\n if (routeId < 305) {\n if (routeId < 297) {\n if (routeId < 293) {\n if (routeId < 291) {\n if (routeId == 289) {\n return\n 0x6Efc86B40573e4C7F28659B13327D55ae955C483;\n } else {\n return\n 0x06BcC25CF8e0E72316F53631b3aA7134E9f73Ae0;\n }\n } else {\n if (routeId == 291) {\n return\n 0x710b6414E1D53882b1FCD3A168aD5Ccd435fc6D0;\n } else {\n return\n 0x5Ebb2C3d78c4e9818074559e7BaE7FCc99781DC1;\n }\n }\n } else {\n if (routeId < 295) {\n if (routeId == 293) {\n return\n 0xAf0a409c3AEe0bD08015cfb29D89E90b6e89A88F;\n } else {\n return\n 0x522559d8b99773C693B80cE06DF559036295Ce44;\n }\n } else {\n if (routeId == 295) {\n return\n 0xB65290A5Bae838aaa7825c9ECEC68041841a1B64;\n } else {\n return\n 0x801b8F2068edd5Bcb659E6BDa0c425909043C420;\n }\n }\n }\n } else {\n if (routeId < 301) {\n if (routeId < 299) {\n if (routeId == 297) {\n return\n 0x29b5F00515d093627E0B7bd0b5c8E84F6b4cDb87;\n } else {\n return\n 0x652839Ae74683cbF9f1293F1019D938F87464D3E;\n }\n } else {\n if (routeId == 299) {\n return\n 0x5Bc95dCebDDE9B79F2b6DC76121BC7936eF8D666;\n } else {\n return\n 0x90db359CEA62E53051158Ab5F99811C0a07Fe686;\n }\n }\n } else {\n if (routeId < 303) {\n if (routeId == 301) {\n return\n 0x2c3625EedadbDcDbB5330eb0d17b3C39ff269807;\n } else {\n return\n 0xC3f0324471b5c9d415acD625b8d8694a4e48e001;\n }\n } else {\n if (routeId == 303) {\n return\n 0x8C60e7E05fa0FfB6F720233736f245134685799d;\n } else {\n return\n 0x98fAF2c09aa4EBb995ad0B56152993E7291a500e;\n }\n }\n }\n }\n } else {\n if (routeId < 313) {\n if (routeId < 309) {\n if (routeId < 307) {\n if (routeId == 305) {\n return\n 0x802c1063a861414dFAEc16bacb81429FC0d40D6e;\n } else {\n return\n 0x11C4AeFCC0dC156f64195f6513CB1Fb3Be0Ae056;\n }\n } else {\n if (routeId == 307) {\n return\n 0xEff1F3258214E31B6B4F640b4389d55715C3Be2B;\n } else {\n return\n 0x47e379Abe8DDFEA4289aBa01235EFF7E93758fd7;\n }\n }\n } else {\n if (routeId < 311) {\n if (routeId == 309) {\n return\n 0x3CC26384c3eA31dDc8D9789e8872CeA6F20cD3ff;\n } else {\n return\n 0xEdd9EFa6c69108FAA4611097d643E20Ba0Ed1634;\n }\n } else {\n if (routeId == 311) {\n return\n 0xCb93525CA5f3D371F74F3D112bC19526740717B8;\n } else {\n return\n 0x7071E0124EB4438137e60dF1b8DD8Af1BfB362cF;\n }\n }\n }\n } else {\n if (routeId < 317) {\n if (routeId < 315) {\n if (routeId == 313) {\n return\n 0x4691096EB0b78C8F4b4A8091E5B66b18e1835c10;\n } else {\n return\n 0x8d953c9b2d1C2137CF95992079f3A77fCd793272;\n }\n } else {\n if (routeId == 315) {\n return\n 0xbdCc2A3Bf6e3Ba49ff86595e6b2b8D70d8368c92;\n } else {\n return\n 0x95E6948aB38c61b2D294E8Bd896BCc4cCC0713cf;\n }\n }\n } else {\n if (routeId < 319) {\n if (routeId == 317) {\n return\n 0x607b27C881fFEE4Cb95B1c5862FaE7224ccd0b4A;\n } else {\n return\n 0x09D28aFA166e566A2Ee1cB834ea8e78C7E627eD2;\n }\n } else {\n if (routeId == 319) {\n return\n 0x9c01449b38bDF0B263818401044Fb1401B29fDfA;\n } else {\n return\n 0x1F7723599bbB658c051F8A39bE2688388d22ceD6;\n }\n }\n }\n }\n }\n }\n } else {\n if (routeId < 353) {\n if (routeId < 337) {\n if (routeId < 329) {\n if (routeId < 325) {\n if (routeId < 323) {\n if (routeId == 321) {\n return\n 0x52B71603f7b8A5d15B4482e965a0619aa3210194;\n } else {\n return\n 0x01c0f072CB210406653752FecFA70B42dA9173a2;\n }\n } else {\n if (routeId == 323) {\n return\n 0x3021142f021E943e57fc1886cAF58D06147D09A6;\n } else {\n return\n 0xe6f2AF38e76AB09Db59225d97d3E770942D3D842;\n }\n }\n } else {\n if (routeId < 327) {\n if (routeId == 325) {\n return\n 0x06a25554e5135F08b9e2eD1DEC1fc3CEd52e0B48;\n } else {\n return\n 0x71d75e670EE3511C8290C705E0620126B710BF8D;\n }\n } else {\n if (routeId == 327) {\n return\n 0x8b9cE142b80FeA7c932952EC533694b1DF9B3c54;\n } else {\n return\n 0xd7Be24f32f39231116B3fDc483C2A12E1521f73B;\n }\n }\n }\n } else {\n if (routeId < 333) {\n if (routeId < 331) {\n if (routeId == 329) {\n return\n 0xb40cafBC4797d4Ff64087E087F6D2e661f954CbE;\n } else {\n return\n 0xBdDCe7771EfEe81893e838f62204A4c76D72757e;\n }\n } else {\n if (routeId == 331) {\n return\n 0x5d3D299EA7Fd4F39AcDb336E26631Dfee41F9287;\n } else {\n return\n 0x6BfEE09E1Fc0684e0826A9A0dC1352a14B136FAC;\n }\n }\n } else {\n if (routeId < 335) {\n if (routeId == 333) {\n return\n 0xd0001bB8E2Cb661436093f96458a4358B5156E3c;\n } else {\n return\n 0x1867c6485CfD1eD448988368A22bfB17a7747293;\n }\n } else {\n if (routeId == 335) {\n return\n 0x8997EF9F95dF24aB67703AB6C262aABfeEBE33bD;\n } else {\n return\n 0x1e39E9E601922deD91BCFc8F78836302133465e2;\n }\n }\n }\n }\n } else {\n if (routeId < 345) {\n if (routeId < 341) {\n if (routeId < 339) {\n if (routeId == 337) {\n return\n 0x8A8ec6CeacFf502a782216774E5AF3421562C6ff;\n } else {\n return\n 0x3B8FC561df5415c8DC01e97Ee6E38435A8F9C40A;\n }\n } else {\n if (routeId == 339) {\n return\n 0xD5d5f5B37E67c43ceA663aEDADFFc3a93a2065B0;\n } else {\n return\n 0xCC8F55EC43B4f25013CE1946FBB740c43Be5B96D;\n }\n }\n } else {\n if (routeId < 343) {\n if (routeId == 341) {\n return\n 0x18f586E816eEeDbb57B8011239150367561B58Fb;\n } else {\n return\n 0xd0CD802B19c1a52501cb2f07d656e3Cd7B0Ce124;\n }\n } else {\n if (routeId == 343) {\n return\n 0xe0AeD899b39C6e4f2d83e4913a1e9e0cf6368abE;\n } else {\n return\n 0x0606e1b6c0f1A398C38825DCcc4678a7Cbc2737c;\n }\n }\n }\n } else {\n if (routeId < 349) {\n if (routeId < 347) {\n if (routeId == 345) {\n return\n 0x2d188e85b27d18EF80f16686EA1593ABF7Ed2A63;\n } else {\n return\n 0x64412292fA4A135a3300E24366E99ff59Db2eAc1;\n }\n } else {\n if (routeId == 347) {\n return\n 0x38b74c173f3733E8b90aAEf0e98B89791266149F;\n } else {\n return\n 0x36DAA49A79aaEF4E7a217A11530D3cCD84414124;\n }\n }\n } else {\n if (routeId < 351) {\n if (routeId == 349) {\n return\n 0x10f088FE2C88F90270E4449c46c8B1b232511d58;\n } else {\n return\n 0x4FeDbd25B58586838ABD17D10272697dF1dC3087;\n }\n } else {\n if (routeId == 351) {\n return\n 0x685278209248CB058E5cEe93e37f274A80Faf6eb;\n } else {\n return\n 0xDd9F8F1eeC3955f78168e2Fb2d1e808fa8A8f15b;\n }\n }\n }\n }\n }\n } else {\n if (routeId < 369) {\n if (routeId < 361) {\n if (routeId < 357) {\n if (routeId < 355) {\n if (routeId == 353) {\n return\n 0x7392aEeFD5825aaC28817031dEEBbFaAA20983D9;\n } else {\n return\n 0x0Cc182555E00767D6FB8AD161A10d0C04C476d91;\n }\n } else {\n if (routeId == 355) {\n return\n 0x90E52837d56715c79FD592E8D58bFD20365798b2;\n } else {\n return\n 0x6F4451DE14049B6770ad5BF4013118529e68A40C;\n }\n }\n } else {\n if (routeId < 359) {\n if (routeId == 357) {\n return\n 0x89B97ef2aFAb9ed9c7f0FDb095d02E6840b52d9c;\n } else {\n return\n 0x92A5cC5C42d94d3e23aeB1214fFf43Db2B97759E;\n }\n } else {\n if (routeId == 359) {\n return\n 0x63ddc52F135A1dcBA831EAaC11C63849F018b739;\n } else {\n return\n 0x692A691533B571C2c54C1D7F8043A204b3d8120E;\n }\n }\n }\n } else {\n if (routeId < 365) {\n if (routeId < 363) {\n if (routeId == 361) {\n return\n 0x97c7492CF083969F61C6f302d45c8270391b921c;\n } else {\n return\n 0xDeFD2B8643553dAd19548eB14fd94A57F4B9e543;\n }\n } else {\n if (routeId == 363) {\n return\n 0x30645C04205cA3f670B67b02F971B088930ACB8C;\n } else {\n return\n 0xA6f80ed2d607Cd67aEB4109B64A0BEcc4D7d03CF;\n }\n }\n } else {\n if (routeId < 367) {\n if (routeId == 365) {\n return\n 0xBbbbC6c276eB3F7E674f2D39301509236001c42f;\n } else {\n return\n 0xC20E77d349FB40CE88eB01824e2873ad9f681f3C;\n }\n } else {\n if (routeId == 367) {\n return\n 0x5fCfD9a962De19294467C358C1FA55082285960b;\n } else {\n return\n 0x4D87BD6a0E4E5cc6332923cb3E85fC71b287F58A;\n }\n }\n }\n }\n } else {\n if (routeId < 377) {\n if (routeId < 373) {\n if (routeId < 371) {\n if (routeId == 369) {\n return\n 0x3AA5B757cd6Dde98214E56D57Dde7fcF0F7aB04E;\n } else {\n return\n 0xe28eFCE7192e11a2297f44059113C1fD6967b2d4;\n }\n } else {\n if (routeId == 371) {\n return\n 0x3251cAE10a1Cf246e0808D76ACC26F7B5edA0eE5;\n } else {\n return\n 0xbA2091cc9357Cf4c4F25D64F30d1b4Ba3A5a174B;\n }\n }\n } else {\n if (routeId < 375) {\n if (routeId == 373) {\n return\n 0x49c8e1Da9693692096F63C82D11b52d738566d55;\n } else {\n return\n 0xA0731615aB5FFF451031E9551367A4F7dB27b39c;\n }\n } else {\n if (routeId == 375) {\n return\n 0xFb214541888671AE1403CecC1D59763a12fc1609;\n } else {\n return\n 0x1D6bCB17642E2336405df73dF22F07688cAec020;\n }\n }\n }\n } else {\n if (routeId < 381) {\n if (routeId < 379) {\n if (routeId == 377) {\n return\n 0xfC9c0C7bfe187120fF7f4E21446161794A617a9e;\n } else {\n return\n 0xBa5bF37678EeE2dAB17AEf9D898153258252250E;\n }\n } else {\n if (routeId == 379) {\n return\n 0x7c55690bd2C9961576A32c02f8EB29ed36415Ec7;\n } else {\n return\n 0xcA40073E868E8Bc611aEc8Fe741D17E68Fe422f6;\n }\n }\n } else {\n if (routeId < 383) {\n if (routeId == 381) {\n return\n 0x31641bAFb87E9A58f78835050a7BE56921986339;\n } else {\n return\n 0xA54766424f6dA74b45EbCc5Bf0Bd1D74D2CCcaAB;\n }\n } else {\n if (routeId == 383) {\n return\n 0xc7bBa57F8C179EDDBaa62117ddA360e28f3F8252;\n } else {\n return\n 0x5e663ED97ea77d393B8858C90d0683bF180E0ffd;\n }\n }\n }\n }\n }\n }\n }\n }\n }\n\n if (routes[routeId] == address(0)) revert ZeroAddressNotAllowed();\n return routes[routeId];\n }\n\n /// @notice fallback function to handle swap, bridge execution\n /// @dev ensure routeId is converted to bytes4 and sent as msg.sig in the transaction\n fallback() external payable {\n address routeAddress = addressAt(uint32(msg.sig));\n\n bytes memory result;\n\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 4, sub(calldatasize(), 4))\n // execute function call using the facet\n result := delegatecall(\n gas(),\n routeAddress,\n 0,\n sub(calldatasize(), 4),\n 0,\n 0\n )\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n}\n"},"src/bridges/hop/interfaces/IHopL1Bridge.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/**\n * @title L1Bridge Hop Interface\n * @notice L1 Hop Bridge, Used to transfer from L1 to L2s.\n */\ninterface IHopL1Bridge {\n /**\n * @notice `amountOutMin` and `deadline` should be 0 when no swap is intended at the destination.\n * @notice `amount` is the total amount the user wants to send including the relayer fee\n * @dev Send tokens to a supported layer-2 to mint hToken and optionally swap the hToken in the\n * AMM at the destination.\n * @param chainId The chainId of the destination chain\n * @param recipient The address receiving funds at the destination\n * @param amount The amount being sent\n * @param amountOutMin The minimum amount received after attempting to swap in the destination\n * AMM market. 0 if no swap is intended.\n * @param deadline The deadline for swapping in the destination AMM market. 0 if no\n * swap is intended.\n * @param relayer The address of the relayer at the destination.\n * @param relayerFee The amount distributed to the relayer at the destination. This is subtracted from the `amount`.\n */\n function sendToL2(\n uint256 chainId,\n address recipient,\n uint256 amount,\n uint256 amountOutMin,\n uint256 deadline,\n address relayer,\n uint256 relayerFee\n ) external payable;\n}\n"},"src/bridges/refuel/interfaces/refuel.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity >=0.8.0;\n\n/// @notice interface with functions to interact with Refuel contract\ninterface IRefuel {\n /**\n * @notice function to deposit nativeToken to Destination-address on destinationChain\n * @param destinationChainId chainId of the Destination chain\n * @param _to recipient address\n */\n function depositNativeToken(\n uint256 destinationChainId,\n address _to\n ) external payable;\n}\n"},"src/bridges/stargate/interfaces/stargate.sol":{"content":"// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity >=0.8.0;\n\n/**\n * @title IBridgeStargate Interface Contract.\n * @notice Interface used by Stargate-L1 and L2 Router implementations\n * @dev router and routerETH addresses will be distinct for L1 and L2\n */\ninterface IBridgeStargate {\n // @notice Struct to hold the additional-data for bridging ERC20 token\n struct lzTxObj {\n // gas limit to bridge the token in Stargate to destinationChain\n uint256 dstGasForCall;\n // destination nativeAmount, this is always set as 0\n uint256 dstNativeAmount;\n // destination nativeAddress, this is always set as 0x\n bytes dstNativeAddr;\n }\n\n /// @notice function in stargate bridge which is used to bridge ERC20 tokens to recipient on destinationChain\n function swap(\n uint16 _dstChainId,\n uint256 _srcPoolId,\n uint256 _dstPoolId,\n address payable _refundAddress,\n uint256 _amountLD,\n uint256 _minAmountLD,\n lzTxObj memory _lzTxParams,\n bytes calldata _to,\n bytes calldata _payload\n ) external payable;\n\n /// @notice function in stargate bridge which is used to bridge native tokens to recipient on destinationChain\n function swapETH(\n uint16 _dstChainId, // destination Stargate chainId\n address payable _refundAddress, // refund additional messageFee to this address\n bytes calldata _toAddress, // the receiver of the destination ETH\n uint256 _amountLD, // the amount, in Local Decimals, to be swapped\n uint256 _minAmountLD // the minimum amount accepted out on destination\n ) external payable;\n}\n"},"src/controllers/FeesTakerController.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {BaseController} from \"./BaseController.sol\";\nimport {ISocketRequest} from \"../interfaces/ISocketRequest.sol\";\n\n/**\n * @title FeesTaker-Controller Implementation\n * @notice Controller with composed actions to deduct-fees followed by Refuel, Swap and Bridge\n * to be executed Sequentially and this is atomic\n * @author Socket dot tech.\n */\ncontract FeesTakerController is BaseController {\n using SafeTransferLib for ERC20;\n\n /// @notice event emitted upon fee-deduction to fees-taker address\n event SocketFeesDeducted(\n uint256 fees,\n address feesToken,\n address feesTaker\n );\n\n /// @notice Function-selector to invoke deduct-fees and swap token\n /// @dev This function selector is to be used while building transaction-data\n bytes4 public immutable FEES_TAKER_SWAP_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\"takeFeesAndSwap((address,address,uint256,uint32,bytes))\")\n );\n\n /// @notice Function-selector to invoke deduct-fees and bridge token\n /// @dev This function selector is to be used while building transaction-data\n bytes4 public immutable FEES_TAKER_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"takeFeesAndBridge((address,address,uint256,uint32,bytes))\"\n )\n );\n\n /// @notice Function-selector to invoke deduct-fees and bridge multiple tokens\n /// @dev This function selector is to be used while building transaction-data\n bytes4 public immutable FEES_TAKER_MULTI_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"takeFeesAndMultiBridge((address,address,uint256,uint32[],bytes[]))\"\n )\n );\n\n /// @notice Function-selector to invoke deduct-fees followed by swapping of a token and bridging the swapped bridge\n /// @dev This function selector is to be used while building transaction-data\n bytes4 public immutable FEES_TAKER_SWAP_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"takeFeeAndSwapAndBridge((address,address,uint256,uint32,bytes,uint32,bytes))\"\n )\n );\n\n /// @notice Function-selector to invoke deduct-fees refuel\n /// @notice followed by swapping of a token and bridging the swapped bridge\n /// @dev This function selector is to be used while building transaction-data\n bytes4 public immutable FEES_TAKER_REFUEL_SWAP_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"takeFeeAndRefuelAndSwapAndBridge((address,address,uint256,uint32,bytes,uint32,bytes,uint32,bytes))\"\n )\n );\n\n /// @notice socketGatewayAddress to be initialised via storage variable BaseController\n constructor(\n address _socketGatewayAddress\n ) BaseController(_socketGatewayAddress) {}\n\n /**\n * @notice function to deduct-fees to fees-taker address on source-chain and swap token\n * @dev ensure correct function selector is used to generate transaction-data for bridgeRequest\n * @param ftsRequest feesTakerSwapRequest object generated either off-chain or the calling contract using\n * the function-selector FEES_TAKER_SWAP_FUNCTION_SELECTOR\n * @return output bytes from the swap operation (last operation in the composed actions)\n */\n function takeFeesAndSwap(\n ISocketRequest.FeesTakerSwapRequest calldata ftsRequest\n ) external payable returns (bytes memory) {\n if (ftsRequest.feesToken == NATIVE_TOKEN_ADDRESS) {\n //transfer the native amount to the feeTakerAddress\n payable(ftsRequest.feesTakerAddress).transfer(\n ftsRequest.feesAmount\n );\n } else {\n //transfer feesAmount to feesTakerAddress\n ERC20(ftsRequest.feesToken).safeTransferFrom(\n msg.sender,\n ftsRequest.feesTakerAddress,\n ftsRequest.feesAmount\n );\n }\n\n emit SocketFeesDeducted(\n ftsRequest.feesAmount,\n ftsRequest.feesTakerAddress,\n ftsRequest.feesToken\n );\n\n //call bridge function (executeRoute for the swapRequestData)\n return _executeRoute(ftsRequest.routeId, ftsRequest.swapRequestData);\n }\n\n /**\n * @notice function to deduct-fees to fees-taker address on source-chain and bridge amount to destinationChain\n * @dev ensure correct function selector is used to generate transaction-data for bridgeRequest\n * @param ftbRequest feesTakerBridgeRequest object generated either off-chain or the calling contract using\n * the function-selector FEES_TAKER_BRIDGE_FUNCTION_SELECTOR\n * @return output bytes from the bridge operation (last operation in the composed actions)\n */\n function takeFeesAndBridge(\n ISocketRequest.FeesTakerBridgeRequest calldata ftbRequest\n ) external payable returns (bytes memory) {\n if (ftbRequest.feesToken == NATIVE_TOKEN_ADDRESS) {\n //transfer the native amount to the feeTakerAddress\n payable(ftbRequest.feesTakerAddress).transfer(\n ftbRequest.feesAmount\n );\n } else {\n //transfer feesAmount to feesTakerAddress\n ERC20(ftbRequest.feesToken).safeTransferFrom(\n msg.sender,\n ftbRequest.feesTakerAddress,\n ftbRequest.feesAmount\n );\n }\n\n emit SocketFeesDeducted(\n ftbRequest.feesAmount,\n ftbRequest.feesTakerAddress,\n ftbRequest.feesToken\n );\n\n //call bridge function (executeRoute for the bridgeData)\n return _executeRoute(ftbRequest.routeId, ftbRequest.bridgeRequestData);\n }\n\n /**\n * @notice function to deduct-fees to fees-taker address on source-chain and bridge amount to destinationChain\n * @notice multiple bridge-requests are to be generated and sequence and number of routeIds should match with the bridgeData array\n * @dev ensure correct function selector is used to generate transaction-data for bridgeRequest\n * @param ftmbRequest feesTakerMultiBridgeRequest object generated either off-chain or the calling contract using\n * the function-selector FEES_TAKER_MULTI_BRIDGE_FUNCTION_SELECTOR\n */\n function takeFeesAndMultiBridge(\n ISocketRequest.FeesTakerMultiBridgeRequest calldata ftmbRequest\n ) external payable {\n if (ftmbRequest.feesToken == NATIVE_TOKEN_ADDRESS) {\n //transfer the native amount to the feeTakerAddress\n payable(ftmbRequest.feesTakerAddress).transfer(\n ftmbRequest.feesAmount\n );\n } else {\n //transfer feesAmount to feesTakerAddress\n ERC20(ftmbRequest.feesToken).safeTransferFrom(\n msg.sender,\n ftmbRequest.feesTakerAddress,\n ftmbRequest.feesAmount\n );\n }\n\n emit SocketFeesDeducted(\n ftmbRequest.feesAmount,\n ftmbRequest.feesTakerAddress,\n ftmbRequest.feesToken\n );\n\n // multiple bridge-requests are to be generated and sequence and number of routeIds should match with the bridgeData array\n for (\n uint256 index = 0;\n index < ftmbRequest.bridgeRouteIds.length;\n ++index\n ) {\n //call bridge function (executeRoute for the bridgeData)\n _executeRoute(\n ftmbRequest.bridgeRouteIds[index],\n ftmbRequest.bridgeRequestDataItems[index]\n );\n }\n }\n\n /**\n * @notice function to deduct-fees to fees-taker address on source-chain followed by swap the amount on sourceChain followed by\n * bridging the swapped amount to destinationChain\n * @dev while generating implData for swap and bridgeRequests, ensure correct function selector is used\n * bridge action corresponds to the bridgeAfterSwap function of the bridgeImplementation\n * @param fsbRequest feesTakerSwapBridgeRequest object generated either off-chain or the calling contract using\n * the function-selector FEES_TAKER_SWAP_BRIDGE_FUNCTION_SELECTOR\n */\n function takeFeeAndSwapAndBridge(\n ISocketRequest.FeesTakerSwapBridgeRequest calldata fsbRequest\n ) external payable returns (bytes memory) {\n if (fsbRequest.feesToken == NATIVE_TOKEN_ADDRESS) {\n //transfer the native amount to the feeTakerAddress\n payable(fsbRequest.feesTakerAddress).transfer(\n fsbRequest.feesAmount\n );\n } else {\n //transfer feesAmount to feesTakerAddress\n ERC20(fsbRequest.feesToken).safeTransferFrom(\n msg.sender,\n fsbRequest.feesTakerAddress,\n fsbRequest.feesAmount\n );\n }\n\n emit SocketFeesDeducted(\n fsbRequest.feesAmount,\n fsbRequest.feesTakerAddress,\n fsbRequest.feesToken\n );\n\n // execute swap operation\n bytes memory swapResponseData = _executeRoute(\n fsbRequest.swapRouteId,\n fsbRequest.swapData\n );\n\n uint256 swapAmount = abi.decode(swapResponseData, (uint256));\n\n // swapped amount is to be bridged to the recipient on destinationChain\n bytes memory bridgeImpldata = abi.encodeWithSelector(\n BRIDGE_AFTER_SWAP_SELECTOR,\n swapAmount,\n fsbRequest.bridgeData\n );\n\n // execute bridge operation and return the byte-data from response of bridge operation\n return _executeRoute(fsbRequest.bridgeRouteId, bridgeImpldata);\n }\n\n /**\n * @notice function to deduct-fees to fees-taker address on source-chain followed by refuel followed by\n * swap the amount on sourceChain followed by bridging the swapped amount to destinationChain\n * @dev while generating implData for refuel, swap and bridge Requests, ensure correct function selector is used\n * bridge action corresponds to the bridgeAfterSwap function of the bridgeImplementation\n * @param frsbRequest feesTakerRefuelSwapBridgeRequest object generated either off-chain or the calling contract using\n * the function-selector FEES_TAKER_REFUEL_SWAP_BRIDGE_FUNCTION_SELECTOR\n */\n function takeFeeAndRefuelAndSwapAndBridge(\n ISocketRequest.FeesTakerRefuelSwapBridgeRequest calldata frsbRequest\n ) external payable returns (bytes memory) {\n if (frsbRequest.feesToken == NATIVE_TOKEN_ADDRESS) {\n //transfer the native amount to the feeTakerAddress\n payable(frsbRequest.feesTakerAddress).transfer(\n frsbRequest.feesAmount\n );\n } else {\n //transfer feesAmount to feesTakerAddress\n ERC20(frsbRequest.feesToken).safeTransferFrom(\n msg.sender,\n frsbRequest.feesTakerAddress,\n frsbRequest.feesAmount\n );\n }\n\n emit SocketFeesDeducted(\n frsbRequest.feesAmount,\n frsbRequest.feesTakerAddress,\n frsbRequest.feesToken\n );\n\n // refuel is also done via bridge execution via refuelRouteImplementation identified by refuelRouteId\n _executeRoute(frsbRequest.refuelRouteId, frsbRequest.refuelData);\n\n // execute swap operation\n bytes memory swapResponseData = _executeRoute(\n frsbRequest.swapRouteId,\n frsbRequest.swapData\n );\n\n uint256 swapAmount = abi.decode(swapResponseData, (uint256));\n\n // swapped amount is to be bridged to the recipient on destinationChain\n bytes memory bridgeImpldata = abi.encodeWithSelector(\n BRIDGE_AFTER_SWAP_SELECTOR,\n swapAmount,\n frsbRequest.bridgeData\n );\n\n // execute bridge operation and return the byte-data from response of bridge operation\n return _executeRoute(frsbRequest.bridgeRouteId, bridgeImpldata);\n }\n}\n"},"src/errors/SocketErrors.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nerror CelerRefundNotReady();\nerror OnlySocketDeployer();\nerror OnlySocketGatewayOwner();\nerror OnlySocketGateway();\nerror OnlyOwner();\nerror OnlyNominee();\nerror TransferIdExists();\nerror TransferIdDoesnotExist();\nerror Address0Provided();\nerror SwapFailed();\nerror UnsupportedInterfaceId();\nerror InvalidCelerRefund();\nerror CelerAlreadyRefunded();\nerror IncorrectBridgeRatios();\nerror ZeroAddressNotAllowed();\nerror ArrayLengthMismatch();\n"},"src/bridges/hop/l1/HopImplL1.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\nimport \"../interfaces/IHopL1Bridge.sol\";\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {BridgeImplBase} from \"../../BridgeImplBase.sol\";\nimport {HOP} from \"../../../static/RouteIdentifiers.sol\";\n\n/**\n * @title Hop-L1 Route Implementation\n * @notice Route implementation with functions to bridge ERC20 and Native via Hop-Bridge from L1 to Supported L2s\n * Called via SocketGateway if the routeId in the request maps to the routeId of HopImplementation\n * Contains function to handle bridging as post-step i.e linked to a preceeding step for swap\n * RequestData is different to just bride and bridging chained with swap\n * @author Socket dot tech.\n */\ncontract HopImplL1 is BridgeImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable HopIdentifier = HOP;\n\n /// @notice Function-selector for ERC20-token bridging on Hop-L1-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge ERC20 tokens\n bytes4 public immutable HOP_L1_ERC20_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeERC20To(address,address,address,address,uint256,uint256,uint256,uint256,(uint256,bytes32))\"\n )\n );\n\n /// @notice Function-selector for Native bridging on Hop-L1-Route\n /// @dev This function selector is to be used while building transaction-data to bridge Native tokens\n bytes4 public immutable HOP_L1_NATIVE_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeNativeTo(address,address,address,uint256,uint256,uint256,uint256,uint256,bytes32)\"\n )\n );\n\n bytes4 public immutable HOP_L1_SWAP_BRIDGE_SELECTOR =\n bytes4(\n keccak256(\n \"swapAndBridge(uint32,bytes,(address,address,address,uint256,uint256,uint256,uint256,bytes32))\"\n )\n );\n\n /// @notice socketGatewayAddress to be initialised via storage variable BridgeImplBase\n constructor(\n address _socketGateway,\n address _socketDeployFactory\n ) BridgeImplBase(_socketGateway, _socketDeployFactory) {}\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct HopDataNoToken {\n // The address receiving funds at the destination\n address receiverAddress;\n // address of the Hop-L1-Bridge to handle bridging the tokens\n address l1bridgeAddr;\n // relayerFee The amount distributed to the relayer at the destination. This is subtracted from the `_amount`.\n address relayer;\n // The chainId of the destination chain\n uint256 toChainId;\n // The minimum amount received after attempting to swap in the destination AMM market. 0 if no swap is intended.\n uint256 amountOutMin;\n // The amount distributed to the relayer at the destination. This is subtracted from the `amount`.\n uint256 relayerFee;\n // The deadline for swapping in the destination AMM market. 0 if no swap is intended.\n uint256 deadline;\n // socket offchain created hash\n bytes32 metadata;\n }\n\n struct HopData {\n /// @notice address of token being bridged\n address token;\n // The address receiving funds at the destination\n address receiverAddress;\n // address of the Hop-L1-Bridge to handle bridging the tokens\n address l1bridgeAddr;\n // relayerFee The amount distributed to the relayer at the destination. This is subtracted from the `_amount`.\n address relayer;\n // The chainId of the destination chain\n uint256 toChainId;\n // The minimum amount received after attempting to swap in the destination AMM market. 0 if no swap is intended.\n uint256 amountOutMin;\n // The amount distributed to the relayer at the destination. This is subtracted from the `amount`.\n uint256 relayerFee;\n // The deadline for swapping in the destination AMM market. 0 if no swap is intended.\n uint256 deadline;\n // socket offchain created hash\n bytes32 metadata;\n }\n\n struct HopERC20Data {\n uint256 deadline;\n bytes32 metadata;\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from swapAndBridge, this function is called when the swap has already happened at a different place.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in HopBridgeData struct\n * @param amount amount of tokens being bridged. this can be ERC20 or native\n * @param bridgeData encoded data for Hop-L1-Bridge\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable override {\n HopData memory hopData = abi.decode(bridgeData, (HopData));\n\n if (hopData.token == NATIVE_TOKEN_ADDRESS) {\n IHopL1Bridge(hopData.l1bridgeAddr).sendToL2{value: amount}(\n hopData.toChainId,\n hopData.receiverAddress,\n amount,\n hopData.amountOutMin,\n hopData.deadline,\n hopData.relayer,\n hopData.relayerFee\n );\n } else {\n ERC20(hopData.token).safeApprove(hopData.l1bridgeAddr, amount);\n\n // perform bridging\n IHopL1Bridge(hopData.l1bridgeAddr).sendToL2(\n hopData.toChainId,\n hopData.receiverAddress,\n amount,\n hopData.amountOutMin,\n hopData.deadline,\n hopData.relayer,\n hopData.relayerFee\n );\n }\n\n emit SocketBridge(\n amount,\n hopData.token,\n hopData.toChainId,\n HopIdentifier,\n msg.sender,\n hopData.receiverAddress,\n hopData.metadata\n );\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from bridgeAfterSwap since this function holds the logic for swapping tokens too.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in HopBridgeData struct\n * @param swapId routeId for the swapImpl\n * @param swapData encoded data for swap\n * @param hopData encoded data for HopData\n */\n function swapAndBridge(\n uint32 swapId,\n bytes calldata swapData,\n HopDataNoToken calldata hopData\n ) external payable {\n (bool success, bytes memory result) = socketRoute\n .getRoute(swapId)\n .delegatecall(swapData);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n (uint256 bridgeAmount, address token) = abi.decode(\n result,\n (uint256, address)\n );\n\n if (token == NATIVE_TOKEN_ADDRESS) {\n IHopL1Bridge(hopData.l1bridgeAddr).sendToL2{value: bridgeAmount}(\n hopData.toChainId,\n hopData.receiverAddress,\n bridgeAmount,\n hopData.amountOutMin,\n hopData.deadline,\n hopData.relayer,\n hopData.relayerFee\n );\n } else {\n ERC20(token).safeApprove(hopData.l1bridgeAddr, bridgeAmount);\n\n // perform bridging\n IHopL1Bridge(hopData.l1bridgeAddr).sendToL2(\n hopData.toChainId,\n hopData.receiverAddress,\n bridgeAmount,\n hopData.amountOutMin,\n hopData.deadline,\n hopData.relayer,\n hopData.relayerFee\n );\n }\n\n emit SocketBridge(\n bridgeAmount,\n token,\n hopData.toChainId,\n HopIdentifier,\n msg.sender,\n hopData.receiverAddress,\n hopData.metadata\n );\n }\n\n /**\n * @notice function to handle ERC20 bridging to receipent via Hop-L1-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param receiverAddress The address receiving funds at the destination\n * @param token token being bridged\n * @param l1bridgeAddr address of the Hop-L1-Bridge to handle bridging the tokens\n * @param relayer The amount distributed to the relayer at the destination. This is subtracted from the `_amount`.\n * @param toChainId The chainId of the destination chain\n * @param amount The amount being sent\n * @param amountOutMin The minimum amount received after attempting to swap in the destination AMM market. 0 if no swap is intended.\n * @param relayerFee The amount distributed to the relayer at the destination. This is subtracted from the `amount`.\n * @param hopData extra data needed to build the tx\n */\n function bridgeERC20To(\n address receiverAddress,\n address token,\n address l1bridgeAddr,\n address relayer,\n uint256 toChainId,\n uint256 amount,\n uint256 amountOutMin,\n uint256 relayerFee,\n HopERC20Data calldata hopData\n ) external payable {\n ERC20 tokenInstance = ERC20(token);\n tokenInstance.safeTransferFrom(msg.sender, socketGateway, amount);\n tokenInstance.safeApprove(l1bridgeAddr, amount);\n\n // perform bridging\n IHopL1Bridge(l1bridgeAddr).sendToL2(\n toChainId,\n receiverAddress,\n amount,\n amountOutMin,\n hopData.deadline,\n relayer,\n relayerFee\n );\n\n emit SocketBridge(\n amount,\n token,\n toChainId,\n HopIdentifier,\n msg.sender,\n receiverAddress,\n hopData.metadata\n );\n }\n\n /**\n * @notice function to handle Native bridging to receipent via Hop-L1-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param receiverAddress The address receiving funds at the destination\n * @param l1bridgeAddr address of the Hop-L1-Bridge to handle bridging the tokens\n * @param relayer The amount distributed to the relayer at the destination. This is subtracted from the `_amount`.\n * @param toChainId The chainId of the destination chain\n * @param amount The amount being sent\n * @param amountOutMin The minimum amount received after attempting to swap in the destination AMM market. 0 if no swap is intended.\n * @param relayerFee The amount distributed to the relayer at the destination. This is subtracted from the `amount`.\n * @param deadline The deadline for swapping in the destination AMM market. 0 if no swap is intended.\n */\n function bridgeNativeTo(\n address receiverAddress,\n address l1bridgeAddr,\n address relayer,\n uint256 toChainId,\n uint256 amount,\n uint256 amountOutMin,\n uint256 relayerFee,\n uint256 deadline,\n bytes32 metadata\n ) external payable {\n IHopL1Bridge(l1bridgeAddr).sendToL2{value: amount}(\n toChainId,\n receiverAddress,\n amount,\n amountOutMin,\n deadline,\n relayer,\n relayerFee\n );\n\n emit SocketBridge(\n amount,\n NATIVE_TOKEN_ADDRESS,\n toChainId,\n HopIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n}\n"},"src/static/RouteIdentifiers.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\nbytes32 constant ACROSS = keccak256(\"Across\");\n\nbytes32 constant ANYSWAP = keccak256(\"Anyswap\");\n\nbytes32 constant CBRIDGE = keccak256(\"CBridge\");\n\nbytes32 constant HOP = keccak256(\"Hop\");\n\nbytes32 constant HYPHEN = keccak256(\"Hyphen\");\n\nbytes32 constant NATIVE_OPTIMISM = keccak256(\"NativeOptimism\");\n\nbytes32 constant NATIVE_ARBITRUM = keccak256(\"NativeArbitrum\");\n\nbytes32 constant NATIVE_POLYGON = keccak256(\"NativePolygon\");\n\nbytes32 constant REFUEL = keccak256(\"Refuel\");\n\nbytes32 constant STARGATE = keccak256(\"Stargate\");\n\nbytes32 constant ONEINCH = keccak256(\"OneInch\");\n\nbytes32 constant ZEROX = keccak256(\"Zerox\");\n\nbytes32 constant RAINBOW = keccak256(\"Rainbow\");\n"},"src/SocketGateway.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\npragma experimental ABIEncoderV2;\n\nimport \"./utils/Ownable.sol\";\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {LibUtil} from \"./libraries/LibUtil.sol\";\nimport \"./libraries/LibBytes.sol\";\nimport {ISocketRoute} from \"./interfaces/ISocketRoute.sol\";\nimport {ISocketRequest} from \"./interfaces/ISocketRequest.sol\";\nimport {ISocketGateway} from \"./interfaces/ISocketGateway.sol\";\nimport {IncorrectBridgeRatios, ZeroAddressNotAllowed, ArrayLengthMismatch} from \"./errors/SocketErrors.sol\";\n\n/// @title SocketGatewayContract\n/// @notice Socketgateway is a contract with entrypoint functions for all interactions with socket liquidity layer\n/// @author Socket Team\ncontract SocketGatewayTemplate is Ownable {\n using LibBytes for bytes;\n using LibBytes for bytes4;\n using SafeTransferLib for ERC20;\n\n /// @notice FunctionSelector used to delegatecall from swap to the function of bridge router implementation\n bytes4 public immutable BRIDGE_AFTER_SWAP_SELECTOR =\n bytes4(keccak256(\"bridgeAfterSwap(uint256,bytes)\"));\n\n /// @notice storage variable to keep track of total number of routes registered in socketgateway\n uint32 public routesCount = 385;\n\n /// @notice storage variable to keep track of total number of controllers registered in socketgateway\n uint32 public controllerCount;\n\n address public immutable disabledRouteAddress;\n\n uint256 public constant CENT_PERCENT = 100e18;\n\n /// @notice storage mapping for route implementation addresses\n mapping(uint32 => address) public routes;\n\n /// storage mapping for controller implemenation addresses\n mapping(uint32 => address) public controllers;\n\n // Events ------------------------------------------------------------------------------------------------------->\n\n /// @notice Event emitted when a router is added to socketgateway\n event NewRouteAdded(uint32 indexed routeId, address indexed route);\n\n /// @notice Event emitted when a route is disabled\n event RouteDisabled(uint32 indexed routeId);\n\n /// @notice Event emitted when ownership transfer is requested by socket-gateway-owner\n event OwnershipTransferRequested(\n address indexed _from,\n address indexed _to\n );\n\n /// @notice Event emitted when a controller is added to socketgateway\n event ControllerAdded(\n uint32 indexed controllerId,\n address indexed controllerAddress\n );\n\n /// @notice Event emitted when a controller is disabled\n event ControllerDisabled(uint32 indexed controllerId);\n\n constructor(address _owner, address _disabledRoute) Ownable(_owner) {\n disabledRouteAddress = _disabledRoute;\n }\n\n // Able to receive ether\n // solhint-disable-next-line no-empty-blocks\n receive() external payable {}\n\n /*******************************************\n * EXTERNAL AND PUBLIC FUNCTIONS *\n *******************************************/\n\n /**\n * @notice executes functions in the routes identified using routeId and functionSelectorData\n * @notice The caller must first approve this contract to spend amount of ERC20-Token being bridged/swapped\n * @dev ensure the data in routeData to be built using the function-selector defined as a\n * constant in the route implementation contract\n * @param routeId route identifier\n * @param routeData functionSelectorData generated using the function-selector defined in the route Implementation\n */\n function executeRoute(\n uint32 routeId,\n bytes calldata routeData\n ) external payable returns (bytes memory) {\n (bool success, bytes memory result) = addressAt(routeId).delegatecall(\n routeData\n );\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n return result;\n }\n\n /**\n * @notice swaps a token on sourceChain and split it across multiple bridge-recipients\n * @notice The caller must first approve this contract to spend amount of ERC20-Token being swapped\n * @dev ensure the swap-data and bridge-data is generated using the function-selector defined as a constant in the implementation address\n * @param swapMultiBridgeRequest request\n */\n function swapAndMultiBridge(\n ISocketRequest.SwapMultiBridgeRequest calldata swapMultiBridgeRequest\n ) external payable {\n uint256 requestLength = swapMultiBridgeRequest.bridgeRouteIds.length;\n\n if (\n requestLength != swapMultiBridgeRequest.bridgeImplDataItems.length\n ) {\n revert ArrayLengthMismatch();\n }\n uint256 ratioAggregate;\n for (uint256 index = 0; index < requestLength; ) {\n ratioAggregate += swapMultiBridgeRequest.bridgeRatios[index];\n }\n\n if (ratioAggregate != CENT_PERCENT) {\n revert IncorrectBridgeRatios();\n }\n\n (bool swapSuccess, bytes memory swapResult) = addressAt(\n swapMultiBridgeRequest.swapRouteId\n ).delegatecall(swapMultiBridgeRequest.swapImplData);\n\n if (!swapSuccess) {\n assembly {\n revert(add(swapResult, 32), mload(swapResult))\n }\n }\n\n uint256 amountReceivedFromSwap = abi.decode(swapResult, (uint256));\n\n uint256 bridgedAmount;\n\n for (uint256 index = 0; index < requestLength; ) {\n uint256 bridgingAmount;\n\n // if it is the last bridge request, bridge the remaining amount\n if (index == requestLength - 1) {\n bridgingAmount = amountReceivedFromSwap - bridgedAmount;\n } else {\n // bridging amount is the multiplication of bridgeRatio and amountReceivedFromSwap\n bridgingAmount =\n (amountReceivedFromSwap *\n swapMultiBridgeRequest.bridgeRatios[index]) /\n (CENT_PERCENT);\n }\n\n // update the bridged amount, this would be used for computation for last bridgeRequest\n bridgedAmount += bridgingAmount;\n\n bytes memory bridgeImpldata = abi.encodeWithSelector(\n BRIDGE_AFTER_SWAP_SELECTOR,\n bridgingAmount,\n swapMultiBridgeRequest.bridgeImplDataItems[index]\n );\n\n (bool bridgeSuccess, bytes memory bridgeResult) = addressAt(\n swapMultiBridgeRequest.bridgeRouteIds[index]\n ).delegatecall(bridgeImpldata);\n\n if (!bridgeSuccess) {\n assembly {\n revert(add(bridgeResult, 32), mload(bridgeResult))\n }\n }\n\n unchecked {\n ++index;\n }\n }\n }\n\n /**\n * @notice sequentially executes functions in the routes identified using routeId and functionSelectorData\n * @notice The caller must first approve this contract to spend amount of ERC20-Token being bridged/swapped\n * @dev ensure the data in each dataItem to be built using the function-selector defined as a\n * constant in the route implementation contract\n * @param routeIds a list of route identifiers\n * @param dataItems a list of functionSelectorData generated using the function-selector defined in the route Implementation\n */\n function executeRoutes(\n uint32[] calldata routeIds,\n bytes[] calldata dataItems\n ) external payable {\n uint256 routeIdslength = routeIds.length;\n if (routeIdslength != dataItems.length) revert ArrayLengthMismatch();\n for (uint256 index = 0; index < routeIdslength; ) {\n (bool success, bytes memory result) = addressAt(routeIds[index])\n .delegatecall(dataItems[index]);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n unchecked {\n ++index;\n }\n }\n }\n\n /**\n * @notice execute a controller function identified using the controllerId in the request\n * @notice The caller must first approve this contract to spend amount of ERC20-Token being bridged/swapped\n * @dev ensure the data in request to be built using the function-selector defined as a\n * constant in the controller implementation contract\n * @param socketControllerRequest socketControllerRequest with controllerId to identify the\n * controllerAddress and byteData constructed using functionSelector\n * of the function being invoked\n * @return bytes data received from the call delegated to controller\n */\n function executeController(\n ISocketGateway.SocketControllerRequest calldata socketControllerRequest\n ) external payable returns (bytes memory) {\n (bool success, bytes memory result) = controllers[\n socketControllerRequest.controllerId\n ].delegatecall(socketControllerRequest.data);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n return result;\n }\n\n /**\n * @notice sequentially executes all controller requests\n * @notice The caller must first approve this contract to spend amount of ERC20-Token being bridged/swapped\n * @dev ensure the data in each controller-request to be built using the function-selector defined as a\n * constant in the controller implementation contract\n * @param controllerRequests a list of socketControllerRequest\n * Each controllerRequest contains controllerId to identify the controllerAddress and\n * byteData constructed using functionSelector of the function being invoked\n */\n function executeControllers(\n ISocketGateway.SocketControllerRequest[] calldata controllerRequests\n ) external payable {\n for (uint32 index = 0; index < controllerRequests.length; ) {\n (bool success, bytes memory result) = controllers[\n controllerRequests[index].controllerId\n ].delegatecall(controllerRequests[index].data);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n unchecked {\n ++index;\n }\n }\n }\n\n /**************************************\n * ADMIN FUNCTIONS *\n **************************************/\n\n /**\n * @notice Add route to the socketGateway\n This is a restricted function to be called by only socketGatewayOwner\n * @dev ensure routeAddress is a verified bridge or middleware implementation address\n * @param routeAddress The address of bridge or middleware implementation contract deployed\n * @return Id of the route added to the routes-mapping in socketGateway storage\n */\n function addRoute(\n address routeAddress\n ) external onlyOwner returns (uint32) {\n uint32 routeId = routesCount;\n routes[routeId] = routeAddress;\n\n routesCount += 1;\n\n emit NewRouteAdded(routeId, routeAddress);\n\n return routeId;\n }\n\n /**\n * @notice Give Infinite or 0 approval to bridgeRoute for the tokenAddress\n This is a restricted function to be called by only socketGatewayOwner\n */\n\n function setApprovalForRouters(\n address[] memory routeAddresses,\n address[] memory tokenAddresses,\n bool isMax\n ) external onlyOwner {\n for (uint32 index = 0; index < routeAddresses.length; ) {\n ERC20(tokenAddresses[index]).approve(\n routeAddresses[index],\n isMax ? type(uint256).max : 0\n );\n unchecked {\n ++index;\n }\n }\n }\n\n /**\n * @notice Add controller to the socketGateway\n This is a restricted function to be called by only socketGatewayOwner\n * @dev ensure controllerAddress is a verified controller implementation address\n * @param controllerAddress The address of controller implementation contract deployed\n * @return Id of the controller added to the controllers-mapping in socketGateway storage\n */\n function addController(\n address controllerAddress\n ) external onlyOwner returns (uint32) {\n uint32 controllerId = controllerCount;\n\n controllers[controllerId] = controllerAddress;\n\n controllerCount += 1;\n\n emit ControllerAdded(controllerId, controllerAddress);\n\n return controllerId;\n }\n\n /**\n * @notice disable controller by setting ZeroAddress to the entry in controllers-mapping\n identified by controllerId as key.\n This is a restricted function to be called by only socketGatewayOwner\n * @param controllerId The Id of controller-implementation in the controllers mapping\n */\n function disableController(uint32 controllerId) public onlyOwner {\n controllers[controllerId] = disabledRouteAddress;\n emit ControllerDisabled(controllerId);\n }\n\n /**\n * @notice disable a route by setting ZeroAddress to the entry in routes-mapping\n identified by routeId as key.\n This is a restricted function to be called by only socketGatewayOwner\n * @param routeId The Id of route-implementation in the routes mapping\n */\n function disableRoute(uint32 routeId) external onlyOwner {\n routes[routeId] = disabledRouteAddress;\n emit RouteDisabled(routeId);\n }\n\n /*******************************************\n * RESTRICTED RESCUE FUNCTIONS *\n *******************************************/\n\n /**\n * @notice Rescues the ERC20 token to an address\n this is a restricted function to be called by only socketGatewayOwner\n * @dev as this is a restricted to socketGatewayOwner, ensure the userAddress is a known address\n * @param token address of the ERC20 token being rescued\n * @param userAddress address to which ERC20 is to be rescued\n * @param amount amount of ERC20 tokens being rescued\n */\n function rescueFunds(\n address token,\n address userAddress,\n uint256 amount\n ) external onlyOwner {\n ERC20(token).safeTransfer(userAddress, amount);\n }\n\n /**\n * @notice Rescues the native balance to an address\n this is a restricted function to be called by only socketGatewayOwner\n * @dev as this is a restricted to socketGatewayOwner, ensure the userAddress is a known address\n * @param userAddress address to which native-balance is to be rescued\n * @param amount amount of native-balance being rescued\n */\n function rescueEther(\n address payable userAddress,\n uint256 amount\n ) external onlyOwner {\n userAddress.transfer(amount);\n }\n\n /*******************************************\n * VIEW FUNCTIONS *\n *******************************************/\n\n /**\n * @notice Get routeImplementation address mapped to the routeId\n * @param routeId routeId is the key in the mapping for routes\n * @return route-implementation address\n */\n function getRoute(uint32 routeId) public view returns (address) {\n return addressAt(routeId);\n }\n\n /**\n * @notice Get controllerImplementation address mapped to the controllerId\n * @param controllerId controllerId is the key in the mapping for controllers\n * @return controller-implementation address\n */\n function getController(uint32 controllerId) public view returns (address) {\n return controllers[controllerId];\n }\n\n function addressAt(uint32 routeId) public view returns (address) {\n if (routeId < 385) {\n if (routeId < 257) {\n if (routeId < 129) {\n if (routeId < 65) {\n if (routeId < 33) {\n if (routeId < 17) {\n if (routeId < 9) {\n if (routeId < 5) {\n if (routeId < 3) {\n if (routeId == 1) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 3) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 7) {\n if (routeId == 5) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 7) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 13) {\n if (routeId < 11) {\n if (routeId == 9) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 11) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 15) {\n if (routeId == 13) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 15) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n } else {\n if (routeId < 25) {\n if (routeId < 21) {\n if (routeId < 19) {\n if (routeId == 17) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 19) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 23) {\n if (routeId == 21) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 23) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 29) {\n if (routeId < 27) {\n if (routeId == 25) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 27) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 31) {\n if (routeId == 29) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 31) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n }\n } else {\n if (routeId < 49) {\n if (routeId < 41) {\n if (routeId < 37) {\n if (routeId < 35) {\n if (routeId == 33) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 35) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 39) {\n if (routeId == 37) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 39) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 45) {\n if (routeId < 43) {\n if (routeId == 41) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 43) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 47) {\n if (routeId == 45) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 47) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n } else {\n if (routeId < 57) {\n if (routeId < 53) {\n if (routeId < 51) {\n if (routeId == 49) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 51) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 55) {\n if (routeId == 53) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 55) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 61) {\n if (routeId < 59) {\n if (routeId == 57) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 59) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 63) {\n if (routeId == 61) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 63) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n }\n }\n } else {\n if (routeId < 97) {\n if (routeId < 81) {\n if (routeId < 73) {\n if (routeId < 69) {\n if (routeId < 67) {\n if (routeId == 65) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 67) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 71) {\n if (routeId == 69) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 71) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 77) {\n if (routeId < 75) {\n if (routeId == 73) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 75) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 79) {\n if (routeId == 77) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 79) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n } else {\n if (routeId < 89) {\n if (routeId < 85) {\n if (routeId < 83) {\n if (routeId == 81) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 83) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 87) {\n if (routeId == 85) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 87) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 93) {\n if (routeId < 91) {\n if (routeId == 89) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 91) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 95) {\n if (routeId == 93) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 95) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n }\n } else {\n if (routeId < 113) {\n if (routeId < 105) {\n if (routeId < 101) {\n if (routeId < 99) {\n if (routeId == 97) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 99) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 103) {\n if (routeId == 101) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 103) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 109) {\n if (routeId < 107) {\n if (routeId == 105) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 107) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 111) {\n if (routeId == 109) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 111) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n } else {\n if (routeId < 121) {\n if (routeId < 117) {\n if (routeId < 115) {\n if (routeId == 113) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 115) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 119) {\n if (routeId == 117) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 119) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 125) {\n if (routeId < 123) {\n if (routeId == 121) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 123) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 127) {\n if (routeId == 125) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 127) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n }\n }\n }\n } else {\n if (routeId < 193) {\n if (routeId < 161) {\n if (routeId < 145) {\n if (routeId < 137) {\n if (routeId < 133) {\n if (routeId < 131) {\n if (routeId == 129) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 131) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 135) {\n if (routeId == 133) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 135) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 141) {\n if (routeId < 139) {\n if (routeId == 137) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 139) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 143) {\n if (routeId == 141) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 143) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n } else {\n if (routeId < 153) {\n if (routeId < 149) {\n if (routeId < 147) {\n if (routeId == 145) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 147) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 151) {\n if (routeId == 149) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 151) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 157) {\n if (routeId < 155) {\n if (routeId == 153) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 155) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 159) {\n if (routeId == 157) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 159) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n }\n } else {\n if (routeId < 177) {\n if (routeId < 169) {\n if (routeId < 165) {\n if (routeId < 163) {\n if (routeId == 161) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 163) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 167) {\n if (routeId == 165) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 167) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 173) {\n if (routeId < 171) {\n if (routeId == 169) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 171) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 175) {\n if (routeId == 173) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 175) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n } else {\n if (routeId < 185) {\n if (routeId < 181) {\n if (routeId < 179) {\n if (routeId == 177) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 179) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 183) {\n if (routeId == 181) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 183) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 189) {\n if (routeId < 187) {\n if (routeId == 185) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 187) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 191) {\n if (routeId == 189) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 191) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n }\n }\n } else {\n if (routeId < 225) {\n if (routeId < 209) {\n if (routeId < 201) {\n if (routeId < 197) {\n if (routeId < 195) {\n if (routeId == 193) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 195) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 199) {\n if (routeId == 197) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 199) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 205) {\n if (routeId < 203) {\n if (routeId == 201) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 203) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 207) {\n if (routeId == 205) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 207) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n } else {\n if (routeId < 217) {\n if (routeId < 213) {\n if (routeId < 211) {\n if (routeId == 209) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 211) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 215) {\n if (routeId == 213) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 215) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 221) {\n if (routeId < 219) {\n if (routeId == 217) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 219) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 223) {\n if (routeId == 221) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 223) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n }\n } else {\n if (routeId < 241) {\n if (routeId < 233) {\n if (routeId < 229) {\n if (routeId < 227) {\n if (routeId == 225) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 227) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 231) {\n if (routeId == 229) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 231) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 237) {\n if (routeId < 235) {\n if (routeId == 233) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 235) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 239) {\n if (routeId == 237) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 239) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n } else {\n if (routeId < 249) {\n if (routeId < 245) {\n if (routeId < 243) {\n if (routeId == 241) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 243) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 247) {\n if (routeId == 245) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 247) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 253) {\n if (routeId < 251) {\n if (routeId == 249) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 251) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 255) {\n if (routeId == 253) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 255) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n }\n }\n }\n }\n } else {\n if (routeId < 321) {\n if (routeId < 289) {\n if (routeId < 273) {\n if (routeId < 265) {\n if (routeId < 261) {\n if (routeId < 259) {\n if (routeId == 257) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 259) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 263) {\n if (routeId == 261) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 263) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 269) {\n if (routeId < 267) {\n if (routeId == 265) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 267) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 271) {\n if (routeId == 269) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 271) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n } else {\n if (routeId < 281) {\n if (routeId < 277) {\n if (routeId < 275) {\n if (routeId == 273) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 275) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 279) {\n if (routeId == 277) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 279) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 285) {\n if (routeId < 283) {\n if (routeId == 281) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 283) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 287) {\n if (routeId == 285) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 287) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n }\n } else {\n if (routeId < 305) {\n if (routeId < 297) {\n if (routeId < 293) {\n if (routeId < 291) {\n if (routeId == 289) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 291) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 295) {\n if (routeId == 293) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 295) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 301) {\n if (routeId < 299) {\n if (routeId == 297) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 299) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 303) {\n if (routeId == 301) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 303) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n } else {\n if (routeId < 313) {\n if (routeId < 309) {\n if (routeId < 307) {\n if (routeId == 305) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 307) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 311) {\n if (routeId == 309) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 311) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 317) {\n if (routeId < 315) {\n if (routeId == 313) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 315) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 319) {\n if (routeId == 317) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 319) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n }\n }\n } else {\n if (routeId < 353) {\n if (routeId < 337) {\n if (routeId < 329) {\n if (routeId < 325) {\n if (routeId < 323) {\n if (routeId == 321) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 323) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 327) {\n if (routeId == 325) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 327) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 333) {\n if (routeId < 331) {\n if (routeId == 329) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 331) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 335) {\n if (routeId == 333) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 335) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n } else {\n if (routeId < 345) {\n if (routeId < 341) {\n if (routeId < 339) {\n if (routeId == 337) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 339) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 343) {\n if (routeId == 341) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 343) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 349) {\n if (routeId < 347) {\n if (routeId == 345) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 347) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 351) {\n if (routeId == 349) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 351) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n }\n } else {\n if (routeId < 369) {\n if (routeId < 361) {\n if (routeId < 357) {\n if (routeId < 355) {\n if (routeId == 353) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 355) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 359) {\n if (routeId == 357) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 359) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 365) {\n if (routeId < 363) {\n if (routeId == 361) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 363) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 367) {\n if (routeId == 365) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 367) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n } else {\n if (routeId < 377) {\n if (routeId < 373) {\n if (routeId < 371) {\n if (routeId == 369) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 371) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 375) {\n if (routeId == 373) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 375) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n } else {\n if (routeId < 381) {\n if (routeId < 379) {\n if (routeId == 377) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 379) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n } else {\n if (routeId < 383) {\n if (routeId == 381) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n } else {\n if (routeId == 383) {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n } else {\n return\n 0x822D4B4e63499a576Ab1cc152B86D1CFFf794F4f;\n }\n }\n }\n }\n }\n }\n }\n }\n }\n\n if (routes[routeId] == address(0)) revert ZeroAddressNotAllowed();\n return routes[routeId];\n }\n\n /// @notice fallback function to handle swap, bridge execution\n /// @dev ensure routeId is converted to bytes4 and sent as msg.sig in the transaction\n fallback() external payable {\n address routeAddress = addressAt(uint32(msg.sig));\n\n bytes memory result;\n\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 4, sub(calldatasize(), 4))\n // execute function call using the facet\n result := delegatecall(\n gas(),\n routeAddress,\n 0,\n sub(calldatasize(), 4),\n 0,\n 0\n )\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n}\n"},"src/swap/rainbow/Rainbow.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport \"../SwapImplBase.sol\";\nimport {Address0Provided, SwapFailed} from \"../../errors/SocketErrors.sol\";\nimport {RAINBOW} from \"../../static/RouteIdentifiers.sol\";\n\n/**\n * @title Rainbow-Swap-Route Implementation\n * @notice Route implementation with functions to swap tokens via Rainbow-Swap\n * Called via SocketGateway if the routeId in the request maps to the routeId of RainbowImplementation\n * @author Socket dot tech.\n */\ncontract RainbowSwapImpl is SwapImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable RainbowIdentifier = RAINBOW;\n\n /// @notice unique name to identify the router, used to emit event upon successful bridging\n bytes32 public immutable NAME = keccak256(\"Rainbow-Router\");\n\n /// @notice address of rainbow-swap-aggregator to swap the tokens on Chain\n address payable public immutable rainbowSwapAggregator;\n\n /// @notice socketGatewayAddress to be initialised via storage variable SwapImplBase\n /// @notice rainbow swap aggregator contract is payable to allow ethereum swaps\n /// @dev ensure _rainbowSwapAggregator are set properly for the chainId in which the contract is being deployed\n constructor(\n address _rainbowSwapAggregator,\n address _socketGateway,\n address _socketDeployFactory\n ) SwapImplBase(_socketGateway, _socketDeployFactory) {\n rainbowSwapAggregator = payable(_rainbowSwapAggregator);\n }\n\n receive() external payable {}\n\n fallback() external payable {}\n\n /**\n * @notice function to swap tokens on the chain and transfer to receiver address\n * @notice This method is payable because the caller is doing token transfer and swap operation\n * @param fromToken address of token being Swapped\n * @param toToken address of token that recipient will receive after swap\n * @param amount amount of fromToken being swapped\n * @param receiverAddress recipient-address\n * @param swapExtraData additional Data to perform Swap via Rainbow-Aggregator\n * @return swapped amount (in toToken Address)\n */\n function performAction(\n address fromToken,\n address toToken,\n uint256 amount,\n address receiverAddress,\n bytes calldata swapExtraData\n ) external payable override returns (uint256) {\n if (fromToken == address(0)) {\n revert Address0Provided();\n }\n\n bytes memory swapCallData = abi.decode(swapExtraData, (bytes));\n\n uint256 _initialBalanceTokenOut;\n uint256 _finalBalanceTokenOut;\n\n ERC20 toTokenERC20 = ERC20(toToken);\n if (toToken != NATIVE_TOKEN_ADDRESS) {\n _initialBalanceTokenOut = toTokenERC20.balanceOf(socketGateway);\n } else {\n _initialBalanceTokenOut = address(this).balance;\n }\n\n if (fromToken != NATIVE_TOKEN_ADDRESS) {\n ERC20 token = ERC20(fromToken);\n token.safeTransferFrom(msg.sender, socketGateway, amount);\n token.safeApprove(rainbowSwapAggregator, amount);\n\n // solhint-disable-next-line\n (bool success, ) = rainbowSwapAggregator.call(swapCallData);\n\n if (!success) {\n revert SwapFailed();\n }\n\n token.safeApprove(rainbowSwapAggregator, 0);\n } else {\n (bool success, ) = rainbowSwapAggregator.call{value: amount}(\n swapCallData\n );\n if (!success) {\n revert SwapFailed();\n }\n }\n\n if (toToken != NATIVE_TOKEN_ADDRESS) {\n _finalBalanceTokenOut = toTokenERC20.balanceOf(socketGateway);\n } else {\n _finalBalanceTokenOut = address(this).balance;\n }\n\n uint256 returnAmount = _finalBalanceTokenOut - _initialBalanceTokenOut;\n\n if (toToken == NATIVE_TOKEN_ADDRESS) {\n payable(receiverAddress).transfer(returnAmount);\n } else {\n toTokenERC20.transfer(receiverAddress, returnAmount);\n }\n\n emit SocketSwapTokens(\n fromToken,\n toToken,\n returnAmount,\n amount,\n RainbowIdentifier,\n receiverAddress\n );\n\n return returnAmount;\n }\n\n /**\n * @notice function to swapWithIn SocketGateway - swaps tokens on the chain to socketGateway as recipient\n * @param fromToken token to be swapped\n * @param toToken token to which fromToken has to be swapped\n * @param amount amount of fromToken being swapped\n * @param swapExtraData encoded value of properties in the swapData Struct\n * @return swapped amount (in toToken Address)\n */\n function performActionWithIn(\n address fromToken,\n address toToken,\n uint256 amount,\n bytes calldata swapExtraData\n ) external payable override returns (uint256, address) {\n if (fromToken == address(0)) {\n revert Address0Provided();\n }\n\n bytes memory swapCallData = abi.decode(swapExtraData, (bytes));\n\n uint256 _initialBalanceTokenOut;\n uint256 _finalBalanceTokenOut;\n\n ERC20 toTokenERC20 = ERC20(toToken);\n if (toToken != NATIVE_TOKEN_ADDRESS) {\n _initialBalanceTokenOut = toTokenERC20.balanceOf(socketGateway);\n } else {\n _initialBalanceTokenOut = address(this).balance;\n }\n\n if (fromToken != NATIVE_TOKEN_ADDRESS) {\n ERC20 token = ERC20(fromToken);\n token.safeTransferFrom(msg.sender, socketGateway, amount);\n token.safeApprove(rainbowSwapAggregator, amount);\n\n // solhint-disable-next-line\n (bool success, ) = rainbowSwapAggregator.call(swapCallData);\n\n if (!success) {\n revert SwapFailed();\n }\n\n token.safeApprove(rainbowSwapAggregator, 0);\n } else {\n (bool success, ) = rainbowSwapAggregator.call{value: amount}(\n swapCallData\n );\n if (!success) {\n revert SwapFailed();\n }\n }\n\n if (toToken != NATIVE_TOKEN_ADDRESS) {\n _finalBalanceTokenOut = toTokenERC20.balanceOf(socketGateway);\n } else {\n _finalBalanceTokenOut = address(this).balance;\n }\n\n uint256 returnAmount = _finalBalanceTokenOut - _initialBalanceTokenOut;\n\n emit SocketSwapTokens(\n fromToken,\n toToken,\n returnAmount,\n amount,\n RainbowIdentifier,\n socketGateway\n );\n\n return (returnAmount, toToken);\n }\n}\n"},"src/interfaces/ISocketBridgeBase.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface ISocketBridgeBase {\n function killme() external;\n}\n"},"src/interfaces/ISocketRequest.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/**\n * @title ISocketRoute\n * @notice Interface with Request DataStructures to invoke controller functions.\n * @author Socket dot tech.\n */\ninterface ISocketRequest {\n struct SwapMultiBridgeRequest {\n uint32 swapRouteId;\n bytes swapImplData;\n uint32[] bridgeRouteIds;\n bytes[] bridgeImplDataItems;\n uint256[] bridgeRatios;\n bytes[] eventDataItems;\n }\n\n // Datastructure for Refuel-Swap-Bridge function\n struct RefuelSwapBridgeRequest {\n uint32 refuelRouteId;\n bytes refuelData;\n uint32 swapRouteId;\n bytes swapData;\n uint32 bridgeRouteId;\n bytes bridgeData;\n }\n\n // Datastructure for DeductFees-Swap function\n struct FeesTakerSwapRequest {\n address feesTakerAddress;\n address feesToken;\n uint256 feesAmount;\n uint32 routeId;\n bytes swapRequestData;\n }\n\n // Datastructure for DeductFees-Bridge function\n struct FeesTakerBridgeRequest {\n address feesTakerAddress;\n address feesToken;\n uint256 feesAmount;\n uint32 routeId;\n bytes bridgeRequestData;\n }\n\n // Datastructure for DeductFees-MultiBridge function\n struct FeesTakerMultiBridgeRequest {\n address feesTakerAddress;\n address feesToken;\n uint256 feesAmount;\n uint32[] bridgeRouteIds;\n bytes[] bridgeRequestDataItems;\n }\n\n // Datastructure for DeductFees-Swap-Bridge function\n struct FeesTakerSwapBridgeRequest {\n address feesTakerAddress;\n address feesToken;\n uint256 feesAmount;\n uint32 swapRouteId;\n bytes swapData;\n uint32 bridgeRouteId;\n bytes bridgeData;\n }\n\n // Datastructure for DeductFees-Refuel-Swap-Bridge function\n struct FeesTakerRefuelSwapBridgeRequest {\n address feesTakerAddress;\n address feesToken;\n uint256 feesAmount;\n uint32 refuelRouteId;\n bytes refuelData;\n uint32 swapRouteId;\n bytes swapData;\n uint32 bridgeRouteId;\n bytes bridgeData;\n }\n}\n"},"src/utils/Ownable.sol":{"content":"// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.4;\n\nimport {OnlyOwner, OnlyNominee} from \"../errors/SocketErrors.sol\";\n\nabstract contract Ownable {\n address private _owner;\n address private _nominee;\n\n event OwnerNominated(address indexed nominee);\n event OwnerClaimed(address indexed claimer);\n\n constructor(address owner_) {\n _claimOwner(owner_);\n }\n\n modifier onlyOwner() {\n if (msg.sender != _owner) {\n revert OnlyOwner();\n }\n _;\n }\n\n function owner() public view returns (address) {\n return _owner;\n }\n\n function nominee() public view returns (address) {\n return _nominee;\n }\n\n function nominateOwner(address nominee_) external {\n if (msg.sender != _owner) {\n revert OnlyOwner();\n }\n _nominee = nominee_;\n emit OwnerNominated(_nominee);\n }\n\n function claimOwner() external {\n if (msg.sender != _nominee) {\n revert OnlyNominee();\n }\n _claimOwner(msg.sender);\n }\n\n function _claimOwner(address claimer_) internal {\n _owner = claimer_;\n _nominee = address(0);\n emit OwnerClaimed(claimer_);\n }\n}\n"},"lib/solmate/src/tokens/ERC20.sol":{"content":"// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.\n/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)\n/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)\n/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.\nabstract contract ERC20 {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event Transfer(address indexed from, address indexed to, uint256 amount);\n\n event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n /*//////////////////////////////////////////////////////////////\n METADATA STORAGE\n //////////////////////////////////////////////////////////////*/\n\n string public name;\n\n string public symbol;\n\n uint8 public immutable decimals;\n\n /*//////////////////////////////////////////////////////////////\n ERC20 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 public totalSupply;\n\n mapping(address => uint256) public balanceOf;\n\n mapping(address => mapping(address => uint256)) public allowance;\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 internal immutable INITIAL_CHAIN_ID;\n\n bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;\n\n mapping(address => uint256) public nonces;\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(\n string memory _name,\n string memory _symbol,\n uint8 _decimals\n ) {\n name = _name;\n symbol = _symbol;\n decimals = _decimals;\n\n INITIAL_CHAIN_ID = block.chainid;\n INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC20 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 amount) public virtual returns (bool) {\n allowance[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n\n return true;\n }\n\n function transfer(address to, uint256 amount) public virtual returns (bool) {\n balanceOf[msg.sender] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(msg.sender, to, amount);\n\n return true;\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual returns (bool) {\n uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.\n\n if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;\n\n balanceOf[from] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n return true;\n }\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual {\n require(deadline >= block.timestamp, \"PERMIT_DEADLINE_EXPIRED\");\n\n // Unchecked because the only math done is incrementing\n // the owner's nonce which cannot realistically overflow.\n unchecked {\n address recoveredAddress = ecrecover(\n keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR(),\n keccak256(\n abi.encode(\n keccak256(\n \"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\"\n ),\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n )\n ),\n v,\n r,\n s\n );\n\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"INVALID_SIGNER\");\n\n allowance[recoveredAddress][spender] = value;\n }\n\n emit Approval(owner, spender, value);\n }\n\n function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\n return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();\n }\n\n function computeDomainSeparator() internal view virtual returns (bytes32) {\n return\n keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name)),\n keccak256(\"1\"),\n block.chainid,\n address(this)\n )\n );\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL MINT/BURN LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _mint(address to, uint256 amount) internal virtual {\n totalSupply += amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(address(0), to, amount);\n }\n\n function _burn(address from, uint256 amount) internal virtual {\n balanceOf[from] -= amount;\n\n // Cannot underflow because a user's balance\n // will never be larger than the total supply.\n unchecked {\n totalSupply -= amount;\n }\n\n emit Transfer(from, address(0), amount);\n }\n}\n"},"src/controllers/RefuelSwapAndBridgeController.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {ISocketRequest} from \"../interfaces/ISocketRequest.sol\";\nimport {ISocketRoute} from \"../interfaces/ISocketRoute.sol\";\nimport {BaseController} from \"./BaseController.sol\";\n\n/**\n * @title RefuelSwapAndBridge Controller Implementation\n * @notice Controller with composed actions for Refuel,Swap and Bridge to be executed Sequentially and this is atomic\n * @author Socket dot tech.\n */\ncontract RefuelSwapAndBridgeController is BaseController {\n /// @notice Function-selector to invoke refuel-swap-bridge function\n /// @dev This function selector is to be used while buidling transaction-data\n bytes4 public immutable REFUEL_SWAP_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"refuelAndSwapAndBridge((uint32,bytes,uint32,bytes,uint32,bytes))\"\n )\n );\n\n /// @notice socketGatewayAddress to be initialised via storage variable BaseController\n constructor(\n address _socketGatewayAddress\n ) BaseController(_socketGatewayAddress) {}\n\n /**\n * @notice function to handle refuel followed by Swap and Bridge actions\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param rsbRequest Request with data to execute refuel followed by swap and bridge\n * @return output data from bridging operation\n */\n function refuelAndSwapAndBridge(\n ISocketRequest.RefuelSwapBridgeRequest calldata rsbRequest\n ) public payable returns (bytes memory) {\n _executeRoute(rsbRequest.refuelRouteId, rsbRequest.refuelData);\n\n // refuel is also a bridging activity via refuel-route-implementation\n bytes memory swapResponseData = _executeRoute(\n rsbRequest.swapRouteId,\n rsbRequest.swapData\n );\n\n uint256 swapAmount = abi.decode(swapResponseData, (uint256));\n\n //sequence of arguments for implData: amount, token, data\n // Bridging the swapAmount received in the preceeding step\n bytes memory bridgeImpldata = abi.encodeWithSelector(\n BRIDGE_AFTER_SWAP_SELECTOR,\n swapAmount,\n rsbRequest.bridgeData\n );\n\n return _executeRoute(rsbRequest.bridgeRouteId, bridgeImpldata);\n }\n}\n"},"src/interfaces/ISocketGateway.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/**\n * @title ISocketGateway\n * @notice Interface for SocketGateway functions.\n * @dev functions can be added here for invocation from external contracts or off-chain\n * @author Socket dot tech.\n */\ninterface ISocketGateway {\n /**\n * @notice Request-struct for controllerRequests\n * @dev ensure the value for data is generated using the function-selectors defined in the controllerImplementation contracts\n */\n struct SocketControllerRequest {\n // controllerId is the id mapped to the controllerAddress\n uint32 controllerId;\n // transactionImplData generated off-chain or by caller using function-selector of the controllerContract\n bytes data;\n }\n\n // @notice view to get owner-address\n function owner() external view returns (address);\n}\n"},"src/libraries/Pb.sol":{"content":"// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity ^0.8.4;\n\n// runtime proto sol library\nlibrary Pb {\n enum WireType {\n Varint,\n Fixed64,\n LengthDelim,\n StartGroup,\n EndGroup,\n Fixed32\n }\n\n struct Buffer {\n uint256 idx; // the start index of next read. when idx=b.length, we're done\n bytes b; // hold serialized proto msg, readonly\n }\n\n // create a new in-memory Buffer object from raw msg bytes\n function fromBytes(\n bytes memory raw\n ) internal pure returns (Buffer memory buf) {\n buf.b = raw;\n buf.idx = 0;\n }\n\n // whether there are unread bytes\n function hasMore(Buffer memory buf) internal pure returns (bool) {\n return buf.idx < buf.b.length;\n }\n\n // decode current field number and wiretype\n function decKey(\n Buffer memory buf\n ) internal pure returns (uint256 tag, WireType wiretype) {\n uint256 v = decVarint(buf);\n tag = v / 8;\n wiretype = WireType(v & 7);\n }\n\n // read varint from current buf idx, move buf.idx to next read, return the int value\n function decVarint(Buffer memory buf) internal pure returns (uint256 v) {\n bytes10 tmp; // proto int is at most 10 bytes (7 bits can be used per byte)\n bytes memory bb = buf.b; // get buf.b mem addr to use in assembly\n v = buf.idx; // use v to save one additional uint variable\n assembly {\n tmp := mload(add(add(bb, 32), v)) // load 10 bytes from buf.b[buf.idx] to tmp\n }\n uint256 b; // store current byte content\n v = 0; // reset to 0 for return value\n for (uint256 i = 0; i < 10; i++) {\n assembly {\n b := byte(i, tmp) // don't use tmp[i] because it does bound check and costs extra\n }\n v |= (b & 0x7F) << (i * 7);\n if (b & 0x80 == 0) {\n buf.idx += i + 1;\n return v;\n }\n }\n revert(); // i=10, invalid varint stream\n }\n\n // read length delimited field and return bytes\n function decBytes(\n Buffer memory buf\n ) internal pure returns (bytes memory b) {\n uint256 len = decVarint(buf);\n uint256 end = buf.idx + len;\n require(end <= buf.b.length); // avoid overflow\n b = new bytes(len);\n bytes memory bufB = buf.b; // get buf.b mem addr to use in assembly\n uint256 bStart;\n uint256 bufBStart = buf.idx;\n assembly {\n bStart := add(b, 32)\n bufBStart := add(add(bufB, 32), bufBStart)\n }\n for (uint256 i = 0; i < len; i += 32) {\n assembly {\n mstore(add(bStart, i), mload(add(bufBStart, i)))\n }\n }\n buf.idx = end;\n }\n\n // move idx pass current value field, to beginning of next tag or msg end\n function skipValue(Buffer memory buf, WireType wire) internal pure {\n if (wire == WireType.Varint) {\n decVarint(buf);\n } else if (wire == WireType.LengthDelim) {\n uint256 len = decVarint(buf);\n buf.idx += len; // skip len bytes value data\n require(buf.idx <= buf.b.length); // avoid overflow\n } else {\n revert();\n } // unsupported wiretype\n }\n\n function _uint256(bytes memory b) internal pure returns (uint256 v) {\n require(b.length <= 32); // b's length must be smaller than or equal to 32\n assembly {\n v := mload(add(b, 32))\n } // load all 32bytes to v\n v = v >> (8 * (32 - b.length)); // only first b.length is valid\n }\n\n function _address(bytes memory b) internal pure returns (address v) {\n v = _addressPayable(b);\n }\n\n function _addressPayable(\n bytes memory b\n ) internal pure returns (address payable v) {\n require(b.length == 20);\n //load 32bytes then shift right 12 bytes\n assembly {\n v := div(mload(add(b, 32)), 0x1000000000000000000000000)\n }\n }\n\n function _bytes32(bytes memory b) internal pure returns (bytes32 v) {\n require(b.length == 32);\n assembly {\n v := mload(add(b, 32))\n }\n }\n}\n"},"src/bridges/BridgeImplBase.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {ISocketGateway} from \"../interfaces/ISocketGateway.sol\";\nimport {ISocketRoute} from \"../interfaces/ISocketRoute.sol\";\nimport {OnlySocketGatewayOwner, OnlySocketDeployer} from \"../errors/SocketErrors.sol\";\n\n/**\n * @title Abstract Implementation Contract.\n * @notice All Bridge Implementation will follow this interface.\n */\nabstract contract BridgeImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n /// @notice Address used to identify if it is a native token transfer or not\n address public immutable NATIVE_TOKEN_ADDRESS =\n address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);\n\n /// @notice immutable variable to store the socketGateway address\n address public immutable socketGateway;\n\n /// @notice immutable variable to store the socketGateway address\n address public immutable socketDeployFactory;\n\n /// @notice immutable variable with instance of SocketRoute to access route functions\n ISocketRoute public immutable socketRoute;\n\n /// @notice FunctionSelector used to delegatecall from swap to the function of bridge router implementation\n bytes4 public immutable BRIDGE_AFTER_SWAP_SELECTOR =\n bytes4(keccak256(\"bridgeAfterSwap(uint256,bytes)\"));\n\n /****************************************\n * EVENTS *\n ****************************************/\n\n event SocketBridge(\n uint256 amount,\n address token,\n uint256 toChainId,\n bytes32 bridgeName,\n address sender,\n address receiver,\n bytes32 metadata\n );\n\n /**\n * @notice Construct the base for all BridgeImplementations.\n * @param _socketGateway Socketgateway address, an immutable variable to set.\n * @param _socketDeployFactory Socket Deploy Factory address, an immutable variable to set.\n */\n constructor(address _socketGateway, address _socketDeployFactory) {\n socketGateway = _socketGateway;\n socketDeployFactory = _socketDeployFactory;\n socketRoute = ISocketRoute(_socketGateway);\n }\n\n /****************************************\n * MODIFIERS *\n ****************************************/\n\n /// @notice Implementing contract needs to make use of the modifier where restricted access is to be used\n modifier isSocketGatewayOwner() {\n if (msg.sender != ISocketGateway(socketGateway).owner()) {\n revert OnlySocketGatewayOwner();\n }\n _;\n }\n\n /// @notice Implementing contract needs to make use of the modifier where restricted access is to be used\n modifier isSocketDeployFactory() {\n if (msg.sender != socketDeployFactory) {\n revert OnlySocketDeployer();\n }\n _;\n }\n\n /****************************************\n * RESTRICTED FUNCTIONS *\n ****************************************/\n\n /**\n * @notice function to rescue the ERC20 tokens in the bridge Implementation contract\n * @notice this is a function restricted to Owner of SocketGateway only\n * @param token address of ERC20 token being rescued\n * @param userAddress receipient address to which ERC20 tokens will be rescued to\n * @param amount amount of ERC20 tokens being rescued\n */\n function rescueFunds(\n address token,\n address userAddress,\n uint256 amount\n ) external isSocketGatewayOwner {\n ERC20(token).safeTransfer(userAddress, amount);\n }\n\n /**\n * @notice function to rescue the native-balance in the bridge Implementation contract\n * @notice this is a function restricted to Owner of SocketGateway only\n * @param userAddress receipient address to which native-balance will be rescued to\n * @param amount amount of native balance tokens being rescued\n */\n function rescueEther(\n address payable userAddress,\n uint256 amount\n ) external isSocketGatewayOwner {\n userAddress.transfer(amount);\n }\n\n function killme() external isSocketDeployFactory {\n selfdestruct(payable(msg.sender));\n }\n\n /******************************\n * VIRTUAL FUNCTIONS *\n *****************************/\n\n /**\n * @notice function to bridge which is succeeding the swap function\n * @notice this function is to be used only when bridging as a succeeding step\n * @notice All bridge implementation contracts must implement this function\n * @notice bridge-implementations will have a bridge specific struct with properties used in bridging\n * @param bridgeData encoded value of properties in the bridgeData Struct\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable virtual;\n}\n"},"src/bridges/cbridge/CelerImpl.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport \"../../libraries/Pb.sol\";\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport \"./interfaces/cbridge.sol\";\nimport \"./interfaces/ICelerStorageWrapper.sol\";\nimport {TransferIdExists, InvalidCelerRefund, CelerAlreadyRefunded, CelerRefundNotReady} from \"../../errors/SocketErrors.sol\";\nimport {BridgeImplBase} from \"../BridgeImplBase.sol\";\nimport {CBRIDGE} from \"../../static/RouteIdentifiers.sol\";\n\n/**\n * @title Celer-Route Implementation\n * @notice Route implementation with functions to bridge ERC20 and Native via Celer-Bridge\n * Called via SocketGateway if the routeId in the request maps to the routeId of CelerImplementation\n * Contains function to handle bridging as post-step i.e linked to a preceeding step for swap\n * RequestData is different to just bride and bridging chained with swap\n * @author Socket dot tech.\n */\ncontract CelerImpl is BridgeImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable CBridgeIdentifier = CBRIDGE;\n\n /// @notice Utility to perform operation on Buffer\n using Pb for Pb.Buffer;\n\n /// @notice Function-selector for ERC20-token bridging on Celer-Route\n /// @dev This function selector is to be used while building transaction-data to bridge ERC20 tokens\n bytes4 public immutable CELER_ERC20_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeERC20To(address,address,uint256,bytes32,uint64,uint64,uint32)\"\n )\n );\n\n /// @notice Function-selector for Native bridging on Celer-Route\n /// @dev This function selector is to be used while building transaction-data to bridge Native tokens\n bytes4 public immutable CELER_NATIVE_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeNativeTo(address,uint256,bytes32,uint64,uint64,uint32)\"\n )\n );\n\n bytes4 public immutable CELER_SWAP_BRIDGE_SELECTOR =\n bytes4(\n keccak256(\n \"swapAndBridge(uint32,bytes,(address,uint64,uint32,uint64,bytes32))\"\n )\n );\n\n /// @notice router Contract instance used to deposit ERC20 and Native on to Celer-Bridge\n /// @dev contract instance is to be initialized in the constructor using the routerAddress passed as constructor argument\n ICBridge public immutable router;\n\n /// @notice celerStorageWrapper Contract instance used to store the transferId generated during ERC20 and Native bridge on to Celer-Bridge\n /// @dev contract instance is to be initialized in the constructor using the celerStorageWrapperAddress passed as constructor argument\n ICelerStorageWrapper public immutable celerStorageWrapper;\n\n /// @notice WETH token address\n address public immutable weth;\n\n /// @notice chainId used during generation of transferId generated while bridging ERC20 and Native on to Celer-Bridge\n /// @dev this is to be initialised in the constructor\n uint64 public immutable chainId;\n\n struct WithdrawMsg {\n uint64 chainid; // tag: 1\n uint64 seqnum; // tag: 2\n address receiver; // tag: 3\n address token; // tag: 4\n uint256 amount; // tag: 5\n bytes32 refid; // tag: 6\n }\n\n /// @notice socketGatewayAddress to be initialised via storage variable BridgeImplBase\n /// @dev ensure routerAddress, weth-address, celerStorageWrapperAddress are set properly for the chainId in which the contract is being deployed\n constructor(\n address _routerAddress,\n address _weth,\n address _celerStorageWrapperAddress,\n address _socketGateway,\n address _socketDeployFactory\n ) BridgeImplBase(_socketGateway, _socketDeployFactory) {\n router = ICBridge(_routerAddress);\n celerStorageWrapper = ICelerStorageWrapper(_celerStorageWrapperAddress);\n weth = _weth;\n chainId = uint64(block.chainid);\n }\n\n // Function to receive Ether. msg.data must be empty\n receive() external payable {}\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct CelerBridgeDataNoToken {\n address receiverAddress;\n uint64 toChainId;\n uint32 maxSlippage;\n uint64 nonce;\n bytes32 metadata;\n }\n\n struct CelerBridgeData {\n address token;\n address receiverAddress;\n uint64 toChainId;\n uint32 maxSlippage;\n uint64 nonce;\n bytes32 metadata;\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from swapAndBridge, this function is called when the swap has already happened at a different place.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in CelerBridgeData struct\n * @param amount amount of tokens being bridged. this can be ERC20 or native\n * @param bridgeData encoded data for CelerBridge\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable override {\n CelerBridgeData memory celerBridgeData = abi.decode(\n bridgeData,\n (CelerBridgeData)\n );\n\n if (celerBridgeData.token == NATIVE_TOKEN_ADDRESS) {\n // transferId is generated using the request-params and nonce of the account\n // transferId should be unique for each request and this is used while handling refund from celerBridge\n bytes32 transferId = keccak256(\n abi.encodePacked(\n address(this),\n celerBridgeData.receiverAddress,\n weth,\n amount,\n celerBridgeData.toChainId,\n celerBridgeData.nonce,\n chainId\n )\n );\n\n // transferId is stored in CelerStorageWrapper with in a mapping where key is transferId and value is the msg-sender\n celerStorageWrapper.setAddressForTransferId(transferId, msg.sender);\n\n router.sendNative{value: amount}(\n celerBridgeData.receiverAddress,\n amount,\n celerBridgeData.toChainId,\n celerBridgeData.nonce,\n celerBridgeData.maxSlippage\n );\n } else {\n // transferId is generated using the request-params and nonce of the account\n // transferId should be unique for each request and this is used while handling refund from celerBridge\n bytes32 transferId = keccak256(\n abi.encodePacked(\n address(this),\n celerBridgeData.receiverAddress,\n celerBridgeData.token,\n amount,\n celerBridgeData.toChainId,\n celerBridgeData.nonce,\n chainId\n )\n );\n\n // transferId is stored in CelerStorageWrapper with in a mapping where key is transferId and value is the msg-sender\n celerStorageWrapper.setAddressForTransferId(transferId, msg.sender);\n router.send(\n celerBridgeData.receiverAddress,\n celerBridgeData.token,\n amount,\n celerBridgeData.toChainId,\n celerBridgeData.nonce,\n celerBridgeData.maxSlippage\n );\n }\n\n emit SocketBridge(\n amount,\n celerBridgeData.token,\n celerBridgeData.toChainId,\n CBridgeIdentifier,\n msg.sender,\n celerBridgeData.receiverAddress,\n celerBridgeData.metadata\n );\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from bridgeAfterSwap since this function holds the logic for swapping tokens too.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in CelerBridgeData struct\n * @param swapId routeId for the swapImpl\n * @param swapData encoded data for swap\n * @param celerBridgeData encoded data for CelerBridgeData\n */\n function swapAndBridge(\n uint32 swapId,\n bytes calldata swapData,\n CelerBridgeDataNoToken calldata celerBridgeData\n ) external payable {\n (bool success, bytes memory result) = socketRoute\n .getRoute(swapId)\n .delegatecall(swapData);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n (uint256 bridgeAmount, address token) = abi.decode(\n result,\n (uint256, address)\n );\n\n if (token == NATIVE_TOKEN_ADDRESS) {\n // transferId is generated using the request-params and nonce of the account\n // transferId should be unique for each request and this is used while handling refund from celerBridge\n bytes32 transferId = keccak256(\n abi.encodePacked(\n address(this),\n celerBridgeData.receiverAddress,\n weth,\n bridgeAmount,\n celerBridgeData.toChainId,\n celerBridgeData.nonce,\n chainId\n )\n );\n\n // transferId is stored in CelerStorageWrapper with in a mapping where key is transferId and value is the msg-sender\n celerStorageWrapper.setAddressForTransferId(transferId, msg.sender);\n\n router.sendNative{value: bridgeAmount}(\n celerBridgeData.receiverAddress,\n bridgeAmount,\n celerBridgeData.toChainId,\n celerBridgeData.nonce,\n celerBridgeData.maxSlippage\n );\n } else {\n // transferId is generated using the request-params and nonce of the account\n // transferId should be unique for each request and this is used while handling refund from celerBridge\n bytes32 transferId = keccak256(\n abi.encodePacked(\n address(this),\n celerBridgeData.receiverAddress,\n token,\n bridgeAmount,\n celerBridgeData.toChainId,\n celerBridgeData.nonce,\n chainId\n )\n );\n\n // transferId is stored in CelerStorageWrapper with in a mapping where key is transferId and value is the msg-sender\n celerStorageWrapper.setAddressForTransferId(transferId, msg.sender);\n router.send(\n celerBridgeData.receiverAddress,\n token,\n bridgeAmount,\n celerBridgeData.toChainId,\n celerBridgeData.nonce,\n celerBridgeData.maxSlippage\n );\n }\n\n emit SocketBridge(\n bridgeAmount,\n token,\n celerBridgeData.toChainId,\n CBridgeIdentifier,\n msg.sender,\n celerBridgeData.receiverAddress,\n celerBridgeData.metadata\n );\n }\n\n /**\n * @notice function to handle ERC20 bridging to receipent via Celer-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param receiverAddress address of recipient\n * @param token address of token being bridged\n * @param amount amount of token for bridging\n * @param toChainId destination ChainId\n * @param nonce nonce of the sender-account address\n * @param maxSlippage maximum Slippage for the bridging\n */\n function bridgeERC20To(\n address receiverAddress,\n address token,\n uint256 amount,\n bytes32 metadata,\n uint64 toChainId,\n uint64 nonce,\n uint32 maxSlippage\n ) external payable {\n /// @notice transferId is generated using the request-params and nonce of the account\n /// @notice transferId should be unique for each request and this is used while handling refund from celerBridge\n bytes32 transferId = keccak256(\n abi.encodePacked(\n address(this),\n receiverAddress,\n token,\n amount,\n toChainId,\n nonce,\n chainId\n )\n );\n\n /// @notice stored in the CelerStorageWrapper contract\n celerStorageWrapper.setAddressForTransferId(transferId, msg.sender);\n\n ERC20 tokenInstance = ERC20(token);\n tokenInstance.safeTransferFrom(msg.sender, socketGateway, amount);\n router.send(\n receiverAddress,\n token,\n amount,\n toChainId,\n nonce,\n maxSlippage\n );\n\n emit SocketBridge(\n amount,\n token,\n toChainId,\n CBridgeIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n\n /**\n * @notice function to handle Native bridging to receipent via Celer-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param receiverAddress address of recipient\n * @param amount amount of token for bridging\n * @param toChainId destination ChainId\n * @param nonce nonce of the sender-account address\n * @param maxSlippage maximum Slippage for the bridging\n */\n function bridgeNativeTo(\n address receiverAddress,\n uint256 amount,\n bytes32 metadata,\n uint64 toChainId,\n uint64 nonce,\n uint32 maxSlippage\n ) external payable {\n bytes32 transferId = keccak256(\n abi.encodePacked(\n address(this),\n receiverAddress,\n weth,\n amount,\n toChainId,\n nonce,\n chainId\n )\n );\n\n celerStorageWrapper.setAddressForTransferId(transferId, msg.sender);\n\n router.sendNative{value: amount}(\n receiverAddress,\n amount,\n toChainId,\n nonce,\n maxSlippage\n );\n\n emit SocketBridge(\n amount,\n NATIVE_TOKEN_ADDRESS,\n toChainId,\n CBridgeIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n\n /**\n * @notice function to handle refund from CelerBridge-Router\n * @param _request request data generated offchain using the celer-SDK\n * @param _sigs generated offchain using the celer-SDK\n * @param _signers generated offchain using the celer-SDK\n * @param _powers generated offchain using the celer-SDK\n */\n function refundCelerUser(\n bytes calldata _request,\n bytes[] calldata _sigs,\n address[] calldata _signers,\n uint256[] calldata _powers\n ) external payable {\n WithdrawMsg memory request = decWithdrawMsg(_request);\n bytes32 transferId = keccak256(\n abi.encodePacked(\n request.chainid,\n request.seqnum,\n request.receiver,\n request.token,\n request.amount\n )\n );\n uint256 _initialNativeBalance = address(this).balance;\n uint256 _initialTokenBalance = ERC20(request.token).balanceOf(\n address(this)\n );\n if (!router.withdraws(transferId)) {\n router.withdraw(_request, _sigs, _signers, _powers);\n }\n\n if (request.receiver != socketGateway) {\n revert InvalidCelerRefund();\n }\n\n address _receiver = celerStorageWrapper.getAddressFromTransferId(\n request.refid\n );\n celerStorageWrapper.deleteTransferId(request.refid);\n\n if (_receiver == address(0)) {\n revert CelerAlreadyRefunded();\n }\n\n uint256 _nativeBalanceAfter = address(this).balance;\n uint256 _tokenBalanceAfter = ERC20(request.token).balanceOf(\n address(this)\n );\n if (_nativeBalanceAfter > _initialNativeBalance) {\n if ((_nativeBalanceAfter - _initialNativeBalance) != request.amount)\n revert CelerRefundNotReady();\n payable(_receiver).transfer(request.amount);\n return;\n }\n\n if (_tokenBalanceAfter > _initialTokenBalance) {\n if ((_tokenBalanceAfter - _initialTokenBalance) != request.amount)\n revert CelerRefundNotReady();\n ERC20(request.token).safeTransfer(_receiver, request.amount);\n return;\n }\n\n revert CelerRefundNotReady();\n }\n\n function decWithdrawMsg(\n bytes memory raw\n ) internal pure returns (WithdrawMsg memory m) {\n Pb.Buffer memory buf = Pb.fromBytes(raw);\n\n uint256 tag;\n Pb.WireType wire;\n while (buf.hasMore()) {\n (tag, wire) = buf.decKey();\n if (false) {}\n // solidity has no switch/case\n else if (tag == 1) {\n m.chainid = uint64(buf.decVarint());\n } else if (tag == 2) {\n m.seqnum = uint64(buf.decVarint());\n } else if (tag == 3) {\n m.receiver = Pb._address(buf.decBytes());\n } else if (tag == 4) {\n m.token = Pb._address(buf.decBytes());\n } else if (tag == 5) {\n m.amount = Pb._uint256(buf.decBytes());\n } else if (tag == 6) {\n m.refid = Pb._bytes32(buf.decBytes());\n } else {\n buf.skipValue(wire);\n } // skip value of unknown tag\n }\n } // end decoder WithdrawMsg\n}\n"},"src/libraries/LibBytes.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n// Functions taken out from https://github.com/GNSPS/solidity-bytes-utils/blob/master/contracts/BytesLib.sol\nlibrary LibBytes {\n // solhint-disable no-inline-assembly\n\n // LibBytes specific errors\n error SliceOverflow();\n error SliceOutOfBounds();\n error AddressOutOfBounds();\n error UintOutOfBounds();\n\n // -------------------------\n\n function concat(\n bytes memory _preBytes,\n bytes memory _postBytes\n ) internal pure returns (bytes memory) {\n bytes memory tempBytes;\n\n assembly {\n // Get a location of some free memory and store it in tempBytes as\n // Solidity does for memory variables.\n tempBytes := mload(0x40)\n\n // Store the length of the first bytes array at the beginning of\n // the memory for tempBytes.\n let length := mload(_preBytes)\n mstore(tempBytes, length)\n\n // Maintain a memory counter for the current write location in the\n // temp bytes array by adding the 32 bytes for the array length to\n // the starting location.\n let mc := add(tempBytes, 0x20)\n // Stop copying when the memory counter reaches the length of the\n // first bytes array.\n let end := add(mc, length)\n\n for {\n // Initialize a copy counter to the start of the _preBytes data,\n // 32 bytes into its memory.\n let cc := add(_preBytes, 0x20)\n } lt(mc, end) {\n // Increase both counters by 32 bytes each iteration.\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n // Write the _preBytes data into the tempBytes memory 32 bytes\n // at a time.\n mstore(mc, mload(cc))\n }\n\n // Add the length of _postBytes to the current length of tempBytes\n // and store it as the new length in the first 32 bytes of the\n // tempBytes memory.\n length := mload(_postBytes)\n mstore(tempBytes, add(length, mload(tempBytes)))\n\n // Move the memory counter back from a multiple of 0x20 to the\n // actual end of the _preBytes data.\n mc := end\n // Stop copying when the memory counter reaches the new combined\n // length of the arrays.\n end := add(mc, length)\n\n for {\n let cc := add(_postBytes, 0x20)\n } lt(mc, end) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n mstore(mc, mload(cc))\n }\n\n // Update the free-memory pointer by padding our last write location\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\n // next 32 byte block, then round down to the nearest multiple of\n // 32. If the sum of the length of the two arrays is zero then add\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\n mstore(\n 0x40,\n and(\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\n not(31) // Round down to the nearest 32 bytes.\n )\n )\n }\n\n return tempBytes;\n }\n\n function slice(\n bytes memory _bytes,\n uint256 _start,\n uint256 _length\n ) internal pure returns (bytes memory) {\n if (_length + 31 < _length) {\n revert SliceOverflow();\n }\n if (_bytes.length < _start + _length) {\n revert SliceOutOfBounds();\n }\n\n bytes memory tempBytes;\n\n assembly {\n switch iszero(_length)\n case 0 {\n // Get a location of some free memory and store it in tempBytes as\n // Solidity does for memory variables.\n tempBytes := mload(0x40)\n\n // The first word of the slice result is potentially a partial\n // word read from the original array. To read it, we calculate\n // the length of that partial word and start copying that many\n // bytes into the array. The first word we copy will start with\n // data we don't care about, but the last `lengthmod` bytes will\n // land at the beginning of the contents of the new array. When\n // we're done copying, we overwrite the full first word with\n // the actual length of the slice.\n let lengthmod := and(_length, 31)\n\n // The multiplication in the next line is necessary\n // because when slicing multiples of 32 bytes (lengthmod == 0)\n // the following copy loop was copying the origin's length\n // and then ending prematurely not copying everything it should.\n let mc := add(\n add(tempBytes, lengthmod),\n mul(0x20, iszero(lengthmod))\n )\n let end := add(mc, _length)\n\n for {\n // The multiplication in the next line has the same exact purpose\n // as the one above.\n let cc := add(\n add(\n add(_bytes, lengthmod),\n mul(0x20, iszero(lengthmod))\n ),\n _start\n )\n } lt(mc, end) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n mstore(mc, mload(cc))\n }\n\n mstore(tempBytes, _length)\n\n //update free-memory pointer\n //allocating the array padded to 32 bytes like the compiler does now\n mstore(0x40, and(add(mc, 31), not(31)))\n }\n //if we want a zero-length slice let's just return a zero-length array\n default {\n tempBytes := mload(0x40)\n //zero out the 32 bytes slice we are about to return\n //we need to do it because Solidity does not garbage collect\n mstore(tempBytes, 0)\n\n mstore(0x40, add(tempBytes, 0x20))\n }\n }\n\n return tempBytes;\n }\n}\n"},"src/bridges/hyphen/interfaces/hyphen.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity >=0.8.0;\n\n/**\n * @title HyphenLiquidityPoolManager\n * @notice interface with functions to bridge ERC20 and Native via Hyphen-Bridge\n * @author Socket dot tech.\n */\ninterface HyphenLiquidityPoolManager {\n /**\n * @dev Function used to deposit tokens into pool to initiate a cross chain token transfer.\n * @param toChainId Chain id where funds needs to be transfered\n * @param tokenAddress ERC20 Token address that needs to be transfered\n * @param receiver Address on toChainId where tokens needs to be transfered\n * @param amount Amount of token being transfered\n */\n function depositErc20(\n uint256 toChainId,\n address tokenAddress,\n address receiver,\n uint256 amount,\n string calldata tag\n ) external;\n\n /**\n * @dev Function used to deposit native token into pool to initiate a cross chain token transfer.\n * @param receiver Address on toChainId where tokens needs to be transfered\n * @param toChainId Chain id where funds needs to be transfered\n */\n function depositNative(\n address receiver,\n uint256 toChainId,\n string calldata tag\n ) external payable;\n}\n"},"src/swap/SwapImplBase.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport {ISocketGateway} from \"../interfaces/ISocketGateway.sol\";\nimport {OnlySocketGatewayOwner, OnlySocketDeployer} from \"../errors/SocketErrors.sol\";\n\n/**\n * @title Abstract Implementation Contract.\n * @notice All Swap Implementation will follow this interface.\n * @author Socket dot tech.\n */\nabstract contract SwapImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n /// @notice Address used to identify if it is a native token transfer or not\n address public immutable NATIVE_TOKEN_ADDRESS =\n address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);\n\n /// @notice immutable variable to store the socketGateway address\n address public immutable socketGateway;\n\n /// @notice immutable variable to store the socketGateway address\n address public immutable socketDeployFactory;\n\n /// @notice FunctionSelector used to delegatecall to the performAction function of swap-router-implementation\n bytes4 public immutable SWAP_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\"performAction(address,address,uint256,address,bytes)\")\n );\n\n /// @notice FunctionSelector used to delegatecall to the performActionWithIn function of swap-router-implementation\n bytes4 public immutable SWAP_WITHIN_FUNCTION_SELECTOR =\n bytes4(keccak256(\"performActionWithIn(address,address,uint256,bytes)\"));\n\n /****************************************\n * EVENTS *\n ****************************************/\n\n event SocketSwapTokens(\n address fromToken,\n address toToken,\n uint256 buyAmount,\n uint256 sellAmount,\n bytes32 routeName,\n address receiver\n );\n\n /**\n * @notice Construct the base for all SwapImplementations.\n * @param _socketGateway Socketgateway address, an immutable variable to set.\n */\n constructor(address _socketGateway, address _socketDeployFactory) {\n socketGateway = _socketGateway;\n socketDeployFactory = _socketDeployFactory;\n }\n\n /****************************************\n * MODIFIERS *\n ****************************************/\n\n /// @notice Implementing contract needs to make use of the modifier where restricted access is to be used\n modifier isSocketGatewayOwner() {\n if (msg.sender != ISocketGateway(socketGateway).owner()) {\n revert OnlySocketGatewayOwner();\n }\n _;\n }\n\n /// @notice Implementing contract needs to make use of the modifier where restricted access is to be used\n modifier isSocketDeployFactory() {\n if (msg.sender != socketDeployFactory) {\n revert OnlySocketDeployer();\n }\n _;\n }\n\n /****************************************\n * RESTRICTED FUNCTIONS *\n ****************************************/\n\n /**\n * @notice function to rescue the ERC20 tokens in the Swap-Implementation contract\n * @notice this is a function restricted to Owner of SocketGateway only\n * @param token address of ERC20 token being rescued\n * @param userAddress receipient address to which ERC20 tokens will be rescued to\n * @param amount amount of ERC20 tokens being rescued\n */\n function rescueFunds(\n address token,\n address userAddress,\n uint256 amount\n ) external isSocketGatewayOwner {\n ERC20(token).safeTransfer(userAddress, amount);\n }\n\n /**\n * @notice function to rescue the native-balance in the Swap-Implementation contract\n * @notice this is a function restricted to Owner of SocketGateway only\n * @param userAddress receipient address to which native-balance will be rescued to\n * @param amount amount of native balance tokens being rescued\n */\n function rescueEther(\n address payable userAddress,\n uint256 amount\n ) external isSocketGatewayOwner {\n userAddress.transfer(amount);\n }\n\n function killme() external isSocketDeployFactory {\n selfdestruct(payable(msg.sender));\n }\n\n /******************************\n * VIRTUAL FUNCTIONS *\n *****************************/\n\n /**\n * @notice function to swap tokens on the chain\n * All swap implementation contracts must implement this function\n * @param fromToken token to be swapped\n * @param toToken token to which fromToken has to be swapped\n * @param amount amount of fromToken being swapped\n * @param receiverAddress recipient address of toToken\n * @param data encoded value of properties in the swapData Struct\n */\n function performAction(\n address fromToken,\n address toToken,\n uint256 amount,\n address receiverAddress,\n bytes memory data\n ) external payable virtual returns (uint256);\n\n /**\n * @notice function to swapWith - swaps tokens on the chain to socketGateway as recipient\n * All swap implementation contracts must implement this function\n * @param fromToken token to be swapped\n * @param toToken token to which fromToken has to be swapped\n * @param amount amount of fromToken being swapped\n * @param swapExtraData encoded value of properties in the swapData Struct\n */\n function performActionWithIn(\n address fromToken,\n address toToken,\n uint256 amount,\n bytes memory swapExtraData\n ) external payable virtual returns (uint256, address);\n}\n"},"src/swap/zerox/ZeroXSwapImpl.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport \"../SwapImplBase.sol\";\nimport {Address0Provided, SwapFailed} from \"../../errors/SocketErrors.sol\";\nimport {ZEROX} from \"../../static/RouteIdentifiers.sol\";\n\n/**\n * @title ZeroX-Swap-Route Implementation\n * @notice Route implementation with functions to swap tokens via ZeroX-Swap\n * Called via SocketGateway if the routeId in the request maps to the routeId of ZeroX-Swap-Implementation\n * @author Socket dot tech.\n */\ncontract ZeroXSwapImpl is SwapImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable ZeroXIdentifier = ZEROX;\n\n /// @notice unique name to identify the router, used to emit event upon successful bridging\n bytes32 public immutable NAME = keccak256(\"Zerox-Router\");\n\n /// @notice address of ZeroX-Exchange-Proxy to swap the tokens on Chain\n address payable public immutable zeroXExchangeProxy;\n\n /// @notice socketGatewayAddress to be initialised via storage variable SwapImplBase\n /// @notice ZeroXExchangeProxy contract is payable to allow ethereum swaps\n /// @dev ensure _zeroXExchangeProxy are set properly for the chainId in which the contract is being deployed\n constructor(\n address _zeroXExchangeProxy,\n address _socketGateway,\n address _socketDeployFactory\n ) SwapImplBase(_socketGateway, _socketDeployFactory) {\n zeroXExchangeProxy = payable(_zeroXExchangeProxy);\n }\n\n receive() external payable {}\n\n fallback() external payable {}\n\n /**\n * @notice function to swap tokens on the chain and transfer to receiver address\n * @dev This is called only when there is a request for a swap.\n * @param fromToken token to be swapped\n * @param toToken token to which fromToken is to be swapped\n * @param amount amount to be swapped\n * @param receiverAddress address of toToken recipient\n * @param swapExtraData data required for zeroX Exchange to get the swap done\n */\n function performAction(\n address fromToken,\n address toToken,\n uint256 amount,\n address receiverAddress,\n bytes calldata swapExtraData\n ) external payable override returns (uint256) {\n if (fromToken == address(0)) {\n revert Address0Provided();\n }\n\n bytes memory swapCallData = abi.decode(swapExtraData, (bytes));\n\n uint256 _initialBalanceTokenOut;\n uint256 _finalBalanceTokenOut;\n\n ERC20 erc20ToToken = ERC20(toToken);\n if (toToken != NATIVE_TOKEN_ADDRESS) {\n _initialBalanceTokenOut = erc20ToToken.balanceOf(address(this));\n } else {\n _initialBalanceTokenOut = address(this).balance;\n }\n\n if (fromToken != NATIVE_TOKEN_ADDRESS) {\n ERC20 token = ERC20(fromToken);\n token.safeTransferFrom(msg.sender, address(this), amount);\n token.safeApprove(zeroXExchangeProxy, amount);\n\n // solhint-disable-next-line\n (bool success, ) = zeroXExchangeProxy.call(swapCallData);\n\n if (!success) {\n revert SwapFailed();\n }\n\n token.safeApprove(zeroXExchangeProxy, 0);\n } else {\n (bool success, ) = zeroXExchangeProxy.call{value: amount}(\n swapCallData\n );\n if (!success) {\n revert SwapFailed();\n }\n }\n\n if (toToken != NATIVE_TOKEN_ADDRESS) {\n _finalBalanceTokenOut = erc20ToToken.balanceOf(address(this));\n } else {\n _finalBalanceTokenOut = address(this).balance;\n }\n\n uint256 returnAmount = _finalBalanceTokenOut - _initialBalanceTokenOut;\n\n if (toToken == NATIVE_TOKEN_ADDRESS) {\n payable(receiverAddress).transfer(returnAmount);\n } else {\n erc20ToToken.transfer(receiverAddress, returnAmount);\n }\n\n emit SocketSwapTokens(\n fromToken,\n toToken,\n returnAmount,\n amount,\n ZeroXIdentifier,\n receiverAddress\n );\n\n return returnAmount;\n }\n\n /**\n * @notice function to swapWithIn SocketGateway - swaps tokens on the chain to socketGateway as recipient\n * @param fromToken token to be swapped\n * @param toToken token to which fromToken has to be swapped\n * @param amount amount of fromToken being swapped\n * @param swapExtraData encoded value of properties in the swapData Struct\n * @return swapped amount (in toToken Address)\n */\n function performActionWithIn(\n address fromToken,\n address toToken,\n uint256 amount,\n bytes calldata swapExtraData\n ) external payable override returns (uint256, address) {\n if (fromToken == address(0)) {\n revert Address0Provided();\n }\n\n bytes memory swapCallData = abi.decode(swapExtraData, (bytes));\n\n uint256 _initialBalanceTokenOut;\n uint256 _finalBalanceTokenOut;\n\n ERC20 erc20ToToken = ERC20(toToken);\n if (toToken != NATIVE_TOKEN_ADDRESS) {\n _initialBalanceTokenOut = erc20ToToken.balanceOf(address(this));\n } else {\n _initialBalanceTokenOut = address(this).balance;\n }\n\n if (fromToken != NATIVE_TOKEN_ADDRESS) {\n ERC20 token = ERC20(fromToken);\n token.safeTransferFrom(msg.sender, address(this), amount);\n token.safeApprove(zeroXExchangeProxy, amount);\n\n // solhint-disable-next-line\n (bool success, ) = zeroXExchangeProxy.call(swapCallData);\n\n if (!success) {\n revert SwapFailed();\n }\n\n token.safeApprove(zeroXExchangeProxy, 0);\n } else {\n (bool success, ) = zeroXExchangeProxy.call{value: amount}(\n swapCallData\n );\n if (!success) {\n revert SwapFailed();\n }\n }\n\n if (toToken != NATIVE_TOKEN_ADDRESS) {\n _finalBalanceTokenOut = erc20ToToken.balanceOf(address(this));\n } else {\n _finalBalanceTokenOut = address(this).balance;\n }\n\n uint256 returnAmount = _finalBalanceTokenOut - _initialBalanceTokenOut;\n\n emit SocketSwapTokens(\n fromToken,\n toToken,\n returnAmount,\n amount,\n ZeroXIdentifier,\n socketGateway\n );\n\n return (returnAmount, toToken);\n }\n}\n"},"src/bridges/cbridge/interfaces/cbridge.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity >=0.8.0;\n\ninterface ICBridge {\n function send(\n address _receiver,\n address _token,\n uint256 _amount,\n uint64 _dstChinId,\n uint64 _nonce,\n uint32 _maxSlippage\n ) external;\n\n function sendNative(\n address _receiver,\n uint256 _amount,\n uint64 _dstChinId,\n uint64 _nonce,\n uint32 _maxSlippage\n ) external payable;\n\n function withdraws(bytes32 withdrawId) external view returns (bool);\n\n function withdraw(\n bytes calldata _wdmsg,\n bytes[] calldata _sigs,\n address[] calldata _signers,\n uint256[] calldata _powers\n ) external;\n}\n"},"src/bridges/stargate/l2/Stargate.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {SafeTransferLib} from \"lib/solmate/src/utils/SafeTransferLib.sol\";\nimport {ERC20} from \"lib/solmate/src/tokens/ERC20.sol\";\nimport \"../interfaces/stargate.sol\";\nimport \"../../../errors/SocketErrors.sol\";\nimport {BridgeImplBase} from \"../../BridgeImplBase.sol\";\nimport {STARGATE} from \"../../../static/RouteIdentifiers.sol\";\n\n/**\n * @title Stargate-L2-Route Implementation\n * @notice Route implementation with functions to bridge ERC20 and Native via Stargate-L2-Bridge\n * Called via SocketGateway if the routeId in the request maps to the routeId of Stargate-L2-Implementation\n * Contains function to handle bridging as post-step i.e linked to a preceeding step for swap\n * RequestData is different to just bride and bridging chained with swap\n * @author Socket dot tech.\n */\ncontract StargateImplL2 is BridgeImplBase {\n /// @notice SafeTransferLib - library for safe and optimised operations on ERC20 tokens\n using SafeTransferLib for ERC20;\n\n bytes32 public immutable StargateIdentifier = STARGATE;\n\n /// @notice Function-selector for ERC20-token bridging on Stargate-L2-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge ERC20 tokens\n bytes4\n public immutable STARGATE_L2_ERC20_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeERC20To(address,address,address,uint256,uint256,uint256,(uint256,uint256,uint256,uint256,bytes32,bytes,uint16))\"\n )\n );\n\n bytes4 public immutable STARGATE_L1_SWAP_BRIDGE_SELECTOR =\n bytes4(\n keccak256(\n \"swapAndBridge(uint32,bytes,(address,address,uint16,uint256,uint256,uint256,uint256,uint256,uint256,bytes32,bytes))\"\n )\n );\n\n /// @notice Function-selector for Native bridging on Stargate-L2-Route\n /// @dev This function selector is to be used while buidling transaction-data to bridge Native tokens\n bytes4\n public immutable STARGATE_L2_NATIVE_EXTERNAL_BRIDGE_FUNCTION_SELECTOR =\n bytes4(\n keccak256(\n \"bridgeNativeTo(address,address,uint16,uint256,uint256,uint256,bytes32)\"\n )\n );\n\n /// @notice Stargate Router to bridge ERC20 tokens\n IBridgeStargate public immutable router;\n\n /// @notice Stargate Router to bridge native tokens\n IBridgeStargate public immutable routerETH;\n\n /// @notice socketGatewayAddress to be initialised via storage variable BridgeImplBase\n /// @dev ensure router, routerEth are set properly for the chainId in which the contract is being deployed\n constructor(\n address _router,\n address _routerEth,\n address _socketGateway,\n address _socketDeployFactory\n ) BridgeImplBase(_socketGateway, _socketDeployFactory) {\n router = IBridgeStargate(_router);\n routerETH = IBridgeStargate(_routerEth);\n }\n\n /// @notice Struct to be used as a input parameter for Bridging tokens via Stargate-L2-route\n /// @dev while building transactionData,values should be set in this sequence of properties in this struct\n struct StargateBridgeExtraData {\n uint256 srcPoolId;\n uint256 dstPoolId;\n uint256 destinationGasLimit;\n uint256 minReceivedAmt;\n bytes32 metadata;\n bytes destinationPayload;\n uint16 stargateDstChainId; // stargate defines chain id in its way\n }\n\n /// @notice Struct to be used in decode step from input parameter - a specific case of bridging after swap.\n /// @dev the data being encoded in offchain or by caller should have values set in this sequence of properties in this struct\n struct StargateBridgeDataNoToken {\n address receiverAddress;\n address senderAddress;\n uint16 stargateDstChainId; // stargate defines chain id in its way\n uint256 value;\n // a unique identifier that is uses to dedup transfers\n // this value is the a timestamp sent from frontend, but in theory can be any unique number\n uint256 srcPoolId;\n uint256 dstPoolId;\n uint256 minReceivedAmt; // defines the slippage, the min qty you would accept on the destination\n uint256 optionalValue;\n uint256 destinationGasLimit;\n bytes32 metadata;\n bytes destinationPayload;\n }\n\n struct StargateBridgeData {\n address token;\n address receiverAddress;\n address senderAddress;\n uint16 stargateDstChainId; // stargate defines chain id in its way\n uint256 value;\n // a unique identifier that is uses to dedup transfers\n // this value is the a timestamp sent from frontend, but in theory can be any unique number\n uint256 srcPoolId;\n uint256 dstPoolId;\n uint256 minReceivedAmt; // defines the slippage, the min qty you would accept on the destination\n uint256 optionalValue;\n uint256 destinationGasLimit;\n bytes32 metadata;\n bytes destinationPayload;\n }\n\n /**\n * @notice function to bridge tokens after swap.\n * @notice this is different from swapAndBridge, this function is called when the swap has already happened at a different place.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in Stargate-BridgeData struct\n * @param amount amount of tokens being bridged. this can be ERC20 or native\n * @param bridgeData encoded data for Stargate-L1-Bridge\n */\n function bridgeAfterSwap(\n uint256 amount,\n bytes calldata bridgeData\n ) external payable override {\n StargateBridgeData memory stargateBridgeData = abi.decode(\n bridgeData,\n (StargateBridgeData)\n );\n\n if (stargateBridgeData.token == NATIVE_TOKEN_ADDRESS) {\n // perform bridging\n routerETH.swapETH{value: amount + stargateBridgeData.optionalValue}(\n stargateBridgeData.stargateDstChainId,\n payable(stargateBridgeData.senderAddress),\n abi.encodePacked(stargateBridgeData.receiverAddress),\n amount,\n stargateBridgeData.minReceivedAmt\n );\n } else {\n ERC20(stargateBridgeData.token).safeApprove(\n address(router),\n amount\n );\n {\n router.swap{value: stargateBridgeData.value}(\n stargateBridgeData.stargateDstChainId,\n stargateBridgeData.srcPoolId,\n stargateBridgeData.dstPoolId,\n payable(stargateBridgeData.senderAddress), // default to refund to main contract\n amount,\n stargateBridgeData.minReceivedAmt,\n IBridgeStargate.lzTxObj(\n stargateBridgeData.destinationGasLimit,\n 0, // zero amount since this is a ERC20 bridging\n \"0x\" //empty data since this is for only ERC20\n ),\n abi.encodePacked(stargateBridgeData.receiverAddress),\n stargateBridgeData.destinationPayload\n );\n }\n }\n\n emit SocketBridge(\n amount,\n stargateBridgeData.token,\n stargateBridgeData.stargateDstChainId,\n StargateIdentifier,\n msg.sender,\n stargateBridgeData.receiverAddress,\n stargateBridgeData.metadata\n );\n }\n\n /**\n * @notice function to bridge tokens after swapping.\n * @notice this is different from bridgeAfterSwap since this function holds the logic for swapping tokens too.\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @dev for usage, refer to controller implementations\n * encodedData for bridge should follow the sequence of properties in Stargate-BridgeData struct\n * @param swapId routeId for the swapImpl\n * @param swapData encoded data for swap\n * @param stargateBridgeData encoded data for StargateBridgeData\n */\n function swapAndBridge(\n uint32 swapId,\n bytes calldata swapData,\n StargateBridgeDataNoToken calldata stargateBridgeData\n ) external payable {\n (bool success, bytes memory result) = socketRoute\n .getRoute(swapId)\n .delegatecall(swapData);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n\n (uint256 bridgeAmount, address token) = abi.decode(\n result,\n (uint256, address)\n );\n\n if (token == NATIVE_TOKEN_ADDRESS) {\n routerETH.swapETH{\n value: bridgeAmount + stargateBridgeData.optionalValue\n }(\n stargateBridgeData.stargateDstChainId,\n payable(stargateBridgeData.senderAddress),\n abi.encodePacked(stargateBridgeData.receiverAddress),\n bridgeAmount,\n stargateBridgeData.minReceivedAmt\n );\n } else {\n ERC20(token).safeApprove(address(router), bridgeAmount);\n {\n router.swap{value: stargateBridgeData.value}(\n stargateBridgeData.stargateDstChainId,\n stargateBridgeData.srcPoolId,\n stargateBridgeData.dstPoolId,\n payable(stargateBridgeData.senderAddress), // default to refund to main contract\n bridgeAmount,\n stargateBridgeData.minReceivedAmt,\n IBridgeStargate.lzTxObj(\n stargateBridgeData.destinationGasLimit,\n 0,\n \"0x\"\n ),\n abi.encodePacked(stargateBridgeData.receiverAddress),\n stargateBridgeData.destinationPayload\n );\n }\n }\n\n emit SocketBridge(\n bridgeAmount,\n token,\n stargateBridgeData.stargateDstChainId,\n StargateIdentifier,\n msg.sender,\n stargateBridgeData.receiverAddress,\n stargateBridgeData.metadata\n );\n }\n\n /**\n * @notice function to handle ERC20 bridging to receipent via Stargate-L1-Bridge\n * @notice This method is payable because the caller is doing token transfer and briding operation\n * @param token address of token being bridged\n * @param senderAddress address of sender\n * @param receiverAddress address of recipient\n * @param amount amount of token being bridge\n * @param value value\n * @param optionalValue optionalValue\n * @param stargateBridgeExtraData stargate bridge extradata\n */\n function bridgeERC20To(\n address token,\n address senderAddress,\n address receiverAddress,\n uint256 amount,\n uint256 value,\n uint256 optionalValue,\n StargateBridgeExtraData calldata stargateBridgeExtraData\n ) external payable {\n // token address might not be indication thats why passed through extraData\n if (token == NATIVE_TOKEN_ADDRESS) {\n // perform bridging\n routerETH.swapETH{value: amount + optionalValue}(\n stargateBridgeExtraData.stargateDstChainId,\n payable(senderAddress),\n abi.encodePacked(receiverAddress),\n amount,\n stargateBridgeExtraData.minReceivedAmt\n );\n } else {\n ERC20 tokenInstance = ERC20(token);\n tokenInstance.safeTransferFrom(msg.sender, socketGateway, amount);\n tokenInstance.safeApprove(address(router), amount);\n {\n router.swap{value: value}(\n stargateBridgeExtraData.stargateDstChainId,\n stargateBridgeExtraData.srcPoolId,\n stargateBridgeExtraData.dstPoolId,\n payable(senderAddress), // default to refund to main contract\n amount,\n stargateBridgeExtraData.minReceivedAmt,\n IBridgeStargate.lzTxObj(\n stargateBridgeExtraData.destinationGasLimit,\n 0, // zero amount since this is a ERC20 bridging\n \"0x\" //empty data since this is for only ERC20\n ),\n abi.encodePacked(receiverAddress),\n stargateBridgeExtraData.destinationPayload\n );\n }\n }\n\n emit SocketBridge(\n amount,\n token,\n stargateBridgeExtraData.stargateDstChainId,\n StargateIdentifier,\n msg.sender,\n receiverAddress,\n stargateBridgeExtraData.metadata\n );\n }\n\n function bridgeNativeTo(\n address receiverAddress,\n address senderAddress,\n uint16 stargateDstChainId,\n uint256 amount,\n uint256 minReceivedAmt,\n uint256 optionalValue,\n bytes32 metadata\n ) external payable {\n // perform bridging\n routerETH.swapETH{value: amount + optionalValue}(\n stargateDstChainId,\n payable(senderAddress),\n abi.encodePacked(receiverAddress),\n amount,\n minReceivedAmt\n );\n\n emit SocketBridge(\n amount,\n NATIVE_TOKEN_ADDRESS,\n stargateDstChainId,\n StargateIdentifier,\n msg.sender,\n receiverAddress,\n metadata\n );\n }\n}\n"}},"settings":{"optimizer":{"enabled":true,"runs":1000000},"outputSelection":{"*":{"*":["evm.bytecode","evm.deployedBytecode","devdoc","userdoc","metadata","abi"]}},"metadata":{"useLiteralContent":true},"libraries":{}}},"ABI":"[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_disabledRoute\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayLengthMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectBridgeRatios\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyNominee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"controllerId\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"controllerAddress\",\"type\":\"address\"}],\"name\":\"ControllerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"controllerId\",\"type\":\"uint32\"}],\"name\":\"ControllerDisabled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"routeId\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"route\",\"type\":\"address\"}],\"name\":\"NewRouteAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"claimer\",\"type\":\"address\"}],\"name\":\"OwnerClaimed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"nominee\",\"type\":\"address\"}],\"name\":\"OwnerNominated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"routeId\",\"type\":\"uint32\"}],\"name\":\"RouteDisabled\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"BRIDGE_AFTER_SWAP_SELECTOR\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"CENT_PERCENT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"controllerAddress\",\"type\":\"address\"}],\"name\":\"addController\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"routeAddress\",\"type\":\"address\"}],\"name\":\"addRoute\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"routeId\",\"type\":\"uint32\"}],\"name\":\"addressAt\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"controllerCount\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"name\":\"controllers\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"controllerId\",\"type\":\"uint32\"}],\"name\":\"disableController\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"routeId\",\"type\":\"uint32\"}],\"name\":\"disableRoute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"disabledRouteAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"controllerId\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"struct ISocketGateway.SocketControllerRequest\",\"name\":\"socketControllerRequest\",\"type\":\"tuple\"}],\"name\":\"executeController\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"controllerId\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"struct ISocketGateway.SocketControllerRequest[]\",\"name\":\"controllerRequests\",\"type\":\"tuple[]\"}],\"name\":\"executeControllers\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"routeId\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"routeData\",\"type\":\"bytes\"}],\"name\":\"executeRoute\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"routeIds\",\"type\":\"uint32[]\"},{\"internalType\":\"bytes[]\",\"name\":\"dataItems\",\"type\":\"bytes[]\"}],\"name\":\"executeRoutes\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"controllerId\",\"type\":\"uint32\"}],\"name\":\"getController\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"routeId\",\"type\":\"uint32\"}],\"name\":\"getRoute\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"nominee_\",\"type\":\"address\"}],\"name\":\"nominateOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nominee\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"userAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"rescueEther\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"userAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"rescueFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"name\":\"routes\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"routesCount\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"routeAddresses\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"tokenAddresses\",\"type\":\"address[]\"},{\"internalType\":\"bool\",\"name\":\"isMax\",\"type\":\"bool\"}],\"name\":\"setApprovalForRouters\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"swapRouteId\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"swapImplData\",\"type\":\"bytes\"},{\"internalType\":\"uint32[]\",\"name\":\"bridgeRouteIds\",\"type\":\"uint32[]\"},{\"internalType\":\"bytes[]\",\"name\":\"bridgeImplDataItems\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256[]\",\"name\":\"bridgeRatios\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"eventDataItems\",\"type\":\"bytes[]\"}],\"internalType\":\"struct ISocketRequest.SwapMultiBridgeRequest\",\"name\":\"swapMultiBridgeRequest\",\"type\":\"tuple\"}],\"name\":\"swapAndMultiBridge\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]","ContractName":"SocketGateway","CompilerVersion":"v0.8.7+commit.e28d00a7","OptimizationUsed":1,"Runs":1000000,"ConstructorArguments":"0x000000000000000000000000e8dd38e673a93ccfc2e3d7053efccb5c93f493650000000000000000000000000f34a522ff82151c90679b73211955068fd854f1","EVMVersion":"Default","Library":"","LicenseType":"","Proxy":1,"Implementation":"0xa3c4e32af0da5efaddb20cc9fb26159f55c8c42f","SwarmSource":""}] \ No newline at end of file diff --git a/testdata/etherscan/0x71356E37e0368Bd10bFDbF41dC052fE5FA24cD05/creation_data.json b/testdata/etherscan/0x71356E37e0368Bd10bFDbF41dC052fE5FA24cD05/creation_data.json index b3976447f248..08b838e2bc41 100644 --- a/testdata/etherscan/0x71356E37e0368Bd10bFDbF41dC052fE5FA24cD05/creation_data.json +++ b/testdata/etherscan/0x71356E37e0368Bd10bFDbF41dC052fE5FA24cD05/creation_data.json @@ -1,5 +1 @@ -{ - "contractAddress": "0x71356e37e0368bd10bfdbf41dc052fe5fa24cd05", - "contractCreator": "0xaa1d342354d755ec515f40e7d5e83cb4184bb9ee", - "txHash": "0x1c800c2c2d5230823602cae6896a8db1ab7d1341ca697c6c64d9f0edf11dabe2" -} \ No newline at end of file +{"contractAddress":"0x71356e37e0368bd10bfdbf41dc052fe5fa24cd05","contractCreator":"0xaa1d342354d755ec515f40e7d5e83cb4184bb9ee","txHash":"0x1c800c2c2d5230823602cae6896a8db1ab7d1341ca697c6c64d9f0edf11dabe2"} \ No newline at end of file diff --git a/testdata/etherscan/0x71356E37e0368Bd10bFDbF41dC052fE5FA24cD05/metadata.json b/testdata/etherscan/0x71356E37e0368Bd10bFDbF41dC052fE5FA24cD05/metadata.json index cc890a571122..08318ba41edf 100644 --- a/testdata/etherscan/0x71356E37e0368Bd10bFDbF41dC052fE5FA24cD05/metadata.json +++ b/testdata/etherscan/0x71356E37e0368Bd10bFDbF41dC052fE5FA24cD05/metadata.json @@ -1,129 +1 @@ -[ - { - "SourceCode": { - "language": "Solidity", - "sources": { - "@openzeppelin/contracts/access/IAccessControl.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" - }, - "@openzeppelin/contracts/token/ERC721/IERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n}\n" - }, - "@openzeppelin/contracts/access/IAccessControlEnumerable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerable is IAccessControl {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" - }, - "@openzeppelin/contracts/utils/StorageSlot.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n assembly {\n r.slot := slot\n }\n }\n}\n" - }, - "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" - }, - "contracts/v0.8/extensions/GatewayV2.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/security/Pausable.sol\";\nimport \"../interfaces/IQuorum.sol\";\nimport \"../interfaces/IWeightedValidator.sol\";\nimport \"./HasProxyAdmin.sol\";\n\nabstract contract GatewayV2 is HasProxyAdmin, Pausable, IQuorum {\n /// @dev Emitted when the validator contract address is updated.\n event ValidatorContractUpdated(IWeightedValidator);\n\n uint256 internal _num;\n uint256 internal _denom;\n\n IWeightedValidator public validatorContract;\n uint256 public nonce;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n */\n uint256[50] private ______gap;\n\n /**\n * @dev See {IQuorum-getThreshold}.\n */\n function getThreshold() external view virtual returns (uint256, uint256) {\n return (_num, _denom);\n }\n\n /**\n * @dev See {IQuorum-checkThreshold}.\n */\n function checkThreshold(uint256 _voteWeight) external view virtual returns (bool) {\n return _voteWeight * _denom >= _num * validatorContract.totalWeights();\n }\n\n /**\n * @dev See {IQuorum-setThreshold}.\n */\n function setThreshold(uint256 _numerator, uint256 _denominator)\n external\n virtual\n onlyAdmin\n returns (uint256, uint256)\n {\n return _setThreshold(_numerator, _denominator);\n }\n\n /**\n * @dev Triggers paused state.\n */\n function pause() external onlyAdmin {\n _pause();\n }\n\n /**\n * @dev Triggers unpaused state.\n */\n function unpause() external onlyAdmin {\n _unpause();\n }\n\n /**\n * @dev Sets validator contract address.\n *\n * Requirements:\n * - The method caller is admin.\n *\n * Emits the `ValidatorContractUpdated` event.\n *\n */\n function setValidatorContract(IWeightedValidator _validatorContract) external virtual onlyAdmin {\n _setValidatorContract(_validatorContract);\n }\n\n /**\n * @dev See {IQuorum-minimumVoteWeight}.\n */\n function minimumVoteWeight() public view virtual returns (uint256) {\n return _minimumVoteWeight(validatorContract.totalWeights());\n }\n\n /**\n * @dev Sets validator contract address.\n *\n * Emits the `ValidatorContractUpdated` event.\n *\n */\n function _setValidatorContract(IWeightedValidator _validatorContract) internal virtual {\n validatorContract = _validatorContract;\n emit ValidatorContractUpdated(_validatorContract);\n }\n\n /**\n * @dev Sets threshold and returns the old one.\n *\n * Emits the `ThresholdUpdated` event.\n *\n */\n function _setThreshold(uint256 _numerator, uint256 _denominator)\n internal\n virtual\n returns (uint256 _previousNum, uint256 _previousDenom)\n {\n require(_numerator <= _denominator, \"GatewayV2: invalid threshold\");\n _previousNum = _num;\n _previousDenom = _denom;\n _num = _numerator;\n _denom = _denominator;\n emit ThresholdUpdated(nonce++, _numerator, _denominator, _previousNum, _previousDenom);\n }\n\n /**\n * @dev Returns minimum vote weight.\n */\n function _minimumVoteWeight(uint256 _totalWeight) internal view virtual returns (uint256) {\n return (_num * _totalWeight + _denom - 1) / _denom;\n }\n}\n" - }, - "@openzeppelin/contracts/proxy/utils/Initializable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() initializer {}\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Modifier to protect an initializer function from being invoked twice.\n */\n modifier initializer() {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\n // contract may have been reentered.\n require(_initializing ? _isConstructor() : !_initialized, \"Initializable: contract is already initialized\");\n\n bool isTopLevelCall = !_initializing;\n if (isTopLevelCall) {\n _initializing = true;\n _initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n _initializing = false;\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} modifier, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n function _isConstructor() private view returns (bool) {\n return !Address.isContract(address(this));\n }\n}\n" - }, - "contracts/v0.8/extensions/WithdrawalLimitation.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./GatewayV2.sol\";\n\nabstract contract WithdrawalLimitation is GatewayV2 {\n /// @dev Emitted when the high-tier vote weight threshold is updated\n event HighTierVoteWeightThresholdUpdated(\n uint256 indexed nonce,\n uint256 indexed numerator,\n uint256 indexed denominator,\n uint256 previousNumerator,\n uint256 previousDenominator\n );\n /// @dev Emitted when the thresholds for high-tier withdrawals that requires high-tier vote weights are updated\n event HighTierThresholdsUpdated(address[] tokens, uint256[] thresholds);\n /// @dev Emitted when the thresholds for locked withdrawals are updated\n event LockedThresholdsUpdated(address[] tokens, uint256[] thresholds);\n /// @dev Emitted when the fee percentages to unlock withdraw are updated\n event UnlockFeePercentagesUpdated(address[] tokens, uint256[] percentages);\n /// @dev Emitted when the daily limit thresholds are updated\n event DailyWithdrawalLimitsUpdated(address[] tokens, uint256[] limits);\n\n uint256 public constant _MAX_PERCENTAGE = 1_000_000;\n\n uint256 internal _highTierVWNum;\n uint256 internal _highTierVWDenom;\n\n /// @dev Mapping from mainchain token => the amount thresholds for high-tier withdrawals that requires high-tier vote weights\n mapping(address => uint256) public highTierThreshold;\n /// @dev Mapping from mainchain token => the amount thresholds to lock withdrawal\n mapping(address => uint256) public lockedThreshold;\n /// @dev Mapping from mainchain token => unlock fee percentages for unlocker\n /// @notice Values 0-1,000,000 map to 0%-100%\n mapping(address => uint256) public unlockFeePercentages;\n /// @dev Mapping from mainchain token => daily limit amount for withdrawal\n mapping(address => uint256) public dailyWithdrawalLimit;\n /// @dev Mapping from token address => today withdrawal amount\n mapping(address => uint256) public lastSyncedWithdrawal;\n /// @dev Mapping from token address => last date synced to record the `lastSyncedWithdrawal`\n mapping(address => uint256) public lastDateSynced;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n */\n uint256[50] private ______gap;\n\n /**\n * @dev Override {GatewayV2-setThreshold}.\n *\n * Requirements:\n * - The high-tier vote weight threshold must equal to or larger than the normal threshold.\n *\n */\n function setThreshold(uint256 _numerator, uint256 _denominator)\n external\n virtual\n override\n onlyAdmin\n returns (uint256 _previousNum, uint256 _previousDenom)\n {\n (_previousNum, _previousDenom) = _setThreshold(_numerator, _denominator);\n _verifyThresholds();\n }\n\n /**\n * @dev Returns the high-tier vote weight threshold.\n */\n function getHighTierVoteWeightThreshold() external view virtual returns (uint256, uint256) {\n return (_highTierVWNum, _highTierVWDenom);\n }\n\n /**\n * @dev Checks whether the `_voteWeight` passes the high-tier vote weight threshold.\n */\n function checkHighTierVoteWeightThreshold(uint256 _voteWeight) external view virtual returns (bool) {\n return _voteWeight * _highTierVWDenom >= _highTierVWNum * validatorContract.totalWeights();\n }\n\n /**\n * @dev Sets high-tier vote weight threshold and returns the old one.\n *\n * Requirements:\n * - The method caller is admin.\n * - The high-tier vote weight threshold must equal to or larger than the normal threshold.\n *\n * Emits the `HighTierVoteWeightThresholdUpdated` event.\n *\n */\n function setHighTierVoteWeightThreshold(uint256 _numerator, uint256 _denominator)\n external\n virtual\n onlyAdmin\n returns (uint256 _previousNum, uint256 _previousDenom)\n {\n (_previousNum, _previousDenom) = _setHighTierVoteWeightThreshold(_numerator, _denominator);\n _verifyThresholds();\n }\n\n /**\n * @dev Sets the thresholds for high-tier withdrawals that requires high-tier vote weights.\n *\n * Requirements:\n * - The method caller is admin.\n * - The arrays have the same length and its length larger than 0.\n *\n * Emits the `HighTierThresholdsUpdated` event.\n *\n */\n function setHighTierThresholds(address[] calldata _tokens, uint256[] calldata _thresholds)\n external\n virtual\n onlyAdmin\n {\n require(_tokens.length > 0, \"WithdrawalLimitation: invalid array length\");\n _setHighTierThresholds(_tokens, _thresholds);\n }\n\n /**\n * @dev Sets the amount thresholds to lock withdrawal.\n *\n * Requirements:\n * - The method caller is admin.\n * - The arrays have the same length and its length larger than 0.\n *\n * Emits the `LockedThresholdsUpdated` event.\n *\n */\n function setLockedThresholds(address[] calldata _tokens, uint256[] calldata _thresholds) external virtual onlyAdmin {\n require(_tokens.length > 0, \"WithdrawalLimitation: invalid array length\");\n _setLockedThresholds(_tokens, _thresholds);\n }\n\n /**\n * @dev Sets fee percentages to unlock withdrawal.\n *\n * Requirements:\n * - The method caller is admin.\n * - The arrays have the same length and its length larger than 0.\n *\n * Emits the `UnlockFeePercentagesUpdated` event.\n *\n */\n function setUnlockFeePercentages(address[] calldata _tokens, uint256[] calldata _percentages)\n external\n virtual\n onlyAdmin\n {\n require(_tokens.length > 0, \"WithdrawalLimitation: invalid array length\");\n _setUnlockFeePercentages(_tokens, _percentages);\n }\n\n /**\n * @dev Sets daily limit amounts for the withdrawals.\n *\n * Requirements:\n * - The method caller is admin.\n * - The arrays have the same length and its length larger than 0.\n *\n * Emits the `DailyWithdrawalLimitsUpdated` event.\n *\n */\n function setDailyWithdrawalLimits(address[] calldata _tokens, uint256[] calldata _limits) external virtual onlyAdmin {\n require(_tokens.length > 0, \"WithdrawalLimitation: invalid array length\");\n _setDailyWithdrawalLimits(_tokens, _limits);\n }\n\n /**\n * @dev Checks whether the withdrawal reaches the limitation.\n */\n function reachedWithdrawalLimit(address _token, uint256 _quantity) external view virtual returns (bool) {\n return _reachedWithdrawalLimit(_token, _quantity);\n }\n\n /**\n * @dev Sets high-tier vote weight threshold and returns the old one.\n *\n * Emits the `HighTierVoteWeightThresholdUpdated` event.\n *\n */\n function _setHighTierVoteWeightThreshold(uint256 _numerator, uint256 _denominator)\n internal\n returns (uint256 _previousNum, uint256 _previousDenom)\n {\n require(_numerator <= _denominator, \"WithdrawalLimitation: invalid threshold\");\n _previousNum = _highTierVWNum;\n _previousDenom = _highTierVWDenom;\n _highTierVWNum = _numerator;\n _highTierVWDenom = _denominator;\n emit HighTierVoteWeightThresholdUpdated(nonce++, _numerator, _denominator, _previousNum, _previousDenom);\n }\n\n /**\n * @dev Sets the thresholds for high-tier withdrawals that requires high-tier vote weights.\n *\n * Requirements:\n * - The array lengths are equal.\n *\n * Emits the `HighTierThresholdsUpdated` event.\n *\n */\n function _setHighTierThresholds(address[] calldata _tokens, uint256[] calldata _thresholds) internal virtual {\n require(_tokens.length == _thresholds.length, \"WithdrawalLimitation: invalid array length\");\n for (uint256 _i; _i < _tokens.length; _i++) {\n highTierThreshold[_tokens[_i]] = _thresholds[_i];\n }\n emit HighTierThresholdsUpdated(_tokens, _thresholds);\n }\n\n /**\n * @dev Sets the amount thresholds to lock withdrawal.\n *\n * Requirements:\n * - The array lengths are equal.\n *\n * Emits the `LockedThresholdsUpdated` event.\n *\n */\n function _setLockedThresholds(address[] calldata _tokens, uint256[] calldata _thresholds) internal virtual {\n require(_tokens.length == _thresholds.length, \"WithdrawalLimitation: invalid array length\");\n for (uint256 _i; _i < _tokens.length; _i++) {\n lockedThreshold[_tokens[_i]] = _thresholds[_i];\n }\n emit LockedThresholdsUpdated(_tokens, _thresholds);\n }\n\n /**\n * @dev Sets fee percentages to unlock withdrawal.\n *\n * Requirements:\n * - The array lengths are equal.\n * - The percentage is equal to or less than 100_000.\n *\n * Emits the `UnlockFeePercentagesUpdated` event.\n *\n */\n function _setUnlockFeePercentages(address[] calldata _tokens, uint256[] calldata _percentages) internal virtual {\n require(_tokens.length == _percentages.length, \"WithdrawalLimitation: invalid array length\");\n for (uint256 _i; _i < _tokens.length; _i++) {\n require(_percentages[_i] <= _MAX_PERCENTAGE, \"WithdrawalLimitation: invalid percentage\");\n unlockFeePercentages[_tokens[_i]] = _percentages[_i];\n }\n emit UnlockFeePercentagesUpdated(_tokens, _percentages);\n }\n\n /**\n * @dev Sets daily limit amounts for the withdrawals.\n *\n * Requirements:\n * - The array lengths are equal.\n *\n * Emits the `DailyWithdrawalLimitsUpdated` event.\n *\n */\n function _setDailyWithdrawalLimits(address[] calldata _tokens, uint256[] calldata _limits) internal virtual {\n require(_tokens.length == _limits.length, \"WithdrawalLimitation: invalid array length\");\n for (uint256 _i; _i < _tokens.length; _i++) {\n dailyWithdrawalLimit[_tokens[_i]] = _limits[_i];\n }\n emit DailyWithdrawalLimitsUpdated(_tokens, _limits);\n }\n\n /**\n * @dev Checks whether the withdrawal reaches the daily limitation.\n *\n * Requirements:\n * - The daily withdrawal threshold should not apply for locked withdrawals.\n *\n */\n function _reachedWithdrawalLimit(address _token, uint256 _quantity) internal view virtual returns (bool) {\n if (_lockedWithdrawalRequest(_token, _quantity)) {\n return false;\n }\n\n uint256 _currentDate = block.timestamp / 1 days;\n if (_currentDate > lastDateSynced[_token]) {\n return dailyWithdrawalLimit[_token] <= _quantity;\n } else {\n return dailyWithdrawalLimit[_token] <= lastSyncedWithdrawal[_token] + _quantity;\n }\n }\n\n /**\n * @dev Record withdrawal token.\n */\n function _recordWithdrawal(address _token, uint256 _quantity) internal virtual {\n uint256 _currentDate = block.timestamp / 1 days;\n if (_currentDate > lastDateSynced[_token]) {\n lastDateSynced[_token] = _currentDate;\n lastSyncedWithdrawal[_token] = _quantity;\n } else {\n lastSyncedWithdrawal[_token] += _quantity;\n }\n }\n\n /**\n * @dev Returns whether the withdrawal request is locked or not.\n */\n function _lockedWithdrawalRequest(address _token, uint256 _quantity) internal view virtual returns (bool) {\n return lockedThreshold[_token] <= _quantity;\n }\n\n /**\n * @dev Computes fee percentage.\n */\n function _computeFeePercentage(uint256 _amount, uint256 _percentage) internal view virtual returns (uint256) {\n return (_amount * _percentage) / _MAX_PERCENTAGE;\n }\n\n /**\n * @dev Returns high-tier vote weight.\n */\n function _highTierVoteWeight(uint256 _totalWeight) internal view virtual returns (uint256) {\n return (_highTierVWNum * _totalWeight + _highTierVWDenom - 1) / _highTierVWDenom;\n }\n\n /**\n * @dev Validates whether the high-tier vote weight threshold is larger than the normal threshold.\n */\n function _verifyThresholds() internal view {\n require(_num * _highTierVWDenom <= _highTierVWNum * _denom, \"WithdrawalLimitation: invalid thresholds\");\n }\n}\n" - }, - "contracts/v0.8/interfaces/MappedTokenConsumer.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"../library/Token.sol\";\n\ninterface MappedTokenConsumer {\n struct MappedToken {\n Token.Standard erc;\n address tokenAddr;\n }\n}\n" - }, - "contracts/v0.8/library/Token.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"../interfaces/IWETH.sol\";\n\nlibrary Token {\n enum Standard {\n ERC20,\n ERC721\n }\n struct Info {\n Standard erc;\n // For ERC20: the id must be 0 and the quantity is larger than 0.\n // For ERC721: the quantity must be 0.\n uint256 id;\n uint256 quantity;\n }\n\n // keccak256(\"TokenInfo(uint8 erc,uint256 id,uint256 quantity)\");\n bytes32 public constant INFO_TYPE_HASH = 0x1e2b74b2a792d5c0f0b6e59b037fa9d43d84fbb759337f0112fcc15ca414fc8d;\n\n /**\n * @dev Returns token info struct hash.\n */\n function hash(Info memory _info) internal pure returns (bytes32) {\n return keccak256(abi.encode(INFO_TYPE_HASH, _info.erc, _info.id, _info.quantity));\n }\n\n /**\n * @dev Validates the token info.\n */\n function validate(Info memory _info) internal pure {\n require(\n (_info.erc == Standard.ERC20 && _info.quantity > 0 && _info.id == 0) ||\n (_info.erc == Standard.ERC721 && _info.quantity == 0),\n \"Token: invalid info\"\n );\n }\n\n /**\n * @dev Transfer asset from.\n *\n * Requirements:\n * - The `_from` address must approve for the contract using this library.\n *\n */\n function transferFrom(\n Info memory _info,\n address _from,\n address _to,\n address _token\n ) internal {\n bool _success;\n bytes memory _data;\n if (_info.erc == Standard.ERC20) {\n (_success, _data) = _token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, _from, _to, _info.quantity));\n _success = _success && (_data.length == 0 || abi.decode(_data, (bool)));\n } else if (_info.erc == Standard.ERC721) {\n // bytes4(keccak256(\"transferFrom(address,address,uint256)\"))\n (_success, ) = _token.call(abi.encodeWithSelector(0x23b872dd, _from, _to, _info.id));\n } else {\n revert(\"Token: unsupported token standard\");\n }\n\n if (!_success) {\n revert(\n string(\n abi.encodePacked(\n \"Token: could not transfer \",\n toString(_info),\n \" from \",\n Strings.toHexString(uint160(_from), 20),\n \" to \",\n Strings.toHexString(uint160(_to), 20),\n \" token \",\n Strings.toHexString(uint160(_token), 20)\n )\n )\n );\n }\n }\n\n /**\n * @dev Transfers ERC721 token and returns the result.\n */\n function tryTransferERC721(\n address _token,\n address _to,\n uint256 _id\n ) internal returns (bool _success) {\n (_success, ) = _token.call(abi.encodeWithSelector(IERC721.transferFrom.selector, address(this), _to, _id));\n }\n\n /**\n * @dev Transfers ERC20 token and returns the result.\n */\n function tryTransferERC20(\n address _token,\n address _to,\n uint256 _quantity\n ) internal returns (bool _success) {\n bytes memory _data;\n (_success, _data) = _token.call(abi.encodeWithSelector(IERC20.transfer.selector, _to, _quantity));\n _success = _success && (_data.length == 0 || abi.decode(_data, (bool)));\n }\n\n /**\n * @dev Transfer assets from current address to `_to` address.\n */\n function transfer(\n Info memory _info,\n address _to,\n address _token\n ) internal {\n bool _success;\n if (_info.erc == Standard.ERC20) {\n _success = tryTransferERC20(_token, _to, _info.quantity);\n } else if (_info.erc == Standard.ERC721) {\n _success = tryTransferERC721(_token, _to, _info.id);\n } else {\n revert(\"Token: unsupported token standard\");\n }\n\n if (!_success) {\n revert(\n string(\n abi.encodePacked(\n \"Token: could not transfer \",\n toString(_info),\n \" to \",\n Strings.toHexString(uint160(_to), 20),\n \" token \",\n Strings.toHexString(uint160(_token), 20)\n )\n )\n );\n }\n }\n\n /**\n * @dev Tries minting and transfering assets.\n *\n * @notice Prioritizes transfer native token if the token is wrapped.\n *\n */\n function handleAssetTransfer(\n Info memory _info,\n address payable _to,\n address _token,\n IWETH _wrappedNativeToken\n ) internal {\n bool _success;\n if (_token == address(_wrappedNativeToken)) {\n // Try sending the native token before transferring the wrapped token\n if (!_to.send(_info.quantity)) {\n _wrappedNativeToken.deposit{ value: _info.quantity }();\n transfer(_info, _to, _token);\n }\n } else if (_info.erc == Token.Standard.ERC20) {\n uint256 _balance = IERC20(_token).balanceOf(address(this));\n\n if (_balance < _info.quantity) {\n // bytes4(keccak256(\"mint(address,uint256)\"))\n (_success, ) = _token.call(abi.encodeWithSelector(0x40c10f19, address(this), _info.quantity - _balance));\n require(_success, \"Token: ERC20 minting failed\");\n }\n\n transfer(_info, _to, _token);\n } else if (_info.erc == Token.Standard.ERC721) {\n if (!tryTransferERC721(_token, _to, _info.id)) {\n // bytes4(keccak256(\"mint(address,uint256)\"))\n (_success, ) = _token.call(abi.encodeWithSelector(0x40c10f19, _to, _info.id));\n require(_success, \"Token: ERC721 minting failed\");\n }\n } else {\n revert(\"Token: unsupported token standard\");\n }\n }\n\n /**\n * @dev Returns readable string.\n */\n function toString(Info memory _info) internal pure returns (string memory) {\n return\n string(\n abi.encodePacked(\n \"TokenInfo(\",\n Strings.toHexString(uint160(_info.erc), 1),\n \",\",\n Strings.toHexString(_info.id),\n \",\",\n Strings.toHexString(_info.quantity),\n \")\"\n )\n );\n }\n\n struct Owner {\n address addr;\n address tokenAddr;\n uint256 chainId;\n }\n\n // keccak256(\"TokenOwner(address addr,address tokenAddr,uint256 chainId)\");\n bytes32 public constant OWNER_TYPE_HASH = 0x353bdd8d69b9e3185b3972e08b03845c0c14a21a390215302776a7a34b0e8764;\n\n /**\n * @dev Returns ownership struct hash.\n */\n function hash(Owner memory _owner) internal pure returns (bytes32) {\n return keccak256(abi.encode(OWNER_TYPE_HASH, _owner.addr, _owner.tokenAddr, _owner.chainId));\n }\n}\n" - }, - "contracts/v0.8/mainchain/IMainchainGatewayV2.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"../interfaces/IWETH.sol\";\nimport \"../library/Transfer.sol\";\nimport \"../interfaces/SignatureConsumer.sol\";\nimport \"../interfaces/MappedTokenConsumer.sol\";\n\ninterface IMainchainGatewayV2 is SignatureConsumer, MappedTokenConsumer {\n /// @dev Emitted when the deposit is requested\n event DepositRequested(bytes32 receiptHash, Transfer.Receipt receipt);\n /// @dev Emitted when the assets are withdrawn\n event Withdrew(bytes32 receiptHash, Transfer.Receipt receipt);\n /// @dev Emitted when the tokens are mapped\n event TokenMapped(address[] mainchainTokens, address[] roninTokens, Token.Standard[] standards);\n /// @dev Emitted when the wrapped native token contract is updated\n event WrappedNativeTokenContractUpdated(IWETH weth);\n /// @dev Emitted when the withdrawal is locked\n event WithdrawalLocked(bytes32 receiptHash, Transfer.Receipt receipt);\n /// @dev Emitted when the withdrawal is unlocked\n event WithdrawalUnlocked(bytes32 receiptHash, Transfer.Receipt receipt);\n\n /**\n * @dev Returns the domain seperator.\n */\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n\n /**\n * @dev Returns deposit count.\n */\n function depositCount() external view returns (uint256);\n\n /**\n * @dev Sets the wrapped native token contract.\n *\n * Requirements:\n * - The method caller is admin.\n *\n * Emits the `WrappedNativeTokenContractUpdated` event.\n *\n */\n function setWrappedNativeTokenContract(IWETH _wrappedToken) external;\n\n /**\n * @dev Returns whether the withdrawal is locked.\n */\n function withdrawalLocked(uint256 withdrawalId) external view returns (bool);\n\n /**\n * @dev Returns the withdrawal hash.\n */\n function withdrawalHash(uint256 withdrawalId) external view returns (bytes32);\n\n /**\n * @dev Locks the assets and request deposit.\n */\n function requestDepositFor(Transfer.Request calldata _request) external payable;\n\n /**\n * @dev Withdraws based on the receipt and the validator signatures.\n * Returns whether the withdrawal is locked.\n *\n * Emits the `Withdrew` once the assets are released.\n *\n */\n function submitWithdrawal(Transfer.Receipt memory _receipt, Signature[] memory _signatures)\n external\n returns (bool _locked);\n\n /**\n * @dev Approves a specific withdrawal.\n *\n * Requirements:\n * - The method caller is a validator.\n *\n * Emits the `Withdrew` once the assets are released.\n *\n */\n function unlockWithdrawal(Transfer.Receipt calldata _receipt) external;\n\n /**\n * @dev Maps mainchain tokens to Ronin network.\n *\n * Requirement:\n * - The method caller is admin.\n * - The arrays have the same length and its length larger than 0.\n *\n * Emits the `TokenMapped` event.\n *\n */\n function mapTokens(\n address[] calldata _mainchainTokens,\n address[] calldata _roninTokens,\n Token.Standard[] calldata _standards\n ) external;\n\n /**\n * @dev Maps mainchain tokens to Ronin network and sets thresholds.\n *\n * Requirement:\n * - The method caller is admin.\n * - The arrays have the same length and its length larger than 0.\n *\n * Emits the `TokenMapped` event.\n *\n */\n function mapTokensAndThresholds(\n address[] calldata _mainchainTokens,\n address[] calldata _roninTokens,\n Token.Standard[] calldata _standards,\n uint256[][4] calldata _thresholds\n ) external;\n\n /**\n * @dev Returns token address on Ronin network.\n * @notice Reverts for unsupported token.\n */\n function getRoninToken(address _mainchainToken) external view returns (MappedToken memory _token);\n}\n" - }, - "contracts/v0.8/mainchain/MainchainGatewayV2.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/access/AccessControlEnumerable.sol\";\nimport \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport \"../extensions/GatewayV2.sol\";\nimport \"../extensions/WithdrawalLimitation.sol\";\nimport \"../library/Transfer.sol\";\nimport \"./IMainchainGatewayV2.sol\";\n\ncontract MainchainGatewayV2 is WithdrawalLimitation, Initializable, AccessControlEnumerable, IMainchainGatewayV2 {\n using Token for Token.Info;\n using Transfer for Transfer.Request;\n using Transfer for Transfer.Receipt;\n\n /// @dev Withdrawal unlocker role hash\n bytes32 public constant WITHDRAWAL_UNLOCKER_ROLE = keccak256(\"WITHDRAWAL_UNLOCKER_ROLE\");\n\n /// @dev Wrapped native token address\n IWETH public wrappedNativeToken;\n /// @dev Ronin network id\n uint256 public roninChainId;\n /// @dev Total deposit\n uint256 public depositCount;\n /// @dev Domain seperator\n bytes32 internal _domainSeparator;\n /// @dev Mapping from mainchain token => token address on Ronin network\n mapping(address => MappedToken) internal _roninToken;\n /// @dev Mapping from withdrawal id => withdrawal hash\n mapping(uint256 => bytes32) public withdrawalHash;\n /// @dev Mapping from withdrawal id => locked\n mapping(uint256 => bool) public withdrawalLocked;\n\n fallback() external payable {\n _fallback();\n }\n\n receive() external payable {\n _fallback();\n }\n\n /**\n * @dev Initializes contract storage.\n */\n function initialize(\n address _roleSetter,\n IWETH _wrappedToken,\n IWeightedValidator _validatorContract,\n uint256 _roninChainId,\n uint256 _numerator,\n uint256 _highTierVWNumerator,\n uint256 _denominator,\n // _addresses[0]: mainchainTokens\n // _addresses[1]: roninTokens\n // _addresses[2]: withdrawalUnlockers\n address[][3] calldata _addresses,\n // _thresholds[0]: highTierThreshold\n // _thresholds[1]: lockedThreshold\n // _thresholds[2]: unlockFeePercentages\n // _thresholds[3]: dailyWithdrawalLimit\n uint256[][4] calldata _thresholds,\n Token.Standard[] calldata _standards\n ) external payable virtual initializer {\n _setupRole(DEFAULT_ADMIN_ROLE, _roleSetter);\n roninChainId = _roninChainId;\n\n _setWrappedNativeTokenContract(_wrappedToken);\n _setValidatorContract(_validatorContract);\n _updateDomainSeparator();\n _setThreshold(_numerator, _denominator);\n _setHighTierVoteWeightThreshold(_highTierVWNumerator, _denominator);\n _verifyThresholds();\n\n if (_addresses[0].length > 0) {\n // Map mainchain tokens to ronin tokens\n _mapTokens(_addresses[0], _addresses[1], _standards);\n // Sets thresholds based on the mainchain tokens\n _setHighTierThresholds(_addresses[0], _thresholds[0]);\n _setLockedThresholds(_addresses[0], _thresholds[1]);\n _setUnlockFeePercentages(_addresses[0], _thresholds[2]);\n _setDailyWithdrawalLimits(_addresses[0], _thresholds[3]);\n }\n\n // Grant role for withdrawal unlocker\n for (uint256 _i; _i < _addresses[2].length; _i++) {\n _grantRole(WITHDRAWAL_UNLOCKER_ROLE, _addresses[2][_i]);\n }\n }\n\n /**\n * @dev Receives ether without doing anything. Use this function to topup native token.\n */\n function receiveEther() external payable {}\n\n /**\n * @dev See {IMainchainGatewayV2-DOMAIN_SEPARATOR}.\n */\n function DOMAIN_SEPARATOR() external view virtual returns (bytes32) {\n return _domainSeparator;\n }\n\n /**\n * @dev See {IMainchainGatewayV2-setWrappedNativeTokenContract}.\n */\n function setWrappedNativeTokenContract(IWETH _wrappedToken) external virtual onlyAdmin {\n _setWrappedNativeTokenContract(_wrappedToken);\n }\n\n /**\n * @dev See {IMainchainGatewayV2-requestDepositFor}.\n */\n function requestDepositFor(Transfer.Request calldata _request) external payable virtual whenNotPaused {\n _requestDepositFor(_request, msg.sender);\n }\n\n /**\n * @dev See {IMainchainGatewayV2-submitWithdrawal}.\n */\n function submitWithdrawal(Transfer.Receipt calldata _receipt, Signature[] calldata _signatures)\n external\n virtual\n whenNotPaused\n returns (bool _locked)\n {\n return _submitWithdrawal(_receipt, _signatures);\n }\n\n /**\n * @dev See {IMainchainGatewayV2-unlockWithdrawal}.\n */\n function unlockWithdrawal(Transfer.Receipt calldata _receipt) external onlyRole(WITHDRAWAL_UNLOCKER_ROLE) {\n bytes32 _receiptHash = _receipt.hash();\n require(withdrawalHash[_receipt.id] == _receipt.hash(), \"MainchainGatewayV2: invalid receipt\");\n require(withdrawalLocked[_receipt.id], \"MainchainGatewayV2: query for approved withdrawal\");\n delete withdrawalLocked[_receipt.id];\n emit WithdrawalUnlocked(_receiptHash, _receipt);\n\n address _token = _receipt.mainchain.tokenAddr;\n if (_receipt.info.erc == Token.Standard.ERC20) {\n Token.Info memory _feeInfo = _receipt.info;\n _feeInfo.quantity = _computeFeePercentage(_receipt.info.quantity, unlockFeePercentages[_token]);\n Token.Info memory _withdrawInfo = _receipt.info;\n _withdrawInfo.quantity = _receipt.info.quantity - _feeInfo.quantity;\n\n _feeInfo.handleAssetTransfer(payable(msg.sender), _token, wrappedNativeToken);\n _withdrawInfo.handleAssetTransfer(payable(_receipt.mainchain.addr), _token, wrappedNativeToken);\n } else {\n _receipt.info.handleAssetTransfer(payable(_receipt.mainchain.addr), _token, wrappedNativeToken);\n }\n\n emit Withdrew(_receiptHash, _receipt);\n }\n\n /**\n * @dev See {IMainchainGatewayV2-mapTokens}.\n */\n function mapTokens(\n address[] calldata _mainchainTokens,\n address[] calldata _roninTokens,\n Token.Standard[] calldata _standards\n ) external virtual onlyAdmin {\n require(_mainchainTokens.length > 0, \"MainchainGatewayV2: query for empty array\");\n _mapTokens(_mainchainTokens, _roninTokens, _standards);\n }\n\n /**\n * @dev See {IMainchainGatewayV2-mapTokensAndThresholds}.\n */\n function mapTokensAndThresholds(\n address[] calldata _mainchainTokens,\n address[] calldata _roninTokens,\n Token.Standard[] calldata _standards,\n // _thresholds[0]: highTierThreshold\n // _thresholds[1]: lockedThreshold\n // _thresholds[2]: unlockFeePercentages\n // _thresholds[3]: dailyWithdrawalLimit\n uint256[][4] calldata _thresholds\n ) external virtual onlyAdmin {\n require(_mainchainTokens.length > 0, \"MainchainGatewayV2: query for empty array\");\n _mapTokens(_mainchainTokens, _roninTokens, _standards);\n _setHighTierThresholds(_mainchainTokens, _thresholds[0]);\n _setLockedThresholds(_mainchainTokens, _thresholds[1]);\n _setUnlockFeePercentages(_mainchainTokens, _thresholds[2]);\n _setDailyWithdrawalLimits(_mainchainTokens, _thresholds[3]);\n }\n\n /**\n * @dev See {IMainchainGatewayV2-getRoninToken}.\n */\n function getRoninToken(address _mainchainToken) public view returns (MappedToken memory _token) {\n _token = _roninToken[_mainchainToken];\n require(_token.tokenAddr != address(0), \"MainchainGatewayV2: unsupported token\");\n }\n\n /**\n * @dev Maps mainchain tokens to Ronin network.\n *\n * Requirement:\n * - The arrays have the same length.\n *\n * Emits the `TokenMapped` event.\n *\n */\n function _mapTokens(\n address[] calldata _mainchainTokens,\n address[] calldata _roninTokens,\n Token.Standard[] calldata _standards\n ) internal virtual {\n require(\n _mainchainTokens.length == _roninTokens.length && _mainchainTokens.length == _standards.length,\n \"MainchainGatewayV2: invalid array length\"\n );\n\n for (uint256 _i; _i < _mainchainTokens.length; _i++) {\n _roninToken[_mainchainTokens[_i]].tokenAddr = _roninTokens[_i];\n _roninToken[_mainchainTokens[_i]].erc = _standards[_i];\n }\n\n emit TokenMapped(_mainchainTokens, _roninTokens, _standards);\n }\n\n /**\n * @dev Submits withdrawal receipt.\n *\n * Requirements:\n * - The receipt kind is withdrawal.\n * - The receipt is to withdraw on this chain.\n * - The receipt is not used to withdraw before.\n * - The withdrawal is not reached the limit threshold.\n * - The signer weight total is larger than or equal to the minimum threshold.\n * - The signature signers are in order.\n *\n * Emits the `Withdrew` once the assets are released.\n *\n */\n function _submitWithdrawal(Transfer.Receipt calldata _receipt, Signature[] memory _signatures)\n internal\n virtual\n returns (bool _locked)\n {\n uint256 _id = _receipt.id;\n uint256 _quantity = _receipt.info.quantity;\n address _tokenAddr = _receipt.mainchain.tokenAddr;\n\n _receipt.info.validate();\n require(_receipt.kind == Transfer.Kind.Withdrawal, \"MainchainGatewayV2: invalid receipt kind\");\n require(_receipt.mainchain.chainId == block.chainid, \"MainchainGatewayV2: invalid chain id\");\n MappedToken memory _token = getRoninToken(_receipt.mainchain.tokenAddr);\n require(\n _token.erc == _receipt.info.erc && _token.tokenAddr == _receipt.ronin.tokenAddr,\n \"MainchainGatewayV2: invalid receipt\"\n );\n require(withdrawalHash[_id] == bytes32(0), \"MainchainGatewayV2: query for processed withdrawal\");\n require(\n _receipt.info.erc == Token.Standard.ERC721 || !_reachedWithdrawalLimit(_tokenAddr, _quantity),\n \"MainchainGatewayV2: reached daily withdrawal limit\"\n );\n\n bytes32 _receiptHash = _receipt.hash();\n bytes32 _receiptDigest = Transfer.receiptDigest(_domainSeparator, _receiptHash);\n IWeightedValidator _validatorContract = validatorContract;\n\n uint256 _minimumVoteWeight;\n (_minimumVoteWeight, _locked) = _computeMinVoteWeight(_receipt.info.erc, _tokenAddr, _quantity, _validatorContract);\n\n {\n bool _passed;\n address _signer;\n address _lastSigner;\n Signature memory _sig;\n uint256 _weight;\n for (uint256 _i; _i < _signatures.length; _i++) {\n _sig = _signatures[_i];\n _signer = ecrecover(_receiptDigest, _sig.v, _sig.r, _sig.s);\n require(_lastSigner < _signer, \"MainchainGatewayV2: invalid order\");\n _lastSigner = _signer;\n\n _weight += _validatorContract.getValidatorWeight(_signer);\n if (_weight >= _minimumVoteWeight) {\n _passed = true;\n break;\n }\n }\n require(_passed, \"MainchainGatewayV2: query for insufficient vote weight\");\n withdrawalHash[_id] = _receiptHash;\n }\n\n if (_locked) {\n withdrawalLocked[_id] = true;\n emit WithdrawalLocked(_receiptHash, _receipt);\n return _locked;\n }\n\n _recordWithdrawal(_tokenAddr, _quantity);\n _receipt.info.handleAssetTransfer(payable(_receipt.mainchain.addr), _tokenAddr, wrappedNativeToken);\n emit Withdrew(_receiptHash, _receipt);\n }\n\n /**\n * @dev Requests deposit made by `_requester` address.\n *\n * Requirements:\n * - The token info is valid.\n * - The `msg.value` is 0 while depositing ERC20 token.\n * - The `msg.value` is equal to deposit quantity while depositing native token.\n *\n * Emits the `DepositRequested` event.\n *\n */\n function _requestDepositFor(Transfer.Request memory _request, address _requester) internal virtual {\n MappedToken memory _token;\n address _weth = address(wrappedNativeToken);\n\n _request.info.validate();\n if (_request.tokenAddr == address(0)) {\n require(_request.info.quantity == msg.value, \"MainchainGatewayV2: invalid request\");\n _token = getRoninToken(_weth);\n require(_token.erc == _request.info.erc, \"MainchainGatewayV2: invalid token standard\");\n _request.tokenAddr = _weth;\n } else {\n require(msg.value == 0, \"MainchainGatewayV2: invalid request\");\n _token = getRoninToken(_request.tokenAddr);\n require(_token.erc == _request.info.erc, \"MainchainGatewayV2: invalid token standard\");\n _request.info.transferFrom(_requester, address(this), _request.tokenAddr);\n // Withdraw if token is WETH\n if (_weth == _request.tokenAddr) {\n IWETH(_weth).withdraw(_request.info.quantity);\n }\n }\n\n uint256 _depositId = depositCount++;\n Transfer.Receipt memory _receipt = _request.into_deposit_receipt(\n _requester,\n _depositId,\n _token.tokenAddr,\n roninChainId\n );\n\n emit DepositRequested(_receipt.hash(), _receipt);\n }\n\n /**\n * @dev Returns the minimum vote weight for the token.\n */\n function _computeMinVoteWeight(\n Token.Standard _erc,\n address _token,\n uint256 _quantity,\n IWeightedValidator _validatorContract\n ) internal virtual returns (uint256 _weight, bool _locked) {\n uint256 _totalWeights = _validatorContract.totalWeights();\n _weight = _minimumVoteWeight(_totalWeights);\n if (_erc == Token.Standard.ERC20) {\n if (highTierThreshold[_token] <= _quantity) {\n _weight = _highTierVoteWeight(_totalWeights);\n }\n _locked = _lockedWithdrawalRequest(_token, _quantity);\n }\n }\n\n /**\n * @dev Update domain seperator.\n */\n function _updateDomainSeparator() internal {\n _domainSeparator = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(\"MainchainGatewayV2\"),\n keccak256(\"2\"),\n block.chainid,\n address(this)\n )\n );\n }\n\n /**\n * @dev Sets the WETH contract.\n *\n * Emits the `WrappedNativeTokenContractUpdated` event.\n *\n */\n function _setWrappedNativeTokenContract(IWETH _wrapedToken) internal {\n wrappedNativeToken = _wrapedToken;\n emit WrappedNativeTokenContractUpdated(_wrapedToken);\n }\n\n /**\n * @dev Receives ETH from WETH or creates deposit request.\n */\n function _fallback() internal virtual whenNotPaused {\n if (msg.sender != address(wrappedNativeToken)) {\n Transfer.Request memory _request;\n _request.recipientAddr = msg.sender;\n _request.info.quantity = msg.value;\n _requestDepositFor(_request, _request.recipientAddr);\n }\n }\n}\n" - }, - "contracts/v0.8/interfaces/IWeightedValidator.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./IQuorum.sol\";\n\ninterface IWeightedValidator is IQuorum {\n struct WeightedValidator {\n address validator;\n address governor;\n uint256 weight;\n }\n\n /// @dev Emitted when the validators are added\n event ValidatorsAdded(uint256 indexed nonce, WeightedValidator[] validators);\n /// @dev Emitted when the validators are updated\n event ValidatorsUpdated(uint256 indexed nonce, WeightedValidator[] validators);\n /// @dev Emitted when the validators are removed\n event ValidatorsRemoved(uint256 indexed nonce, address[] validators);\n\n /**\n * @dev Returns validator weight of the validator.\n */\n function getValidatorWeight(address _addr) external view returns (uint256);\n\n /**\n * @dev Returns governor weight of the governor.\n */\n function getGovernorWeight(address _addr) external view returns (uint256);\n\n /**\n * @dev Returns total validator weights of the address list.\n */\n function sumValidatorWeights(address[] calldata _addrList) external view returns (uint256 _weight);\n\n /**\n * @dev Returns total governor weights of the address list.\n */\n function sumGovernorWeights(address[] calldata _addrList) external view returns (uint256 _weight);\n\n /**\n * @dev Returns the validator list attached with governor address and weight.\n */\n function getValidatorInfo() external view returns (WeightedValidator[] memory _list);\n\n /**\n * @dev Returns the validator list.\n */\n function getValidators() external view returns (address[] memory _validators);\n\n /**\n * @dev Returns the validator at `_index` position.\n */\n function validators(uint256 _index) external view returns (WeightedValidator memory);\n\n /**\n * @dev Returns total of validators.\n */\n function totalValidators() external view returns (uint256);\n\n /**\n * @dev Returns total weights.\n */\n function totalWeights() external view returns (uint256);\n\n /**\n * @dev Adds validators.\n *\n * Requirements:\n * - The weights are larger than 0.\n * - The validators are not added.\n * - The method caller is admin.\n *\n * Emits the `ValidatorsAdded` event.\n *\n */\n function addValidators(WeightedValidator[] calldata _validators) external;\n\n /**\n * @dev Updates validators.\n *\n * Requirements:\n * - The weights are larger than 0.\n * - The validators are added.\n * - The method caller is admin.\n *\n * Emits the `ValidatorsUpdated` event.\n *\n */\n function updateValidators(WeightedValidator[] calldata _validators) external;\n\n /**\n * @dev Removes validators.\n *\n * Requirements:\n * - The validators are added.\n * - The method caller is admin.\n *\n * Emits the `ValidatorsRemoved` event.\n *\n */\n function removeValidators(address[] calldata _validators) external;\n}\n" - }, - "contracts/v0.8/extensions/HasProxyAdmin.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/utils/StorageSlot.sol\";\n\nabstract contract HasProxyAdmin {\n // bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n modifier onlyAdmin() {\n require(msg.sender == _getAdmin(), \"HasProxyAdmin: unauthorized sender\");\n _;\n }\n\n /**\n * @dev Returns proxy admin.\n */\n function _getAdmin() internal view returns (address) {\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n }\n}\n" - }, - "@openzeppelin/contracts/utils/introspection/IERC165.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" - }, - "contracts/v0.8/interfaces/SignatureConsumer.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface SignatureConsumer {\n struct Signature {\n uint8 v;\n bytes32 r;\n bytes32 s;\n }\n}\n" - }, - "@openzeppelin/contracts/utils/Strings.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n" - }, - "@openzeppelin/contracts/utils/introspection/ERC165.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" - }, - "@openzeppelin/contracts/access/AccessControlEnumerable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerable.sol\";\nimport \"./AccessControl.sol\";\nimport \"../utils/structs/EnumerableSet.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n}\n" - }, - "contracts/v0.8/library/Transfer.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"./Token.sol\";\n\nlibrary Transfer {\n using ECDSA for bytes32;\n\n enum Kind {\n Deposit,\n Withdrawal\n }\n\n struct Request {\n // For deposit request: Recipient address on Ronin network\n // For withdrawal request: Recipient address on mainchain network\n address recipientAddr;\n // Token address to deposit/withdraw\n // Value 0: native token\n address tokenAddr;\n Token.Info info;\n }\n\n /**\n * @dev Converts the transfer request into the deposit receipt.\n */\n function into_deposit_receipt(\n Request memory _request,\n address _requester,\n uint256 _id,\n address _roninTokenAddr,\n uint256 _roninChainId\n ) internal view returns (Receipt memory _receipt) {\n _receipt.id = _id;\n _receipt.kind = Kind.Deposit;\n _receipt.mainchain.addr = _requester;\n _receipt.mainchain.tokenAddr = _request.tokenAddr;\n _receipt.mainchain.chainId = block.chainid;\n _receipt.ronin.addr = _request.recipientAddr;\n _receipt.ronin.tokenAddr = _roninTokenAddr;\n _receipt.ronin.chainId = _roninChainId;\n _receipt.info = _request.info;\n }\n\n /**\n * @dev Converts the transfer request into the withdrawal receipt.\n */\n function into_withdrawal_receipt(\n Request memory _request,\n address _requester,\n uint256 _id,\n address _mainchainTokenAddr,\n uint256 _mainchainId\n ) internal view returns (Receipt memory _receipt) {\n _receipt.id = _id;\n _receipt.kind = Kind.Withdrawal;\n _receipt.ronin.addr = _requester;\n _receipt.ronin.tokenAddr = _request.tokenAddr;\n _receipt.ronin.chainId = block.chainid;\n _receipt.mainchain.addr = _request.recipientAddr;\n _receipt.mainchain.tokenAddr = _mainchainTokenAddr;\n _receipt.mainchain.chainId = _mainchainId;\n _receipt.info = _request.info;\n }\n\n struct Receipt {\n uint256 id;\n Kind kind;\n Token.Owner mainchain;\n Token.Owner ronin;\n Token.Info info;\n }\n\n // keccak256(\"Receipt(uint256 id,uint8 kind,TokenOwner mainchain,TokenOwner ronin,TokenInfo info)TokenInfo(uint8 erc,uint256 id,uint256 quantity)TokenOwner(address addr,address tokenAddr,uint256 chainId)\");\n bytes32 public constant TYPE_HASH = 0xb9d1fe7c9deeec5dc90a2f47ff1684239519f2545b2228d3d91fb27df3189eea;\n\n /**\n * @dev Returns token info struct hash.\n */\n function hash(Receipt memory _receipt) internal pure returns (bytes32) {\n return\n keccak256(\n abi.encode(\n TYPE_HASH,\n _receipt.id,\n _receipt.kind,\n Token.hash(_receipt.mainchain),\n Token.hash(_receipt.ronin),\n Token.hash(_receipt.info)\n )\n );\n }\n\n /**\n * @dev Returns the receipt digest.\n */\n function receiptDigest(bytes32 _domainSeparator, bytes32 _receiptHash) internal pure returns (bytes32) {\n return _domainSeparator.toTypedDataHash(_receiptHash);\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/security/Pausable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n constructor() {\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n require(!paused(), \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n require(paused(), \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n" - }, - "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" - }, - "contracts/v0.8/interfaces/IQuorum.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IQuorum {\n /// @dev Emitted when the threshold is updated\n event ThresholdUpdated(\n uint256 indexed nonce,\n uint256 indexed numerator,\n uint256 indexed denominator,\n uint256 previousNumerator,\n uint256 previousDenominator\n );\n\n /**\n * @dev Returns the threshold.\n */\n function getThreshold() external view returns (uint256 _num, uint256 _denom);\n\n /**\n * @dev Checks whether the `_voteWeight` passes the threshold.\n */\n function checkThreshold(uint256 _voteWeight) external view returns (bool);\n\n /**\n * @dev Returns the minimum vote weight to pass the threshold.\n */\n function minimumVoteWeight() external view returns (uint256);\n\n /**\n * @dev Sets the threshold.\n *\n * Requirements:\n * - The method caller is admin.\n *\n * Emits the `ThresholdUpdated` event.\n *\n */\n function setThreshold(uint256 _numerator, uint256 _denominator)\n external\n returns (uint256 _previousNum, uint256 _previousDenom);\n}\n" - }, - "contracts/v0.8/interfaces/IWETH.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IWETH {\n function deposit() external payable;\n\n function withdraw(uint256 _wad) external;\n\n function balanceOf(address) external view returns (uint256);\n}\n" - }, - "@openzeppelin/contracts/access/AccessControl.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\nimport \"../utils/Context.sol\";\nimport \"../utils/Strings.sol\";\nimport \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role, _msgSender());\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n Strings.toHexString(uint160(account), 20),\n \" is missing role \",\n Strings.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\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/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" - } - }, - "settings": { - "evmVersion": "london", - "libraries": {}, - "metadata": { - "bytecodeHash": "ipfs", - "useLiteralContent": true - }, - "optimizer": { - "enabled": true, - "runs": 1000 - }, - "remappings": [], - "outputSelection": { - "*": { - "*": [ - "evm.bytecode", - "evm.deployedBytecode", - "devdoc", - "userdoc", - "metadata", - "abi" - ] - } - } - } - }, - "ABI": "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"limits\",\"type\":\"uint256[]\"}],\"name\":\"DailyWithdrawalLimitsUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"receiptHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"enum Transfer.Kind\",\"name\":\"kind\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Owner\",\"name\":\"mainchain\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Owner\",\"name\":\"ronin\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"enum Token.Standard\",\"name\":\"erc\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Info\",\"name\":\"info\",\"type\":\"tuple\"}],\"indexed\":false,\"internalType\":\"struct Transfer.Receipt\",\"name\":\"receipt\",\"type\":\"tuple\"}],\"name\":\"DepositRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"thresholds\",\"type\":\"uint256[]\"}],\"name\":\"HighTierThresholdsUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"numerator\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"denominator\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousNumerator\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousDenominator\",\"type\":\"uint256\"}],\"name\":\"HighTierVoteWeightThresholdUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"thresholds\",\"type\":\"uint256[]\"}],\"name\":\"LockedThresholdsUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"previousAdminRole\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"newAdminRole\",\"type\":\"bytes32\"}],\"name\":\"RoleAdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"numerator\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"denominator\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousNumerator\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousDenominator\",\"type\":\"uint256\"}],\"name\":\"ThresholdUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"mainchainTokens\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"roninTokens\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"enum Token.Standard[]\",\"name\":\"standards\",\"type\":\"uint8[]\"}],\"name\":\"TokenMapped\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"percentages\",\"type\":\"uint256[]\"}],\"name\":\"UnlockFeePercentagesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IWeightedValidator\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"ValidatorContractUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"receiptHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"enum Transfer.Kind\",\"name\":\"kind\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Owner\",\"name\":\"mainchain\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Owner\",\"name\":\"ronin\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"enum Token.Standard\",\"name\":\"erc\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Info\",\"name\":\"info\",\"type\":\"tuple\"}],\"indexed\":false,\"internalType\":\"struct Transfer.Receipt\",\"name\":\"receipt\",\"type\":\"tuple\"}],\"name\":\"WithdrawalLocked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"receiptHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"enum Transfer.Kind\",\"name\":\"kind\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Owner\",\"name\":\"mainchain\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Owner\",\"name\":\"ronin\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"enum Token.Standard\",\"name\":\"erc\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Info\",\"name\":\"info\",\"type\":\"tuple\"}],\"indexed\":false,\"internalType\":\"struct Transfer.Receipt\",\"name\":\"receipt\",\"type\":\"tuple\"}],\"name\":\"WithdrawalUnlocked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"receiptHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"enum Transfer.Kind\",\"name\":\"kind\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Owner\",\"name\":\"mainchain\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Owner\",\"name\":\"ronin\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"enum Token.Standard\",\"name\":\"erc\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Info\",\"name\":\"info\",\"type\":\"tuple\"}],\"indexed\":false,\"internalType\":\"struct Transfer.Receipt\",\"name\":\"receipt\",\"type\":\"tuple\"}],\"name\":\"Withdrew\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IWETH\",\"name\":\"weth\",\"type\":\"address\"}],\"name\":\"WrappedNativeTokenContractUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"DEFAULT_ADMIN_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"WITHDRAWAL_UNLOCKER_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"_MAX_PERCENTAGE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_voteWeight\",\"type\":\"uint256\"}],\"name\":\"checkHighTierVoteWeightThreshold\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_voteWeight\",\"type\":\"uint256\"}],\"name\":\"checkThreshold\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"dailyWithdrawalLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"depositCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getHighTierVoteWeightThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleAdmin\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"getRoleMember\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleMemberCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_mainchainToken\",\"type\":\"address\"}],\"name\":\"getRoninToken\",\"outputs\":[{\"components\":[{\"internalType\":\"enum Token.Standard\",\"name\":\"erc\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"}],\"internalType\":\"struct MappedTokenConsumer.MappedToken\",\"name\":\"_token\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"grantRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"hasRole\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"highTierThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_roleSetter\",\"type\":\"address\"},{\"internalType\":\"contract IWETH\",\"name\":\"_wrappedToken\",\"type\":\"address\"},{\"internalType\":\"contract IWeightedValidator\",\"name\":\"_validatorContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_roninChainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_numerator\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_highTierVWNumerator\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_denominator\",\"type\":\"uint256\"},{\"internalType\":\"address[][3]\",\"name\":\"_addresses\",\"type\":\"address[][3]\"},{\"internalType\":\"uint256[][4]\",\"name\":\"_thresholds\",\"type\":\"uint256[][4]\"},{\"internalType\":\"enum Token.Standard[]\",\"name\":\"_standards\",\"type\":\"uint8[]\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"lastDateSynced\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"lastSyncedWithdrawal\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"lockedThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_mainchainTokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"_roninTokens\",\"type\":\"address[]\"},{\"internalType\":\"enum Token.Standard[]\",\"name\":\"_standards\",\"type\":\"uint8[]\"}],\"name\":\"mapTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_mainchainTokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"_roninTokens\",\"type\":\"address[]\"},{\"internalType\":\"enum Token.Standard[]\",\"name\":\"_standards\",\"type\":\"uint8[]\"},{\"internalType\":\"uint256[][4]\",\"name\":\"_thresholds\",\"type\":\"uint256[][4]\"}],\"name\":\"mapTokensAndThresholds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minimumVoteWeight\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_quantity\",\"type\":\"uint256\"}],\"name\":\"reachedWithdrawalLimit\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"receiveEther\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"renounceRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"recipientAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"enum Token.Standard\",\"name\":\"erc\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Info\",\"name\":\"info\",\"type\":\"tuple\"}],\"internalType\":\"struct Transfer.Request\",\"name\":\"_request\",\"type\":\"tuple\"}],\"name\":\"requestDepositFor\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"revokeRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"roninChainId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_tokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_limits\",\"type\":\"uint256[]\"}],\"name\":\"setDailyWithdrawalLimits\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_tokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_thresholds\",\"type\":\"uint256[]\"}],\"name\":\"setHighTierThresholds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_numerator\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_denominator\",\"type\":\"uint256\"}],\"name\":\"setHighTierVoteWeightThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_previousNum\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_previousDenom\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_tokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_thresholds\",\"type\":\"uint256[]\"}],\"name\":\"setLockedThresholds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_numerator\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_denominator\",\"type\":\"uint256\"}],\"name\":\"setThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_previousNum\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_previousDenom\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_tokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_percentages\",\"type\":\"uint256[]\"}],\"name\":\"setUnlockFeePercentages\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IWeightedValidator\",\"name\":\"_validatorContract\",\"type\":\"address\"}],\"name\":\"setValidatorContract\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IWETH\",\"name\":\"_wrappedToken\",\"type\":\"address\"}],\"name\":\"setWrappedNativeTokenContract\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"enum Transfer.Kind\",\"name\":\"kind\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Owner\",\"name\":\"mainchain\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Owner\",\"name\":\"ronin\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"enum Token.Standard\",\"name\":\"erc\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Info\",\"name\":\"info\",\"type\":\"tuple\"}],\"internalType\":\"struct Transfer.Receipt\",\"name\":\"_receipt\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"struct SignatureConsumer.Signature[]\",\"name\":\"_signatures\",\"type\":\"tuple[]\"}],\"name\":\"submitWithdrawal\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"_locked\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"unlockFeePercentages\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"enum Transfer.Kind\",\"name\":\"kind\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Owner\",\"name\":\"mainchain\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Owner\",\"name\":\"ronin\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"enum Token.Standard\",\"name\":\"erc\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Info\",\"name\":\"info\",\"type\":\"tuple\"}],\"internalType\":\"struct Transfer.Receipt\",\"name\":\"_receipt\",\"type\":\"tuple\"}],\"name\":\"unlockWithdrawal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"validatorContract\",\"outputs\":[{\"internalType\":\"contract IWeightedValidator\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"withdrawalHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"withdrawalLocked\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"wrappedNativeToken\",\"outputs\":[{\"internalType\":\"contract IWETH\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", - "ContractName": "MainchainGatewayV2", - "CompilerVersion": "v0.8.9+commit.e5eed63a", - "OptimizationUsed": 1, - "Runs": 1000, - "ConstructorArguments": "0x", - "EVMVersion": "Default", - "Library": "", - "LicenseType": "MIT", - "Proxy": 0, - "SwarmSource": "" - } -] \ No newline at end of file +[{"SourceCode":{"language":"Solidity","sources":{"@openzeppelin/contracts/access/IAccessControl.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n"},"@openzeppelin/contracts/token/ERC721/IERC721.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n}\n"},"@openzeppelin/contracts/access/IAccessControlEnumerable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerable is IAccessControl {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n"},"@openzeppelin/contracts/utils/StorageSlot.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n assembly {\n r.slot := slot\n }\n }\n}\n"},"@openzeppelin/contracts/utils/cryptography/ECDSA.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n"},"contracts/v0.8/extensions/GatewayV2.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/security/Pausable.sol\";\nimport \"../interfaces/IQuorum.sol\";\nimport \"../interfaces/IWeightedValidator.sol\";\nimport \"./HasProxyAdmin.sol\";\n\nabstract contract GatewayV2 is HasProxyAdmin, Pausable, IQuorum {\n /// @dev Emitted when the validator contract address is updated.\n event ValidatorContractUpdated(IWeightedValidator);\n\n uint256 internal _num;\n uint256 internal _denom;\n\n IWeightedValidator public validatorContract;\n uint256 public nonce;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n */\n uint256[50] private ______gap;\n\n /**\n * @dev See {IQuorum-getThreshold}.\n */\n function getThreshold() external view virtual returns (uint256, uint256) {\n return (_num, _denom);\n }\n\n /**\n * @dev See {IQuorum-checkThreshold}.\n */\n function checkThreshold(uint256 _voteWeight) external view virtual returns (bool) {\n return _voteWeight * _denom >= _num * validatorContract.totalWeights();\n }\n\n /**\n * @dev See {IQuorum-setThreshold}.\n */\n function setThreshold(uint256 _numerator, uint256 _denominator)\n external\n virtual\n onlyAdmin\n returns (uint256, uint256)\n {\n return _setThreshold(_numerator, _denominator);\n }\n\n /**\n * @dev Triggers paused state.\n */\n function pause() external onlyAdmin {\n _pause();\n }\n\n /**\n * @dev Triggers unpaused state.\n */\n function unpause() external onlyAdmin {\n _unpause();\n }\n\n /**\n * @dev Sets validator contract address.\n *\n * Requirements:\n * - The method caller is admin.\n *\n * Emits the `ValidatorContractUpdated` event.\n *\n */\n function setValidatorContract(IWeightedValidator _validatorContract) external virtual onlyAdmin {\n _setValidatorContract(_validatorContract);\n }\n\n /**\n * @dev See {IQuorum-minimumVoteWeight}.\n */\n function minimumVoteWeight() public view virtual returns (uint256) {\n return _minimumVoteWeight(validatorContract.totalWeights());\n }\n\n /**\n * @dev Sets validator contract address.\n *\n * Emits the `ValidatorContractUpdated` event.\n *\n */\n function _setValidatorContract(IWeightedValidator _validatorContract) internal virtual {\n validatorContract = _validatorContract;\n emit ValidatorContractUpdated(_validatorContract);\n }\n\n /**\n * @dev Sets threshold and returns the old one.\n *\n * Emits the `ThresholdUpdated` event.\n *\n */\n function _setThreshold(uint256 _numerator, uint256 _denominator)\n internal\n virtual\n returns (uint256 _previousNum, uint256 _previousDenom)\n {\n require(_numerator <= _denominator, \"GatewayV2: invalid threshold\");\n _previousNum = _num;\n _previousDenom = _denom;\n _num = _numerator;\n _denom = _denominator;\n emit ThresholdUpdated(nonce++, _numerator, _denominator, _previousNum, _previousDenom);\n }\n\n /**\n * @dev Returns minimum vote weight.\n */\n function _minimumVoteWeight(uint256 _totalWeight) internal view virtual returns (uint256) {\n return (_num * _totalWeight + _denom - 1) / _denom;\n }\n}\n"},"@openzeppelin/contracts/proxy/utils/Initializable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() initializer {}\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Modifier to protect an initializer function from being invoked twice.\n */\n modifier initializer() {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\n // contract may have been reentered.\n require(_initializing ? _isConstructor() : !_initialized, \"Initializable: contract is already initialized\");\n\n bool isTopLevelCall = !_initializing;\n if (isTopLevelCall) {\n _initializing = true;\n _initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n _initializing = false;\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} modifier, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n function _isConstructor() private view returns (bool) {\n return !Address.isContract(address(this));\n }\n}\n"},"contracts/v0.8/extensions/WithdrawalLimitation.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./GatewayV2.sol\";\n\nabstract contract WithdrawalLimitation is GatewayV2 {\n /// @dev Emitted when the high-tier vote weight threshold is updated\n event HighTierVoteWeightThresholdUpdated(\n uint256 indexed nonce,\n uint256 indexed numerator,\n uint256 indexed denominator,\n uint256 previousNumerator,\n uint256 previousDenominator\n );\n /// @dev Emitted when the thresholds for high-tier withdrawals that requires high-tier vote weights are updated\n event HighTierThresholdsUpdated(address[] tokens, uint256[] thresholds);\n /// @dev Emitted when the thresholds for locked withdrawals are updated\n event LockedThresholdsUpdated(address[] tokens, uint256[] thresholds);\n /// @dev Emitted when the fee percentages to unlock withdraw are updated\n event UnlockFeePercentagesUpdated(address[] tokens, uint256[] percentages);\n /// @dev Emitted when the daily limit thresholds are updated\n event DailyWithdrawalLimitsUpdated(address[] tokens, uint256[] limits);\n\n uint256 public constant _MAX_PERCENTAGE = 1_000_000;\n\n uint256 internal _highTierVWNum;\n uint256 internal _highTierVWDenom;\n\n /// @dev Mapping from mainchain token => the amount thresholds for high-tier withdrawals that requires high-tier vote weights\n mapping(address => uint256) public highTierThreshold;\n /// @dev Mapping from mainchain token => the amount thresholds to lock withdrawal\n mapping(address => uint256) public lockedThreshold;\n /// @dev Mapping from mainchain token => unlock fee percentages for unlocker\n /// @notice Values 0-1,000,000 map to 0%-100%\n mapping(address => uint256) public unlockFeePercentages;\n /// @dev Mapping from mainchain token => daily limit amount for withdrawal\n mapping(address => uint256) public dailyWithdrawalLimit;\n /// @dev Mapping from token address => today withdrawal amount\n mapping(address => uint256) public lastSyncedWithdrawal;\n /// @dev Mapping from token address => last date synced to record the `lastSyncedWithdrawal`\n mapping(address => uint256) public lastDateSynced;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n */\n uint256[50] private ______gap;\n\n /**\n * @dev Override {GatewayV2-setThreshold}.\n *\n * Requirements:\n * - The high-tier vote weight threshold must equal to or larger than the normal threshold.\n *\n */\n function setThreshold(uint256 _numerator, uint256 _denominator)\n external\n virtual\n override\n onlyAdmin\n returns (uint256 _previousNum, uint256 _previousDenom)\n {\n (_previousNum, _previousDenom) = _setThreshold(_numerator, _denominator);\n _verifyThresholds();\n }\n\n /**\n * @dev Returns the high-tier vote weight threshold.\n */\n function getHighTierVoteWeightThreshold() external view virtual returns (uint256, uint256) {\n return (_highTierVWNum, _highTierVWDenom);\n }\n\n /**\n * @dev Checks whether the `_voteWeight` passes the high-tier vote weight threshold.\n */\n function checkHighTierVoteWeightThreshold(uint256 _voteWeight) external view virtual returns (bool) {\n return _voteWeight * _highTierVWDenom >= _highTierVWNum * validatorContract.totalWeights();\n }\n\n /**\n * @dev Sets high-tier vote weight threshold and returns the old one.\n *\n * Requirements:\n * - The method caller is admin.\n * - The high-tier vote weight threshold must equal to or larger than the normal threshold.\n *\n * Emits the `HighTierVoteWeightThresholdUpdated` event.\n *\n */\n function setHighTierVoteWeightThreshold(uint256 _numerator, uint256 _denominator)\n external\n virtual\n onlyAdmin\n returns (uint256 _previousNum, uint256 _previousDenom)\n {\n (_previousNum, _previousDenom) = _setHighTierVoteWeightThreshold(_numerator, _denominator);\n _verifyThresholds();\n }\n\n /**\n * @dev Sets the thresholds for high-tier withdrawals that requires high-tier vote weights.\n *\n * Requirements:\n * - The method caller is admin.\n * - The arrays have the same length and its length larger than 0.\n *\n * Emits the `HighTierThresholdsUpdated` event.\n *\n */\n function setHighTierThresholds(address[] calldata _tokens, uint256[] calldata _thresholds)\n external\n virtual\n onlyAdmin\n {\n require(_tokens.length > 0, \"WithdrawalLimitation: invalid array length\");\n _setHighTierThresholds(_tokens, _thresholds);\n }\n\n /**\n * @dev Sets the amount thresholds to lock withdrawal.\n *\n * Requirements:\n * - The method caller is admin.\n * - The arrays have the same length and its length larger than 0.\n *\n * Emits the `LockedThresholdsUpdated` event.\n *\n */\n function setLockedThresholds(address[] calldata _tokens, uint256[] calldata _thresholds) external virtual onlyAdmin {\n require(_tokens.length > 0, \"WithdrawalLimitation: invalid array length\");\n _setLockedThresholds(_tokens, _thresholds);\n }\n\n /**\n * @dev Sets fee percentages to unlock withdrawal.\n *\n * Requirements:\n * - The method caller is admin.\n * - The arrays have the same length and its length larger than 0.\n *\n * Emits the `UnlockFeePercentagesUpdated` event.\n *\n */\n function setUnlockFeePercentages(address[] calldata _tokens, uint256[] calldata _percentages)\n external\n virtual\n onlyAdmin\n {\n require(_tokens.length > 0, \"WithdrawalLimitation: invalid array length\");\n _setUnlockFeePercentages(_tokens, _percentages);\n }\n\n /**\n * @dev Sets daily limit amounts for the withdrawals.\n *\n * Requirements:\n * - The method caller is admin.\n * - The arrays have the same length and its length larger than 0.\n *\n * Emits the `DailyWithdrawalLimitsUpdated` event.\n *\n */\n function setDailyWithdrawalLimits(address[] calldata _tokens, uint256[] calldata _limits) external virtual onlyAdmin {\n require(_tokens.length > 0, \"WithdrawalLimitation: invalid array length\");\n _setDailyWithdrawalLimits(_tokens, _limits);\n }\n\n /**\n * @dev Checks whether the withdrawal reaches the limitation.\n */\n function reachedWithdrawalLimit(address _token, uint256 _quantity) external view virtual returns (bool) {\n return _reachedWithdrawalLimit(_token, _quantity);\n }\n\n /**\n * @dev Sets high-tier vote weight threshold and returns the old one.\n *\n * Emits the `HighTierVoteWeightThresholdUpdated` event.\n *\n */\n function _setHighTierVoteWeightThreshold(uint256 _numerator, uint256 _denominator)\n internal\n returns (uint256 _previousNum, uint256 _previousDenom)\n {\n require(_numerator <= _denominator, \"WithdrawalLimitation: invalid threshold\");\n _previousNum = _highTierVWNum;\n _previousDenom = _highTierVWDenom;\n _highTierVWNum = _numerator;\n _highTierVWDenom = _denominator;\n emit HighTierVoteWeightThresholdUpdated(nonce++, _numerator, _denominator, _previousNum, _previousDenom);\n }\n\n /**\n * @dev Sets the thresholds for high-tier withdrawals that requires high-tier vote weights.\n *\n * Requirements:\n * - The array lengths are equal.\n *\n * Emits the `HighTierThresholdsUpdated` event.\n *\n */\n function _setHighTierThresholds(address[] calldata _tokens, uint256[] calldata _thresholds) internal virtual {\n require(_tokens.length == _thresholds.length, \"WithdrawalLimitation: invalid array length\");\n for (uint256 _i; _i < _tokens.length; _i++) {\n highTierThreshold[_tokens[_i]] = _thresholds[_i];\n }\n emit HighTierThresholdsUpdated(_tokens, _thresholds);\n }\n\n /**\n * @dev Sets the amount thresholds to lock withdrawal.\n *\n * Requirements:\n * - The array lengths are equal.\n *\n * Emits the `LockedThresholdsUpdated` event.\n *\n */\n function _setLockedThresholds(address[] calldata _tokens, uint256[] calldata _thresholds) internal virtual {\n require(_tokens.length == _thresholds.length, \"WithdrawalLimitation: invalid array length\");\n for (uint256 _i; _i < _tokens.length; _i++) {\n lockedThreshold[_tokens[_i]] = _thresholds[_i];\n }\n emit LockedThresholdsUpdated(_tokens, _thresholds);\n }\n\n /**\n * @dev Sets fee percentages to unlock withdrawal.\n *\n * Requirements:\n * - The array lengths are equal.\n * - The percentage is equal to or less than 100_000.\n *\n * Emits the `UnlockFeePercentagesUpdated` event.\n *\n */\n function _setUnlockFeePercentages(address[] calldata _tokens, uint256[] calldata _percentages) internal virtual {\n require(_tokens.length == _percentages.length, \"WithdrawalLimitation: invalid array length\");\n for (uint256 _i; _i < _tokens.length; _i++) {\n require(_percentages[_i] <= _MAX_PERCENTAGE, \"WithdrawalLimitation: invalid percentage\");\n unlockFeePercentages[_tokens[_i]] = _percentages[_i];\n }\n emit UnlockFeePercentagesUpdated(_tokens, _percentages);\n }\n\n /**\n * @dev Sets daily limit amounts for the withdrawals.\n *\n * Requirements:\n * - The array lengths are equal.\n *\n * Emits the `DailyWithdrawalLimitsUpdated` event.\n *\n */\n function _setDailyWithdrawalLimits(address[] calldata _tokens, uint256[] calldata _limits) internal virtual {\n require(_tokens.length == _limits.length, \"WithdrawalLimitation: invalid array length\");\n for (uint256 _i; _i < _tokens.length; _i++) {\n dailyWithdrawalLimit[_tokens[_i]] = _limits[_i];\n }\n emit DailyWithdrawalLimitsUpdated(_tokens, _limits);\n }\n\n /**\n * @dev Checks whether the withdrawal reaches the daily limitation.\n *\n * Requirements:\n * - The daily withdrawal threshold should not apply for locked withdrawals.\n *\n */\n function _reachedWithdrawalLimit(address _token, uint256 _quantity) internal view virtual returns (bool) {\n if (_lockedWithdrawalRequest(_token, _quantity)) {\n return false;\n }\n\n uint256 _currentDate = block.timestamp / 1 days;\n if (_currentDate > lastDateSynced[_token]) {\n return dailyWithdrawalLimit[_token] <= _quantity;\n } else {\n return dailyWithdrawalLimit[_token] <= lastSyncedWithdrawal[_token] + _quantity;\n }\n }\n\n /**\n * @dev Record withdrawal token.\n */\n function _recordWithdrawal(address _token, uint256 _quantity) internal virtual {\n uint256 _currentDate = block.timestamp / 1 days;\n if (_currentDate > lastDateSynced[_token]) {\n lastDateSynced[_token] = _currentDate;\n lastSyncedWithdrawal[_token] = _quantity;\n } else {\n lastSyncedWithdrawal[_token] += _quantity;\n }\n }\n\n /**\n * @dev Returns whether the withdrawal request is locked or not.\n */\n function _lockedWithdrawalRequest(address _token, uint256 _quantity) internal view virtual returns (bool) {\n return lockedThreshold[_token] <= _quantity;\n }\n\n /**\n * @dev Computes fee percentage.\n */\n function _computeFeePercentage(uint256 _amount, uint256 _percentage) internal view virtual returns (uint256) {\n return (_amount * _percentage) / _MAX_PERCENTAGE;\n }\n\n /**\n * @dev Returns high-tier vote weight.\n */\n function _highTierVoteWeight(uint256 _totalWeight) internal view virtual returns (uint256) {\n return (_highTierVWNum * _totalWeight + _highTierVWDenom - 1) / _highTierVWDenom;\n }\n\n /**\n * @dev Validates whether the high-tier vote weight threshold is larger than the normal threshold.\n */\n function _verifyThresholds() internal view {\n require(_num * _highTierVWDenom <= _highTierVWNum * _denom, \"WithdrawalLimitation: invalid thresholds\");\n }\n}\n"},"contracts/v0.8/interfaces/MappedTokenConsumer.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"../library/Token.sol\";\n\ninterface MappedTokenConsumer {\n struct MappedToken {\n Token.Standard erc;\n address tokenAddr;\n }\n}\n"},"contracts/v0.8/library/Token.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"../interfaces/IWETH.sol\";\n\nlibrary Token {\n enum Standard {\n ERC20,\n ERC721\n }\n struct Info {\n Standard erc;\n // For ERC20: the id must be 0 and the quantity is larger than 0.\n // For ERC721: the quantity must be 0.\n uint256 id;\n uint256 quantity;\n }\n\n // keccak256(\"TokenInfo(uint8 erc,uint256 id,uint256 quantity)\");\n bytes32 public constant INFO_TYPE_HASH = 0x1e2b74b2a792d5c0f0b6e59b037fa9d43d84fbb759337f0112fcc15ca414fc8d;\n\n /**\n * @dev Returns token info struct hash.\n */\n function hash(Info memory _info) internal pure returns (bytes32) {\n return keccak256(abi.encode(INFO_TYPE_HASH, _info.erc, _info.id, _info.quantity));\n }\n\n /**\n * @dev Validates the token info.\n */\n function validate(Info memory _info) internal pure {\n require(\n (_info.erc == Standard.ERC20 && _info.quantity > 0 && _info.id == 0) ||\n (_info.erc == Standard.ERC721 && _info.quantity == 0),\n \"Token: invalid info\"\n );\n }\n\n /**\n * @dev Transfer asset from.\n *\n * Requirements:\n * - The `_from` address must approve for the contract using this library.\n *\n */\n function transferFrom(\n Info memory _info,\n address _from,\n address _to,\n address _token\n ) internal {\n bool _success;\n bytes memory _data;\n if (_info.erc == Standard.ERC20) {\n (_success, _data) = _token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, _from, _to, _info.quantity));\n _success = _success && (_data.length == 0 || abi.decode(_data, (bool)));\n } else if (_info.erc == Standard.ERC721) {\n // bytes4(keccak256(\"transferFrom(address,address,uint256)\"))\n (_success, ) = _token.call(abi.encodeWithSelector(0x23b872dd, _from, _to, _info.id));\n } else {\n revert(\"Token: unsupported token standard\");\n }\n\n if (!_success) {\n revert(\n string(\n abi.encodePacked(\n \"Token: could not transfer \",\n toString(_info),\n \" from \",\n Strings.toHexString(uint160(_from), 20),\n \" to \",\n Strings.toHexString(uint160(_to), 20),\n \" token \",\n Strings.toHexString(uint160(_token), 20)\n )\n )\n );\n }\n }\n\n /**\n * @dev Transfers ERC721 token and returns the result.\n */\n function tryTransferERC721(\n address _token,\n address _to,\n uint256 _id\n ) internal returns (bool _success) {\n (_success, ) = _token.call(abi.encodeWithSelector(IERC721.transferFrom.selector, address(this), _to, _id));\n }\n\n /**\n * @dev Transfers ERC20 token and returns the result.\n */\n function tryTransferERC20(\n address _token,\n address _to,\n uint256 _quantity\n ) internal returns (bool _success) {\n bytes memory _data;\n (_success, _data) = _token.call(abi.encodeWithSelector(IERC20.transfer.selector, _to, _quantity));\n _success = _success && (_data.length == 0 || abi.decode(_data, (bool)));\n }\n\n /**\n * @dev Transfer assets from current address to `_to` address.\n */\n function transfer(\n Info memory _info,\n address _to,\n address _token\n ) internal {\n bool _success;\n if (_info.erc == Standard.ERC20) {\n _success = tryTransferERC20(_token, _to, _info.quantity);\n } else if (_info.erc == Standard.ERC721) {\n _success = tryTransferERC721(_token, _to, _info.id);\n } else {\n revert(\"Token: unsupported token standard\");\n }\n\n if (!_success) {\n revert(\n string(\n abi.encodePacked(\n \"Token: could not transfer \",\n toString(_info),\n \" to \",\n Strings.toHexString(uint160(_to), 20),\n \" token \",\n Strings.toHexString(uint160(_token), 20)\n )\n )\n );\n }\n }\n\n /**\n * @dev Tries minting and transfering assets.\n *\n * @notice Prioritizes transfer native token if the token is wrapped.\n *\n */\n function handleAssetTransfer(\n Info memory _info,\n address payable _to,\n address _token,\n IWETH _wrappedNativeToken\n ) internal {\n bool _success;\n if (_token == address(_wrappedNativeToken)) {\n // Try sending the native token before transferring the wrapped token\n if (!_to.send(_info.quantity)) {\n _wrappedNativeToken.deposit{ value: _info.quantity }();\n transfer(_info, _to, _token);\n }\n } else if (_info.erc == Token.Standard.ERC20) {\n uint256 _balance = IERC20(_token).balanceOf(address(this));\n\n if (_balance < _info.quantity) {\n // bytes4(keccak256(\"mint(address,uint256)\"))\n (_success, ) = _token.call(abi.encodeWithSelector(0x40c10f19, address(this), _info.quantity - _balance));\n require(_success, \"Token: ERC20 minting failed\");\n }\n\n transfer(_info, _to, _token);\n } else if (_info.erc == Token.Standard.ERC721) {\n if (!tryTransferERC721(_token, _to, _info.id)) {\n // bytes4(keccak256(\"mint(address,uint256)\"))\n (_success, ) = _token.call(abi.encodeWithSelector(0x40c10f19, _to, _info.id));\n require(_success, \"Token: ERC721 minting failed\");\n }\n } else {\n revert(\"Token: unsupported token standard\");\n }\n }\n\n /**\n * @dev Returns readable string.\n */\n function toString(Info memory _info) internal pure returns (string memory) {\n return\n string(\n abi.encodePacked(\n \"TokenInfo(\",\n Strings.toHexString(uint160(_info.erc), 1),\n \",\",\n Strings.toHexString(_info.id),\n \",\",\n Strings.toHexString(_info.quantity),\n \")\"\n )\n );\n }\n\n struct Owner {\n address addr;\n address tokenAddr;\n uint256 chainId;\n }\n\n // keccak256(\"TokenOwner(address addr,address tokenAddr,uint256 chainId)\");\n bytes32 public constant OWNER_TYPE_HASH = 0x353bdd8d69b9e3185b3972e08b03845c0c14a21a390215302776a7a34b0e8764;\n\n /**\n * @dev Returns ownership struct hash.\n */\n function hash(Owner memory _owner) internal pure returns (bytes32) {\n return keccak256(abi.encode(OWNER_TYPE_HASH, _owner.addr, _owner.tokenAddr, _owner.chainId));\n }\n}\n"},"contracts/v0.8/mainchain/IMainchainGatewayV2.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"../interfaces/IWETH.sol\";\nimport \"../library/Transfer.sol\";\nimport \"../interfaces/SignatureConsumer.sol\";\nimport \"../interfaces/MappedTokenConsumer.sol\";\n\ninterface IMainchainGatewayV2 is SignatureConsumer, MappedTokenConsumer {\n /// @dev Emitted when the deposit is requested\n event DepositRequested(bytes32 receiptHash, Transfer.Receipt receipt);\n /// @dev Emitted when the assets are withdrawn\n event Withdrew(bytes32 receiptHash, Transfer.Receipt receipt);\n /// @dev Emitted when the tokens are mapped\n event TokenMapped(address[] mainchainTokens, address[] roninTokens, Token.Standard[] standards);\n /// @dev Emitted when the wrapped native token contract is updated\n event WrappedNativeTokenContractUpdated(IWETH weth);\n /// @dev Emitted when the withdrawal is locked\n event WithdrawalLocked(bytes32 receiptHash, Transfer.Receipt receipt);\n /// @dev Emitted when the withdrawal is unlocked\n event WithdrawalUnlocked(bytes32 receiptHash, Transfer.Receipt receipt);\n\n /**\n * @dev Returns the domain seperator.\n */\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n\n /**\n * @dev Returns deposit count.\n */\n function depositCount() external view returns (uint256);\n\n /**\n * @dev Sets the wrapped native token contract.\n *\n * Requirements:\n * - The method caller is admin.\n *\n * Emits the `WrappedNativeTokenContractUpdated` event.\n *\n */\n function setWrappedNativeTokenContract(IWETH _wrappedToken) external;\n\n /**\n * @dev Returns whether the withdrawal is locked.\n */\n function withdrawalLocked(uint256 withdrawalId) external view returns (bool);\n\n /**\n * @dev Returns the withdrawal hash.\n */\n function withdrawalHash(uint256 withdrawalId) external view returns (bytes32);\n\n /**\n * @dev Locks the assets and request deposit.\n */\n function requestDepositFor(Transfer.Request calldata _request) external payable;\n\n /**\n * @dev Withdraws based on the receipt and the validator signatures.\n * Returns whether the withdrawal is locked.\n *\n * Emits the `Withdrew` once the assets are released.\n *\n */\n function submitWithdrawal(Transfer.Receipt memory _receipt, Signature[] memory _signatures)\n external\n returns (bool _locked);\n\n /**\n * @dev Approves a specific withdrawal.\n *\n * Requirements:\n * - The method caller is a validator.\n *\n * Emits the `Withdrew` once the assets are released.\n *\n */\n function unlockWithdrawal(Transfer.Receipt calldata _receipt) external;\n\n /**\n * @dev Maps mainchain tokens to Ronin network.\n *\n * Requirement:\n * - The method caller is admin.\n * - The arrays have the same length and its length larger than 0.\n *\n * Emits the `TokenMapped` event.\n *\n */\n function mapTokens(\n address[] calldata _mainchainTokens,\n address[] calldata _roninTokens,\n Token.Standard[] calldata _standards\n ) external;\n\n /**\n * @dev Maps mainchain tokens to Ronin network and sets thresholds.\n *\n * Requirement:\n * - The method caller is admin.\n * - The arrays have the same length and its length larger than 0.\n *\n * Emits the `TokenMapped` event.\n *\n */\n function mapTokensAndThresholds(\n address[] calldata _mainchainTokens,\n address[] calldata _roninTokens,\n Token.Standard[] calldata _standards,\n uint256[][4] calldata _thresholds\n ) external;\n\n /**\n * @dev Returns token address on Ronin network.\n * @notice Reverts for unsupported token.\n */\n function getRoninToken(address _mainchainToken) external view returns (MappedToken memory _token);\n}\n"},"contracts/v0.8/mainchain/MainchainGatewayV2.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/access/AccessControlEnumerable.sol\";\nimport \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport \"../extensions/GatewayV2.sol\";\nimport \"../extensions/WithdrawalLimitation.sol\";\nimport \"../library/Transfer.sol\";\nimport \"./IMainchainGatewayV2.sol\";\n\ncontract MainchainGatewayV2 is WithdrawalLimitation, Initializable, AccessControlEnumerable, IMainchainGatewayV2 {\n using Token for Token.Info;\n using Transfer for Transfer.Request;\n using Transfer for Transfer.Receipt;\n\n /// @dev Withdrawal unlocker role hash\n bytes32 public constant WITHDRAWAL_UNLOCKER_ROLE = keccak256(\"WITHDRAWAL_UNLOCKER_ROLE\");\n\n /// @dev Wrapped native token address\n IWETH public wrappedNativeToken;\n /// @dev Ronin network id\n uint256 public roninChainId;\n /// @dev Total deposit\n uint256 public depositCount;\n /// @dev Domain seperator\n bytes32 internal _domainSeparator;\n /// @dev Mapping from mainchain token => token address on Ronin network\n mapping(address => MappedToken) internal _roninToken;\n /// @dev Mapping from withdrawal id => withdrawal hash\n mapping(uint256 => bytes32) public withdrawalHash;\n /// @dev Mapping from withdrawal id => locked\n mapping(uint256 => bool) public withdrawalLocked;\n\n fallback() external payable {\n _fallback();\n }\n\n receive() external payable {\n _fallback();\n }\n\n /**\n * @dev Initializes contract storage.\n */\n function initialize(\n address _roleSetter,\n IWETH _wrappedToken,\n IWeightedValidator _validatorContract,\n uint256 _roninChainId,\n uint256 _numerator,\n uint256 _highTierVWNumerator,\n uint256 _denominator,\n // _addresses[0]: mainchainTokens\n // _addresses[1]: roninTokens\n // _addresses[2]: withdrawalUnlockers\n address[][3] calldata _addresses,\n // _thresholds[0]: highTierThreshold\n // _thresholds[1]: lockedThreshold\n // _thresholds[2]: unlockFeePercentages\n // _thresholds[3]: dailyWithdrawalLimit\n uint256[][4] calldata _thresholds,\n Token.Standard[] calldata _standards\n ) external payable virtual initializer {\n _setupRole(DEFAULT_ADMIN_ROLE, _roleSetter);\n roninChainId = _roninChainId;\n\n _setWrappedNativeTokenContract(_wrappedToken);\n _setValidatorContract(_validatorContract);\n _updateDomainSeparator();\n _setThreshold(_numerator, _denominator);\n _setHighTierVoteWeightThreshold(_highTierVWNumerator, _denominator);\n _verifyThresholds();\n\n if (_addresses[0].length > 0) {\n // Map mainchain tokens to ronin tokens\n _mapTokens(_addresses[0], _addresses[1], _standards);\n // Sets thresholds based on the mainchain tokens\n _setHighTierThresholds(_addresses[0], _thresholds[0]);\n _setLockedThresholds(_addresses[0], _thresholds[1]);\n _setUnlockFeePercentages(_addresses[0], _thresholds[2]);\n _setDailyWithdrawalLimits(_addresses[0], _thresholds[3]);\n }\n\n // Grant role for withdrawal unlocker\n for (uint256 _i; _i < _addresses[2].length; _i++) {\n _grantRole(WITHDRAWAL_UNLOCKER_ROLE, _addresses[2][_i]);\n }\n }\n\n /**\n * @dev Receives ether without doing anything. Use this function to topup native token.\n */\n function receiveEther() external payable {}\n\n /**\n * @dev See {IMainchainGatewayV2-DOMAIN_SEPARATOR}.\n */\n function DOMAIN_SEPARATOR() external view virtual returns (bytes32) {\n return _domainSeparator;\n }\n\n /**\n * @dev See {IMainchainGatewayV2-setWrappedNativeTokenContract}.\n */\n function setWrappedNativeTokenContract(IWETH _wrappedToken) external virtual onlyAdmin {\n _setWrappedNativeTokenContract(_wrappedToken);\n }\n\n /**\n * @dev See {IMainchainGatewayV2-requestDepositFor}.\n */\n function requestDepositFor(Transfer.Request calldata _request) external payable virtual whenNotPaused {\n _requestDepositFor(_request, msg.sender);\n }\n\n /**\n * @dev See {IMainchainGatewayV2-submitWithdrawal}.\n */\n function submitWithdrawal(Transfer.Receipt calldata _receipt, Signature[] calldata _signatures)\n external\n virtual\n whenNotPaused\n returns (bool _locked)\n {\n return _submitWithdrawal(_receipt, _signatures);\n }\n\n /**\n * @dev See {IMainchainGatewayV2-unlockWithdrawal}.\n */\n function unlockWithdrawal(Transfer.Receipt calldata _receipt) external onlyRole(WITHDRAWAL_UNLOCKER_ROLE) {\n bytes32 _receiptHash = _receipt.hash();\n require(withdrawalHash[_receipt.id] == _receipt.hash(), \"MainchainGatewayV2: invalid receipt\");\n require(withdrawalLocked[_receipt.id], \"MainchainGatewayV2: query for approved withdrawal\");\n delete withdrawalLocked[_receipt.id];\n emit WithdrawalUnlocked(_receiptHash, _receipt);\n\n address _token = _receipt.mainchain.tokenAddr;\n if (_receipt.info.erc == Token.Standard.ERC20) {\n Token.Info memory _feeInfo = _receipt.info;\n _feeInfo.quantity = _computeFeePercentage(_receipt.info.quantity, unlockFeePercentages[_token]);\n Token.Info memory _withdrawInfo = _receipt.info;\n _withdrawInfo.quantity = _receipt.info.quantity - _feeInfo.quantity;\n\n _feeInfo.handleAssetTransfer(payable(msg.sender), _token, wrappedNativeToken);\n _withdrawInfo.handleAssetTransfer(payable(_receipt.mainchain.addr), _token, wrappedNativeToken);\n } else {\n _receipt.info.handleAssetTransfer(payable(_receipt.mainchain.addr), _token, wrappedNativeToken);\n }\n\n emit Withdrew(_receiptHash, _receipt);\n }\n\n /**\n * @dev See {IMainchainGatewayV2-mapTokens}.\n */\n function mapTokens(\n address[] calldata _mainchainTokens,\n address[] calldata _roninTokens,\n Token.Standard[] calldata _standards\n ) external virtual onlyAdmin {\n require(_mainchainTokens.length > 0, \"MainchainGatewayV2: query for empty array\");\n _mapTokens(_mainchainTokens, _roninTokens, _standards);\n }\n\n /**\n * @dev See {IMainchainGatewayV2-mapTokensAndThresholds}.\n */\n function mapTokensAndThresholds(\n address[] calldata _mainchainTokens,\n address[] calldata _roninTokens,\n Token.Standard[] calldata _standards,\n // _thresholds[0]: highTierThreshold\n // _thresholds[1]: lockedThreshold\n // _thresholds[2]: unlockFeePercentages\n // _thresholds[3]: dailyWithdrawalLimit\n uint256[][4] calldata _thresholds\n ) external virtual onlyAdmin {\n require(_mainchainTokens.length > 0, \"MainchainGatewayV2: query for empty array\");\n _mapTokens(_mainchainTokens, _roninTokens, _standards);\n _setHighTierThresholds(_mainchainTokens, _thresholds[0]);\n _setLockedThresholds(_mainchainTokens, _thresholds[1]);\n _setUnlockFeePercentages(_mainchainTokens, _thresholds[2]);\n _setDailyWithdrawalLimits(_mainchainTokens, _thresholds[3]);\n }\n\n /**\n * @dev See {IMainchainGatewayV2-getRoninToken}.\n */\n function getRoninToken(address _mainchainToken) public view returns (MappedToken memory _token) {\n _token = _roninToken[_mainchainToken];\n require(_token.tokenAddr != address(0), \"MainchainGatewayV2: unsupported token\");\n }\n\n /**\n * @dev Maps mainchain tokens to Ronin network.\n *\n * Requirement:\n * - The arrays have the same length.\n *\n * Emits the `TokenMapped` event.\n *\n */\n function _mapTokens(\n address[] calldata _mainchainTokens,\n address[] calldata _roninTokens,\n Token.Standard[] calldata _standards\n ) internal virtual {\n require(\n _mainchainTokens.length == _roninTokens.length && _mainchainTokens.length == _standards.length,\n \"MainchainGatewayV2: invalid array length\"\n );\n\n for (uint256 _i; _i < _mainchainTokens.length; _i++) {\n _roninToken[_mainchainTokens[_i]].tokenAddr = _roninTokens[_i];\n _roninToken[_mainchainTokens[_i]].erc = _standards[_i];\n }\n\n emit TokenMapped(_mainchainTokens, _roninTokens, _standards);\n }\n\n /**\n * @dev Submits withdrawal receipt.\n *\n * Requirements:\n * - The receipt kind is withdrawal.\n * - The receipt is to withdraw on this chain.\n * - The receipt is not used to withdraw before.\n * - The withdrawal is not reached the limit threshold.\n * - The signer weight total is larger than or equal to the minimum threshold.\n * - The signature signers are in order.\n *\n * Emits the `Withdrew` once the assets are released.\n *\n */\n function _submitWithdrawal(Transfer.Receipt calldata _receipt, Signature[] memory _signatures)\n internal\n virtual\n returns (bool _locked)\n {\n uint256 _id = _receipt.id;\n uint256 _quantity = _receipt.info.quantity;\n address _tokenAddr = _receipt.mainchain.tokenAddr;\n\n _receipt.info.validate();\n require(_receipt.kind == Transfer.Kind.Withdrawal, \"MainchainGatewayV2: invalid receipt kind\");\n require(_receipt.mainchain.chainId == block.chainid, \"MainchainGatewayV2: invalid chain id\");\n MappedToken memory _token = getRoninToken(_receipt.mainchain.tokenAddr);\n require(\n _token.erc == _receipt.info.erc && _token.tokenAddr == _receipt.ronin.tokenAddr,\n \"MainchainGatewayV2: invalid receipt\"\n );\n require(withdrawalHash[_id] == bytes32(0), \"MainchainGatewayV2: query for processed withdrawal\");\n require(\n _receipt.info.erc == Token.Standard.ERC721 || !_reachedWithdrawalLimit(_tokenAddr, _quantity),\n \"MainchainGatewayV2: reached daily withdrawal limit\"\n );\n\n bytes32 _receiptHash = _receipt.hash();\n bytes32 _receiptDigest = Transfer.receiptDigest(_domainSeparator, _receiptHash);\n IWeightedValidator _validatorContract = validatorContract;\n\n uint256 _minimumVoteWeight;\n (_minimumVoteWeight, _locked) = _computeMinVoteWeight(_receipt.info.erc, _tokenAddr, _quantity, _validatorContract);\n\n {\n bool _passed;\n address _signer;\n address _lastSigner;\n Signature memory _sig;\n uint256 _weight;\n for (uint256 _i; _i < _signatures.length; _i++) {\n _sig = _signatures[_i];\n _signer = ecrecover(_receiptDigest, _sig.v, _sig.r, _sig.s);\n require(_lastSigner < _signer, \"MainchainGatewayV2: invalid order\");\n _lastSigner = _signer;\n\n _weight += _validatorContract.getValidatorWeight(_signer);\n if (_weight >= _minimumVoteWeight) {\n _passed = true;\n break;\n }\n }\n require(_passed, \"MainchainGatewayV2: query for insufficient vote weight\");\n withdrawalHash[_id] = _receiptHash;\n }\n\n if (_locked) {\n withdrawalLocked[_id] = true;\n emit WithdrawalLocked(_receiptHash, _receipt);\n return _locked;\n }\n\n _recordWithdrawal(_tokenAddr, _quantity);\n _receipt.info.handleAssetTransfer(payable(_receipt.mainchain.addr), _tokenAddr, wrappedNativeToken);\n emit Withdrew(_receiptHash, _receipt);\n }\n\n /**\n * @dev Requests deposit made by `_requester` address.\n *\n * Requirements:\n * - The token info is valid.\n * - The `msg.value` is 0 while depositing ERC20 token.\n * - The `msg.value` is equal to deposit quantity while depositing native token.\n *\n * Emits the `DepositRequested` event.\n *\n */\n function _requestDepositFor(Transfer.Request memory _request, address _requester) internal virtual {\n MappedToken memory _token;\n address _weth = address(wrappedNativeToken);\n\n _request.info.validate();\n if (_request.tokenAddr == address(0)) {\n require(_request.info.quantity == msg.value, \"MainchainGatewayV2: invalid request\");\n _token = getRoninToken(_weth);\n require(_token.erc == _request.info.erc, \"MainchainGatewayV2: invalid token standard\");\n _request.tokenAddr = _weth;\n } else {\n require(msg.value == 0, \"MainchainGatewayV2: invalid request\");\n _token = getRoninToken(_request.tokenAddr);\n require(_token.erc == _request.info.erc, \"MainchainGatewayV2: invalid token standard\");\n _request.info.transferFrom(_requester, address(this), _request.tokenAddr);\n // Withdraw if token is WETH\n if (_weth == _request.tokenAddr) {\n IWETH(_weth).withdraw(_request.info.quantity);\n }\n }\n\n uint256 _depositId = depositCount++;\n Transfer.Receipt memory _receipt = _request.into_deposit_receipt(\n _requester,\n _depositId,\n _token.tokenAddr,\n roninChainId\n );\n\n emit DepositRequested(_receipt.hash(), _receipt);\n }\n\n /**\n * @dev Returns the minimum vote weight for the token.\n */\n function _computeMinVoteWeight(\n Token.Standard _erc,\n address _token,\n uint256 _quantity,\n IWeightedValidator _validatorContract\n ) internal virtual returns (uint256 _weight, bool _locked) {\n uint256 _totalWeights = _validatorContract.totalWeights();\n _weight = _minimumVoteWeight(_totalWeights);\n if (_erc == Token.Standard.ERC20) {\n if (highTierThreshold[_token] <= _quantity) {\n _weight = _highTierVoteWeight(_totalWeights);\n }\n _locked = _lockedWithdrawalRequest(_token, _quantity);\n }\n }\n\n /**\n * @dev Update domain seperator.\n */\n function _updateDomainSeparator() internal {\n _domainSeparator = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(\"MainchainGatewayV2\"),\n keccak256(\"2\"),\n block.chainid,\n address(this)\n )\n );\n }\n\n /**\n * @dev Sets the WETH contract.\n *\n * Emits the `WrappedNativeTokenContractUpdated` event.\n *\n */\n function _setWrappedNativeTokenContract(IWETH _wrapedToken) internal {\n wrappedNativeToken = _wrapedToken;\n emit WrappedNativeTokenContractUpdated(_wrapedToken);\n }\n\n /**\n * @dev Receives ETH from WETH or creates deposit request.\n */\n function _fallback() internal virtual whenNotPaused {\n if (msg.sender != address(wrappedNativeToken)) {\n Transfer.Request memory _request;\n _request.recipientAddr = msg.sender;\n _request.info.quantity = msg.value;\n _requestDepositFor(_request, _request.recipientAddr);\n }\n }\n}\n"},"contracts/v0.8/interfaces/IWeightedValidator.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./IQuorum.sol\";\n\ninterface IWeightedValidator is IQuorum {\n struct WeightedValidator {\n address validator;\n address governor;\n uint256 weight;\n }\n\n /// @dev Emitted when the validators are added\n event ValidatorsAdded(uint256 indexed nonce, WeightedValidator[] validators);\n /// @dev Emitted when the validators are updated\n event ValidatorsUpdated(uint256 indexed nonce, WeightedValidator[] validators);\n /// @dev Emitted when the validators are removed\n event ValidatorsRemoved(uint256 indexed nonce, address[] validators);\n\n /**\n * @dev Returns validator weight of the validator.\n */\n function getValidatorWeight(address _addr) external view returns (uint256);\n\n /**\n * @dev Returns governor weight of the governor.\n */\n function getGovernorWeight(address _addr) external view returns (uint256);\n\n /**\n * @dev Returns total validator weights of the address list.\n */\n function sumValidatorWeights(address[] calldata _addrList) external view returns (uint256 _weight);\n\n /**\n * @dev Returns total governor weights of the address list.\n */\n function sumGovernorWeights(address[] calldata _addrList) external view returns (uint256 _weight);\n\n /**\n * @dev Returns the validator list attached with governor address and weight.\n */\n function getValidatorInfo() external view returns (WeightedValidator[] memory _list);\n\n /**\n * @dev Returns the validator list.\n */\n function getValidators() external view returns (address[] memory _validators);\n\n /**\n * @dev Returns the validator at `_index` position.\n */\n function validators(uint256 _index) external view returns (WeightedValidator memory);\n\n /**\n * @dev Returns total of validators.\n */\n function totalValidators() external view returns (uint256);\n\n /**\n * @dev Returns total weights.\n */\n function totalWeights() external view returns (uint256);\n\n /**\n * @dev Adds validators.\n *\n * Requirements:\n * - The weights are larger than 0.\n * - The validators are not added.\n * - The method caller is admin.\n *\n * Emits the `ValidatorsAdded` event.\n *\n */\n function addValidators(WeightedValidator[] calldata _validators) external;\n\n /**\n * @dev Updates validators.\n *\n * Requirements:\n * - The weights are larger than 0.\n * - The validators are added.\n * - The method caller is admin.\n *\n * Emits the `ValidatorsUpdated` event.\n *\n */\n function updateValidators(WeightedValidator[] calldata _validators) external;\n\n /**\n * @dev Removes validators.\n *\n * Requirements:\n * - The validators are added.\n * - The method caller is admin.\n *\n * Emits the `ValidatorsRemoved` event.\n *\n */\n function removeValidators(address[] calldata _validators) external;\n}\n"},"contracts/v0.8/extensions/HasProxyAdmin.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/utils/StorageSlot.sol\";\n\nabstract contract HasProxyAdmin {\n // bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n modifier onlyAdmin() {\n require(msg.sender == _getAdmin(), \"HasProxyAdmin: unauthorized sender\");\n _;\n }\n\n /**\n * @dev Returns proxy admin.\n */\n function _getAdmin() internal view returns (address) {\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n }\n}\n"},"@openzeppelin/contracts/utils/introspection/IERC165.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"},"contracts/v0.8/interfaces/SignatureConsumer.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface SignatureConsumer {\n struct Signature {\n uint8 v;\n bytes32 r;\n bytes32 s;\n }\n}\n"},"@openzeppelin/contracts/utils/Strings.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n"},"@openzeppelin/contracts/utils/introspection/ERC165.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n"},"@openzeppelin/contracts/access/AccessControlEnumerable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerable.sol\";\nimport \"./AccessControl.sol\";\nimport \"../utils/structs/EnumerableSet.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n}\n"},"contracts/v0.8/library/Transfer.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"./Token.sol\";\n\nlibrary Transfer {\n using ECDSA for bytes32;\n\n enum Kind {\n Deposit,\n Withdrawal\n }\n\n struct Request {\n // For deposit request: Recipient address on Ronin network\n // For withdrawal request: Recipient address on mainchain network\n address recipientAddr;\n // Token address to deposit/withdraw\n // Value 0: native token\n address tokenAddr;\n Token.Info info;\n }\n\n /**\n * @dev Converts the transfer request into the deposit receipt.\n */\n function into_deposit_receipt(\n Request memory _request,\n address _requester,\n uint256 _id,\n address _roninTokenAddr,\n uint256 _roninChainId\n ) internal view returns (Receipt memory _receipt) {\n _receipt.id = _id;\n _receipt.kind = Kind.Deposit;\n _receipt.mainchain.addr = _requester;\n _receipt.mainchain.tokenAddr = _request.tokenAddr;\n _receipt.mainchain.chainId = block.chainid;\n _receipt.ronin.addr = _request.recipientAddr;\n _receipt.ronin.tokenAddr = _roninTokenAddr;\n _receipt.ronin.chainId = _roninChainId;\n _receipt.info = _request.info;\n }\n\n /**\n * @dev Converts the transfer request into the withdrawal receipt.\n */\n function into_withdrawal_receipt(\n Request memory _request,\n address _requester,\n uint256 _id,\n address _mainchainTokenAddr,\n uint256 _mainchainId\n ) internal view returns (Receipt memory _receipt) {\n _receipt.id = _id;\n _receipt.kind = Kind.Withdrawal;\n _receipt.ronin.addr = _requester;\n _receipt.ronin.tokenAddr = _request.tokenAddr;\n _receipt.ronin.chainId = block.chainid;\n _receipt.mainchain.addr = _request.recipientAddr;\n _receipt.mainchain.tokenAddr = _mainchainTokenAddr;\n _receipt.mainchain.chainId = _mainchainId;\n _receipt.info = _request.info;\n }\n\n struct Receipt {\n uint256 id;\n Kind kind;\n Token.Owner mainchain;\n Token.Owner ronin;\n Token.Info info;\n }\n\n // keccak256(\"Receipt(uint256 id,uint8 kind,TokenOwner mainchain,TokenOwner ronin,TokenInfo info)TokenInfo(uint8 erc,uint256 id,uint256 quantity)TokenOwner(address addr,address tokenAddr,uint256 chainId)\");\n bytes32 public constant TYPE_HASH = 0xb9d1fe7c9deeec5dc90a2f47ff1684239519f2545b2228d3d91fb27df3189eea;\n\n /**\n * @dev Returns token info struct hash.\n */\n function hash(Receipt memory _receipt) internal pure returns (bytes32) {\n return\n keccak256(\n abi.encode(\n TYPE_HASH,\n _receipt.id,\n _receipt.kind,\n Token.hash(_receipt.mainchain),\n Token.hash(_receipt.ronin),\n Token.hash(_receipt.info)\n )\n );\n }\n\n /**\n * @dev Returns the receipt digest.\n */\n function receiptDigest(bytes32 _domainSeparator, bytes32 _receiptHash) internal pure returns (bytes32) {\n return _domainSeparator.toTypedDataHash(_receiptHash);\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/security/Pausable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n constructor() {\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n require(!paused(), \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n require(paused(), \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"},"@openzeppelin/contracts/utils/structs/EnumerableSet.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n"},"contracts/v0.8/interfaces/IQuorum.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IQuorum {\n /// @dev Emitted when the threshold is updated\n event ThresholdUpdated(\n uint256 indexed nonce,\n uint256 indexed numerator,\n uint256 indexed denominator,\n uint256 previousNumerator,\n uint256 previousDenominator\n );\n\n /**\n * @dev Returns the threshold.\n */\n function getThreshold() external view returns (uint256 _num, uint256 _denom);\n\n /**\n * @dev Checks whether the `_voteWeight` passes the threshold.\n */\n function checkThreshold(uint256 _voteWeight) external view returns (bool);\n\n /**\n * @dev Returns the minimum vote weight to pass the threshold.\n */\n function minimumVoteWeight() external view returns (uint256);\n\n /**\n * @dev Sets the threshold.\n *\n * Requirements:\n * - The method caller is admin.\n *\n * Emits the `ThresholdUpdated` event.\n *\n */\n function setThreshold(uint256 _numerator, uint256 _denominator)\n external\n returns (uint256 _previousNum, uint256 _previousDenom);\n}\n"},"contracts/v0.8/interfaces/IWETH.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IWETH {\n function deposit() external payable;\n\n function withdraw(uint256 _wad) external;\n\n function balanceOf(address) external view returns (uint256);\n}\n"},"@openzeppelin/contracts/access/AccessControl.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\nimport \"../utils/Context.sol\";\nimport \"../utils/Strings.sol\";\nimport \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role, _msgSender());\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n Strings.toHexString(uint160(account), 20),\n \" is missing role \",\n Strings.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\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/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"}},"settings":{"evmVersion":"london","libraries":{},"metadata":{"bytecodeHash":"ipfs","useLiteralContent":true},"optimizer":{"enabled":true,"runs":1000},"remappings":[],"outputSelection":{"*":{"*":["evm.bytecode","evm.deployedBytecode","devdoc","userdoc","metadata","abi"]}}}},"ABI":"[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"limits\",\"type\":\"uint256[]\"}],\"name\":\"DailyWithdrawalLimitsUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"receiptHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"enum Transfer.Kind\",\"name\":\"kind\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Owner\",\"name\":\"mainchain\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Owner\",\"name\":\"ronin\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"enum Token.Standard\",\"name\":\"erc\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Info\",\"name\":\"info\",\"type\":\"tuple\"}],\"indexed\":false,\"internalType\":\"struct Transfer.Receipt\",\"name\":\"receipt\",\"type\":\"tuple\"}],\"name\":\"DepositRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"thresholds\",\"type\":\"uint256[]\"}],\"name\":\"HighTierThresholdsUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"numerator\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"denominator\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousNumerator\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousDenominator\",\"type\":\"uint256\"}],\"name\":\"HighTierVoteWeightThresholdUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"thresholds\",\"type\":\"uint256[]\"}],\"name\":\"LockedThresholdsUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"previousAdminRole\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"newAdminRole\",\"type\":\"bytes32\"}],\"name\":\"RoleAdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"numerator\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"denominator\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousNumerator\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousDenominator\",\"type\":\"uint256\"}],\"name\":\"ThresholdUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"mainchainTokens\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"roninTokens\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"enum Token.Standard[]\",\"name\":\"standards\",\"type\":\"uint8[]\"}],\"name\":\"TokenMapped\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"percentages\",\"type\":\"uint256[]\"}],\"name\":\"UnlockFeePercentagesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IWeightedValidator\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"ValidatorContractUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"receiptHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"enum Transfer.Kind\",\"name\":\"kind\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Owner\",\"name\":\"mainchain\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Owner\",\"name\":\"ronin\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"enum Token.Standard\",\"name\":\"erc\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Info\",\"name\":\"info\",\"type\":\"tuple\"}],\"indexed\":false,\"internalType\":\"struct Transfer.Receipt\",\"name\":\"receipt\",\"type\":\"tuple\"}],\"name\":\"WithdrawalLocked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"receiptHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"enum Transfer.Kind\",\"name\":\"kind\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Owner\",\"name\":\"mainchain\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Owner\",\"name\":\"ronin\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"enum Token.Standard\",\"name\":\"erc\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Info\",\"name\":\"info\",\"type\":\"tuple\"}],\"indexed\":false,\"internalType\":\"struct Transfer.Receipt\",\"name\":\"receipt\",\"type\":\"tuple\"}],\"name\":\"WithdrawalUnlocked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"receiptHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"enum Transfer.Kind\",\"name\":\"kind\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Owner\",\"name\":\"mainchain\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Owner\",\"name\":\"ronin\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"enum Token.Standard\",\"name\":\"erc\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Info\",\"name\":\"info\",\"type\":\"tuple\"}],\"indexed\":false,\"internalType\":\"struct Transfer.Receipt\",\"name\":\"receipt\",\"type\":\"tuple\"}],\"name\":\"Withdrew\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IWETH\",\"name\":\"weth\",\"type\":\"address\"}],\"name\":\"WrappedNativeTokenContractUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"DEFAULT_ADMIN_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"WITHDRAWAL_UNLOCKER_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"_MAX_PERCENTAGE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_voteWeight\",\"type\":\"uint256\"}],\"name\":\"checkHighTierVoteWeightThreshold\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_voteWeight\",\"type\":\"uint256\"}],\"name\":\"checkThreshold\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"dailyWithdrawalLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"depositCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getHighTierVoteWeightThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleAdmin\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"getRoleMember\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleMemberCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_mainchainToken\",\"type\":\"address\"}],\"name\":\"getRoninToken\",\"outputs\":[{\"components\":[{\"internalType\":\"enum Token.Standard\",\"name\":\"erc\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"}],\"internalType\":\"struct MappedTokenConsumer.MappedToken\",\"name\":\"_token\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"grantRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"hasRole\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"highTierThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_roleSetter\",\"type\":\"address\"},{\"internalType\":\"contract IWETH\",\"name\":\"_wrappedToken\",\"type\":\"address\"},{\"internalType\":\"contract IWeightedValidator\",\"name\":\"_validatorContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_roninChainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_numerator\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_highTierVWNumerator\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_denominator\",\"type\":\"uint256\"},{\"internalType\":\"address[][3]\",\"name\":\"_addresses\",\"type\":\"address[][3]\"},{\"internalType\":\"uint256[][4]\",\"name\":\"_thresholds\",\"type\":\"uint256[][4]\"},{\"internalType\":\"enum Token.Standard[]\",\"name\":\"_standards\",\"type\":\"uint8[]\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"lastDateSynced\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"lastSyncedWithdrawal\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"lockedThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_mainchainTokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"_roninTokens\",\"type\":\"address[]\"},{\"internalType\":\"enum Token.Standard[]\",\"name\":\"_standards\",\"type\":\"uint8[]\"}],\"name\":\"mapTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_mainchainTokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"_roninTokens\",\"type\":\"address[]\"},{\"internalType\":\"enum Token.Standard[]\",\"name\":\"_standards\",\"type\":\"uint8[]\"},{\"internalType\":\"uint256[][4]\",\"name\":\"_thresholds\",\"type\":\"uint256[][4]\"}],\"name\":\"mapTokensAndThresholds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minimumVoteWeight\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_quantity\",\"type\":\"uint256\"}],\"name\":\"reachedWithdrawalLimit\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"receiveEther\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"renounceRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"recipientAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"enum Token.Standard\",\"name\":\"erc\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Info\",\"name\":\"info\",\"type\":\"tuple\"}],\"internalType\":\"struct Transfer.Request\",\"name\":\"_request\",\"type\":\"tuple\"}],\"name\":\"requestDepositFor\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"revokeRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"roninChainId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_tokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_limits\",\"type\":\"uint256[]\"}],\"name\":\"setDailyWithdrawalLimits\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_tokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_thresholds\",\"type\":\"uint256[]\"}],\"name\":\"setHighTierThresholds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_numerator\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_denominator\",\"type\":\"uint256\"}],\"name\":\"setHighTierVoteWeightThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_previousNum\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_previousDenom\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_tokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_thresholds\",\"type\":\"uint256[]\"}],\"name\":\"setLockedThresholds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_numerator\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_denominator\",\"type\":\"uint256\"}],\"name\":\"setThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_previousNum\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_previousDenom\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_tokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_percentages\",\"type\":\"uint256[]\"}],\"name\":\"setUnlockFeePercentages\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IWeightedValidator\",\"name\":\"_validatorContract\",\"type\":\"address\"}],\"name\":\"setValidatorContract\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IWETH\",\"name\":\"_wrappedToken\",\"type\":\"address\"}],\"name\":\"setWrappedNativeTokenContract\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"enum Transfer.Kind\",\"name\":\"kind\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Owner\",\"name\":\"mainchain\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Owner\",\"name\":\"ronin\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"enum Token.Standard\",\"name\":\"erc\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Info\",\"name\":\"info\",\"type\":\"tuple\"}],\"internalType\":\"struct Transfer.Receipt\",\"name\":\"_receipt\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"struct SignatureConsumer.Signature[]\",\"name\":\"_signatures\",\"type\":\"tuple[]\"}],\"name\":\"submitWithdrawal\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"_locked\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"unlockFeePercentages\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"enum Transfer.Kind\",\"name\":\"kind\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Owner\",\"name\":\"mainchain\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Owner\",\"name\":\"ronin\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"enum Token.Standard\",\"name\":\"erc\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"internalType\":\"struct Token.Info\",\"name\":\"info\",\"type\":\"tuple\"}],\"internalType\":\"struct Transfer.Receipt\",\"name\":\"_receipt\",\"type\":\"tuple\"}],\"name\":\"unlockWithdrawal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"validatorContract\",\"outputs\":[{\"internalType\":\"contract IWeightedValidator\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"withdrawalHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"withdrawalLocked\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"wrappedNativeToken\",\"outputs\":[{\"internalType\":\"contract IWETH\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]","ContractName":"MainchainGatewayV2","CompilerVersion":"v0.8.9+commit.e5eed63a","OptimizationUsed":1,"Runs":1000,"ConstructorArguments":"0x","EVMVersion":"Default","Library":"","LicenseType":"MIT","Proxy":0,"SwarmSource":""}] \ No newline at end of file diff --git a/testdata/etherscan/0x8B3D32cf2bb4d0D16656f4c0b04Fa546274f1545/creation_data.json b/testdata/etherscan/0x8B3D32cf2bb4d0D16656f4c0b04Fa546274f1545/creation_data.json index fa26d9cad425..f4dfea9e7de4 100644 --- a/testdata/etherscan/0x8B3D32cf2bb4d0D16656f4c0b04Fa546274f1545/creation_data.json +++ b/testdata/etherscan/0x8B3D32cf2bb4d0D16656f4c0b04Fa546274f1545/creation_data.json @@ -1,5 +1 @@ -{ - "contractAddress": "0x8b3d32cf2bb4d0d16656f4c0b04fa546274f1545", - "contractCreator": "0x958892b4a0512b28aaac890fc938868bbd42f064", - "txHash": "0x79820495643caf5a1e7e96578361c9ddba0e0735cd684ada7450254f6fd58f51" -} \ No newline at end of file +{"contractAddress":"0x8b3d32cf2bb4d0d16656f4c0b04fa546274f1545","contractCreator":"0x958892b4a0512b28aaac890fc938868bbd42f064","txHash":"0x79820495643caf5a1e7e96578361c9ddba0e0735cd684ada7450254f6fd58f51"} \ No newline at end of file diff --git a/testdata/etherscan/0x8B3D32cf2bb4d0D16656f4c0b04Fa546274f1545/metadata.json b/testdata/etherscan/0x8B3D32cf2bb4d0D16656f4c0b04Fa546274f1545/metadata.json index 5921b5b303ee..1fd95fa4fe5d 100644 --- a/testdata/etherscan/0x8B3D32cf2bb4d0D16656f4c0b04Fa546274f1545/metadata.json +++ b/testdata/etherscan/0x8B3D32cf2bb4d0D16656f4c0b04Fa546274f1545/metadata.json @@ -1,63 +1 @@ -[ - { - "SourceCode": { - "language": "Solidity", - "sources": { - "contracts/governance/governor/GovernorStorage.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./IIpt.sol\";\nimport \"./Structs.sol\";\n\ncontract GovernorCharlieDelegatorStorage {\n /// @notice Active brains of Governor\n address public implementation;\n}\n\n/**\n * @title Storage for Governor Charlie Delegate\n * @notice For future upgrades, do not change GovernorCharlieDelegateStorage. Create a new\n * contract which implements GovernorCharlieDelegateStorage and following the naming convention\n * GovernorCharlieDelegateStorageVX.\n */\n//solhint-disable-next-line max-states-count\ncontract GovernorCharlieDelegateStorage is GovernorCharlieDelegatorStorage {\n /// @notice The number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed\n uint256 public quorumVotes;\n\n /// @notice The number of votes in support of a proposal required in order for an emergency quorum to be reached and for a vote to succeed\n uint256 public emergencyQuorumVotes;\n\n /// @notice The delay before voting on a proposal may take place, once proposed, in blocks\n uint256 public votingDelay;\n\n /// @notice The duration of voting on a proposal, in blocks\n uint256 public votingPeriod;\n\n /// @notice The number of votes required in order for a voter to become a proposer\n uint256 public proposalThreshold;\n\n /// @notice Initial proposal id set at become\n uint256 public initialProposalId;\n\n /// @notice The total number of proposals\n uint256 public proposalCount;\n\n /// @notice The address of the Interest Protocol governance token\n IIpt public ipt;\n\n /// @notice The official record of all proposals ever proposed\n mapping(uint256 => Proposal) public proposals;\n\n /// @notice The latest proposal for each proposer\n mapping(address => uint256) public latestProposalIds;\n\n /// @notice The latest proposal for each proposer\n mapping(bytes32 => bool) public queuedTransactions;\n\n /// @notice The proposal holding period\n uint256 public proposalTimelockDelay;\n\n /// @notice Stores the expiration of account whitelist status as a timestamp\n mapping(address => uint256) public whitelistAccountExpirations;\n\n /// @notice Address which manages whitelisted proposals and whitelist accounts\n address public whitelistGuardian;\n\n /// @notice The duration of the voting on a emergency proposal, in blocks\n uint256 public emergencyVotingPeriod;\n\n /// @notice The emergency proposal holding period\n uint256 public emergencyTimelockDelay;\n\n /// all receipts for proposal\n mapping(uint256 => mapping(address => Receipt)) public proposalReceipts;\n\n /// @notice The emergency proposal holding period\n bool public initialized;\n\n /// @notice The number of votes to reject an optimistic proposal\n uint256 public optimisticQuorumVotes; \n\n /// @notice The delay period before voting begins\n uint256 public optimisticVotingDelay; \n\n /// @notice The maximum number of seconds an address can be whitelisted for\n uint256 public maxWhitelistPeriod; \n}\n" - }, - "hardhat/console.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >= 0.4.22 <0.9.0;\n\nlibrary console {\n\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\n\n\tfunction _sendLogPayload(bytes memory payload) private view {\n\t\tuint256 payloadLength = payload.length;\n\t\taddress consoleAddress = CONSOLE_ADDRESS;\n\t\tassembly {\n\t\t\tlet payloadStart := add(payload, 32)\n\t\t\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\n\t\t}\n\t}\n\n\tfunction log() internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log()\"));\n\t}\n\n\tfunction logInt(int p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(int)\", p0));\n\t}\n\n\tfunction logUint(uint p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint)\", p0));\n\t}\n\n\tfunction logString(string memory p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n\t}\n\n\tfunction logBool(bool p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n\t}\n\n\tfunction logAddress(address p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n\t}\n\n\tfunction logBytes(bytes memory p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes)\", p0));\n\t}\n\n\tfunction logBytes1(bytes1 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes1)\", p0));\n\t}\n\n\tfunction logBytes2(bytes2 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes2)\", p0));\n\t}\n\n\tfunction logBytes3(bytes3 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes3)\", p0));\n\t}\n\n\tfunction logBytes4(bytes4 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes4)\", p0));\n\t}\n\n\tfunction logBytes5(bytes5 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes5)\", p0));\n\t}\n\n\tfunction logBytes6(bytes6 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes6)\", p0));\n\t}\n\n\tfunction logBytes7(bytes7 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes7)\", p0));\n\t}\n\n\tfunction logBytes8(bytes8 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes8)\", p0));\n\t}\n\n\tfunction logBytes9(bytes9 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes9)\", p0));\n\t}\n\n\tfunction logBytes10(bytes10 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes10)\", p0));\n\t}\n\n\tfunction logBytes11(bytes11 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes11)\", p0));\n\t}\n\n\tfunction logBytes12(bytes12 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes12)\", p0));\n\t}\n\n\tfunction logBytes13(bytes13 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes13)\", p0));\n\t}\n\n\tfunction logBytes14(bytes14 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes14)\", p0));\n\t}\n\n\tfunction logBytes15(bytes15 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes15)\", p0));\n\t}\n\n\tfunction logBytes16(bytes16 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes16)\", p0));\n\t}\n\n\tfunction logBytes17(bytes17 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes17)\", p0));\n\t}\n\n\tfunction logBytes18(bytes18 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes18)\", p0));\n\t}\n\n\tfunction logBytes19(bytes19 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes19)\", p0));\n\t}\n\n\tfunction logBytes20(bytes20 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes20)\", p0));\n\t}\n\n\tfunction logBytes21(bytes21 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes21)\", p0));\n\t}\n\n\tfunction logBytes22(bytes22 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes22)\", p0));\n\t}\n\n\tfunction logBytes23(bytes23 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes23)\", p0));\n\t}\n\n\tfunction logBytes24(bytes24 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes24)\", p0));\n\t}\n\n\tfunction logBytes25(bytes25 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes25)\", p0));\n\t}\n\n\tfunction logBytes26(bytes26 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes26)\", p0));\n\t}\n\n\tfunction logBytes27(bytes27 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes27)\", p0));\n\t}\n\n\tfunction logBytes28(bytes28 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes28)\", p0));\n\t}\n\n\tfunction logBytes29(bytes29 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes29)\", p0));\n\t}\n\n\tfunction logBytes30(bytes30 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes30)\", p0));\n\t}\n\n\tfunction logBytes31(bytes31 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes31)\", p0));\n\t}\n\n\tfunction logBytes32(bytes32 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes32)\", p0));\n\t}\n\n\tfunction log(uint p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint)\", p0));\n\t}\n\n\tfunction log(string memory p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n\t}\n\n\tfunction log(bool p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n\t}\n\n\tfunction log(address p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n\t}\n\n\tfunction log(uint p0, uint p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint)\", p0, p1));\n\t}\n\n\tfunction log(uint p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string)\", p0, p1));\n\t}\n\n\tfunction log(uint p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool)\", p0, p1));\n\t}\n\n\tfunction log(uint p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, uint p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, uint p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n\t}\n\n\tfunction log(address p0, uint p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint)\", p0, p1));\n\t}\n\n\tfunction log(address p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n\t}\n\n\tfunction log(address p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n\t}\n\n\tfunction log(address p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, uint p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, address p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n}\n" - }, - "contracts/governance/governor/IGovernor.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./Structs.sol\";\n\n/// @title interface to interact with TokenDelgator\ninterface IGovernorCharlieDelegator {\n function _setImplementation(address implementation_) external;\n\n fallback() external payable;\n\n receive() external payable;\n}\n\n/// @title interface to interact with TokenDelgate\ninterface IGovernorCharlieDelegate {\n function initialize(\n address ipt_\n ) external;\n\n function propose(\n address[] memory targets,\n uint256[] memory values,\n string[] memory signatures,\n bytes[] memory calldatas,\n string memory description,\n bool emergency\n ) external returns (uint256);\n\n function queue(uint256 proposalId) external;\n\n function execute(uint256 proposalId) external payable;\n\n function executeTransaction(\n address target,\n uint256 value,\n string memory signature,\n bytes memory data,\n uint256 eta\n ) external payable;\n\n function cancel(uint256 proposalId) external;\n\n function getActions(uint256 proposalId)\n external\n view\n returns (\n address[] memory targets,\n uint256[] memory values,\n string[] memory signatures,\n bytes[] memory calldatas\n );\n\n function getReceipt(uint256 proposalId, address voter) external view returns (Receipt memory);\n\n function state(uint256 proposalId) external view returns (ProposalState);\n\n function castVote(uint256 proposalId, uint8 support) external;\n\n function castVoteWithReason(\n uint256 proposalId,\n uint8 support,\n string calldata reason\n ) external;\n\n function castVoteBySig(\n uint256 proposalId,\n uint8 support,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n function isWhitelisted(address account) external view returns (bool);\n\n function _setDelay(uint256 proposalTimelockDelay_) external;\n\n function _setEmergencyDelay(uint256 emergencyTimelockDelay_) external;\n\n function _setVotingDelay(uint256 newVotingDelay) external;\n\n function _setVotingPeriod(uint256 newVotingPeriod) external;\n\n function _setEmergencyVotingPeriod(uint256 newEmergencyVotingPeriod) external;\n\n function _setProposalThreshold(uint256 newProposalThreshold) external;\n\n function _setQuorumVotes(uint256 newQuorumVotes) external;\n\n function _setEmergencyQuorumVotes(uint256 newEmergencyQuorumVotes) external;\n\n function _setWhitelistAccountExpiration(address account, uint256 expiration) external;\n\n function _setWhitelistGuardian(address account) external;\n\n function _setOptimisticDelay(uint256 newOptimisticVotingDelay) external;\n\n function _setOptimisticQuorumVotes(uint256 newOptimisticQuorumVotes) external;\n}\n\n/// @title interface which contains all events emitted by delegator & delegate\ninterface GovernorCharlieEvents {\n /// @notice An event emitted when a new proposal is created\n event ProposalCreated(\n uint256 indexed id,\n address indexed proposer,\n address[] targets,\n uint256[] values,\n string[] signatures,\n bytes[] calldatas,\n uint256 indexed startBlock,\n uint256 endBlock,\n string description\n );\n\n /// @notice An event emitted when a vote has been cast on a proposal\n /// @param voter The address which casted a vote\n /// @param proposalId The proposal id which was voted on\n /// @param support Support value for the vote. 0=against, 1=for, 2=abstain\n /// @param votes Number of votes which were cast by the voter\n /// @param reason The reason given for the vote by the voter\n event VoteCast(address indexed voter, uint256 indexed proposalId, uint8 support, uint256 votes, string reason);\n\n /// @notice An event emitted when a proposal has been canceled\n event ProposalCanceled(uint256 indexed id);\n\n /// @notice An event emitted when a proposal has been queued in the Timelock\n event ProposalQueued(uint256 indexed id, uint256 eta);\n\n /// @notice An event emitted when a proposal has been executed in the Timelock\n event ProposalExecuted(uint256 indexed id);\n\n /// @notice An event emitted when the voting delay is set\n event VotingDelaySet(uint256 oldVotingDelay, uint256 newVotingDelay);\n\n /// @notice An event emitted when the voting period is set\n event VotingPeriodSet(uint256 oldVotingPeriod, uint256 newVotingPeriod);\n\n /// @notice An event emitted when the emergency voting period is set\n event EmergencyVotingPeriodSet(uint256 oldEmergencyVotingPeriod, uint256 emergencyVotingPeriod);\n\n /// @notice Emitted when implementation is changed\n event NewImplementation(address oldImplementation, address newImplementation);\n\n /// @notice Emitted when proposal threshold is set\n event ProposalThresholdSet(uint256 oldProposalThreshold, uint256 newProposalThreshold);\n\n /// @notice Emitted when pendingAdmin is changed\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\n\n /// @notice Emitted when pendingAdmin is accepted, which means admin is updated\n event NewAdmin(address oldAdmin, address newAdmin);\n\n /// @notice Emitted when whitelist account expiration is set\n event WhitelistAccountExpirationSet(address account, uint256 expiration);\n\n /// @notice Emitted when the whitelistGuardian is set\n event WhitelistGuardianSet(address oldGuardian, address newGuardian);\n\n /// @notice Emitted when the a new delay is set\n event NewDelay(uint256 oldTimelockDelay, uint256 proposalTimelockDelay);\n\n /// @notice Emitted when the a new emergency delay is set\n event NewEmergencyDelay(uint256 oldEmergencyTimelockDelay, uint256 emergencyTimelockDelay);\n\n /// @notice Emitted when the quorum is updated\n event NewQuorum(uint256 oldQuorumVotes, uint256 quorumVotes);\n\n /// @notice Emitted when the emergency quorum is updated\n event NewEmergencyQuorum(uint256 oldEmergencyQuorumVotes, uint256 emergencyQuorumVotes);\n\n /// @notice An event emitted when the optimistic voting delay is set\n event OptimisticVotingDelaySet(uint256 oldOptimisticVotingDelay, uint256 optimisticVotingDelay);\n\n /// @notice Emitted when the optimistic quorum is updated\n event OptimisticQuorumVotesSet(uint256 oldOptimisticQuorumVotes, uint256 optimisticQuorumVotes);\n\n /// @notice Emitted when a transaction is canceled\n event CancelTransaction(\n bytes32 indexed txHash,\n address indexed target,\n uint256 value,\n string signature,\n bytes data,\n uint256 eta\n );\n\n /// @notice Emitted when a transaction is executed\n event ExecuteTransaction(\n bytes32 indexed txHash,\n address indexed target,\n uint256 value,\n string signature,\n bytes data,\n uint256 eta\n );\n\n /// @notice Emitted when a transaction is queued\n event QueueTransaction(\n bytes32 indexed txHash,\n address indexed target,\n uint256 value,\n string signature,\n bytes data,\n uint256 eta\n );\n}\n" - }, - "contracts/governance/governor/Structs.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nstruct Proposal {\n /// @notice Unique id for looking up a proposal\n uint256 id;\n /// @notice Creator of the proposal\n address proposer;\n /// @notice The timestamp that the proposal will be available for execution, set once the vote succeeds\n uint256 eta;\n /// @notice the ordered list of target addresses for calls to be made\n address[] targets;\n /// @notice The ordered list of values (i.e. msg.value) to be passed to the calls to be made\n uint256[] values;\n /// @notice The ordered list of function signatures to be called\n string[] signatures;\n /// @notice The ordered list of calldata to be passed to each call\n bytes[] calldatas;\n /// @notice The block at which voting begins: holders must delegate their votes prior to this block\n uint256 startBlock;\n /// @notice The block at which voting ends: votes must be cast prior to this block\n uint256 endBlock;\n /// @notice Current number of votes in favor of this proposal\n uint256 forVotes;\n /// @notice Current number of votes in opposition to this proposal\n uint256 againstVotes;\n /// @notice Current number of votes for abstaining for this proposal\n uint256 abstainVotes;\n /// @notice Flag marking whether the proposal has been canceled\n bool canceled;\n /// @notice Flag marking whether the proposal has been executed\n bool executed;\n /// @notice Whether the proposal is an emergency proposal\n bool emergency;\n /// @notice quorum votes requires\n uint256 quorumVotes;\n /// @notice time delay\n uint256 delay;\n}\n\n/// @notice Ballot receipt record for a voter\nstruct Receipt {\n /// @notice Whether or not a vote has been cast\n bool hasVoted;\n /// @notice Whether or not the voter supports the proposal or abstains\n uint8 support;\n /// @notice The number of votes the voter had, which were cast\n uint96 votes;\n}\n\n/// @notice Possible states that a proposal may be in\nenum ProposalState {\n Pending,\n Active,\n Canceled,\n Defeated,\n Succeeded,\n Queued,\n Expired,\n Executed\n}\n" - }, - "contracts/governance/governor/IIpt.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\ninterface IIpt {\n function getPriorVotes(address account, uint256 blockNumber) external view returns (uint96);\n}\n" - }, - "contracts/governance/governor/GovernorDelegate.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\npragma experimental ABIEncoderV2;\nimport \"hardhat/console.sol\";\n\nimport \"./IGovernor.sol\";\nimport \"./GovernorStorage.sol\";\n\ncontract GovernorCharlieDelegate is GovernorCharlieDelegateStorage, GovernorCharlieEvents, IGovernorCharlieDelegate {\n /// @notice The name of this contract\n string public constant name = \"Interest Protocol Governor\";\n\n /// @notice The maximum number of actions that can be included in a proposal\n uint256 public constant proposalMaxOperations = 10;\n\n /// @notice The EIP-712 typehash for the contract's domain\n bytes32 public constant DOMAIN_TYPEHASH =\n keccak256(\"EIP712Domain(string name,uint256 chainId,address verifyingContract)\");\n\n /// @notice The EIP-712 typehash for the ballot struct used by the contract\n bytes32 public constant BALLOT_TYPEHASH = keccak256(\"Ballot(uint256 proposalId,uint8 support)\");\n\n /// @notice The time for a proposal to be executed after passing\n uint256 public constant GRACE_PERIOD = 14 days;\n\n /**\n * @notice Used to initialize the contract during delegator contructor\n * @param ipt_ The address of the IPT token\n */\n function initialize(\n address ipt_\n ) external override {\n require(!initialized, \"already been initialized\");\n ipt = IIpt(ipt_);\n votingPeriod = 40320;\n votingDelay = 13140;\n proposalThreshold = 1000000000000000000000000;\n proposalTimelockDelay = 172800;\n proposalCount = 0;\n quorumVotes = 10000000000000000000000000;\n emergencyQuorumVotes = 40000000000000000000000000;\n emergencyVotingPeriod = 6570;\n emergencyTimelockDelay = 43200;\n optimisticQuorumVotes = 2000000000000000000000000;\n optimisticVotingDelay = 18000;\n maxWhitelistPeriod = 31536000;\n\n initialized = true;\n }\n\n /// @notice any function with this modifier will call the pay_interest() function before\n modifier onlyGov() {\n require(_msgSender() == address(this), \"must come from the gov.\");\n _;\n }\n\n /**\n * @notice Function used to propose a new proposal. Sender must have delegates above the proposal threshold\n * @param targets Target addresses for proposal calls\n * @param values Eth values for proposal calls\n * @param signatures Function signatures for proposal calls\n * @param calldatas Calldatas for proposal calls\n * @param description String description of the proposal\n * @return Proposal id of new proposal\n */\n function propose(\n address[] memory targets,\n uint256[] memory values,\n string[] memory signatures,\n bytes[] memory calldatas,\n string memory description,\n bool emergency\n ) public override returns (uint256) {\n // Reject proposals before initiating as Governor\n require(quorumVotes != 0, \"Charlie not active\");\n // Allow addresses above proposal threshold and whitelisted addresses to propose\n require(\n ipt.getPriorVotes(_msgSender(), (block.number - 1)) >= proposalThreshold || isWhitelisted(_msgSender()),\n \"votes below proposal threshold\"\n );\n require(\n targets.length == values.length && targets.length == signatures.length && targets.length == calldatas.length,\n \"information arity mismatch\"\n );\n require(targets.length != 0, \"must provide actions\");\n require(targets.length <= proposalMaxOperations, \"too many actions\");\n\n uint256 latestProposalId = latestProposalIds[_msgSender()];\n if (latestProposalId != 0) {\n ProposalState proposersLatestProposalState = state(latestProposalId);\n require(proposersLatestProposalState != ProposalState.Active, \"one live proposal per proposer\");\n require(proposersLatestProposalState != ProposalState.Pending, \"one live proposal per proposer\");\n }\n\n proposalCount++;\n Proposal memory newProposal = Proposal({\n id: proposalCount,\n proposer: _msgSender(),\n eta: 0,\n targets: targets,\n values: values,\n signatures: signatures,\n calldatas: calldatas,\n startBlock: block.number + votingDelay,\n endBlock: block.number + votingDelay + votingPeriod,\n forVotes: 0,\n againstVotes: 0,\n abstainVotes: 0,\n canceled: false,\n executed: false,\n emergency: emergency,\n quorumVotes: quorumVotes,\n delay: proposalTimelockDelay\n });\n\n //whitelist can't make emergency\n if (emergency && !isWhitelisted(_msgSender())) {\n newProposal.startBlock = block.number;\n newProposal.endBlock = block.number + emergencyVotingPeriod;\n newProposal.quorumVotes = emergencyQuorumVotes;\n newProposal.delay = emergencyTimelockDelay;\n }\n\n //whitelist can only make optimistic proposals\n if (isWhitelisted(_msgSender())) {\n newProposal.quorumVotes = optimisticQuorumVotes;\n newProposal.startBlock = block.number + optimisticVotingDelay;\n newProposal.endBlock = block.number + optimisticVotingDelay + votingPeriod;\n }\n\n proposals[newProposal.id] = newProposal;\n latestProposalIds[newProposal.proposer] = newProposal.id;\n\n emit ProposalCreated(\n newProposal.id,\n _msgSender(),\n targets,\n values,\n signatures,\n calldatas,\n newProposal.startBlock,\n newProposal.endBlock,\n description\n );\n return newProposal.id;\n }\n\n /**\n * @notice Queues a proposal of state succeeded\n * @param proposalId The id of the proposal to queue\n */\n function queue(uint256 proposalId) external override {\n require(state(proposalId) == ProposalState.Succeeded, \"can only be queued if succeeded\");\n Proposal storage proposal = proposals[proposalId];\n uint256 eta = block.timestamp + proposal.delay;\n for (uint256 i = 0; i < proposal.targets.length; i++) {\n require(\n !queuedTransactions[\n keccak256(\n abi.encode(proposal.targets[i], proposal.values[i], proposal.signatures[i], proposal.calldatas[i], eta)\n )\n ],\n \"proposal already queued\"\n );\n queueTransaction(\n proposal.targets[i],\n proposal.values[i],\n proposal.signatures[i],\n proposal.calldatas[i],\n eta,\n proposal.delay\n );\n }\n proposal.eta = eta;\n emit ProposalQueued(proposalId, eta);\n }\n\n function queueTransaction(\n address target,\n uint256 value,\n string memory signature,\n bytes memory data,\n uint256 eta,\n uint256 delay\n ) internal returns (bytes32) {\n require(eta >= (getBlockTimestamp() + delay), \"must satisfy delay.\");\n\n bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));\n queuedTransactions[txHash] = true;\n\n emit QueueTransaction(txHash, target, value, signature, data, eta);\n return txHash;\n }\n\n /**\n * @notice Executes a queued proposal if eta has passed\n * @param proposalId The id of the proposal to execute\n */\n function execute(uint256 proposalId) external payable override {\n require(state(proposalId) == ProposalState.Queued, \"can only be exec'd if queued\");\n Proposal storage proposal = proposals[proposalId];\n proposal.executed = true;\n for (uint256 i = 0; i < proposal.targets.length; i++) {\n this.executeTransaction{value: proposal.values[i]}(\n proposal.targets[i],\n proposal.values[i],\n proposal.signatures[i],\n proposal.calldatas[i],\n proposal.eta\n );\n }\n emit ProposalExecuted(proposalId);\n }\n\n function executeTransaction(\n address target,\n uint256 value,\n string memory signature,\n bytes memory data,\n uint256 eta\n ) external payable override {\n bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));\n require(queuedTransactions[txHash], \"tx hasn't been queued.\");\n require(getBlockTimestamp() >= eta, \"tx hasn't surpassed timelock.\");\n require(getBlockTimestamp() <= eta + GRACE_PERIOD, \"tx is stale.\");\n\n queuedTransactions[txHash] = false;\n\n bytes memory callData;\n\n if (bytes(signature).length == 0) {\n callData = data;\n } else {\n callData = abi.encodePacked(bytes4(keccak256(bytes(signature))), data);\n }\n\n // solhint-disable-next-line avoid-low-level-calls\n (\n bool success, /*bytes memory returnData*/\n\n ) = target.call{value: value}(callData);\n require(success, \"tx execution reverted.\");\n\n emit ExecuteTransaction(txHash, target, value, signature, data, eta);\n }\n\n /**\n * @notice Cancels a proposal only if sender is the proposer, or proposer delegates dropped below proposal threshold\n * @param proposalId The id of the proposal to cancel\n */\n function cancel(uint256 proposalId) external override {\n require(state(proposalId) != ProposalState.Executed, \"cant cancel executed proposal\");\n\n Proposal storage proposal = proposals[proposalId];\n\n // Proposer can cancel\n if (_msgSender() != proposal.proposer) {\n // Whitelisted proposers can't be canceled for falling below proposal threshold\n if (isWhitelisted(proposal.proposer)) {\n require(\n (ipt.getPriorVotes(proposal.proposer, (block.number - 1)) < proposalThreshold) &&\n _msgSender() == whitelistGuardian,\n \"cancel: whitelisted proposer\"\n );\n } else {\n require(\n (ipt.getPriorVotes(proposal.proposer, (block.number - 1)) < proposalThreshold),\n \"cancel: proposer above threshold\"\n );\n }\n }\n\n proposal.canceled = true;\n for (uint256 i = 0; i < proposal.targets.length; i++) {\n cancelTransaction(\n proposal.targets[i],\n proposal.values[i],\n proposal.signatures[i],\n proposal.calldatas[i],\n proposal.eta\n );\n }\n\n emit ProposalCanceled(proposalId);\n }\n\n function cancelTransaction(\n address target,\n uint256 value,\n string memory signature,\n bytes memory data,\n uint256 eta\n ) internal {\n bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));\n queuedTransactions[txHash] = false;\n\n emit CancelTransaction(txHash, target, value, signature, data, eta);\n }\n\n /**\n * @notice Gets actions of a proposal\n * @param proposalId the id of the proposal\n * @return targets proposal targets\n * @return values proposal values\n * @return signatures proposal signatures\n * @return calldatas proposal calldatae\n */\n function getActions(uint256 proposalId)\n external\n view\n override\n returns (\n address[] memory targets,\n uint256[] memory values,\n string[] memory signatures,\n bytes[] memory calldatas\n )\n {\n Proposal storage p = proposals[proposalId];\n return (p.targets, p.values, p.signatures, p.calldatas);\n }\n\n /**\n * @notice Gets the receipt for a voter on a given proposal\n * @param proposalId the id of proposal\n * @param voter The address of the voter\n * @return The voting receipt\n */\n function getReceipt(uint256 proposalId, address voter) external view override returns (Receipt memory) {\n return proposalReceipts[proposalId][voter];\n }\n\n /**\n * @notice Gets the state of a proposal\n * @param proposalId The id of the proposal\n * @return Proposal state\n */\n // solhint-disable-next-line code-complexity\n function state(uint256 proposalId) public view override returns (ProposalState) {\n require(proposalCount >= proposalId && proposalId > initialProposalId, \"state: invalid proposal id\");\n Proposal storage proposal = proposals[proposalId];\n bool whitelisted = isWhitelisted(proposal.proposer);\n if (proposal.canceled) {\n return ProposalState.Canceled;\n } else if (block.number <= proposal.startBlock) {\n return ProposalState.Pending;\n } else if (block.number <= proposal.endBlock) {\n return ProposalState.Active;\n } else if (\n (whitelisted && proposal.againstVotes > proposal.quorumVotes) ||\n (!whitelisted && proposal.forVotes <= proposal.againstVotes) ||\n (!whitelisted && proposal.forVotes < proposal.quorumVotes)\n ) {\n return ProposalState.Defeated;\n } else if (proposal.eta == 0) {\n return ProposalState.Succeeded;\n } else if (proposal.executed) {\n return ProposalState.Executed;\n } else if (block.timestamp >= (proposal.eta + GRACE_PERIOD)) {\n return ProposalState.Expired;\n }\n return ProposalState.Queued;\n }\n\n /**\n * @notice Cast a vote for a proposal\n * @param proposalId The id of the proposal to vote on\n * @param support The support value for the vote. 0=against, 1=for, 2=abstain\n */\n function castVote(uint256 proposalId, uint8 support) external override {\n emit VoteCast(_msgSender(), proposalId, support, castVoteInternal(_msgSender(), proposalId, support), \"\");\n }\n\n /**\n * @notice Cast a vote for a proposal with a reason\n * @param proposalId The id of the proposal to vote on\n * @param support The support value for the vote. 0=against, 1=for, 2=abstain\n * @param reason The reason given for the vote by the voter\n */\n function castVoteWithReason(\n uint256 proposalId,\n uint8 support,\n string calldata reason\n ) external override {\n emit VoteCast(_msgSender(), proposalId, support, castVoteInternal(_msgSender(), proposalId, support), reason);\n }\n\n /**\n * @notice Cast a vote for a proposal by signature\n * @dev external override function that accepts EIP-712 signatures for voting on proposals.\n */\n function castVoteBySig(\n uint256 proposalId,\n uint8 support,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external override {\n bytes32 domainSeparator = keccak256(\n abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainIdInternal(), address(this))\n );\n bytes32 structHash = keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support));\n bytes32 digest = keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n address signatory = ecrecover(digest, v, r, s);\n require(signatory != address(0), \"castVoteBySig: invalid signature\");\n emit VoteCast(signatory, proposalId, support, castVoteInternal(signatory, proposalId, support), \"\");\n }\n\n /**\n * @notice Internal function that caries out voting logic\n * @param voter The voter that is casting their vote\n * @param proposalId The id of the proposal to vote on\n * @param support The support value for the vote. 0=against, 1=for, 2=abstain\n * @return The number of votes cast\n */\n function castVoteInternal(\n address voter,\n uint256 proposalId,\n uint8 support\n ) internal returns (uint96) {\n require(state(proposalId) == ProposalState.Active, \"voting is closed\");\n require(support <= 2, \"invalid vote type\");\n Proposal storage proposal = proposals[proposalId];\n Receipt storage receipt = proposalReceipts[proposalId][voter];\n require(receipt.hasVoted == false, \"voter already voted\");\n uint96 votes = ipt.getPriorVotes(voter, proposal.startBlock);\n\n if (support == 0) {\n proposal.againstVotes = proposal.againstVotes + votes;\n } else if (support == 1) {\n proposal.forVotes = proposal.forVotes + votes;\n } else if (support == 2) {\n proposal.abstainVotes = proposal.abstainVotes + votes;\n }\n\n receipt.hasVoted = true;\n receipt.support = support;\n receipt.votes = votes;\n\n return votes;\n }\n\n /**\n * @notice View function which returns if an account is whitelisted\n * @param account Account to check white list status of\n * @return If the account is whitelisted\n */\n function isWhitelisted(address account) public view override returns (bool) {\n return (whitelistAccountExpirations[account] > block.timestamp);\n }\n\n /**\n * @notice Governance function for setting the governance token\n * @param token_ new token addr\n */\n function _setNewToken(address token_) external onlyGov {\n ipt = IIpt(token_);\n }\n\n /**\n * @notice Used to update the timelock period\n * @param proposalTimelockDelay_ The proposal holding period\n */\n function _setDelay(uint256 proposalTimelockDelay_) public override onlyGov {\n uint256 oldTimelockDelay = proposalTimelockDelay;\n proposalTimelockDelay = proposalTimelockDelay_;\n\n emit NewDelay(oldTimelockDelay, proposalTimelockDelay);\n }\n\n /**\n * @notice Used to update the emergency timelock period\n * @param emergencyTimelockDelay_ The proposal holding period\n */\n function _setEmergencyDelay(uint256 emergencyTimelockDelay_) public override onlyGov {\n uint256 oldEmergencyTimelockDelay = emergencyTimelockDelay;\n emergencyTimelockDelay = emergencyTimelockDelay_;\n\n emit NewEmergencyDelay(oldEmergencyTimelockDelay, emergencyTimelockDelay);\n }\n\n /**\n * @notice Governance function for setting the voting delay\n * @param newVotingDelay new voting delay, in blocks\n */\n function _setVotingDelay(uint256 newVotingDelay) external override onlyGov {\n uint256 oldVotingDelay = votingDelay;\n votingDelay = newVotingDelay;\n\n emit VotingDelaySet(oldVotingDelay, votingDelay);\n }\n\n /**\n * @notice Governance function for setting the voting period\n * @param newVotingPeriod new voting period, in blocks\n */\n function _setVotingPeriod(uint256 newVotingPeriod) external override onlyGov {\n uint256 oldVotingPeriod = votingPeriod;\n votingPeriod = newVotingPeriod;\n\n emit VotingPeriodSet(oldVotingPeriod, votingPeriod);\n }\n\n /**\n * @notice Governance function for setting the emergency voting period\n * @param newEmergencyVotingPeriod new voting period, in blocks\n */\n function _setEmergencyVotingPeriod(uint256 newEmergencyVotingPeriod) external override onlyGov {\n uint256 oldEmergencyVotingPeriod = emergencyVotingPeriod;\n emergencyVotingPeriod = newEmergencyVotingPeriod;\n\n emit EmergencyVotingPeriodSet(oldEmergencyVotingPeriod, emergencyVotingPeriod);\n }\n\n /**\n * @notice Governance function for setting the proposal threshold\n * @param newProposalThreshold new proposal threshold\n */\n function _setProposalThreshold(uint256 newProposalThreshold) external override onlyGov {\n uint256 oldProposalThreshold = proposalThreshold;\n proposalThreshold = newProposalThreshold;\n\n emit ProposalThresholdSet(oldProposalThreshold, proposalThreshold);\n }\n\n /**\n * @notice Governance function for setting the quorum\n * @param newQuorumVotes new proposal quorum\n */\n function _setQuorumVotes(uint256 newQuorumVotes) external override onlyGov {\n uint256 oldQuorumVotes = quorumVotes;\n quorumVotes = newQuorumVotes;\n\n emit NewQuorum(oldQuorumVotes, quorumVotes);\n }\n\n /**\n * @notice Governance function for setting the emergency quorum\n * @param newEmergencyQuorumVotes new proposal quorum\n */\n function _setEmergencyQuorumVotes(uint256 newEmergencyQuorumVotes) external override onlyGov {\n uint256 oldEmergencyQuorumVotes = emergencyQuorumVotes;\n emergencyQuorumVotes = newEmergencyQuorumVotes;\n\n emit NewEmergencyQuorum(oldEmergencyQuorumVotes, emergencyQuorumVotes);\n }\n\n /**\n * @notice Governance function for setting the whitelist expiration as a timestamp\n * for an account. Whitelist status allows accounts to propose without meeting threshold\n * @param account Account address to set whitelist expiration for\n * @param expiration Expiration for account whitelist status as timestamp (if now < expiration, whitelisted)\n */\n function _setWhitelistAccountExpiration(address account, uint256 expiration) external override onlyGov {\n require (expiration < (maxWhitelistPeriod + block.timestamp), \"expiration exceeds max\");\n whitelistAccountExpirations[account] = expiration;\n\n emit WhitelistAccountExpirationSet(account, expiration);\n }\n\n /**\n * @notice Governance function for setting the whitelistGuardian. WhitelistGuardian can cancel proposals from whitelisted addresses\n * @param account Account to set whitelistGuardian to (0x0 to remove whitelistGuardian)\n */\n function _setWhitelistGuardian(address account) external override onlyGov {\n address oldGuardian = whitelistGuardian;\n whitelistGuardian = account;\n\n emit WhitelistGuardianSet(oldGuardian, whitelistGuardian);\n }\n\n /**\n * @notice Governance function for setting the optimistic voting delay\n * @param newOptimisticVotingDelay new optimistic voting delay, in blocks\n */\n function _setOptimisticDelay(uint256 newOptimisticVotingDelay) external override onlyGov {\n uint256 oldOptimisticVotingDelay = optimisticVotingDelay;\n optimisticVotingDelay = newOptimisticVotingDelay;\n\n emit OptimisticVotingDelaySet(oldOptimisticVotingDelay, optimisticVotingDelay);\n }\n\n /**\n * @notice Governance function for setting the optimistic quorum\n * @param newOptimisticQuorumVotes new optimistic quorum votes, in blocks\n */\n function _setOptimisticQuorumVotes(uint256 newOptimisticQuorumVotes) external override onlyGov {\n uint256 oldOptimisticQuorumVotes = optimisticQuorumVotes;\n optimisticQuorumVotes = newOptimisticQuorumVotes;\n\n emit OptimisticQuorumVotesSet(oldOptimisticQuorumVotes, optimisticQuorumVotes);\n }\n\n function getChainIdInternal() internal view returns (uint256) {\n return block.chainid;\n }\n\n function getBlockTimestamp() internal view returns (uint256) {\n // solium-disable-next-line security/no-block-members\n return block.timestamp;\n }\n\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n}\n" - } - }, - "settings": { - "optimizer": { - "enabled": true, - "runs": 200, - "details": { - "orderLiterals": true, - "deduplicate": true, - "cse": true, - "yul": true - } - }, - "outputSelection": { - "*": { - "*": [ - "evm.bytecode", - "evm.deployedBytecode", - "devdoc", - "userdoc", - "metadata", - "abi" - ] - } - }, - "libraries": {} - } - }, - "ABI": "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"signature\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"eta\",\"type\":\"uint256\"}],\"name\":\"CancelTransaction\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldEmergencyVotingPeriod\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"emergencyVotingPeriod\",\"type\":\"uint256\"}],\"name\":\"EmergencyVotingPeriodSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"signature\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"eta\",\"type\":\"uint256\"}],\"name\":\"ExecuteTransaction\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"NewAdmin\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldTimelockDelay\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"proposalTimelockDelay\",\"type\":\"uint256\"}],\"name\":\"NewDelay\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldEmergencyTimelockDelay\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"emergencyTimelockDelay\",\"type\":\"uint256\"}],\"name\":\"NewEmergencyDelay\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldEmergencyQuorumVotes\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"emergencyQuorumVotes\",\"type\":\"uint256\"}],\"name\":\"NewEmergencyQuorum\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldImplementation\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"NewImplementation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldPendingAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newPendingAdmin\",\"type\":\"address\"}],\"name\":\"NewPendingAdmin\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldQuorumVotes\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"quorumVotes\",\"type\":\"uint256\"}],\"name\":\"NewQuorum\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldOptimisticQuorumVotes\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"optimisticQuorumVotes\",\"type\":\"uint256\"}],\"name\":\"OptimisticQuorumVotesSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldOptimisticVotingDelay\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"optimisticVotingDelay\",\"type\":\"uint256\"}],\"name\":\"OptimisticVotingDelaySet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"ProposalCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"targets\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"string[]\",\"name\":\"signatures\",\"type\":\"string[]\"},{\"indexed\":false,\"internalType\":\"bytes[]\",\"name\":\"calldatas\",\"type\":\"bytes[]\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"startBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"endBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"}],\"name\":\"ProposalCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"ProposalExecuted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"eta\",\"type\":\"uint256\"}],\"name\":\"ProposalQueued\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldProposalThreshold\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newProposalThreshold\",\"type\":\"uint256\"}],\"name\":\"ProposalThresholdSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"signature\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"eta\",\"type\":\"uint256\"}],\"name\":\"QueueTransaction\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"proposalId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"support\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"votes\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"reason\",\"type\":\"string\"}],\"name\":\"VoteCast\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldVotingDelay\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newVotingDelay\",\"type\":\"uint256\"}],\"name\":\"VotingDelaySet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldVotingPeriod\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newVotingPeriod\",\"type\":\"uint256\"}],\"name\":\"VotingPeriodSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"}],\"name\":\"WhitelistAccountExpirationSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldGuardian\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newGuardian\",\"type\":\"address\"}],\"name\":\"WhitelistGuardianSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BALLOT_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"GRACE_PERIOD\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"proposalTimelockDelay_\",\"type\":\"uint256\"}],\"name\":\"_setDelay\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"emergencyTimelockDelay_\",\"type\":\"uint256\"}],\"name\":\"_setEmergencyDelay\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newEmergencyQuorumVotes\",\"type\":\"uint256\"}],\"name\":\"_setEmergencyQuorumVotes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newEmergencyVotingPeriod\",\"type\":\"uint256\"}],\"name\":\"_setEmergencyVotingPeriod\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token_\",\"type\":\"address\"}],\"name\":\"_setNewToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newOptimisticVotingDelay\",\"type\":\"uint256\"}],\"name\":\"_setOptimisticDelay\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newOptimisticQuorumVotes\",\"type\":\"uint256\"}],\"name\":\"_setOptimisticQuorumVotes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newProposalThreshold\",\"type\":\"uint256\"}],\"name\":\"_setProposalThreshold\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newQuorumVotes\",\"type\":\"uint256\"}],\"name\":\"_setQuorumVotes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newVotingDelay\",\"type\":\"uint256\"}],\"name\":\"_setVotingDelay\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newVotingPeriod\",\"type\":\"uint256\"}],\"name\":\"_setVotingPeriod\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"}],\"name\":\"_setWhitelistAccountExpiration\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"_setWhitelistGuardian\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"proposalId\",\"type\":\"uint256\"}],\"name\":\"cancel\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"proposalId\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"support\",\"type\":\"uint8\"}],\"name\":\"castVote\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"proposalId\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"support\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"castVoteBySig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"proposalId\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"support\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"reason\",\"type\":\"string\"}],\"name\":\"castVoteWithReason\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"emergencyQuorumVotes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"emergencyTimelockDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"emergencyVotingPeriod\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"proposalId\",\"type\":\"uint256\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"signature\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"eta\",\"type\":\"uint256\"}],\"name\":\"executeTransaction\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"proposalId\",\"type\":\"uint256\"}],\"name\":\"getActions\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"targets\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"},{\"internalType\":\"string[]\",\"name\":\"signatures\",\"type\":\"string[]\"},{\"internalType\":\"bytes[]\",\"name\":\"calldatas\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"proposalId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"}],\"name\":\"getReceipt\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"hasVoted\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"support\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"votes\",\"type\":\"uint96\"}],\"internalType\":\"struct Receipt\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialProposalId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"ipt_\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ipt\",\"outputs\":[{\"internalType\":\"contract IIpt\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"isWhitelisted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"latestProposalIds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxWhitelistPeriod\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"optimisticQuorumVotes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"optimisticVotingDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proposalCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proposalMaxOperations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"proposalReceipts\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"hasVoted\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"support\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"votes\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proposalThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proposalTimelockDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"proposals\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"eta\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"startBlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"endBlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"forVotes\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"againstVotes\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"abstainVotes\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"canceled\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"executed\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"emergency\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"quorumVotes\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"delay\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"targets\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"},{\"internalType\":\"string[]\",\"name\":\"signatures\",\"type\":\"string[]\"},{\"internalType\":\"bytes[]\",\"name\":\"calldatas\",\"type\":\"bytes[]\"},{\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"emergency\",\"type\":\"bool\"}],\"name\":\"propose\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"proposalId\",\"type\":\"uint256\"}],\"name\":\"queue\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"queuedTransactions\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"quorumVotes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"proposalId\",\"type\":\"uint256\"}],\"name\":\"state\",\"outputs\":[{\"internalType\":\"enum ProposalState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"votingDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"votingPeriod\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"whitelistAccountExpirations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"whitelistGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - "ContractName": "GovernorCharlieDelegate", - "CompilerVersion": "v0.8.9+commit.e5eed63a", - "OptimizationUsed": 1, - "Runs": 200, - "ConstructorArguments": "0x", - "EVMVersion": "Default", - "Library": "", - "LicenseType": "", - "Proxy": 0, - "SwarmSource": "" - } -] \ No newline at end of file +[{"SourceCode":{"language":"Solidity","sources":{"contracts/governance/governor/GovernorStorage.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./IIpt.sol\";\nimport \"./Structs.sol\";\n\ncontract GovernorCharlieDelegatorStorage {\n /// @notice Active brains of Governor\n address public implementation;\n}\n\n/**\n * @title Storage for Governor Charlie Delegate\n * @notice For future upgrades, do not change GovernorCharlieDelegateStorage. Create a new\n * contract which implements GovernorCharlieDelegateStorage and following the naming convention\n * GovernorCharlieDelegateStorageVX.\n */\n//solhint-disable-next-line max-states-count\ncontract GovernorCharlieDelegateStorage is GovernorCharlieDelegatorStorage {\n /// @notice The number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed\n uint256 public quorumVotes;\n\n /// @notice The number of votes in support of a proposal required in order for an emergency quorum to be reached and for a vote to succeed\n uint256 public emergencyQuorumVotes;\n\n /// @notice The delay before voting on a proposal may take place, once proposed, in blocks\n uint256 public votingDelay;\n\n /// @notice The duration of voting on a proposal, in blocks\n uint256 public votingPeriod;\n\n /// @notice The number of votes required in order for a voter to become a proposer\n uint256 public proposalThreshold;\n\n /// @notice Initial proposal id set at become\n uint256 public initialProposalId;\n\n /// @notice The total number of proposals\n uint256 public proposalCount;\n\n /// @notice The address of the Interest Protocol governance token\n IIpt public ipt;\n\n /// @notice The official record of all proposals ever proposed\n mapping(uint256 => Proposal) public proposals;\n\n /// @notice The latest proposal for each proposer\n mapping(address => uint256) public latestProposalIds;\n\n /// @notice The latest proposal for each proposer\n mapping(bytes32 => bool) public queuedTransactions;\n\n /// @notice The proposal holding period\n uint256 public proposalTimelockDelay;\n\n /// @notice Stores the expiration of account whitelist status as a timestamp\n mapping(address => uint256) public whitelistAccountExpirations;\n\n /// @notice Address which manages whitelisted proposals and whitelist accounts\n address public whitelistGuardian;\n\n /// @notice The duration of the voting on a emergency proposal, in blocks\n uint256 public emergencyVotingPeriod;\n\n /// @notice The emergency proposal holding period\n uint256 public emergencyTimelockDelay;\n\n /// all receipts for proposal\n mapping(uint256 => mapping(address => Receipt)) public proposalReceipts;\n\n /// @notice The emergency proposal holding period\n bool public initialized;\n\n /// @notice The number of votes to reject an optimistic proposal\n uint256 public optimisticQuorumVotes; \n\n /// @notice The delay period before voting begins\n uint256 public optimisticVotingDelay; \n\n /// @notice The maximum number of seconds an address can be whitelisted for\n uint256 public maxWhitelistPeriod; \n}\n"},"hardhat/console.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity >= 0.4.22 <0.9.0;\n\nlibrary console {\n\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\n\n\tfunction _sendLogPayload(bytes memory payload) private view {\n\t\tuint256 payloadLength = payload.length;\n\t\taddress consoleAddress = CONSOLE_ADDRESS;\n\t\tassembly {\n\t\t\tlet payloadStart := add(payload, 32)\n\t\t\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\n\t\t}\n\t}\n\n\tfunction log() internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log()\"));\n\t}\n\n\tfunction logInt(int p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(int)\", p0));\n\t}\n\n\tfunction logUint(uint p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint)\", p0));\n\t}\n\n\tfunction logString(string memory p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n\t}\n\n\tfunction logBool(bool p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n\t}\n\n\tfunction logAddress(address p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n\t}\n\n\tfunction logBytes(bytes memory p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes)\", p0));\n\t}\n\n\tfunction logBytes1(bytes1 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes1)\", p0));\n\t}\n\n\tfunction logBytes2(bytes2 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes2)\", p0));\n\t}\n\n\tfunction logBytes3(bytes3 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes3)\", p0));\n\t}\n\n\tfunction logBytes4(bytes4 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes4)\", p0));\n\t}\n\n\tfunction logBytes5(bytes5 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes5)\", p0));\n\t}\n\n\tfunction logBytes6(bytes6 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes6)\", p0));\n\t}\n\n\tfunction logBytes7(bytes7 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes7)\", p0));\n\t}\n\n\tfunction logBytes8(bytes8 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes8)\", p0));\n\t}\n\n\tfunction logBytes9(bytes9 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes9)\", p0));\n\t}\n\n\tfunction logBytes10(bytes10 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes10)\", p0));\n\t}\n\n\tfunction logBytes11(bytes11 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes11)\", p0));\n\t}\n\n\tfunction logBytes12(bytes12 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes12)\", p0));\n\t}\n\n\tfunction logBytes13(bytes13 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes13)\", p0));\n\t}\n\n\tfunction logBytes14(bytes14 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes14)\", p0));\n\t}\n\n\tfunction logBytes15(bytes15 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes15)\", p0));\n\t}\n\n\tfunction logBytes16(bytes16 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes16)\", p0));\n\t}\n\n\tfunction logBytes17(bytes17 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes17)\", p0));\n\t}\n\n\tfunction logBytes18(bytes18 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes18)\", p0));\n\t}\n\n\tfunction logBytes19(bytes19 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes19)\", p0));\n\t}\n\n\tfunction logBytes20(bytes20 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes20)\", p0));\n\t}\n\n\tfunction logBytes21(bytes21 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes21)\", p0));\n\t}\n\n\tfunction logBytes22(bytes22 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes22)\", p0));\n\t}\n\n\tfunction logBytes23(bytes23 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes23)\", p0));\n\t}\n\n\tfunction logBytes24(bytes24 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes24)\", p0));\n\t}\n\n\tfunction logBytes25(bytes25 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes25)\", p0));\n\t}\n\n\tfunction logBytes26(bytes26 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes26)\", p0));\n\t}\n\n\tfunction logBytes27(bytes27 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes27)\", p0));\n\t}\n\n\tfunction logBytes28(bytes28 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes28)\", p0));\n\t}\n\n\tfunction logBytes29(bytes29 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes29)\", p0));\n\t}\n\n\tfunction logBytes30(bytes30 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes30)\", p0));\n\t}\n\n\tfunction logBytes31(bytes31 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes31)\", p0));\n\t}\n\n\tfunction logBytes32(bytes32 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes32)\", p0));\n\t}\n\n\tfunction log(uint p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint)\", p0));\n\t}\n\n\tfunction log(string memory p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n\t}\n\n\tfunction log(bool p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n\t}\n\n\tfunction log(address p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n\t}\n\n\tfunction log(uint p0, uint p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint)\", p0, p1));\n\t}\n\n\tfunction log(uint p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string)\", p0, p1));\n\t}\n\n\tfunction log(uint p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool)\", p0, p1));\n\t}\n\n\tfunction log(uint p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, uint p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, uint p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n\t}\n\n\tfunction log(address p0, uint p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint)\", p0, p1));\n\t}\n\n\tfunction log(address p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n\t}\n\n\tfunction log(address p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n\t}\n\n\tfunction log(address p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, uint p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, address p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n}\n"},"contracts/governance/governor/IGovernor.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./Structs.sol\";\n\n/// @title interface to interact with TokenDelgator\ninterface IGovernorCharlieDelegator {\n function _setImplementation(address implementation_) external;\n\n fallback() external payable;\n\n receive() external payable;\n}\n\n/// @title interface to interact with TokenDelgate\ninterface IGovernorCharlieDelegate {\n function initialize(\n address ipt_\n ) external;\n\n function propose(\n address[] memory targets,\n uint256[] memory values,\n string[] memory signatures,\n bytes[] memory calldatas,\n string memory description,\n bool emergency\n ) external returns (uint256);\n\n function queue(uint256 proposalId) external;\n\n function execute(uint256 proposalId) external payable;\n\n function executeTransaction(\n address target,\n uint256 value,\n string memory signature,\n bytes memory data,\n uint256 eta\n ) external payable;\n\n function cancel(uint256 proposalId) external;\n\n function getActions(uint256 proposalId)\n external\n view\n returns (\n address[] memory targets,\n uint256[] memory values,\n string[] memory signatures,\n bytes[] memory calldatas\n );\n\n function getReceipt(uint256 proposalId, address voter) external view returns (Receipt memory);\n\n function state(uint256 proposalId) external view returns (ProposalState);\n\n function castVote(uint256 proposalId, uint8 support) external;\n\n function castVoteWithReason(\n uint256 proposalId,\n uint8 support,\n string calldata reason\n ) external;\n\n function castVoteBySig(\n uint256 proposalId,\n uint8 support,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n function isWhitelisted(address account) external view returns (bool);\n\n function _setDelay(uint256 proposalTimelockDelay_) external;\n\n function _setEmergencyDelay(uint256 emergencyTimelockDelay_) external;\n\n function _setVotingDelay(uint256 newVotingDelay) external;\n\n function _setVotingPeriod(uint256 newVotingPeriod) external;\n\n function _setEmergencyVotingPeriod(uint256 newEmergencyVotingPeriod) external;\n\n function _setProposalThreshold(uint256 newProposalThreshold) external;\n\n function _setQuorumVotes(uint256 newQuorumVotes) external;\n\n function _setEmergencyQuorumVotes(uint256 newEmergencyQuorumVotes) external;\n\n function _setWhitelistAccountExpiration(address account, uint256 expiration) external;\n\n function _setWhitelistGuardian(address account) external;\n\n function _setOptimisticDelay(uint256 newOptimisticVotingDelay) external;\n\n function _setOptimisticQuorumVotes(uint256 newOptimisticQuorumVotes) external;\n}\n\n/// @title interface which contains all events emitted by delegator & delegate\ninterface GovernorCharlieEvents {\n /// @notice An event emitted when a new proposal is created\n event ProposalCreated(\n uint256 indexed id,\n address indexed proposer,\n address[] targets,\n uint256[] values,\n string[] signatures,\n bytes[] calldatas,\n uint256 indexed startBlock,\n uint256 endBlock,\n string description\n );\n\n /// @notice An event emitted when a vote has been cast on a proposal\n /// @param voter The address which casted a vote\n /// @param proposalId The proposal id which was voted on\n /// @param support Support value for the vote. 0=against, 1=for, 2=abstain\n /// @param votes Number of votes which were cast by the voter\n /// @param reason The reason given for the vote by the voter\n event VoteCast(address indexed voter, uint256 indexed proposalId, uint8 support, uint256 votes, string reason);\n\n /// @notice An event emitted when a proposal has been canceled\n event ProposalCanceled(uint256 indexed id);\n\n /// @notice An event emitted when a proposal has been queued in the Timelock\n event ProposalQueued(uint256 indexed id, uint256 eta);\n\n /// @notice An event emitted when a proposal has been executed in the Timelock\n event ProposalExecuted(uint256 indexed id);\n\n /// @notice An event emitted when the voting delay is set\n event VotingDelaySet(uint256 oldVotingDelay, uint256 newVotingDelay);\n\n /// @notice An event emitted when the voting period is set\n event VotingPeriodSet(uint256 oldVotingPeriod, uint256 newVotingPeriod);\n\n /// @notice An event emitted when the emergency voting period is set\n event EmergencyVotingPeriodSet(uint256 oldEmergencyVotingPeriod, uint256 emergencyVotingPeriod);\n\n /// @notice Emitted when implementation is changed\n event NewImplementation(address oldImplementation, address newImplementation);\n\n /// @notice Emitted when proposal threshold is set\n event ProposalThresholdSet(uint256 oldProposalThreshold, uint256 newProposalThreshold);\n\n /// @notice Emitted when pendingAdmin is changed\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\n\n /// @notice Emitted when pendingAdmin is accepted, which means admin is updated\n event NewAdmin(address oldAdmin, address newAdmin);\n\n /// @notice Emitted when whitelist account expiration is set\n event WhitelistAccountExpirationSet(address account, uint256 expiration);\n\n /// @notice Emitted when the whitelistGuardian is set\n event WhitelistGuardianSet(address oldGuardian, address newGuardian);\n\n /// @notice Emitted when the a new delay is set\n event NewDelay(uint256 oldTimelockDelay, uint256 proposalTimelockDelay);\n\n /// @notice Emitted when the a new emergency delay is set\n event NewEmergencyDelay(uint256 oldEmergencyTimelockDelay, uint256 emergencyTimelockDelay);\n\n /// @notice Emitted when the quorum is updated\n event NewQuorum(uint256 oldQuorumVotes, uint256 quorumVotes);\n\n /// @notice Emitted when the emergency quorum is updated\n event NewEmergencyQuorum(uint256 oldEmergencyQuorumVotes, uint256 emergencyQuorumVotes);\n\n /// @notice An event emitted when the optimistic voting delay is set\n event OptimisticVotingDelaySet(uint256 oldOptimisticVotingDelay, uint256 optimisticVotingDelay);\n\n /// @notice Emitted when the optimistic quorum is updated\n event OptimisticQuorumVotesSet(uint256 oldOptimisticQuorumVotes, uint256 optimisticQuorumVotes);\n\n /// @notice Emitted when a transaction is canceled\n event CancelTransaction(\n bytes32 indexed txHash,\n address indexed target,\n uint256 value,\n string signature,\n bytes data,\n uint256 eta\n );\n\n /// @notice Emitted when a transaction is executed\n event ExecuteTransaction(\n bytes32 indexed txHash,\n address indexed target,\n uint256 value,\n string signature,\n bytes data,\n uint256 eta\n );\n\n /// @notice Emitted when a transaction is queued\n event QueueTransaction(\n bytes32 indexed txHash,\n address indexed target,\n uint256 value,\n string signature,\n bytes data,\n uint256 eta\n );\n}\n"},"contracts/governance/governor/Structs.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nstruct Proposal {\n /// @notice Unique id for looking up a proposal\n uint256 id;\n /// @notice Creator of the proposal\n address proposer;\n /// @notice The timestamp that the proposal will be available for execution, set once the vote succeeds\n uint256 eta;\n /// @notice the ordered list of target addresses for calls to be made\n address[] targets;\n /// @notice The ordered list of values (i.e. msg.value) to be passed to the calls to be made\n uint256[] values;\n /// @notice The ordered list of function signatures to be called\n string[] signatures;\n /// @notice The ordered list of calldata to be passed to each call\n bytes[] calldatas;\n /// @notice The block at which voting begins: holders must delegate their votes prior to this block\n uint256 startBlock;\n /// @notice The block at which voting ends: votes must be cast prior to this block\n uint256 endBlock;\n /// @notice Current number of votes in favor of this proposal\n uint256 forVotes;\n /// @notice Current number of votes in opposition to this proposal\n uint256 againstVotes;\n /// @notice Current number of votes for abstaining for this proposal\n uint256 abstainVotes;\n /// @notice Flag marking whether the proposal has been canceled\n bool canceled;\n /// @notice Flag marking whether the proposal has been executed\n bool executed;\n /// @notice Whether the proposal is an emergency proposal\n bool emergency;\n /// @notice quorum votes requires\n uint256 quorumVotes;\n /// @notice time delay\n uint256 delay;\n}\n\n/// @notice Ballot receipt record for a voter\nstruct Receipt {\n /// @notice Whether or not a vote has been cast\n bool hasVoted;\n /// @notice Whether or not the voter supports the proposal or abstains\n uint8 support;\n /// @notice The number of votes the voter had, which were cast\n uint96 votes;\n}\n\n/// @notice Possible states that a proposal may be in\nenum ProposalState {\n Pending,\n Active,\n Canceled,\n Defeated,\n Succeeded,\n Queued,\n Expired,\n Executed\n}\n"},"contracts/governance/governor/IIpt.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\ninterface IIpt {\n function getPriorVotes(address account, uint256 blockNumber) external view returns (uint96);\n}\n"},"contracts/governance/governor/GovernorDelegate.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\npragma experimental ABIEncoderV2;\nimport \"hardhat/console.sol\";\n\nimport \"./IGovernor.sol\";\nimport \"./GovernorStorage.sol\";\n\ncontract GovernorCharlieDelegate is GovernorCharlieDelegateStorage, GovernorCharlieEvents, IGovernorCharlieDelegate {\n /// @notice The name of this contract\n string public constant name = \"Interest Protocol Governor\";\n\n /// @notice The maximum number of actions that can be included in a proposal\n uint256 public constant proposalMaxOperations = 10;\n\n /// @notice The EIP-712 typehash for the contract's domain\n bytes32 public constant DOMAIN_TYPEHASH =\n keccak256(\"EIP712Domain(string name,uint256 chainId,address verifyingContract)\");\n\n /// @notice The EIP-712 typehash for the ballot struct used by the contract\n bytes32 public constant BALLOT_TYPEHASH = keccak256(\"Ballot(uint256 proposalId,uint8 support)\");\n\n /// @notice The time for a proposal to be executed after passing\n uint256 public constant GRACE_PERIOD = 14 days;\n\n /**\n * @notice Used to initialize the contract during delegator contructor\n * @param ipt_ The address of the IPT token\n */\n function initialize(\n address ipt_\n ) external override {\n require(!initialized, \"already been initialized\");\n ipt = IIpt(ipt_);\n votingPeriod = 40320;\n votingDelay = 13140;\n proposalThreshold = 1000000000000000000000000;\n proposalTimelockDelay = 172800;\n proposalCount = 0;\n quorumVotes = 10000000000000000000000000;\n emergencyQuorumVotes = 40000000000000000000000000;\n emergencyVotingPeriod = 6570;\n emergencyTimelockDelay = 43200;\n optimisticQuorumVotes = 2000000000000000000000000;\n optimisticVotingDelay = 18000;\n maxWhitelistPeriod = 31536000;\n\n initialized = true;\n }\n\n /// @notice any function with this modifier will call the pay_interest() function before\n modifier onlyGov() {\n require(_msgSender() == address(this), \"must come from the gov.\");\n _;\n }\n\n /**\n * @notice Function used to propose a new proposal. Sender must have delegates above the proposal threshold\n * @param targets Target addresses for proposal calls\n * @param values Eth values for proposal calls\n * @param signatures Function signatures for proposal calls\n * @param calldatas Calldatas for proposal calls\n * @param description String description of the proposal\n * @return Proposal id of new proposal\n */\n function propose(\n address[] memory targets,\n uint256[] memory values,\n string[] memory signatures,\n bytes[] memory calldatas,\n string memory description,\n bool emergency\n ) public override returns (uint256) {\n // Reject proposals before initiating as Governor\n require(quorumVotes != 0, \"Charlie not active\");\n // Allow addresses above proposal threshold and whitelisted addresses to propose\n require(\n ipt.getPriorVotes(_msgSender(), (block.number - 1)) >= proposalThreshold || isWhitelisted(_msgSender()),\n \"votes below proposal threshold\"\n );\n require(\n targets.length == values.length && targets.length == signatures.length && targets.length == calldatas.length,\n \"information arity mismatch\"\n );\n require(targets.length != 0, \"must provide actions\");\n require(targets.length <= proposalMaxOperations, \"too many actions\");\n\n uint256 latestProposalId = latestProposalIds[_msgSender()];\n if (latestProposalId != 0) {\n ProposalState proposersLatestProposalState = state(latestProposalId);\n require(proposersLatestProposalState != ProposalState.Active, \"one live proposal per proposer\");\n require(proposersLatestProposalState != ProposalState.Pending, \"one live proposal per proposer\");\n }\n\n proposalCount++;\n Proposal memory newProposal = Proposal({\n id: proposalCount,\n proposer: _msgSender(),\n eta: 0,\n targets: targets,\n values: values,\n signatures: signatures,\n calldatas: calldatas,\n startBlock: block.number + votingDelay,\n endBlock: block.number + votingDelay + votingPeriod,\n forVotes: 0,\n againstVotes: 0,\n abstainVotes: 0,\n canceled: false,\n executed: false,\n emergency: emergency,\n quorumVotes: quorumVotes,\n delay: proposalTimelockDelay\n });\n\n //whitelist can't make emergency\n if (emergency && !isWhitelisted(_msgSender())) {\n newProposal.startBlock = block.number;\n newProposal.endBlock = block.number + emergencyVotingPeriod;\n newProposal.quorumVotes = emergencyQuorumVotes;\n newProposal.delay = emergencyTimelockDelay;\n }\n\n //whitelist can only make optimistic proposals\n if (isWhitelisted(_msgSender())) {\n newProposal.quorumVotes = optimisticQuorumVotes;\n newProposal.startBlock = block.number + optimisticVotingDelay;\n newProposal.endBlock = block.number + optimisticVotingDelay + votingPeriod;\n }\n\n proposals[newProposal.id] = newProposal;\n latestProposalIds[newProposal.proposer] = newProposal.id;\n\n emit ProposalCreated(\n newProposal.id,\n _msgSender(),\n targets,\n values,\n signatures,\n calldatas,\n newProposal.startBlock,\n newProposal.endBlock,\n description\n );\n return newProposal.id;\n }\n\n /**\n * @notice Queues a proposal of state succeeded\n * @param proposalId The id of the proposal to queue\n */\n function queue(uint256 proposalId) external override {\n require(state(proposalId) == ProposalState.Succeeded, \"can only be queued if succeeded\");\n Proposal storage proposal = proposals[proposalId];\n uint256 eta = block.timestamp + proposal.delay;\n for (uint256 i = 0; i < proposal.targets.length; i++) {\n require(\n !queuedTransactions[\n keccak256(\n abi.encode(proposal.targets[i], proposal.values[i], proposal.signatures[i], proposal.calldatas[i], eta)\n )\n ],\n \"proposal already queued\"\n );\n queueTransaction(\n proposal.targets[i],\n proposal.values[i],\n proposal.signatures[i],\n proposal.calldatas[i],\n eta,\n proposal.delay\n );\n }\n proposal.eta = eta;\n emit ProposalQueued(proposalId, eta);\n }\n\n function queueTransaction(\n address target,\n uint256 value,\n string memory signature,\n bytes memory data,\n uint256 eta,\n uint256 delay\n ) internal returns (bytes32) {\n require(eta >= (getBlockTimestamp() + delay), \"must satisfy delay.\");\n\n bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));\n queuedTransactions[txHash] = true;\n\n emit QueueTransaction(txHash, target, value, signature, data, eta);\n return txHash;\n }\n\n /**\n * @notice Executes a queued proposal if eta has passed\n * @param proposalId The id of the proposal to execute\n */\n function execute(uint256 proposalId) external payable override {\n require(state(proposalId) == ProposalState.Queued, \"can only be exec'd if queued\");\n Proposal storage proposal = proposals[proposalId];\n proposal.executed = true;\n for (uint256 i = 0; i < proposal.targets.length; i++) {\n this.executeTransaction{value: proposal.values[i]}(\n proposal.targets[i],\n proposal.values[i],\n proposal.signatures[i],\n proposal.calldatas[i],\n proposal.eta\n );\n }\n emit ProposalExecuted(proposalId);\n }\n\n function executeTransaction(\n address target,\n uint256 value,\n string memory signature,\n bytes memory data,\n uint256 eta\n ) external payable override {\n bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));\n require(queuedTransactions[txHash], \"tx hasn't been queued.\");\n require(getBlockTimestamp() >= eta, \"tx hasn't surpassed timelock.\");\n require(getBlockTimestamp() <= eta + GRACE_PERIOD, \"tx is stale.\");\n\n queuedTransactions[txHash] = false;\n\n bytes memory callData;\n\n if (bytes(signature).length == 0) {\n callData = data;\n } else {\n callData = abi.encodePacked(bytes4(keccak256(bytes(signature))), data);\n }\n\n // solhint-disable-next-line avoid-low-level-calls\n (\n bool success, /*bytes memory returnData*/\n\n ) = target.call{value: value}(callData);\n require(success, \"tx execution reverted.\");\n\n emit ExecuteTransaction(txHash, target, value, signature, data, eta);\n }\n\n /**\n * @notice Cancels a proposal only if sender is the proposer, or proposer delegates dropped below proposal threshold\n * @param proposalId The id of the proposal to cancel\n */\n function cancel(uint256 proposalId) external override {\n require(state(proposalId) != ProposalState.Executed, \"cant cancel executed proposal\");\n\n Proposal storage proposal = proposals[proposalId];\n\n // Proposer can cancel\n if (_msgSender() != proposal.proposer) {\n // Whitelisted proposers can't be canceled for falling below proposal threshold\n if (isWhitelisted(proposal.proposer)) {\n require(\n (ipt.getPriorVotes(proposal.proposer, (block.number - 1)) < proposalThreshold) &&\n _msgSender() == whitelistGuardian,\n \"cancel: whitelisted proposer\"\n );\n } else {\n require(\n (ipt.getPriorVotes(proposal.proposer, (block.number - 1)) < proposalThreshold),\n \"cancel: proposer above threshold\"\n );\n }\n }\n\n proposal.canceled = true;\n for (uint256 i = 0; i < proposal.targets.length; i++) {\n cancelTransaction(\n proposal.targets[i],\n proposal.values[i],\n proposal.signatures[i],\n proposal.calldatas[i],\n proposal.eta\n );\n }\n\n emit ProposalCanceled(proposalId);\n }\n\n function cancelTransaction(\n address target,\n uint256 value,\n string memory signature,\n bytes memory data,\n uint256 eta\n ) internal {\n bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));\n queuedTransactions[txHash] = false;\n\n emit CancelTransaction(txHash, target, value, signature, data, eta);\n }\n\n /**\n * @notice Gets actions of a proposal\n * @param proposalId the id of the proposal\n * @return targets proposal targets\n * @return values proposal values\n * @return signatures proposal signatures\n * @return calldatas proposal calldatae\n */\n function getActions(uint256 proposalId)\n external\n view\n override\n returns (\n address[] memory targets,\n uint256[] memory values,\n string[] memory signatures,\n bytes[] memory calldatas\n )\n {\n Proposal storage p = proposals[proposalId];\n return (p.targets, p.values, p.signatures, p.calldatas);\n }\n\n /**\n * @notice Gets the receipt for a voter on a given proposal\n * @param proposalId the id of proposal\n * @param voter The address of the voter\n * @return The voting receipt\n */\n function getReceipt(uint256 proposalId, address voter) external view override returns (Receipt memory) {\n return proposalReceipts[proposalId][voter];\n }\n\n /**\n * @notice Gets the state of a proposal\n * @param proposalId The id of the proposal\n * @return Proposal state\n */\n // solhint-disable-next-line code-complexity\n function state(uint256 proposalId) public view override returns (ProposalState) {\n require(proposalCount >= proposalId && proposalId > initialProposalId, \"state: invalid proposal id\");\n Proposal storage proposal = proposals[proposalId];\n bool whitelisted = isWhitelisted(proposal.proposer);\n if (proposal.canceled) {\n return ProposalState.Canceled;\n } else if (block.number <= proposal.startBlock) {\n return ProposalState.Pending;\n } else if (block.number <= proposal.endBlock) {\n return ProposalState.Active;\n } else if (\n (whitelisted && proposal.againstVotes > proposal.quorumVotes) ||\n (!whitelisted && proposal.forVotes <= proposal.againstVotes) ||\n (!whitelisted && proposal.forVotes < proposal.quorumVotes)\n ) {\n return ProposalState.Defeated;\n } else if (proposal.eta == 0) {\n return ProposalState.Succeeded;\n } else if (proposal.executed) {\n return ProposalState.Executed;\n } else if (block.timestamp >= (proposal.eta + GRACE_PERIOD)) {\n return ProposalState.Expired;\n }\n return ProposalState.Queued;\n }\n\n /**\n * @notice Cast a vote for a proposal\n * @param proposalId The id of the proposal to vote on\n * @param support The support value for the vote. 0=against, 1=for, 2=abstain\n */\n function castVote(uint256 proposalId, uint8 support) external override {\n emit VoteCast(_msgSender(), proposalId, support, castVoteInternal(_msgSender(), proposalId, support), \"\");\n }\n\n /**\n * @notice Cast a vote for a proposal with a reason\n * @param proposalId The id of the proposal to vote on\n * @param support The support value for the vote. 0=against, 1=for, 2=abstain\n * @param reason The reason given for the vote by the voter\n */\n function castVoteWithReason(\n uint256 proposalId,\n uint8 support,\n string calldata reason\n ) external override {\n emit VoteCast(_msgSender(), proposalId, support, castVoteInternal(_msgSender(), proposalId, support), reason);\n }\n\n /**\n * @notice Cast a vote for a proposal by signature\n * @dev external override function that accepts EIP-712 signatures for voting on proposals.\n */\n function castVoteBySig(\n uint256 proposalId,\n uint8 support,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external override {\n bytes32 domainSeparator = keccak256(\n abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainIdInternal(), address(this))\n );\n bytes32 structHash = keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support));\n bytes32 digest = keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n address signatory = ecrecover(digest, v, r, s);\n require(signatory != address(0), \"castVoteBySig: invalid signature\");\n emit VoteCast(signatory, proposalId, support, castVoteInternal(signatory, proposalId, support), \"\");\n }\n\n /**\n * @notice Internal function that caries out voting logic\n * @param voter The voter that is casting their vote\n * @param proposalId The id of the proposal to vote on\n * @param support The support value for the vote. 0=against, 1=for, 2=abstain\n * @return The number of votes cast\n */\n function castVoteInternal(\n address voter,\n uint256 proposalId,\n uint8 support\n ) internal returns (uint96) {\n require(state(proposalId) == ProposalState.Active, \"voting is closed\");\n require(support <= 2, \"invalid vote type\");\n Proposal storage proposal = proposals[proposalId];\n Receipt storage receipt = proposalReceipts[proposalId][voter];\n require(receipt.hasVoted == false, \"voter already voted\");\n uint96 votes = ipt.getPriorVotes(voter, proposal.startBlock);\n\n if (support == 0) {\n proposal.againstVotes = proposal.againstVotes + votes;\n } else if (support == 1) {\n proposal.forVotes = proposal.forVotes + votes;\n } else if (support == 2) {\n proposal.abstainVotes = proposal.abstainVotes + votes;\n }\n\n receipt.hasVoted = true;\n receipt.support = support;\n receipt.votes = votes;\n\n return votes;\n }\n\n /**\n * @notice View function which returns if an account is whitelisted\n * @param account Account to check white list status of\n * @return If the account is whitelisted\n */\n function isWhitelisted(address account) public view override returns (bool) {\n return (whitelistAccountExpirations[account] > block.timestamp);\n }\n\n /**\n * @notice Governance function for setting the governance token\n * @param token_ new token addr\n */\n function _setNewToken(address token_) external onlyGov {\n ipt = IIpt(token_);\n }\n\n /**\n * @notice Used to update the timelock period\n * @param proposalTimelockDelay_ The proposal holding period\n */\n function _setDelay(uint256 proposalTimelockDelay_) public override onlyGov {\n uint256 oldTimelockDelay = proposalTimelockDelay;\n proposalTimelockDelay = proposalTimelockDelay_;\n\n emit NewDelay(oldTimelockDelay, proposalTimelockDelay);\n }\n\n /**\n * @notice Used to update the emergency timelock period\n * @param emergencyTimelockDelay_ The proposal holding period\n */\n function _setEmergencyDelay(uint256 emergencyTimelockDelay_) public override onlyGov {\n uint256 oldEmergencyTimelockDelay = emergencyTimelockDelay;\n emergencyTimelockDelay = emergencyTimelockDelay_;\n\n emit NewEmergencyDelay(oldEmergencyTimelockDelay, emergencyTimelockDelay);\n }\n\n /**\n * @notice Governance function for setting the voting delay\n * @param newVotingDelay new voting delay, in blocks\n */\n function _setVotingDelay(uint256 newVotingDelay) external override onlyGov {\n uint256 oldVotingDelay = votingDelay;\n votingDelay = newVotingDelay;\n\n emit VotingDelaySet(oldVotingDelay, votingDelay);\n }\n\n /**\n * @notice Governance function for setting the voting period\n * @param newVotingPeriod new voting period, in blocks\n */\n function _setVotingPeriod(uint256 newVotingPeriod) external override onlyGov {\n uint256 oldVotingPeriod = votingPeriod;\n votingPeriod = newVotingPeriod;\n\n emit VotingPeriodSet(oldVotingPeriod, votingPeriod);\n }\n\n /**\n * @notice Governance function for setting the emergency voting period\n * @param newEmergencyVotingPeriod new voting period, in blocks\n */\n function _setEmergencyVotingPeriod(uint256 newEmergencyVotingPeriod) external override onlyGov {\n uint256 oldEmergencyVotingPeriod = emergencyVotingPeriod;\n emergencyVotingPeriod = newEmergencyVotingPeriod;\n\n emit EmergencyVotingPeriodSet(oldEmergencyVotingPeriod, emergencyVotingPeriod);\n }\n\n /**\n * @notice Governance function for setting the proposal threshold\n * @param newProposalThreshold new proposal threshold\n */\n function _setProposalThreshold(uint256 newProposalThreshold) external override onlyGov {\n uint256 oldProposalThreshold = proposalThreshold;\n proposalThreshold = newProposalThreshold;\n\n emit ProposalThresholdSet(oldProposalThreshold, proposalThreshold);\n }\n\n /**\n * @notice Governance function for setting the quorum\n * @param newQuorumVotes new proposal quorum\n */\n function _setQuorumVotes(uint256 newQuorumVotes) external override onlyGov {\n uint256 oldQuorumVotes = quorumVotes;\n quorumVotes = newQuorumVotes;\n\n emit NewQuorum(oldQuorumVotes, quorumVotes);\n }\n\n /**\n * @notice Governance function for setting the emergency quorum\n * @param newEmergencyQuorumVotes new proposal quorum\n */\n function _setEmergencyQuorumVotes(uint256 newEmergencyQuorumVotes) external override onlyGov {\n uint256 oldEmergencyQuorumVotes = emergencyQuorumVotes;\n emergencyQuorumVotes = newEmergencyQuorumVotes;\n\n emit NewEmergencyQuorum(oldEmergencyQuorumVotes, emergencyQuorumVotes);\n }\n\n /**\n * @notice Governance function for setting the whitelist expiration as a timestamp\n * for an account. Whitelist status allows accounts to propose without meeting threshold\n * @param account Account address to set whitelist expiration for\n * @param expiration Expiration for account whitelist status as timestamp (if now < expiration, whitelisted)\n */\n function _setWhitelistAccountExpiration(address account, uint256 expiration) external override onlyGov {\n require (expiration < (maxWhitelistPeriod + block.timestamp), \"expiration exceeds max\");\n whitelistAccountExpirations[account] = expiration;\n\n emit WhitelistAccountExpirationSet(account, expiration);\n }\n\n /**\n * @notice Governance function for setting the whitelistGuardian. WhitelistGuardian can cancel proposals from whitelisted addresses\n * @param account Account to set whitelistGuardian to (0x0 to remove whitelistGuardian)\n */\n function _setWhitelistGuardian(address account) external override onlyGov {\n address oldGuardian = whitelistGuardian;\n whitelistGuardian = account;\n\n emit WhitelistGuardianSet(oldGuardian, whitelistGuardian);\n }\n\n /**\n * @notice Governance function for setting the optimistic voting delay\n * @param newOptimisticVotingDelay new optimistic voting delay, in blocks\n */\n function _setOptimisticDelay(uint256 newOptimisticVotingDelay) external override onlyGov {\n uint256 oldOptimisticVotingDelay = optimisticVotingDelay;\n optimisticVotingDelay = newOptimisticVotingDelay;\n\n emit OptimisticVotingDelaySet(oldOptimisticVotingDelay, optimisticVotingDelay);\n }\n\n /**\n * @notice Governance function for setting the optimistic quorum\n * @param newOptimisticQuorumVotes new optimistic quorum votes, in blocks\n */\n function _setOptimisticQuorumVotes(uint256 newOptimisticQuorumVotes) external override onlyGov {\n uint256 oldOptimisticQuorumVotes = optimisticQuorumVotes;\n optimisticQuorumVotes = newOptimisticQuorumVotes;\n\n emit OptimisticQuorumVotesSet(oldOptimisticQuorumVotes, optimisticQuorumVotes);\n }\n\n function getChainIdInternal() internal view returns (uint256) {\n return block.chainid;\n }\n\n function getBlockTimestamp() internal view returns (uint256) {\n // solium-disable-next-line security/no-block-members\n return block.timestamp;\n }\n\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n}\n"}},"settings":{"optimizer":{"enabled":true,"runs":200,"details":{"orderLiterals":true,"deduplicate":true,"cse":true,"yul":true}},"outputSelection":{"*":{"*":["evm.bytecode","evm.deployedBytecode","devdoc","userdoc","metadata","abi"]}},"libraries":{}}},"ABI":"[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"signature\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"eta\",\"type\":\"uint256\"}],\"name\":\"CancelTransaction\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldEmergencyVotingPeriod\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"emergencyVotingPeriod\",\"type\":\"uint256\"}],\"name\":\"EmergencyVotingPeriodSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"signature\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"eta\",\"type\":\"uint256\"}],\"name\":\"ExecuteTransaction\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"NewAdmin\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldTimelockDelay\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"proposalTimelockDelay\",\"type\":\"uint256\"}],\"name\":\"NewDelay\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldEmergencyTimelockDelay\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"emergencyTimelockDelay\",\"type\":\"uint256\"}],\"name\":\"NewEmergencyDelay\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldEmergencyQuorumVotes\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"emergencyQuorumVotes\",\"type\":\"uint256\"}],\"name\":\"NewEmergencyQuorum\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldImplementation\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"NewImplementation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldPendingAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newPendingAdmin\",\"type\":\"address\"}],\"name\":\"NewPendingAdmin\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldQuorumVotes\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"quorumVotes\",\"type\":\"uint256\"}],\"name\":\"NewQuorum\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldOptimisticQuorumVotes\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"optimisticQuorumVotes\",\"type\":\"uint256\"}],\"name\":\"OptimisticQuorumVotesSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldOptimisticVotingDelay\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"optimisticVotingDelay\",\"type\":\"uint256\"}],\"name\":\"OptimisticVotingDelaySet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"ProposalCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"targets\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"string[]\",\"name\":\"signatures\",\"type\":\"string[]\"},{\"indexed\":false,\"internalType\":\"bytes[]\",\"name\":\"calldatas\",\"type\":\"bytes[]\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"startBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"endBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"}],\"name\":\"ProposalCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"ProposalExecuted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"eta\",\"type\":\"uint256\"}],\"name\":\"ProposalQueued\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldProposalThreshold\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newProposalThreshold\",\"type\":\"uint256\"}],\"name\":\"ProposalThresholdSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"signature\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"eta\",\"type\":\"uint256\"}],\"name\":\"QueueTransaction\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"proposalId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"support\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"votes\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"reason\",\"type\":\"string\"}],\"name\":\"VoteCast\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldVotingDelay\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newVotingDelay\",\"type\":\"uint256\"}],\"name\":\"VotingDelaySet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldVotingPeriod\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newVotingPeriod\",\"type\":\"uint256\"}],\"name\":\"VotingPeriodSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"}],\"name\":\"WhitelistAccountExpirationSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldGuardian\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newGuardian\",\"type\":\"address\"}],\"name\":\"WhitelistGuardianSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BALLOT_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"GRACE_PERIOD\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"proposalTimelockDelay_\",\"type\":\"uint256\"}],\"name\":\"_setDelay\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"emergencyTimelockDelay_\",\"type\":\"uint256\"}],\"name\":\"_setEmergencyDelay\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newEmergencyQuorumVotes\",\"type\":\"uint256\"}],\"name\":\"_setEmergencyQuorumVotes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newEmergencyVotingPeriod\",\"type\":\"uint256\"}],\"name\":\"_setEmergencyVotingPeriod\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token_\",\"type\":\"address\"}],\"name\":\"_setNewToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newOptimisticVotingDelay\",\"type\":\"uint256\"}],\"name\":\"_setOptimisticDelay\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newOptimisticQuorumVotes\",\"type\":\"uint256\"}],\"name\":\"_setOptimisticQuorumVotes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newProposalThreshold\",\"type\":\"uint256\"}],\"name\":\"_setProposalThreshold\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newQuorumVotes\",\"type\":\"uint256\"}],\"name\":\"_setQuorumVotes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newVotingDelay\",\"type\":\"uint256\"}],\"name\":\"_setVotingDelay\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newVotingPeriod\",\"type\":\"uint256\"}],\"name\":\"_setVotingPeriod\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"}],\"name\":\"_setWhitelistAccountExpiration\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"_setWhitelistGuardian\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"proposalId\",\"type\":\"uint256\"}],\"name\":\"cancel\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"proposalId\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"support\",\"type\":\"uint8\"}],\"name\":\"castVote\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"proposalId\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"support\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"castVoteBySig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"proposalId\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"support\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"reason\",\"type\":\"string\"}],\"name\":\"castVoteWithReason\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"emergencyQuorumVotes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"emergencyTimelockDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"emergencyVotingPeriod\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"proposalId\",\"type\":\"uint256\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"signature\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"eta\",\"type\":\"uint256\"}],\"name\":\"executeTransaction\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"proposalId\",\"type\":\"uint256\"}],\"name\":\"getActions\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"targets\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"},{\"internalType\":\"string[]\",\"name\":\"signatures\",\"type\":\"string[]\"},{\"internalType\":\"bytes[]\",\"name\":\"calldatas\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"proposalId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"}],\"name\":\"getReceipt\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"hasVoted\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"support\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"votes\",\"type\":\"uint96\"}],\"internalType\":\"struct Receipt\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialProposalId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"ipt_\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ipt\",\"outputs\":[{\"internalType\":\"contract IIpt\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"isWhitelisted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"latestProposalIds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxWhitelistPeriod\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"optimisticQuorumVotes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"optimisticVotingDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proposalCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proposalMaxOperations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"proposalReceipts\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"hasVoted\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"support\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"votes\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proposalThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proposalTimelockDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"proposals\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"eta\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"startBlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"endBlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"forVotes\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"againstVotes\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"abstainVotes\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"canceled\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"executed\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"emergency\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"quorumVotes\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"delay\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"targets\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"},{\"internalType\":\"string[]\",\"name\":\"signatures\",\"type\":\"string[]\"},{\"internalType\":\"bytes[]\",\"name\":\"calldatas\",\"type\":\"bytes[]\"},{\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"emergency\",\"type\":\"bool\"}],\"name\":\"propose\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"proposalId\",\"type\":\"uint256\"}],\"name\":\"queue\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"queuedTransactions\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"quorumVotes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"proposalId\",\"type\":\"uint256\"}],\"name\":\"state\",\"outputs\":[{\"internalType\":\"enum ProposalState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"votingDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"votingPeriod\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"whitelistAccountExpirations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"whitelistGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]","ContractName":"GovernorCharlieDelegate","CompilerVersion":"v0.8.9+commit.e5eed63a","OptimizationUsed":1,"Runs":200,"ConstructorArguments":"0x","EVMVersion":"Default","Library":"","LicenseType":"","Proxy":0,"SwarmSource":""}] \ No newline at end of file diff --git a/testdata/etherscan/0x9AB6b21cDF116f611110b048987E58894786C244/creation_data.json b/testdata/etherscan/0x9AB6b21cDF116f611110b048987E58894786C244/creation_data.json index d145e56aa888..2378ed6aa2a8 100644 --- a/testdata/etherscan/0x9AB6b21cDF116f611110b048987E58894786C244/creation_data.json +++ b/testdata/etherscan/0x9AB6b21cDF116f611110b048987E58894786C244/creation_data.json @@ -1,5 +1 @@ -{ - "contractAddress": "0x9ab6b21cdf116f611110b048987e58894786c244", - "contractCreator": "0x603d50bad151da8becf405e51a8c4abc8ba1c95e", - "txHash": "0x72be611ae1ade09242d9fc9c950a73d076f6c23514564a7b9ac730400dbaf2c0" -} \ No newline at end of file +{"contractAddress":"0x9ab6b21cdf116f611110b048987e58894786c244","contractCreator":"0x603d50bad151da8becf405e51a8c4abc8ba1c95e","txHash":"0x72be611ae1ade09242d9fc9c950a73d076f6c23514564a7b9ac730400dbaf2c0"} \ No newline at end of file diff --git a/testdata/etherscan/0x9AB6b21cDF116f611110b048987E58894786C244/metadata.json b/testdata/etherscan/0x9AB6b21cDF116f611110b048987E58894786C244/metadata.json index ab133f38ff7a..b0f893895eb0 100644 --- a/testdata/etherscan/0x9AB6b21cDF116f611110b048987E58894786C244/metadata.json +++ b/testdata/etherscan/0x9AB6b21cDF116f611110b048987E58894786C244/metadata.json @@ -1,69 +1 @@ -[ - { - "SourceCode": { - "language": "Solidity", - "sources": { - "contracts/InterestRates/InterestRatePositionManager.f.sol": { - "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.19;\n\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\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 /**\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// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n\n/// Parameters for ERC20Permit.permit call\nstruct ERC20PermitSignature {\n IERC20Permit token;\n uint256 value;\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n}\n\nlibrary PermitHelper {\n function applyPermit(\n ERC20PermitSignature calldata p,\n address owner,\n address spender\n ) internal {\n p.token.permit(owner, spender, p.value, p.deadline, p.v, p.r, p.s);\n }\n\n function applyPermits(\n ERC20PermitSignature[] calldata permits,\n address owner,\n address spender\n ) internal {\n for (uint256 i = 0; i < permits.length; i++) {\n applyPermit(permits[i], owner, spender);\n }\n }\n}\n\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC3156FlashLender.sol)\n\n// OpenZeppelin Contracts (last updated v4.7.0) (interfaces/IERC3156FlashBorrower.sol)\n\n/**\n * @dev Interface of the ERC3156 FlashBorrower, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * _Available since v4.1._\n */\ninterface IERC3156FlashBorrower {\n /**\n * @dev Receive a flash loan.\n * @param initiator The initiator of the loan.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @param fee The additional amount of tokens to repay.\n * @param data Arbitrary data structure, intended to contain user-defined parameters.\n * @return The keccak256 hash of \"IERC3156FlashBorrower.onFlashLoan\"\n */\n function onFlashLoan(\n address initiator,\n address token,\n uint256 amount,\n uint256 fee,\n bytes calldata data\n ) external returns (bytes32);\n}\n\n/**\n * @dev Interface of the ERC3156 FlashLender, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * _Available since v4.1._\n */\ninterface IERC3156FlashLender {\n /**\n * @dev The amount of currency available to be lended.\n * @param token The loan currency.\n * @return The amount of `token` that can be borrowed.\n */\n function maxFlashLoan(address token) external view returns (uint256);\n\n /**\n * @dev The fee to be charged for a given loan.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @return The amount of `token` to be charged for the loan, on top of the returned principal.\n */\n function flashFee(address token, uint256 amount) external view returns (uint256);\n\n /**\n * @dev Initiate a flash loan.\n * @param receiver The receiver of the tokens in the loan, and the receiver of the callback.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @param data Arbitrary data structure, intended to contain user-defined parameters.\n */\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n ) external returns (bool);\n}\n\n/// @dev Interface to be used by contracts that collect fees. Contains fee recipient that can be changed by owner.\ninterface IFeeCollector {\n // --- Events ---\n\n /// @dev Fee Recipient is changed to @param feeRecipient address.\n /// @param feeRecipient New fee recipient address.\n event FeeRecipientChanged(address feeRecipient);\n\n // --- Errors ---\n\n /// @dev Invalid fee recipient.\n error InvalidFeeRecipient();\n\n // --- Functions ---\n\n /// @return Address of the current fee recipient.\n function feeRecipient() external view returns (address);\n\n /// @dev Sets new fee recipient address\n /// @param newFeeRecipient Address of the new fee recipient.\n function setFeeRecipient(address newFeeRecipient) external;\n}\n\ninterface IPositionManagerDependent {\n // --- Errors ---\n\n /// @dev Position Manager cannot be zero.\n error PositionManagerCannotBeZero();\n\n /// @dev Caller is not Position Manager.\n error CallerIsNotPositionManager(address caller);\n\n // --- Functions ---\n\n /// @dev Returns address of the PositionManager contract.\n function positionManager() external view returns (address);\n}\n\n/// @dev Interface of R stablecoin token. Implements some standards like IERC20, IERC20Permit, and IERC3156FlashLender.\n/// Raft's specific implementation contains IFeeCollector and IPositionManagerDependent.\n/// PositionManager can mint and burn R when particular actions happen with user's position.\ninterface IRToken is IERC20, IERC20Permit, IERC3156FlashLender, IFeeCollector, IPositionManagerDependent {\n // --- Events ---\n\n /// @dev New R token is deployed\n /// @param positionManager Address of the PositionManager contract that is authorized to mint and burn new tokens.\n /// @param flashMintFeeRecipient Address of flash mint fee recipient.\n event RDeployed(address positionManager, address flashMintFeeRecipient);\n\n /// @dev The Flash Mint Fee Percentage has been changed.\n /// @param flashMintFeePercentage The new Flash Mint Fee Percentage value.\n event FlashMintFeePercentageChanged(uint256 flashMintFeePercentage);\n\n /// --- Errors ---\n\n /// @dev Proposed flash mint fee percentage is too big.\n /// @param feePercentage Proposed flash mint fee percentage.\n error FlashFeePercentageTooBig(uint256 feePercentage);\n\n // --- Functions ---\n\n /// @return Number representing 100 percentage.\n function PERCENTAGE_BASE() external view returns (uint256);\n\n /// @dev Mints new tokens. Callable only by PositionManager contract.\n /// @param to Address that will receive newly minted tokens.\n /// @param amount Amount of tokens to mint.\n function mint(address to, uint256 amount) external;\n\n /// @dev Mints new tokens. Callable only by PositionManager contract.\n /// @param from Address of user whose tokens are burnt.\n /// @param amount Amount of tokens to burn.\n function burn(address from, uint256 amount) external;\n\n /// @return Maximum flash mint fee percentage that can be set by owner.\n function MAX_FLASH_MINT_FEE_PERCENTAGE() external view returns (uint256);\n\n /// @return Current flash mint fee percentage.\n function flashMintFeePercentage() external view returns (uint256);\n\n /// @dev Sets new flash mint fee percentage. Callable only by owner.\n /// @notice The proposed flash mint fee percentage cannot exceed `MAX_FLASH_MINT_FEE_PERCENTAGE`.\n /// @param feePercentage New flash fee percentage.\n function setFlashMintFeePercentage(uint256 feePercentage) external;\n}\n\ninterface IPriceOracle {\n // --- Errors ---\n\n /// @dev Contract initialized with an invalid deviation parameter.\n error InvalidDeviation();\n\n // --- Types ---\n\n struct PriceOracleResponse {\n bool isBrokenOrFrozen;\n bool priceChangeAboveMax;\n uint256 price;\n }\n\n // --- Functions ---\n\n /// @dev Return price oracle response which consists the following information: oracle is broken or frozen, the\n /// price change between two rounds is more than max, and the price.\n function getPriceOracleResponse() external returns (PriceOracleResponse memory);\n\n /// @dev Maximum time period allowed since oracle latest round data timestamp, beyond which oracle is considered\n /// frozen.\n function timeout() external view returns (uint256);\n\n /// @dev Used to convert a price answer to an 18-digit precision uint.\n function TARGET_DIGITS() external view returns (uint256);\n\n /// @dev price deviation for the oracle in percentage.\n function DEVIATION() external view returns (uint256);\n}\n\ninterface IPriceFeed {\n // --- Events ---\n\n /// @dev Last good price has been updated.\n event LastGoodPriceUpdated(uint256 lastGoodPrice);\n\n /// @dev Price difference between oracles has been updated.\n /// @param priceDifferenceBetweenOracles New price difference between oracles.\n event PriceDifferenceBetweenOraclesUpdated(uint256 priceDifferenceBetweenOracles);\n\n /// @dev Primary oracle has been updated.\n /// @param primaryOracle New primary oracle.\n event PrimaryOracleUpdated(IPriceOracle primaryOracle);\n\n /// @dev Secondary oracle has been updated.\n /// @param secondaryOracle New secondary oracle.\n event SecondaryOracleUpdated(IPriceOracle secondaryOracle);\n\n // --- Errors ---\n\n /// @dev Invalid primary oracle.\n error InvalidPrimaryOracle();\n\n /// @dev Invalid secondary oracle.\n error InvalidSecondaryOracle();\n\n /// @dev Primary oracle is broken or frozen or has bad result.\n error PrimaryOracleBrokenOrFrozenOrBadResult();\n\n /// @dev Invalid price difference between oracles.\n error InvalidPriceDifferenceBetweenOracles();\n\n // --- Functions ---\n\n /// @dev Return primary oracle address.\n function primaryOracle() external returns (IPriceOracle);\n\n /// @dev Return secondary oracle address\n function secondaryOracle() external returns (IPriceOracle);\n\n /// @dev The last good price seen from an oracle by Raft.\n function lastGoodPrice() external returns (uint256);\n\n /// @dev The maximum relative price difference between two oracle responses.\n function priceDifferenceBetweenOracles() external returns (uint256);\n\n /// @dev Set primary oracle address.\n /// @param newPrimaryOracle Primary oracle address.\n function setPrimaryOracle(IPriceOracle newPrimaryOracle) external;\n\n /// @dev Set secondary oracle address.\n /// @param newSecondaryOracle Secondary oracle address.\n function setSecondaryOracle(IPriceOracle newSecondaryOracle) external;\n\n /// @dev Set the maximum relative price difference between two oracle responses.\n /// @param newPriceDifferenceBetweenOracles The maximum relative price difference between two oracle responses.\n function setPriceDifferenceBetweenOracles(uint256 newPriceDifferenceBetweenOracles) external;\n\n /// @dev Returns the latest price obtained from the Oracle. Called by Raft functions that require a current price.\n ///\n /// Also callable by anyone externally.\n /// Non-view function - it stores the last good price seen by Raft.\n ///\n /// Uses a primary oracle and a fallback oracle in case primary fails. If both fail,\n /// it uses the last good price seen by Raft.\n ///\n /// @return currentPrice Returned price.\n /// @return deviation Deviation of the reported price in percentage.\n /// @notice Actual returned price is in range `currentPrice` +/- `currentPrice * deviation / ONE`\n function fetchPrice() external returns (uint256 currentPrice, uint256 deviation);\n}\n\ninterface IERC20Indexable is IERC20, IPositionManagerDependent {\n // --- Events ---\n\n /// @dev New token is deployed.\n /// @param positionManager Address of the PositionManager contract that is authorized to mint and burn new tokens.\n event ERC20IndexableDeployed(address positionManager);\n\n /// @dev New index has been set.\n /// @param newIndex Value of the new index.\n event IndexUpdated(uint256 newIndex);\n\n // --- Errors ---\n\n /// @dev Unsupported action for ERC20Indexable contract.\n error NotSupported();\n\n // --- Functions ---\n\n /// @return Precision for token index. Represents index that is equal to 1.\n function INDEX_PRECISION() external view returns (uint256);\n\n /// @return Current index value.\n function currentIndex() external view returns (uint256);\n\n /// @dev Sets new token index. Callable only by PositionManager contract.\n /// @param backingAmount Amount of backing token that is covered by total supply.\n function setIndex(uint256 backingAmount) external;\n\n /// @dev Mints new tokens. Callable only by PositionManager contract.\n /// @param to Address that will receive newly minted tokens.\n /// @param amount Amount of tokens to mint.\n function mint(address to, uint256 amount) external;\n\n /// @dev Mints new tokens. Callable only by PositionManager contract.\n /// @param from Address of user whose tokens are burnt.\n /// @param amount Amount of tokens to burn.\n function burn(address from, uint256 amount) external;\n}\n\ninterface ISplitLiquidationCollateral {\n // --- Functions ---\n\n /// @dev Returns lowest total debt that will be split.\n function LOW_TOTAL_DEBT() external view returns (uint256);\n\n /// @dev Minimum collateralization ratio for position\n function MCR() external view returns (uint256);\n\n /// @dev Splits collateral between protocol and liquidator.\n /// @param totalCollateral Amount of collateral to split.\n /// @param totalDebt Amount of debt to split.\n /// @param price Price of collateral.\n /// @param isRedistribution True if this is a redistribution.\n /// @return collateralToSendToProtocol Amount of collateral to send to protocol.\n /// @return collateralToSentToLiquidator Amount of collateral to send to liquidator.\n function split(\n uint256 totalCollateral,\n uint256 totalDebt,\n uint256 price,\n bool isRedistribution\n )\n external\n view\n returns (uint256 collateralToSendToProtocol, uint256 collateralToSentToLiquidator);\n}\n\n/// @dev Common interface for the Position Manager.\ninterface IPositionManager is IFeeCollector {\n // --- Types ---\n\n /// @dev Information for a Raft indexable collateral token.\n /// @param collateralToken The Raft indexable collateral token.\n /// @param debtToken Corresponding Raft indexable debt token.\n /// @param priceFeed The contract that provides a price for the collateral token.\n /// @param splitLiquidation The contract that calculates collateral split in case of liquidation.\n /// @param isEnabled Whether the token can be used as collateral or not.\n /// @param lastFeeOperationTime Timestamp of the last operation for the collateral token.\n /// @param borrowingSpread The current borrowing spread.\n /// @param baseRate The current base rate.\n /// @param redemptionSpread The current redemption spread.\n /// @param redemptionRebate Percentage of the redemption fee returned to redeemed positions.\n struct CollateralTokenInfo {\n IERC20Indexable collateralToken;\n IERC20Indexable debtToken;\n IPriceFeed priceFeed;\n ISplitLiquidationCollateral splitLiquidation;\n bool isEnabled;\n uint256 lastFeeOperationTime;\n uint256 borrowingSpread;\n uint256 baseRate;\n uint256 redemptionSpread;\n uint256 redemptionRebate;\n }\n\n // --- Events ---\n\n /// @dev New position manager has been token deployed.\n /// @param rToken The R token used by the position manager.\n /// @param feeRecipient The address of fee recipient.\n event PositionManagerDeployed(IRToken rToken, address feeRecipient);\n\n /// @dev New collateral token has been added added to the system.\n /// @param collateralToken The token used as collateral.\n /// @param raftCollateralToken The Raft indexable collateral token for the given collateral token.\n /// @param raftDebtToken The Raft indexable debt token for given collateral token.\n /// @param priceFeed The contract that provides price for the collateral token.\n event CollateralTokenAdded(\n IERC20 collateralToken,\n IERC20Indexable raftCollateralToken,\n IERC20Indexable raftDebtToken,\n IPriceFeed priceFeed\n );\n\n /// @dev Collateral token has been enabled or disabled.\n /// @param collateralToken The token used as collateral.\n /// @param isEnabled True if the token is enabled, false otherwise.\n event CollateralTokenModified(IERC20 collateralToken, bool isEnabled);\n\n /// @dev A delegate has been whitelisted for a certain position.\n /// @param position The position for which the delegate was whitelisted.\n /// @param delegate The delegate which was whitelisted.\n /// @param whitelisted Specifies whether the delegate whitelisting has been enabled (true) or disabled (false).\n event DelegateWhitelisted(address indexed position, address indexed delegate, bool whitelisted);\n\n /// @dev New position has been created.\n /// @param position The address of the user opening new position.\n /// @param collateralToken The token used as collateral for the created position.\n event PositionCreated(address indexed position, IERC20 indexed collateralToken);\n\n /// @dev The position has been closed by either repayment, liquidation, or redemption.\n /// @param position The address of the user whose position is closed.\n event PositionClosed(address indexed position);\n\n /// @dev Collateral amount for the position has been changed.\n /// @param position The address of the user that has opened the position.\n /// @param collateralToken The address of the collateral token being added to position.\n /// @param collateralAmount The amount of collateral added or removed.\n /// @param isCollateralIncrease Whether the collateral is added to the position or removed from it.\n event CollateralChanged(\n address indexed position, IERC20 indexed collateralToken, uint256 collateralAmount, bool isCollateralIncrease\n );\n\n /// @dev Debt amount for position has been changed.\n /// @param position The address of the user that has opened the position.\n /// @param collateralToken The address of the collateral token backing the debt.\n /// @param debtAmount The amount of debt added or removed.\n /// @param isDebtIncrease Whether the debt is added to the position or removed from it.\n event DebtChanged(\n address indexed position, IERC20 indexed collateralToken, uint256 debtAmount, bool isDebtIncrease\n );\n\n /// @dev Borrowing fee has been paid. Emitted only if the actual fee was paid - doesn't happen with no fees are\n /// paid.\n /// @param collateralToken Collateral token used to mint R.\n /// @param position The address of position's owner that triggered the fee payment.\n /// @param feeAmount The amount of tokens paid as the borrowing fee.\n event RBorrowingFeePaid(IERC20 collateralToken, address indexed position, uint256 feeAmount);\n\n /// @dev Liquidation has been executed.\n /// @param liquidator The liquidator that executed the liquidation.\n /// @param position The address of position's owner whose position was liquidated.\n /// @param collateralToken The collateral token used for the liquidation.\n /// @param debtLiquidated The total debt that was liquidated or redistributed.\n /// @param collateralLiquidated The total collateral liquidated.\n /// @param collateralSentToLiquidator The collateral amount sent to the liquidator.\n /// @param collateralLiquidationFeePaid The total collateral paid as the liquidation fee to the fee recipient.\n /// @param isRedistribution Whether the executed liquidation was redistribution or not.\n event Liquidation(\n address indexed liquidator,\n address indexed position,\n IERC20 indexed collateralToken,\n uint256 debtLiquidated,\n uint256 collateralLiquidated,\n uint256 collateralSentToLiquidator,\n uint256 collateralLiquidationFeePaid,\n bool isRedistribution\n );\n\n /// @dev Redemption has been executed.\n /// @param redeemer User that redeemed R.\n /// @param amount Amount of R that was redeemed.\n /// @param collateralSent The amount of collateral sent to the redeemer.\n /// @param fee The amount of fee paid to the fee recipient.\n /// @param rebate Redemption rebate amount.\n event Redemption(address indexed redeemer, uint256 amount, uint256 collateralSent, uint256 fee, uint256 rebate);\n\n /// @dev Borrowing spread has been updated.\n /// @param borrowingSpread The new borrowing spread.\n event BorrowingSpreadUpdated(uint256 borrowingSpread);\n\n /// @dev Redemption rebate has been updated.\n /// @param redemptionRebate The new redemption rebate.\n event RedemptionRebateUpdated(uint256 redemptionRebate);\n\n /// @dev Redemption spread has been updated.\n /// @param collateralToken Collateral token that the spread was set for.\n /// @param redemptionSpread The new redemption spread.\n event RedemptionSpreadUpdated(IERC20 collateralToken, uint256 redemptionSpread);\n\n /// @dev Base rate has been updated.\n /// @param collateralToken Collateral token that the baser rate was updated for.\n /// @param baseRate The new base rate.\n event BaseRateUpdated(IERC20 collateralToken, uint256 baseRate);\n\n /// @dev Last fee operation time has been updated.\n /// @param collateralToken Collateral token that the baser rate was updated for.\n /// @param lastFeeOpTime The new operation time.\n event LastFeeOpTimeUpdated(IERC20 collateralToken, uint256 lastFeeOpTime);\n\n /// @dev Split liquidation collateral has been changed.\n /// @param collateralToken Collateral token whose split liquidation collateral contract is set.\n /// @param newSplitLiquidationCollateral New value that was set to be split liquidation collateral.\n event SplitLiquidationCollateralChanged(\n IERC20 collateralToken, ISplitLiquidationCollateral indexed newSplitLiquidationCollateral\n );\n\n // --- Errors ---\n\n /// @dev Max fee percentage must be between borrowing spread and 100%.\n error InvalidMaxFeePercentage();\n\n /// @dev Max fee percentage must be between 0.5% and 100%.\n error MaxFeePercentageOutOfRange();\n\n /// @dev Amount is zero.\n error AmountIsZero();\n\n /// @dev Nothing to liquidate.\n error NothingToLiquidate();\n\n /// @dev Cannot liquidate last position.\n error CannotLiquidateLastPosition();\n\n /// @dev Cannot redeem collateral below minimum debt threshold.\n /// @param collateralToken Collateral token used to redeem.\n /// @param newTotalDebt New total debt backed by collateral, which is lower than minimum debt.\n error TotalDebtCannotBeLowerThanMinDebt(IERC20 collateralToken, uint256 newTotalDebt);\n\n /// @dev Cannot redeem collateral\n /// @param collateralToken Collateral token used to redeem.\n /// @param newTotalCollateral New total collateral, which is lower than minimum collateral.\n /// @param minimumCollateral Minimum collateral required to complete redeem\n error TotalCollateralCannotBeLowerThanMinCollateral(\n IERC20 collateralToken, uint256 newTotalCollateral, uint256 minimumCollateral\n );\n\n /// @dev Fee would eat up all returned collateral.\n error FeeEatsUpAllReturnedCollateral();\n\n /// @dev Borrowing spread exceeds maximum.\n error BorrowingSpreadExceedsMaximum();\n\n /// @dev Redemption rebate exceeds maximum.\n error RedemptionRebateExceedsMaximum();\n\n /// @dev Redemption spread is out of allowed range.\n error RedemptionSpreadOutOfRange();\n\n /// @dev There must be either a collateral change or a debt change.\n error NoCollateralOrDebtChange();\n\n /// @dev There is some collateral for position that doesn't have debt.\n error InvalidPosition();\n\n /// @dev An operation that would result in ICR < MCR is not permitted.\n /// @param newICR Resulting ICR that is below MCR.\n error NewICRLowerThanMCR(uint256 newICR);\n\n /// @dev Position's net debt must be greater than minimum.\n /// @param netDebt Net debt amount that is below minimum.\n error NetDebtBelowMinimum(uint256 netDebt);\n\n /// @dev The provided delegate address is invalid.\n error InvalidDelegateAddress();\n\n /// @dev A non-whitelisted delegate cannot adjust positions.\n error DelegateNotWhitelisted();\n\n /// @dev Fee exceeded provided maximum fee percentage.\n /// @param fee The fee amount.\n /// @param amount The amount of debt or collateral.\n /// @param maxFeePercentage The maximum fee percentage.\n error FeeExceedsMaxFee(uint256 fee, uint256 amount, uint256 maxFeePercentage);\n\n /// @dev Borrower uses a different collateral token already.\n error PositionCollateralTokenMismatch();\n\n /// @dev Collateral token address cannot be zero.\n error CollateralTokenAddressCannotBeZero();\n\n /// @dev Price feed address cannot be zero.\n error PriceFeedAddressCannotBeZero();\n\n /// @dev Collateral token already added.\n error CollateralTokenAlreadyAdded();\n\n /// @dev Collateral token is not added.\n error CollateralTokenNotAdded();\n\n /// @dev Collateral token is not enabled.\n error CollateralTokenDisabled();\n\n /// @dev Split liquidation collateral cannot be zero.\n error SplitLiquidationCollateralCannotBeZero();\n\n /// @dev Cannot change collateral in case of repaying the whole debt.\n error WrongCollateralParamsForFullRepayment();\n\n // --- Functions ---\n\n /// @return The R token used by position manager.\n function rToken() external view returns (IRToken);\n\n /// @dev Retrieves information about certain collateral type.\n /// @param collateralToken The token used as collateral.\n /// @return raftCollateralToken The Raft indexable collateral token.\n /// @return raftDebtToken The Raft indexable debt token.\n /// @return priceFeed The contract that provides a price for the collateral token.\n /// @return splitLiquidation The contract that calculates collateral split in case of liquidation.\n /// @return isEnabled Whether the collateral token can be used as collateral or not.\n /// @return lastFeeOperationTime Timestamp of the last operation for the collateral token.\n /// @return borrowingSpread The current borrowing spread.\n /// @return baseRate The current base rate.\n /// @return redemptionSpread The current redemption spread.\n /// @return redemptionRebate Percentage of the redemption fee returned to redeemed positions.\n function collateralInfo(IERC20 collateralToken)\n external\n view\n returns (\n IERC20Indexable raftCollateralToken,\n IERC20Indexable raftDebtToken,\n IPriceFeed priceFeed,\n ISplitLiquidationCollateral splitLiquidation,\n bool isEnabled,\n uint256 lastFeeOperationTime,\n uint256 borrowingSpread,\n uint256 baseRate,\n uint256 redemptionSpread,\n uint256 redemptionRebate\n );\n\n /// @param collateralToken Collateral token whose raft collateral indexable token is being queried.\n /// @return Raft collateral token address for given collateral token.\n function raftCollateralToken(IERC20 collateralToken) external view returns (IERC20Indexable);\n\n /// @param collateralToken Collateral token whose raft collateral indexable token is being queried.\n /// @return Raft debt token address for given collateral token.\n function raftDebtToken(IERC20 collateralToken) external view returns (IERC20Indexable);\n\n /// @param collateralToken Collateral token whose price feed contract is being queried.\n /// @return Price feed contract address for given collateral token.\n function priceFeed(IERC20 collateralToken) external view returns (IPriceFeed);\n\n /// @param collateralToken Collateral token whose split liquidation collateral is being queried.\n /// @return Returns address of the split liquidation collateral contract.\n function splitLiquidationCollateral(IERC20 collateralToken) external view returns (ISplitLiquidationCollateral);\n\n /// @param collateralToken Collateral token whose split liquidation collateral is being queried.\n /// @return Returns whether collateral is enabled or nor.\n function collateralEnabled(IERC20 collateralToken) external view returns (bool);\n\n /// @param collateralToken Collateral token we query last operation time fee for.\n /// @return The timestamp of the latest fee operation (redemption or new R issuance).\n function lastFeeOperationTime(IERC20 collateralToken) external view returns (uint256);\n\n /// @param collateralToken Collateral token we query borrowing spread for.\n /// @return The current borrowing spread.\n function borrowingSpread(IERC20 collateralToken) external view returns (uint256);\n\n /// @param collateralToken Collateral token we query base rate for.\n /// @return rate The base rate.\n function baseRate(IERC20 collateralToken) external view returns (uint256 rate);\n\n /// @param collateralToken Collateral token we query redemption spread for.\n /// @return The current redemption spread for collateral token.\n function redemptionSpread(IERC20 collateralToken) external view returns (uint256);\n\n /// @param collateralToken Collateral token we query redemption rebate for.\n /// @return rebate Percentage of the redemption fee returned to redeemed positions.\n function redemptionRebate(IERC20 collateralToken) external view returns (uint256);\n\n /// @param collateralToken Collateral token we query redemption rate for.\n /// @return rate The current redemption rate for collateral token.\n function getRedemptionRate(IERC20 collateralToken) external view returns (uint256 rate);\n\n /// @dev Returns the collateral token that a given position used for their position.\n /// @param position The address of the borrower.\n /// @return collateralToken The collateral token of the borrower's position.\n function collateralTokenForPosition(address position) external view returns (IERC20 collateralToken);\n\n /// @dev Adds a new collateral token to the protocol.\n /// @param collateralToken The new collateral token.\n /// @param priceFeed The price feed for the collateral token.\n /// @param newSplitLiquidationCollateral split liquidation collateral contract address.\n function addCollateralToken(\n IERC20 collateralToken,\n IPriceFeed priceFeed,\n ISplitLiquidationCollateral newSplitLiquidationCollateral\n )\n external;\n\n /// @dev Adds a new collateral token to the protocol.\n /// @param collateralToken The new collateral token.\n /// @param priceFeed The price feed for the collateral token.\n /// @param newSplitLiquidationCollateral split liquidation collateral contract address.\n /// @param raftCollateralToken_ Address of raft collateral token.\n /// @param raftDebtToken_ Address of raft debt token.\n function addCollateralToken(\n IERC20 collateralToken,\n IPriceFeed priceFeed,\n ISplitLiquidationCollateral newSplitLiquidationCollateral,\n IERC20Indexable raftCollateralToken_,\n IERC20Indexable raftDebtToken_\n )\n external;\n\n /// @dev Enables or disables a collateral token. Reverts if the collateral token has not been added.\n /// @param collateralToken The collateral token.\n /// @param isEnabled Whether the collateral token can be used as collateral or not.\n function setCollateralEnabled(IERC20 collateralToken, bool isEnabled) external;\n\n /// @dev Sets the new split liquidation collateral contract.\n /// @param collateralToken Collateral token whose split liquidation collateral is being set.\n /// @param newSplitLiquidationCollateral New split liquidation collateral contract address.\n function setSplitLiquidationCollateral(\n IERC20 collateralToken,\n ISplitLiquidationCollateral newSplitLiquidationCollateral\n )\n external;\n\n /// @dev Liquidates the borrower if its position's ICR is lower than the minimum collateral ratio.\n /// @param position The address of the borrower.\n function liquidate(address position) external;\n\n /// @dev Redeems the collateral token for a given debt amount. It sends @param debtAmount R to the system and\n /// redeems the corresponding amount of collateral from as many positions as are needed to fill the redemption\n /// request.\n /// @param collateralToken The token used as collateral.\n /// @param debtAmount The amount of debt to be redeemed. Must be greater than zero.\n /// @param maxFeePercentage The maximum fee percentage to pay for the redemption.\n function redeemCollateral(IERC20 collateralToken, uint256 debtAmount, uint256 maxFeePercentage) external;\n\n /// @dev Manages the position on behalf of a given borrower.\n /// @param collateralToken The token the borrower used as collateral.\n /// @param position The address of the borrower.\n /// @param collateralChange The amount of collateral to add or remove.\n /// @param isCollateralIncrease True if the collateral is being increased, false otherwise.\n /// @param debtChange The amount of R to add or remove. In case of repayment (isDebtIncrease = false)\n /// `type(uint256).max` value can be used to repay the whole outstanding loan.\n /// @param isDebtIncrease True if the debt is being increased, false otherwise.\n /// @param maxFeePercentage The maximum fee percentage to pay for the position management.\n /// @param permitSignature Optional permit signature for tokens that support IERC20Permit interface.\n /// @notice `permitSignature` it is ignored if permit signature is not for `collateralToken`.\n /// @notice In case of full debt repayment, `isCollateralIncrease` is ignored and `collateralChange` must be 0.\n /// These values are set to `false`(collateral decrease), and the whole collateral balance of the user.\n /// @return actualCollateralChange Actual amount of collateral added/removed.\n /// Can be different to `collateralChange` in case of full repayment.\n /// @return actualDebtChange Actual amount of debt added/removed.\n /// Can be different to `debtChange` in case of passing type(uint256).max as `debtChange`.\n function managePosition(\n IERC20 collateralToken,\n address position,\n uint256 collateralChange,\n bool isCollateralIncrease,\n uint256 debtChange,\n bool isDebtIncrease,\n uint256 maxFeePercentage,\n ERC20PermitSignature calldata permitSignature\n )\n external\n returns (uint256 actualCollateralChange, uint256 actualDebtChange);\n\n /// @return The max borrowing spread.\n function MAX_BORROWING_SPREAD() external view returns (uint256);\n\n /// @return The max borrowing rate.\n function MAX_BORROWING_RATE() external view returns (uint256);\n\n /// @dev Sets the new borrowing spread.\n /// @param collateralToken Collateral token we set borrowing spread for.\n /// @param newBorrowingSpread New borrowing spread to be used.\n function setBorrowingSpread(IERC20 collateralToken, uint256 newBorrowingSpread) external;\n\n /// @param collateralToken Collateral token we query borrowing rate for.\n /// @return The current borrowing rate.\n function getBorrowingRate(IERC20 collateralToken) external view returns (uint256);\n\n /// @param collateralToken Collateral token we query borrowing rate with decay for.\n /// @return The current borrowing rate with decay.\n function getBorrowingRateWithDecay(IERC20 collateralToken) external view returns (uint256);\n\n /// @dev Returns the borrowing fee for a given debt amount.\n /// @param collateralToken Collateral token we query borrowing fee for.\n /// @param debtAmount The amount of debt.\n /// @return The borrowing fee.\n function getBorrowingFee(IERC20 collateralToken, uint256 debtAmount) external view returns (uint256);\n\n /// @dev Sets the new redemption spread.\n /// @param newRedemptionSpread New redemption spread to be used.\n function setRedemptionSpread(IERC20 collateralToken, uint256 newRedemptionSpread) external;\n\n /// @dev Sets new redemption rebate percentage.\n /// @param newRedemptionRebate Value that is being set as a redemption rebate percentage.\n function setRedemptionRebate(IERC20 collateralToken, uint256 newRedemptionRebate) external;\n\n /// @param collateralToken Collateral token we query redemption rate with decay for.\n /// @return The current redemption rate with decay.\n function getRedemptionRateWithDecay(IERC20 collateralToken) external view returns (uint256);\n\n /// @dev Returns the redemption fee for a given collateral amount.\n /// @param collateralToken Collateral token we query redemption fee for.\n /// @param collateralAmount The amount of collateral.\n /// @param priceDeviation Deviation for the reported price by oracle in percentage.\n /// @return The redemption fee.\n function getRedemptionFee(\n IERC20 collateralToken,\n uint256 collateralAmount,\n uint256 priceDeviation\n )\n external\n view\n returns (uint256);\n\n /// @dev Returns the redemption fee with decay for a given collateral amount.\n /// @param collateralToken Collateral token we query redemption fee with decay for.\n /// @param collateralAmount The amount of collateral.\n /// @return The redemption fee with decay.\n function getRedemptionFeeWithDecay(\n IERC20 collateralToken,\n uint256 collateralAmount\n )\n external\n view\n returns (uint256);\n\n /// @return Half-life of 12h (720 min).\n /// @dev (1/2) = d^720 => d = (1/2)^(1/720)\n function MINUTE_DECAY_FACTOR() external view returns (uint256);\n\n /// @dev Returns if a given delegate is whitelisted for a given borrower.\n /// @param position The address of the borrower.\n /// @param delegate The address of the delegate.\n /// @return isWhitelisted True if the delegate is whitelisted for a given borrower, false otherwise.\n function isDelegateWhitelisted(address position, address delegate) external view returns (bool isWhitelisted);\n\n /// @dev Whitelists a delegate.\n /// @param delegate The address of the delegate.\n /// @param whitelisted True if delegate is being whitelisted, false otherwise.\n function whitelistDelegate(address delegate, bool whitelisted) external;\n\n /// @return Parameter by which to divide the redeemed fraction, in order to calc the new base rate from a\n /// redemption. Corresponds to (1 / ALPHA) in the white paper.\n function BETA() external view returns (uint256);\n}\n\n/// @dev Common interface for the Position Manager.\ninterface IInterestRatePositionManager is IPositionManager {\n // --- Events ---\n\n /// @dev Fees coming from accrued interest are minted.\n /// @param collateralToken Collateral token that fees are paid for.\n /// @param amount Amount of R minted.\n event MintedFees(IERC20 collateralToken, uint256 amount);\n\n // --- Errors ---\n\n /// @dev Only registered debt token can be caller.\n /// @param sender Actual caller.\n error InvalidDebtToken(address sender);\n\n // --- Functions ---\n\n /// @dev Mints fees coming from accrued interest. Can be called only from matching debt token.\n /// @param collateralToken Collateral token to mint fees for.\n /// @param amount Amount of R to mint.\n function mintFees(IERC20 collateralToken, uint256 amount) external;\n}\n\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)\n\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\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 functionCallWithValue(target, data, 0, \"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 (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, 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 (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, 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 (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or 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 _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\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 /// @solidity memory-safe-assembly\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/**\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 function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\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\nlibrary Fixed256x18 {\n uint256 internal constant ONE = 1e18; // 18 decimal places\n\n function mulDown(uint256 a, uint256 b) internal pure returns (uint256) {\n return (a * b) / ONE;\n }\n\n function mulUp(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 product = a * b;\n\n if (product == 0) {\n return 0;\n } else {\n return ((product - 1) / ONE) + 1;\n }\n }\n\n function divDown(uint256 a, uint256 b) internal pure returns (uint256) {\n return (a * ONE) / b;\n }\n\n function divUp(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n } else {\n return (((a * ONE) - 1) / b) + 1;\n }\n }\n\n function complement(uint256 x) internal pure returns (uint256) {\n return (x < ONE) ? (ONE - x) : 0;\n }\n}\n\nlibrary MathUtils {\n // --- Constants ---\n\n /// @notice Represents 100%.\n /// @dev 1e18 is the scaling factor (100% == 1e18).\n uint256 public constant _100_PERCENT = Fixed256x18.ONE;\n\n /// @notice Precision for Nominal ICR (independent of price).\n /// @dev Rationale for the value:\n /// - Making it “too high” could lead to overflows.\n /// - Making it “too low” could lead to an ICR equal to zero, due to truncation from floor division.\n ///\n /// This value of 1e20 is chosen for safety: the NICR will only overflow for numerator > ~1e39 collateralToken,\n /// and will only truncate to 0 if the denominator is at least 1e20 times greater than the numerator.\n uint256 internal constant _NICR_PRECISION = 1e20;\n\n /// @notice Number of minutes in 1000 years.\n uint256 internal constant _MINUTES_IN_1000_YEARS = 1000 * 365 days / 1 minutes;\n\n // --- Functions ---\n\n /// @notice Multiplies two decimal numbers and use normal rounding rules:\n /// - round product up if 19'th mantissa digit >= 5\n /// - round product down if 19'th mantissa digit < 5.\n /// @param x First number.\n /// @param y Second number.\n function _decMul(uint256 x, uint256 y) internal pure returns (uint256 decProd) {\n decProd = (x * y + Fixed256x18.ONE / 2) / Fixed256x18.ONE;\n }\n\n /// @notice Exponentiation function for 18-digit decimal base, and integer exponent n.\n ///\n /// @dev Uses the efficient \"exponentiation by squaring\" algorithm. O(log(n)) complexity. The exponent is capped to\n /// avoid reverting due to overflow.\n ///\n /// If a period of > 1000 years is ever used as an exponent in either of the above functions, the result will be\n /// negligibly different from just passing the cap, since the decayed base rate will be 0 for 1000 years or > 1000\n /// years.\n /// @param base The decimal base.\n /// @param exponent The exponent.\n /// @return The result of the exponentiation.\n function _decPow(uint256 base, uint256 exponent) internal pure returns (uint256) {\n if (exponent == 0) {\n return Fixed256x18.ONE;\n }\n\n uint256 y = Fixed256x18.ONE;\n uint256 x = base;\n uint256 n = Math.min(exponent, _MINUTES_IN_1000_YEARS); // cap to avoid overflow\n\n // Exponentiation-by-squaring\n while (n > 1) {\n if (n % 2 != 0) {\n y = _decMul(x, y);\n }\n x = _decMul(x, x);\n n /= 2;\n }\n\n return _decMul(x, y);\n }\n\n /// @notice Computes the Nominal Individual Collateral Ratio (NICR) for given collateral and debt. If debt is zero,\n /// it returns the maximal value for uint256 (represents \"infinite\" CR).\n /// @param collateral Collateral amount.\n /// @param debt Debt amount.\n /// @return NICR.\n function _computeNominalCR(uint256 collateral, uint256 debt) internal pure returns (uint256) {\n return debt > 0 ? collateral * _NICR_PRECISION / debt : type(uint256).max;\n }\n\n /// @notice Computes the Collateral Ratio for given collateral, debt and price. If debt is zero, it returns the\n /// maximal value for uint256 (represents \"infinite\" CR).\n /// @param collateral Collateral amount.\n /// @param debt Debt amount.\n /// @param price Collateral price.\n /// @return Collateral ratio.\n function _computeCR(uint256 collateral, uint256 debt, uint256 price) internal pure returns (uint256) {\n return debt > 0 ? collateral * price / debt : type(uint256).max;\n }\n}\n\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol)\n\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\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\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n\n// OpenZeppelin Contracts (last updated v4.8.0) (access/Ownable2Step.sol)\n\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.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 Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\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 the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\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\n/**\n * @dev Contract module which provides 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} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() external {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n\n/**\n * @dev Extension of {ERC20} that adds a cap to the supply of tokens.\n */\nabstract contract ERC20Capped is ERC20, Ownable2Step {\n uint256 public cap;\n\n /**\n * @dev Total supply cap has been exceeded.\n */\n error ERC20ExceededCap();\n\n /**\n * @dev The supplied cap is not a valid cap.\n */\n error ERC20InvalidCap(uint256 cap);\n\n constructor(uint256 cap_) {\n setCap(cap_);\n }\n\n /**\n * @dev Sets the value of the `cap`.\n */\n function setCap(uint256 cap_) public onlyOwner {\n if (cap_ == 0) {\n revert ERC20InvalidCap(0);\n }\n cap = cap_;\n }\n\n /**\n * @dev See {ERC20-_mint}.\n */\n function _mint(address account, uint256 amount) internal virtual override {\n if (totalSupply() + amount > cap) {\n revert ERC20ExceededCap();\n }\n super._mint(account, amount);\n }\n}\n\nabstract contract PositionManagerDependent is IPositionManagerDependent {\n // --- Immutable variables ---\n\n address public immutable override positionManager;\n\n // --- Modifiers ---\n\n modifier onlyPositionManager() {\n if (msg.sender != positionManager) {\n revert CallerIsNotPositionManager(msg.sender);\n }\n _;\n }\n\n // --- Constructor ---\n\n constructor(address positionManager_) {\n if (positionManager_ == address(0)) {\n revert PositionManagerCannotBeZero();\n }\n positionManager = positionManager_;\n }\n}\n\ncontract ERC20Indexable is IERC20Indexable, ERC20Capped, PositionManagerDependent {\n // --- Types ---\n\n using Fixed256x18 for uint256;\n\n // --- Constants ---\n\n uint256 public constant override INDEX_PRECISION = Fixed256x18.ONE;\n\n // --- Variables ---\n\n uint256 internal storedIndex;\n\n // --- Constructor ---\n\n constructor(\n address positionManager_,\n string memory name_,\n string memory symbol_,\n uint256 cap_\n )\n ERC20(name_, symbol_)\n ERC20Capped(cap_)\n PositionManagerDependent(positionManager_)\n {\n storedIndex = INDEX_PRECISION;\n emit ERC20IndexableDeployed(positionManager_);\n }\n\n // --- Functions ---\n\n function mint(address to, uint256 amount) public virtual override onlyPositionManager {\n _mint(to, amount.divUp(storedIndex));\n }\n\n function burn(address from, uint256 amount) public virtual override onlyPositionManager {\n _burn(from, amount == type(uint256).max ? ERC20.balanceOf(from) : amount.divUp(storedIndex));\n }\n\n function setIndex(uint256 backingAmount) external override onlyPositionManager {\n uint256 supply = ERC20.totalSupply();\n uint256 newIndex = (backingAmount == 0 && supply == 0) ? INDEX_PRECISION : backingAmount.divUp(supply);\n storedIndex = newIndex;\n emit IndexUpdated(newIndex);\n }\n\n function currentIndex() public view virtual override returns (uint256) {\n return storedIndex;\n }\n\n function totalSupply() public view virtual override(IERC20, ERC20) returns (uint256) {\n return ERC20.totalSupply().mulDown(currentIndex());\n }\n\n function balanceOf(address account) public view virtual override(IERC20, ERC20) returns (uint256) {\n return ERC20.balanceOf(account).mulDown(currentIndex());\n }\n\n function transfer(address, uint256) public virtual override(IERC20, ERC20) returns (bool) {\n revert NotSupported();\n }\n\n function allowance(address, address) public view virtual override(IERC20, ERC20) returns (uint256) {\n revert NotSupported();\n }\n\n function approve(address, uint256) public virtual override(IERC20, ERC20) returns (bool) {\n revert NotSupported();\n }\n\n function transferFrom(address, address, uint256) public virtual override(IERC20, ERC20) returns (bool) {\n revert NotSupported();\n }\n\n function increaseAllowance(address, uint256) public virtual override returns (bool) {\n revert NotSupported();\n }\n\n function decreaseAllowance(address, uint256) public virtual override returns (bool) {\n revert NotSupported();\n }\n}\n\nabstract contract FeeCollector is Ownable2Step, IFeeCollector {\n // --- Variables ---\n\n address public override feeRecipient;\n\n // --- Constructor ---\n\n /// @param feeRecipient_ Address of the fee recipient to initialize contract with.\n constructor(address feeRecipient_) {\n if (feeRecipient_ == address(0)) {\n revert InvalidFeeRecipient();\n }\n\n feeRecipient = feeRecipient_;\n }\n\n // --- Functions ---\n\n function setFeeRecipient(address newFeeRecipient) external onlyOwner {\n if (newFeeRecipient == address(0)) {\n revert InvalidFeeRecipient();\n }\n\n feeRecipient = newFeeRecipient;\n emit FeeRecipientChanged(newFeeRecipient);\n }\n}\n\n// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol)\n\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/EIP712.sol)\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n address private immutable _CACHED_THIS;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n );\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = block.chainid;\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _CACHED_THIS = address(this);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n}\n\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) EIP712(name, \"1\") {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n Counters.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n}\n\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/extensions/ERC20FlashMint.sol)\n\n/**\n * @dev Implementation of the ERC3156 Flash loans extension, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * Adds the {flashLoan} method, which provides flash loan support at the token\n * level. By default there is no fee, but this can be changed by overriding {flashFee}.\n *\n * _Available since v4.1._\n */\nabstract contract ERC20FlashMint is ERC20, IERC3156FlashLender {\n bytes32 private constant _RETURN_VALUE = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n /**\n * @dev Returns the maximum amount of tokens available for loan.\n * @param token The address of the token that is requested.\n * @return The amount of token that can be loaned.\n */\n function maxFlashLoan(address token) public view virtual override returns (uint256) {\n return token == address(this) ? type(uint256).max - ERC20.totalSupply() : 0;\n }\n\n /**\n * @dev Returns the fee applied when doing flash loans. This function calls\n * the {_flashFee} function which returns the fee applied when doing flash\n * loans.\n * @param token The token to be flash loaned.\n * @param amount The amount of tokens to be loaned.\n * @return The fees applied to the corresponding flash loan.\n */\n function flashFee(address token, uint256 amount) public view virtual override returns (uint256) {\n require(token == address(this), \"ERC20FlashMint: wrong token\");\n return _flashFee(token, amount);\n }\n\n /**\n * @dev Returns the fee applied when doing flash loans. By default this\n * implementation has 0 fees. This function can be overloaded to make\n * the flash loan mechanism deflationary.\n * @param token The token to be flash loaned.\n * @param amount The amount of tokens to be loaned.\n * @return The fees applied to the corresponding flash loan.\n */\n function _flashFee(address token, uint256 amount) internal view virtual returns (uint256) {\n // silence warning about unused variable without the addition of bytecode.\n token;\n amount;\n return 0;\n }\n\n /**\n * @dev Returns the receiver address of the flash fee. By default this\n * implementation returns the address(0) which means the fee amount will be burnt.\n * This function can be overloaded to change the fee receiver.\n * @return The address for which the flash fee will be sent to.\n */\n function _flashFeeReceiver() internal view virtual returns (address) {\n return address(0);\n }\n\n /**\n * @dev Performs a flash loan. New tokens are minted and sent to the\n * `receiver`, who is required to implement the {IERC3156FlashBorrower}\n * interface. By the end of the flash loan, the receiver is expected to own\n * amount + fee tokens and have them approved back to the token contract itself so\n * they can be burned.\n * @param receiver The receiver of the flash loan. Should implement the\n * {IERC3156FlashBorrower-onFlashLoan} interface.\n * @param token The token to be flash loaned. Only `address(this)` is\n * supported.\n * @param amount The amount of tokens to be loaned.\n * @param data An arbitrary datafield that is passed to the receiver.\n * @return `true` if the flash loan was successful.\n */\n // This function can reenter, but it doesn't pose a risk because it always preserves the property that the amount\n // minted at the beginning is always recovered and burned at the end, or else the entire function will revert.\n // slither-disable-next-line reentrancy-no-eth\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n ) public virtual override returns (bool) {\n require(amount <= maxFlashLoan(token), \"ERC20FlashMint: amount exceeds maxFlashLoan\");\n uint256 fee = flashFee(token, amount);\n _mint(address(receiver), amount);\n require(\n receiver.onFlashLoan(msg.sender, token, amount, fee, data) == _RETURN_VALUE,\n \"ERC20FlashMint: invalid return value\"\n );\n address flashFeeReceiver = _flashFeeReceiver();\n _spendAllowance(address(receiver), address(this), amount + fee);\n if (fee == 0 || flashFeeReceiver == address(0)) {\n _burn(address(receiver), amount + fee);\n } else {\n _burn(address(receiver), amount);\n _transfer(address(receiver), flashFeeReceiver, fee);\n }\n return true;\n }\n}\n\ncontract RToken is ReentrancyGuard, ERC20Permit, ERC20FlashMint, PositionManagerDependent, FeeCollector, IRToken {\n // --- Constants ---\n\n uint256 public constant override PERCENTAGE_BASE = 10_000;\n uint256 public constant override MAX_FLASH_MINT_FEE_PERCENTAGE = 500;\n\n // --- Variables ---\n\n uint256 public override flashMintFeePercentage;\n\n // --- Constructor ---\n\n /// @dev Deploys new R token. Sets flash mint fee percentage to 0. Transfers ownership to @param feeRecipient_.\n /// @param positionManager_ Address of the PositionManager contract that is authorized to mint and burn new tokens.\n /// @param feeRecipient_ Address of flash mint fee recipient.\n constructor(\n address positionManager_,\n address feeRecipient_\n )\n ERC20Permit(\"R Stablecoin\")\n ERC20(\"R Stablecoin\", \"R\")\n PositionManagerDependent(positionManager_)\n FeeCollector(feeRecipient_)\n {\n setFlashMintFeePercentage(PERCENTAGE_BASE / 200); // 0.5%\n\n transferOwnership(feeRecipient_);\n\n emit RDeployed(positionManager_, feeRecipient_);\n }\n\n // --- Functions ---\n\n function mint(address to, uint256 amount) external override onlyPositionManager {\n _mint(to, amount);\n }\n\n function burn(address from, uint256 amount) external override onlyPositionManager {\n _burn(from, amount);\n }\n\n function setFlashMintFeePercentage(uint256 feePercentage) public override onlyOwner {\n if (feePercentage > MAX_FLASH_MINT_FEE_PERCENTAGE) {\n revert FlashFeePercentageTooBig(feePercentage);\n }\n\n flashMintFeePercentage = feePercentage;\n emit FlashMintFeePercentageChanged(flashMintFeePercentage);\n }\n\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n )\n public\n override(ERC20FlashMint, IERC3156FlashLender)\n nonReentrant\n returns (bool)\n {\n return super.flashLoan(receiver, token, amount, data);\n }\n\n /// @dev Inherited from ERC20FlashMint. Defines maximum size of the flash mint.\n /// @param token Token to be flash minted. Returns 0 amount in case of token != address(this).\n function maxFlashLoan(address token)\n public\n view\n virtual\n override(ERC20FlashMint, IERC3156FlashLender)\n returns (uint256)\n {\n return token == address(this) ? Math.min(totalSupply() / 10, ERC20FlashMint.maxFlashLoan(address(this))) : 0;\n }\n\n /// @dev Inherited from ERC20FlashMint. Defines flash mint fee for the flash mint of @param amount tokens.\n /// @param token Token to be flash minted. Returns 0 fee in case of token != address(this).\n /// @param amount Size of the flash mint.\n function _flashFee(address token, uint256 amount) internal view virtual override returns (uint256) {\n return token == address(this) ? amount * flashMintFeePercentage / PERCENTAGE_BASE : 0;\n }\n\n /// @dev Inherited from ERC20FlashMint. Defines flash mint fee receiver.\n /// @return Address that will receive flash mint fees.\n function _flashFeeReceiver() internal view virtual override returns (address) {\n return feeRecipient;\n }\n}\n\n/// @dev Implementation of Position Manager. Current implementation does not support rebasing tokens as collateral.\ncontract PositionManager is FeeCollector, IPositionManager {\n // --- Types ---\n\n using SafeERC20 for IERC20;\n using Fixed256x18 for uint256;\n\n // --- Constants ---\n\n uint256 public constant override MINUTE_DECAY_FACTOR = 999_037_758_833_783_000;\n\n uint256 public constant override MAX_BORROWING_SPREAD = MathUtils._100_PERCENT / 100; // 1%\n uint256 public constant override MAX_BORROWING_RATE = MathUtils._100_PERCENT / 100 * 5; // 5%\n\n uint256 public constant override BETA = 2;\n\n // --- Immutables ---\n\n IRToken public immutable override rToken;\n\n // --- Variables ---\n\n mapping(address position => IERC20 collateralToken) public override collateralTokenForPosition;\n\n mapping(address position => mapping(address delegate => bool isWhitelisted)) public override isDelegateWhitelisted;\n\n mapping(IERC20 collateralToken => CollateralTokenInfo collateralTokenInfo) public override collateralInfo;\n\n // --- Modifiers ---\n\n /// @dev Checks if the collateral token has been added to the position manager, or reverts otherwise.\n /// @param collateralToken The collateral token to check.\n modifier collateralTokenExists(IERC20 collateralToken) {\n if (address(collateralInfo[collateralToken].collateralToken) == address(0)) {\n revert CollateralTokenNotAdded();\n }\n _;\n }\n\n /// @dev Checks if the collateral token has enabled, or reverts otherwise. When the condition is false, the check\n /// is skipped.\n /// @param collateralToken The collateral token to check.\n /// @param condition If true, the check will be performed.\n modifier onlyEnabledCollateralTokenWhen(IERC20 collateralToken, bool condition) {\n if (condition && !collateralInfo[collateralToken].isEnabled) {\n revert CollateralTokenDisabled();\n }\n _;\n }\n\n /// @dev Checks if the borrower has a position with the collateral token or doesn't have a position at all, or\n /// reverts otherwise.\n /// @param position The borrower to check.\n /// @param collateralToken The collateral token to check.\n modifier onlyDepositedCollateralTokenOrNew(address position, IERC20 collateralToken) {\n if (\n collateralTokenForPosition[position] != IERC20(address(0))\n && collateralTokenForPosition[position] != collateralToken\n ) {\n revert PositionCollateralTokenMismatch();\n }\n _;\n }\n\n /// @dev Checks if the max fee percentage is between the borrowing spread and 100%, or reverts otherwise. When the\n /// condition is false, the check is skipped.\n /// @param maxFeePercentage The max fee percentage to check.\n /// @param condition If true, the check will be performed.\n modifier validMaxFeePercentageWhen(uint256 maxFeePercentage, bool condition) {\n if (condition && maxFeePercentage > MathUtils._100_PERCENT) {\n revert InvalidMaxFeePercentage();\n }\n _;\n }\n\n // --- Constructor ---\n\n /// @dev Initializes the position manager.\n constructor(address rToken_) FeeCollector(msg.sender) {\n rToken = rToken_ == address(0) ? new RToken(address(this), msg.sender) : IRToken(rToken_);\n emit PositionManagerDeployed(rToken, msg.sender);\n }\n\n // --- External functions ---\n\n function managePosition(\n IERC20 collateralToken,\n address position,\n uint256 collateralChange,\n bool isCollateralIncrease,\n uint256 debtChange,\n bool isDebtIncrease,\n uint256 maxFeePercentage,\n ERC20PermitSignature calldata permitSignature\n )\n public\n virtual\n override\n collateralTokenExists(collateralToken)\n validMaxFeePercentageWhen(maxFeePercentage, isDebtIncrease)\n onlyDepositedCollateralTokenOrNew(position, collateralToken)\n onlyEnabledCollateralTokenWhen(collateralToken, isDebtIncrease && debtChange > 0)\n returns (uint256 actualCollateralChange, uint256 actualDebtChange)\n {\n if (position != msg.sender && !isDelegateWhitelisted[position][msg.sender]) {\n revert DelegateNotWhitelisted();\n }\n if (collateralChange == 0 && debtChange == 0) {\n revert NoCollateralOrDebtChange();\n }\n if (address(permitSignature.token) == address(collateralToken)) {\n PermitHelper.applyPermit(permitSignature, msg.sender, address(this));\n }\n\n CollateralTokenInfo storage collateralTokenInfo = collateralInfo[collateralToken];\n IERC20Indexable raftCollateralToken = collateralTokenInfo.collateralToken;\n IERC20Indexable raftDebtToken = collateralTokenInfo.debtToken;\n\n uint256 debtBefore = raftDebtToken.balanceOf(position);\n if (!isDebtIncrease && (debtChange == type(uint256).max || (debtBefore != 0 && debtChange == debtBefore))) {\n if (collateralChange != 0 || isCollateralIncrease) {\n revert WrongCollateralParamsForFullRepayment();\n }\n collateralChange = raftCollateralToken.balanceOf(position);\n debtChange = debtBefore;\n }\n\n _adjustDebt(position, collateralToken, raftDebtToken, debtChange, isDebtIncrease, maxFeePercentage);\n _adjustCollateral(collateralToken, raftCollateralToken, position, collateralChange, isCollateralIncrease);\n\n uint256 positionDebt = raftDebtToken.balanceOf(position);\n uint256 positionCollateral = raftCollateralToken.balanceOf(position);\n\n if (positionDebt == 0) {\n if (positionCollateral != 0) {\n revert InvalidPosition();\n }\n // position was closed, remove it\n _closePosition(raftCollateralToken, raftDebtToken, position, false);\n } else {\n _checkValidPosition(collateralToken, positionDebt, positionCollateral);\n\n if (debtBefore == 0) {\n collateralTokenForPosition[position] = collateralToken;\n emit PositionCreated(position, collateralToken);\n }\n }\n return (collateralChange, debtChange);\n }\n\n function liquidate(address position) external override {\n IERC20 collateralToken = collateralTokenForPosition[position];\n CollateralTokenInfo storage collateralTokenInfo = collateralInfo[collateralToken];\n IERC20Indexable raftCollateralToken = collateralTokenInfo.collateralToken;\n IERC20Indexable raftDebtToken = collateralTokenInfo.debtToken;\n ISplitLiquidationCollateral splitLiquidation = collateralTokenInfo.splitLiquidation;\n\n if (address(collateralToken) == address(0)) {\n revert NothingToLiquidate();\n }\n (uint256 price,) = collateralTokenInfo.priceFeed.fetchPrice();\n uint256 entireCollateral = raftCollateralToken.balanceOf(position);\n uint256 entireDebt = raftDebtToken.balanceOf(position);\n uint256 icr = MathUtils._computeCR(entireCollateral, entireDebt, price);\n\n if (icr >= splitLiquidation.MCR()) {\n revert NothingToLiquidate();\n }\n\n uint256 totalDebt = raftDebtToken.totalSupply();\n if (entireDebt == totalDebt) {\n revert CannotLiquidateLastPosition();\n }\n bool isRedistribution = icr <= MathUtils._100_PERCENT;\n\n // prettier: ignore\n (uint256 collateralLiquidationFee, uint256 collateralToSendToLiquidator) =\n splitLiquidation.split(entireCollateral, entireDebt, price, isRedistribution);\n\n if (!isRedistribution) {\n _burnRTokens(msg.sender, entireDebt);\n totalDebt -= entireDebt;\n\n // Collateral is sent to protocol as a fee only in case of liquidation\n collateralToken.safeTransfer(feeRecipient, collateralLiquidationFee);\n }\n\n collateralToken.safeTransfer(msg.sender, collateralToSendToLiquidator);\n\n _closePosition(raftCollateralToken, raftDebtToken, position, true);\n\n _updateDebtAndCollateralIndex(collateralToken, raftCollateralToken, raftDebtToken, totalDebt);\n\n emit Liquidation(\n msg.sender,\n position,\n collateralToken,\n entireDebt,\n entireCollateral,\n collateralToSendToLiquidator,\n collateralLiquidationFee,\n isRedistribution\n );\n }\n\n function redeemCollateral(\n IERC20 collateralToken,\n uint256 debtAmount,\n uint256 maxFeePercentage\n )\n public\n virtual\n override\n {\n if (maxFeePercentage > MathUtils._100_PERCENT) {\n revert MaxFeePercentageOutOfRange();\n }\n if (debtAmount == 0) {\n revert AmountIsZero();\n }\n IERC20Indexable raftDebtToken = collateralInfo[collateralToken].debtToken;\n\n uint256 newTotalDebt = raftDebtToken.totalSupply() - debtAmount;\n uint256 lowTotalDebt = collateralInfo[collateralToken].splitLiquidation.LOW_TOTAL_DEBT();\n if (newTotalDebt < lowTotalDebt) {\n revert TotalDebtCannotBeLowerThanMinDebt(collateralToken, newTotalDebt);\n }\n\n (uint256 price, uint256 deviation) = collateralInfo[collateralToken].priceFeed.fetchPrice();\n uint256 collateralToRedeem = debtAmount.divDown(price);\n uint256 totalCollateral = collateralToken.balanceOf(address(this));\n if (\n totalCollateral - collateralToRedeem == 0\n || totalCollateral - collateralToRedeem < lowTotalDebt.divDown(price)\n ) {\n revert TotalCollateralCannotBeLowerThanMinCollateral(\n collateralToken, totalCollateral - collateralToRedeem, lowTotalDebt.divDown(price)\n );\n }\n\n // Decay the baseRate due to time passed, and then increase it according to the size of this redemption.\n // Use the saved total R supply value, from before it was reduced by the redemption.\n _updateBaseRateFromRedemption(collateralToken, collateralToRedeem, price, rToken.totalSupply());\n\n // Calculate the redemption fee\n uint256 redemptionFee = getRedemptionFee(collateralToken, collateralToRedeem, deviation);\n uint256 rebate = redemptionFee.mulDown(collateralInfo[collateralToken].redemptionRebate);\n\n _checkValidFee(redemptionFee, collateralToRedeem, maxFeePercentage);\n\n // Send the redemption fee to the recipient\n collateralToken.safeTransfer(feeRecipient, redemptionFee - rebate);\n\n // Burn the total R that is cancelled with debt, and send the redeemed collateral to msg.sender\n _burnRTokens(msg.sender, debtAmount);\n\n // Send collateral to account\n collateralToken.safeTransfer(msg.sender, collateralToRedeem - redemptionFee);\n\n _updateDebtAndCollateralIndex(\n collateralToken, collateralInfo[collateralToken].collateralToken, raftDebtToken, newTotalDebt\n );\n\n emit Redemption(msg.sender, debtAmount, collateralToRedeem, redemptionFee, rebate);\n }\n\n function whitelistDelegate(address delegate, bool whitelisted) external override {\n if (delegate == address(0)) {\n revert InvalidDelegateAddress();\n }\n isDelegateWhitelisted[msg.sender][delegate] = whitelisted;\n\n emit DelegateWhitelisted(msg.sender, delegate, whitelisted);\n }\n\n function setBorrowingSpread(IERC20 collateralToken, uint256 newBorrowingSpread) external override onlyOwner {\n if (newBorrowingSpread > MAX_BORROWING_SPREAD) {\n revert BorrowingSpreadExceedsMaximum();\n }\n collateralInfo[collateralToken].borrowingSpread = newBorrowingSpread;\n emit BorrowingSpreadUpdated(newBorrowingSpread);\n }\n\n function setRedemptionRebate(IERC20 collateralToken, uint256 newRedemptionRebate) public override onlyOwner {\n if (newRedemptionRebate > MathUtils._100_PERCENT) {\n revert RedemptionRebateExceedsMaximum();\n }\n collateralInfo[collateralToken].redemptionRebate = newRedemptionRebate;\n emit RedemptionRebateUpdated(newRedemptionRebate);\n }\n\n function getRedemptionFeeWithDecay(\n IERC20 collateralToken,\n uint256 collateralAmount\n )\n external\n view\n override\n returns (uint256 redemptionFee)\n {\n redemptionFee = getRedemptionRateWithDecay(collateralToken).mulDown(collateralAmount);\n if (redemptionFee >= collateralAmount) {\n revert FeeEatsUpAllReturnedCollateral();\n }\n }\n\n // --- Public functions ---\n\n function addCollateralToken(\n IERC20 collateralToken,\n IPriceFeed priceFeed,\n ISplitLiquidationCollateral newSplitLiquidationCollateral\n )\n public\n virtual\n override\n {\n addCollateralToken(\n collateralToken,\n priceFeed,\n newSplitLiquidationCollateral,\n new ERC20Indexable(\n address(this),\n string(bytes.concat(\"Raft \", bytes(IERC20Metadata(address(collateralToken)).name()), \" collateral\")),\n string(bytes.concat(\"r\", bytes(IERC20Metadata(address(collateralToken)).symbol()), \"-c\")),\n type(uint256).max\n ),\n new ERC20Indexable(\n address(this),\n string(bytes.concat(\"Raft \", bytes(IERC20Metadata(address(collateralToken)).name()), \" debt\")),\n string(bytes.concat(\"r\", bytes(IERC20Metadata(address(collateralToken)).symbol()), \"-d\")),\n type(uint256).max\n )\n );\n }\n\n function addCollateralToken(\n IERC20 collateralToken,\n IPriceFeed priceFeed,\n ISplitLiquidationCollateral newSplitLiquidationCollateral,\n IERC20Indexable raftCollateralToken_,\n IERC20Indexable raftDebtToken_\n )\n public\n override\n onlyOwner\n {\n if (address(collateralToken) == address(0)) {\n revert CollateralTokenAddressCannotBeZero();\n }\n if (address(priceFeed) == address(0)) {\n revert PriceFeedAddressCannotBeZero();\n }\n if (address(collateralInfo[collateralToken].collateralToken) != address(0)) {\n revert CollateralTokenAlreadyAdded();\n }\n\n CollateralTokenInfo memory raftCollateralTokenInfo;\n raftCollateralTokenInfo.collateralToken = raftCollateralToken_;\n raftCollateralTokenInfo.debtToken = raftDebtToken_;\n raftCollateralTokenInfo.isEnabled = true;\n raftCollateralTokenInfo.priceFeed = priceFeed;\n\n collateralInfo[collateralToken] = raftCollateralTokenInfo;\n\n setRedemptionSpread(collateralToken, MathUtils._100_PERCENT);\n setRedemptionRebate(collateralToken, MathUtils._100_PERCENT);\n\n setSplitLiquidationCollateral(collateralToken, newSplitLiquidationCollateral);\n\n emit CollateralTokenAdded(\n collateralToken, raftCollateralTokenInfo.collateralToken, raftCollateralTokenInfo.debtToken, priceFeed\n );\n }\n\n function setCollateralEnabled(\n IERC20 collateralToken,\n bool isEnabled\n )\n public\n override\n onlyOwner\n collateralTokenExists(collateralToken)\n {\n bool previousIsEnabled = collateralInfo[collateralToken].isEnabled;\n collateralInfo[collateralToken].isEnabled = isEnabled;\n\n if (previousIsEnabled != isEnabled) {\n emit CollateralTokenModified(collateralToken, isEnabled);\n }\n }\n\n function setSplitLiquidationCollateral(\n IERC20 collateralToken,\n ISplitLiquidationCollateral newSplitLiquidationCollateral\n )\n public\n override\n onlyOwner\n {\n if (address(newSplitLiquidationCollateral) == address(0)) {\n revert SplitLiquidationCollateralCannotBeZero();\n }\n collateralInfo[collateralToken].splitLiquidation = newSplitLiquidationCollateral;\n emit SplitLiquidationCollateralChanged(collateralToken, newSplitLiquidationCollateral);\n }\n\n function setRedemptionSpread(IERC20 collateralToken, uint256 newRedemptionSpread) public override onlyOwner {\n if (newRedemptionSpread > MathUtils._100_PERCENT) {\n revert RedemptionSpreadOutOfRange();\n }\n collateralInfo[collateralToken].redemptionSpread = newRedemptionSpread;\n emit RedemptionSpreadUpdated(collateralToken, newRedemptionSpread);\n }\n\n function getRedemptionRateWithDecay(IERC20 collateralToken) public view override returns (uint256) {\n return _calcRedemptionRate(collateralToken, _calcDecayedBaseRate(collateralToken));\n }\n\n function raftCollateralToken(IERC20 collateralToken) external view override returns (IERC20Indexable) {\n return collateralInfo[collateralToken].collateralToken;\n }\n\n function raftDebtToken(IERC20 collateralToken) external view override returns (IERC20Indexable) {\n return collateralInfo[collateralToken].debtToken;\n }\n\n function priceFeed(IERC20 collateralToken) external view override returns (IPriceFeed) {\n return collateralInfo[collateralToken].priceFeed;\n }\n\n function splitLiquidationCollateral(IERC20 collateralToken) external view returns (ISplitLiquidationCollateral) {\n return collateralInfo[collateralToken].splitLiquidation;\n }\n\n function collateralEnabled(IERC20 collateralToken) external view override returns (bool) {\n return collateralInfo[collateralToken].isEnabled;\n }\n\n function lastFeeOperationTime(IERC20 collateralToken) external view override returns (uint256) {\n return collateralInfo[collateralToken].lastFeeOperationTime;\n }\n\n function borrowingSpread(IERC20 collateralToken) external view override returns (uint256) {\n return collateralInfo[collateralToken].borrowingSpread;\n }\n\n function baseRate(IERC20 collateralToken) external view override returns (uint256) {\n return collateralInfo[collateralToken].baseRate;\n }\n\n function redemptionSpread(IERC20 collateralToken) external view override returns (uint256) {\n return collateralInfo[collateralToken].redemptionSpread;\n }\n\n function redemptionRebate(IERC20 collateralToken) external view override returns (uint256) {\n return collateralInfo[collateralToken].redemptionRebate;\n }\n\n function getRedemptionRate(IERC20 collateralToken) public view override returns (uint256) {\n return _calcRedemptionRate(collateralToken, collateralInfo[collateralToken].baseRate);\n }\n\n function getRedemptionFee(\n IERC20 collateralToken,\n uint256 collateralAmount,\n uint256 priceDeviation\n )\n public\n view\n override\n returns (uint256)\n {\n return Math.min(getRedemptionRate(collateralToken) + priceDeviation, MathUtils._100_PERCENT).mulDown(\n collateralAmount\n );\n }\n\n function getBorrowingRate(IERC20 collateralToken) public view override returns (uint256) {\n return _calcBorrowingRate(collateralToken, collateralInfo[collateralToken].baseRate);\n }\n\n function getBorrowingRateWithDecay(IERC20 collateralToken) public view override returns (uint256) {\n return _calcBorrowingRate(collateralToken, _calcDecayedBaseRate(collateralToken));\n }\n\n function getBorrowingFee(IERC20 collateralToken, uint256 debtAmount) public view override returns (uint256) {\n return getBorrowingRate(collateralToken).mulDown(debtAmount);\n }\n\n // --- Helper functions ---\n\n /// @dev Adjusts the debt of a given borrower by burning or minting the corresponding amount of R and the Raft\n /// debt token. If the debt is being increased, the borrowing fee is also triggered.\n /// @param position The address of the borrower.\n /// @param debtChange The amount of R to add or remove. Must be positive.\n /// @param isDebtIncrease True if the debt is being increased, false otherwise.\n /// @param maxFeePercentage The maximum fee percentage.\n function _adjustDebt(\n address position,\n IERC20 collateralToken,\n IERC20Indexable raftDebtToken,\n uint256 debtChange,\n bool isDebtIncrease,\n uint256 maxFeePercentage\n )\n internal\n {\n if (debtChange == 0) {\n return;\n }\n\n if (isDebtIncrease) {\n uint256 totalDebtChange =\n debtChange + _triggerBorrowingFee(collateralToken, position, debtChange, maxFeePercentage);\n raftDebtToken.mint(position, totalDebtChange);\n _mintRTokens(msg.sender, debtChange);\n } else {\n raftDebtToken.burn(position, debtChange);\n _burnRTokens(msg.sender, debtChange);\n }\n\n emit DebtChanged(position, collateralToken, debtChange, isDebtIncrease);\n }\n\n /// @dev Mints R tokens\n function _mintRTokens(address to, uint256 amount) internal virtual {\n rToken.mint(to, amount);\n }\n\n /// @dev Burns R tokens\n function _burnRTokens(address from, uint256 amount) internal virtual {\n rToken.burn(from, amount);\n }\n\n /// @dev Adjusts the collateral of a given borrower by burning or minting the corresponding amount of Raft\n /// collateral token and transferring the corresponding amount of collateral token.\n /// @param collateralToken The token the borrower used as collateral.\n /// @param position The address of the borrower.\n /// @param collateralChange The amount of collateral to add or remove. Must be positive.\n /// @param isCollateralIncrease True if the collateral is being increased, false otherwise.\n function _adjustCollateral(\n IERC20 collateralToken,\n IERC20Indexable raftCollateralToken,\n address position,\n uint256 collateralChange,\n bool isCollateralIncrease\n )\n internal\n {\n if (collateralChange == 0) {\n return;\n }\n\n if (isCollateralIncrease) {\n raftCollateralToken.mint(position, collateralChange);\n collateralToken.safeTransferFrom(msg.sender, address(this), collateralChange);\n } else {\n raftCollateralToken.burn(position, collateralChange);\n collateralToken.safeTransfer(msg.sender, collateralChange);\n }\n\n emit CollateralChanged(position, collateralToken, collateralChange, isCollateralIncrease);\n }\n\n /// @dev Updates debt and collateral indexes for a given collateral token.\n /// @param collateralToken The collateral token for which to update the indexes.\n /// @param raftCollateralToken The raft collateral indexable token.\n /// @param raftDebtToken The raft debt indexable token.\n /// @param totalDebtForCollateral Totam amount of debt backed by collateral token.\n function _updateDebtAndCollateralIndex(\n IERC20 collateralToken,\n IERC20Indexable raftCollateralToken,\n IERC20Indexable raftDebtToken,\n uint256 totalDebtForCollateral\n )\n internal\n {\n raftDebtToken.setIndex(totalDebtForCollateral);\n raftCollateralToken.setIndex(collateralToken.balanceOf(address(this)));\n }\n\n function _closePosition(\n IERC20Indexable raftCollateralToken,\n IERC20Indexable raftDebtToken,\n address position,\n bool burnTokens\n )\n internal\n {\n collateralTokenForPosition[position] = IERC20(address(0));\n\n if (burnTokens) {\n raftDebtToken.burn(position, type(uint256).max);\n raftCollateralToken.burn(position, type(uint256).max);\n }\n emit PositionClosed(position);\n }\n\n // --- Borrowing & redemption fee helper functions ---\n\n /// @dev Updates the base rate from a redemption operation. Impacts on the base rate:\n /// 1. decays the base rate based on time passed since last redemption or R borrowing operation,\n /// 2. increases the base rate based on the amount redeemed, as a proportion of total supply.\n function _updateBaseRateFromRedemption(\n IERC20 collateralToken,\n uint256 collateralDrawn,\n uint256 price,\n uint256 totalDebtSupply\n )\n internal\n returns (uint256)\n {\n uint256 decayedBaseRate = _calcDecayedBaseRate(collateralToken);\n\n /* Convert the drawn collateral back to R at face value rate (1 R:1 USD), in order to get\n * the fraction of total supply that was redeemed at face value. */\n uint256 redeemedFraction = collateralDrawn * price / totalDebtSupply;\n\n uint256 newBaseRate = decayedBaseRate + redeemedFraction / BETA;\n newBaseRate = Math.min(newBaseRate, MathUtils._100_PERCENT); // cap baseRate at a maximum of 100%\n assert(newBaseRate > 0); // Base rate is always non-zero after redemption\n\n // Update the baseRate state variable\n collateralInfo[collateralToken].baseRate = newBaseRate;\n emit BaseRateUpdated(collateralToken, newBaseRate);\n\n _updateLastFeeOpTime(collateralToken);\n\n return newBaseRate;\n }\n\n function _calcRedemptionRate(IERC20 collateralToken, uint256 baseRate_) internal view returns (uint256) {\n return baseRate_ + collateralInfo[collateralToken].redemptionSpread;\n }\n\n function _calcBorrowingRate(IERC20 collateralToken, uint256 baseRate_) internal view returns (uint256) {\n return Math.min(collateralInfo[collateralToken].borrowingSpread + baseRate_, MAX_BORROWING_RATE);\n }\n\n /// @dev Updates the base rate based on time elapsed since the last redemption or R borrowing operation.\n function _decayBaseRateFromBorrowing(IERC20 collateralToken) internal {\n uint256 decayedBaseRate = _calcDecayedBaseRate(collateralToken);\n assert(decayedBaseRate <= MathUtils._100_PERCENT); // The baseRate can decay to 0\n\n collateralInfo[collateralToken].baseRate = decayedBaseRate;\n emit BaseRateUpdated(collateralToken, decayedBaseRate);\n\n _updateLastFeeOpTime(collateralToken);\n }\n\n /// @dev Update the last fee operation time only if time passed >= decay interval. This prevents base rate\n /// griefing.\n function _updateLastFeeOpTime(IERC20 collateralToken) internal {\n uint256 timePassed = block.timestamp - collateralInfo[collateralToken].lastFeeOperationTime;\n\n if (timePassed >= 1 minutes) {\n collateralInfo[collateralToken].lastFeeOperationTime = block.timestamp;\n emit LastFeeOpTimeUpdated(collateralToken, block.timestamp);\n }\n }\n\n function _calcDecayedBaseRate(IERC20 collateralToken) internal view returns (uint256) {\n uint256 minutesPassed = (block.timestamp - collateralInfo[collateralToken].lastFeeOperationTime) / 1 minutes;\n uint256 decayFactor = MathUtils._decPow(MINUTE_DECAY_FACTOR, minutesPassed);\n\n return collateralInfo[collateralToken].baseRate.mulDown(decayFactor);\n }\n\n function _triggerBorrowingFee(\n IERC20 collateralToken,\n address position,\n uint256 debtAmount,\n uint256 maxFeePercentage\n )\n internal\n virtual\n returns (uint256 borrowingFee)\n {\n _decayBaseRateFromBorrowing(collateralToken); // decay the baseRate state variable\n borrowingFee = getBorrowingFee(collateralToken, debtAmount);\n\n _checkValidFee(borrowingFee, debtAmount, maxFeePercentage);\n\n if (borrowingFee > 0) {\n _mintRTokens(feeRecipient, borrowingFee);\n emit RBorrowingFeePaid(collateralToken, position, borrowingFee);\n }\n }\n\n // --- Validation check helper functions ---\n\n function _checkValidPosition(IERC20 collateralToken, uint256 positionDebt, uint256 positionCollateral) internal {\n ISplitLiquidationCollateral splitCollateral = collateralInfo[collateralToken].splitLiquidation;\n if (positionDebt < splitCollateral.LOW_TOTAL_DEBT()) {\n revert NetDebtBelowMinimum(positionDebt);\n }\n\n (uint256 price,) = collateralInfo[collateralToken].priceFeed.fetchPrice();\n uint256 newICR = MathUtils._computeCR(positionCollateral, positionDebt, price);\n if (newICR < splitCollateral.MCR()) {\n revert NewICRLowerThanMCR(newICR);\n }\n }\n\n function _checkValidFee(uint256 fee, uint256 amount, uint256 maxFeePercentage) internal pure {\n uint256 feePercentage = fee.divDown(amount);\n\n if (feePercentage > maxFeePercentage) {\n revert FeeExceedsMaxFee(fee, amount, maxFeePercentage);\n }\n }\n}\n\ninterface IRMinter {\n /// @dev Emitted when tokens are recovered from the contract.\n /// @param token The address of the token being recovered.\n /// @param to The address receiving the recovered tokens.\n /// @param amount The amount of tokens recovered.\n event TokensRecovered(IERC20 token, address to, uint256 amount);\n\n /// @return Address of the R token.\n function r() external view returns (IRToken);\n\n /// @return Address of the Position manager contract responsible for minting R.\n function positionManager() external view returns (IPositionManager);\n\n /// @dev Recover accidentally sent tokens to the contract\n /// @param token Address of the token contract.\n /// @param to Address of the receiver of the tokens.\n /// @param amount Number of tokens to recover.\n function recoverTokens(IERC20 token, address to, uint256 amount) external;\n}\n\ninterface ILock {\n /// @dev Thrown when contract usage is locked.\n error ContractLocked();\n\n /// @dev Unauthorized call to lock/unlock.\n error Unauthorized();\n\n /// @dev Retrieves if contract is currently locked or not.\n function locked() external view returns (bool);\n\n /// @dev Retrieves address of the locker who can unlock contract.\n function locker() external view returns (address);\n\n /// @dev Unlcoks the usage of the contract.\n function unlock() external;\n\n /// @dev Locks the usage of the contract.\n function lock() external;\n}\n\nabstract contract ERC20RMinter is IRMinter, ERC20, Ownable2Step {\n using SafeERC20 for IERC20;\n\n IRToken public immutable override r;\n IPositionManager public immutable override positionManager;\n\n constructor(IRToken rToken_, string memory name_, string memory symbol_) ERC20(name_, symbol_) {\n r = rToken_;\n positionManager = IPositionManager(rToken_.positionManager());\n\n _approve(address(this), address(positionManager), type(uint256).max);\n }\n\n modifier unlockCall() {\n ILock lockContract = ILock(address(positionManager.priceFeed(IERC20(this))));\n lockContract.unlock();\n _;\n lockContract.lock();\n }\n\n function recoverTokens(IERC20 token, address to, uint256 amount) external override onlyOwner {\n token.safeTransfer(to, amount);\n emit TokensRecovered(token, to, amount);\n }\n\n function _mintR(address to, uint256 amount) internal unlockCall {\n _mint(address(this), amount);\n ERC20PermitSignature memory emptySignature;\n positionManager.managePosition(\n IERC20(address(this)),\n address(this),\n amount,\n true, // collateral increase\n amount,\n true, // debt increase\n 1e18, // 100%\n emptySignature\n );\n r.transfer(to, amount);\n }\n\n function _burnR(address from, uint256 amount) internal unlockCall {\n r.transferFrom(from, address(this), amount);\n ERC20PermitSignature memory emptySignature;\n positionManager.managePosition(\n IERC20(address(this)),\n address(this),\n amount,\n false, // collateral decrease\n amount,\n false, // debt decrease\n 1e18, // 100%\n emptySignature\n );\n _burn(address(this), amount);\n }\n}\n\ncontract InterestRateDebtToken is ERC20Indexable {\n // --- Types ---\n\n using Fixed256x18 for uint256;\n\n // --- Events ---\n\n event IndexIncreasePerSecondSet(uint256 indexIncreasePerSecond);\n\n // --- Immutables ---\n\n IERC20 immutable collateralToken;\n\n // --- Variables ---\n\n uint256 internal storedIndexUpdatedAt;\n\n uint256 public indexIncreasePerSecond;\n\n // --- Constructor ---\n\n constructor(\n address positionManager_,\n string memory name_,\n string memory symbol_,\n IERC20 collateralToken_,\n uint256 cap_,\n uint256 indexIncreasePerSecond_\n )\n ERC20Indexable(positionManager_, name_, symbol_, cap_)\n {\n storedIndexUpdatedAt = block.timestamp;\n collateralToken = collateralToken_;\n setIndexIncreasePerSecond(indexIncreasePerSecond_);\n }\n\n // --- Functions ---\n\n function mint(address to, uint256 amount) public virtual override {\n updateIndexAndPayFees();\n super.mint(to, amount);\n }\n\n function burn(address from, uint256 amount) public virtual override {\n updateIndexAndPayFees();\n super.burn(from, amount);\n }\n\n function currentIndex() public view virtual override returns (uint256) {\n return storedIndex.mulUp(INDEX_PRECISION + indexIncreasePerSecond * (block.timestamp - storedIndexUpdatedAt));\n }\n\n function updateIndexAndPayFees() public {\n uint256 currentIndex_ = currentIndex();\n _payFees(currentIndex_);\n storedIndexUpdatedAt = block.timestamp;\n storedIndex = currentIndex_;\n emit IndexUpdated(currentIndex_);\n }\n\n function setIndexIncreasePerSecond(uint256 indexIncreasePerSecond_) public onlyOwner {\n updateIndexAndPayFees();\n indexIncreasePerSecond = indexIncreasePerSecond_;\n emit IndexIncreasePerSecondSet(indexIncreasePerSecond_);\n }\n\n function unpaidFees() external view returns (uint256) {\n return _unpaidFees(currentIndex());\n }\n\n function _unpaidFees(uint256 currentIndex_) private view returns (uint256) {\n return totalSupply().mulDown(currentIndex_ - storedIndex);\n }\n\n function _payFees(uint256 currentIndex_) private {\n uint256 unpaidFees = _unpaidFees(currentIndex_);\n if (unpaidFees > 0) {\n IInterestRatePositionManager(positionManager).mintFees(collateralToken, unpaidFees);\n }\n }\n}\n\n/// @dev Implementation of Position Manager. Current implementation does not support rebasing tokens as collateral.\ncontract InterestRatePositionManager is ERC20RMinter, PositionManager, IInterestRatePositionManager {\n // --- Errors ---\n\n error Unsupported();\n\n // --- Constructor ---\n\n /// @dev Initializes the position manager.\n constructor(IRToken rToken_)\n PositionManager(address(rToken_))\n ERC20RMinter(rToken_, \"Interest Rate Posman\", \"IRPM\")\n { }\n\n // --- External functions ---\n\n function managePosition(\n IERC20 collateralToken,\n address position,\n uint256 collateralChange,\n bool isCollateralIncrease,\n uint256 debtChange,\n bool isDebtIncrease,\n uint256 maxFeePercentage,\n ERC20PermitSignature calldata permitSignature\n )\n public\n virtual\n override(IPositionManager, PositionManager)\n returns (uint256 actualCollateralChange, uint256 actualDebtChange)\n {\n if (address(permitSignature.token) == address(r)) {\n PermitHelper.applyPermit(permitSignature, msg.sender, address(this));\n }\n return super.managePosition(\n collateralToken,\n position,\n collateralChange,\n isCollateralIncrease,\n debtChange,\n isDebtIncrease,\n maxFeePercentage,\n permitSignature\n );\n }\n\n function mintFees(IERC20 collateralToken, uint256 amount) external {\n if (msg.sender != address(collateralInfo[collateralToken].debtToken)) {\n revert InvalidDebtToken(msg.sender);\n }\n _mintR(feeRecipient, amount);\n\n emit MintedFees(collateralToken, amount);\n }\n\n function redeemCollateral(IERC20, uint256, uint256) public virtual override(IPositionManager, PositionManager) {\n revert Unsupported();\n }\n\n function addCollateralToken(\n IERC20,\n IPriceFeed,\n ISplitLiquidationCollateral\n )\n public\n override(IPositionManager, PositionManager)\n {\n revert Unsupported();\n }\n\n // --- Helper functions ---\n\n function _mintRTokens(address to, uint256 amount) internal virtual override {\n _mintR(to, amount);\n }\n\n function _burnRTokens(address from, uint256 amount) internal virtual override {\n _burnR(from, amount);\n }\n\n function _triggerBorrowingFee(\n IERC20,\n address,\n uint256,\n uint256\n )\n internal\n pure\n virtual\n override\n returns (uint256)\n {\n return 0;\n }\n}\n" - } - }, - "settings": { - "remappings": [ - "@balancer-labs/=node_modules/@balancer-labs/", - "@balancer-labs/v2-interfaces/contracts/=lib/balancer-v2-monorepo/pkg/interfaces/contracts/", - "@chainlink/=node_modules/@chainlink/", - "@eth-optimism/=node_modules/@eth-optimism/", - "@openzeppelin/=node_modules/@openzeppelin/", - "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", - "@redstone-finance/=node_modules/@redstone-finance/", - "@smartcontractkit/chainlink/=lib/chainlink/contracts/src/v0.8/", - "@tempusfinance/=node_modules/@tempusfinance/", - "@tempusfinance/tempus-utils/contracts/=lib/tempus-utils/contracts/", - "balancer-v2-monorepo/=lib/balancer-v2-monorepo/", - "chainlink/=lib/chainlink/", - "ds-test/=lib/forge-std/lib/ds-test/src/", - "erc4626-tests/=lib/chainlink/contracts/foundry-lib/openzeppelin-contracts/lib/erc4626-tests/", - "eth-gas-reporter/=node_modules/eth-gas-reporter/", - "forge-std/=lib/forge-std/src/", - "hardhat/=node_modules/hardhat/", - "openzeppelin-contracts/=lib/openzeppelin-contracts/", - "tempus-utils/=lib/tempus-utils/contracts/" - ], - "optimizer": { - "enabled": true, - "runs": 200000 - }, - "metadata": { - "bytecodeHash": "ipfs", - "appendCBOR": true - }, - "outputSelection": { - "*": { - "*": [ - "evm.bytecode", - "evm.deployedBytecode", - "devdoc", - "userdoc", - "metadata", - "abi" - ] - } - }, - "evmVersion": "london", - "viaIR": true, - "libraries": {} - } - }, - "ABI": "[{\"inputs\":[{\"internalType\":\"contract IRToken\",\"name\":\"rToken_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AmountIsZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BorrowingSpreadExceedsMaximum\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotLiquidateLastPosition\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CollateralTokenAddressCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CollateralTokenAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CollateralTokenDisabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CollateralTokenNotAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DelegateNotWhitelisted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FeeEatsUpAllReturnedCollateral\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePercentage\",\"type\":\"uint256\"}],\"name\":\"FeeExceedsMaxFee\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"InvalidDebtToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDelegateAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidFeeRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMaxFeePercentage\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPosition\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxFeePercentageOutOfRange\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"netDebt\",\"type\":\"uint256\"}],\"name\":\"NetDebtBelowMinimum\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newICR\",\"type\":\"uint256\"}],\"name\":\"NewICRLowerThanMCR\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoCollateralOrDebtChange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NothingToLiquidate\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PositionCollateralTokenMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PriceFeedAddressCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RedemptionRebateExceedsMaximum\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RedemptionSpreadOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SplitLiquidationCollateralCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"newTotalCollateral\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minimumCollateral\",\"type\":\"uint256\"}],\"name\":\"TotalCollateralCannotBeLowerThanMinCollateral\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"newTotalDebt\",\"type\":\"uint256\"}],\"name\":\"TotalDebtCannotBeLowerThanMinDebt\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unsupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongCollateralParamsForFullRepayment\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"baseRate\",\"type\":\"uint256\"}],\"name\":\"BaseRateUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"borrowingSpread\",\"type\":\"uint256\"}],\"name\":\"BorrowingSpreadUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"position\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"collateralAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isCollateralIncrease\",\"type\":\"bool\"}],\"name\":\"CollateralChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contract IERC20Indexable\",\"name\":\"raftCollateralToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contract IERC20Indexable\",\"name\":\"raftDebtToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contract IPriceFeed\",\"name\":\"priceFeed\",\"type\":\"address\"}],\"name\":\"CollateralTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"name\":\"CollateralTokenModified\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"position\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"debtAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isDebtIncrease\",\"type\":\"bool\"}],\"name\":\"DebtChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"position\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"delegate\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"whitelisted\",\"type\":\"bool\"}],\"name\":\"DelegateWhitelisted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeRecipient\",\"type\":\"address\"}],\"name\":\"FeeRecipientChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"lastFeeOpTime\",\"type\":\"uint256\"}],\"name\":\"LastFeeOpTimeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"liquidator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"position\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"debtLiquidated\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"collateralLiquidated\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"collateralSentToLiquidator\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"collateralLiquidationFeePaid\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isRedistribution\",\"type\":\"bool\"}],\"name\":\"Liquidation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"MintedFees\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferStarted\",\"type\":\"event\"},{\"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\":\"position\",\"type\":\"address\"}],\"name\":\"PositionClosed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"position\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"PositionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IRToken\",\"name\":\"rToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeRecipient\",\"type\":\"address\"}],\"name\":\"PositionManagerDeployed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"position\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeAmount\",\"type\":\"uint256\"}],\"name\":\"RBorrowingFeePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"redeemer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"collateralSent\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"rebate\",\"type\":\"uint256\"}],\"name\":\"Redemption\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"redemptionRebate\",\"type\":\"uint256\"}],\"name\":\"RedemptionRebateUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"redemptionSpread\",\"type\":\"uint256\"}],\"name\":\"RedemptionSpreadUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"contract ISplitLiquidationCollateral\",\"name\":\"newSplitLiquidationCollateral\",\"type\":\"address\"}],\"name\":\"SplitLiquidationCollateralChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IERC20\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensRecovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BETA\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_BORROWING_RATE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_BORROWING_SPREAD\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MINUTE_DECAY_FACTOR\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"contract IPriceFeed\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"contract ISplitLiquidationCollateral\",\"name\":\"newSplitLiquidationCollateral\",\"type\":\"address\"},{\"internalType\":\"contract IERC20Indexable\",\"name\":\"raftCollateralToken_\",\"type\":\"address\"},{\"internalType\":\"contract IERC20Indexable\",\"name\":\"raftDebtToken_\",\"type\":\"address\"}],\"name\":\"addCollateralToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"contract IPriceFeed\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"contract ISplitLiquidationCollateral\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"addCollateralToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"baseRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"borrowingSpread\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"collateralEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"collateralInfo\",\"outputs\":[{\"internalType\":\"contract IERC20Indexable\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"contract IERC20Indexable\",\"name\":\"debtToken\",\"type\":\"address\"},{\"internalType\":\"contract IPriceFeed\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"contract ISplitLiquidationCollateral\",\"name\":\"splitLiquidation\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"lastFeeOperationTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"borrowingSpread\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseRate\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"redemptionSpread\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"redemptionRebate\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"position\",\"type\":\"address\"}],\"name\":\"collateralTokenForPosition\",\"outputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feeRecipient\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"debtAmount\",\"type\":\"uint256\"}],\"name\":\"getBorrowingFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"getBorrowingRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"getBorrowingRateWithDecay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"collateralAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"priceDeviation\",\"type\":\"uint256\"}],\"name\":\"getRedemptionFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"collateralAmount\",\"type\":\"uint256\"}],\"name\":\"getRedemptionFeeWithDecay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"redemptionFee\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"getRedemptionRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"getRedemptionRateWithDecay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"position\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"delegate\",\"type\":\"address\"}],\"name\":\"isDelegateWhitelisted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isWhitelisted\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"lastFeeOperationTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"position\",\"type\":\"address\"}],\"name\":\"liquidate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"position\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"collateralChange\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isCollateralIncrease\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"debtChange\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isDebtIncrease\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePercentage\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"contract IERC20Permit\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"struct ERC20PermitSignature\",\"name\":\"permitSignature\",\"type\":\"tuple\"}],\"name\":\"managePosition\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"actualCollateralChange\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualDebtChange\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mintFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"positionManager\",\"outputs\":[{\"internalType\":\"contract IPositionManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"priceFeed\",\"outputs\":[{\"internalType\":\"contract IPriceFeed\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"r\",\"outputs\":[{\"internalType\":\"contract IRToken\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rToken\",\"outputs\":[{\"internalType\":\"contract IRToken\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"raftCollateralToken\",\"outputs\":[{\"internalType\":\"contract IERC20Indexable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"raftDebtToken\",\"outputs\":[{\"internalType\":\"contract IERC20Indexable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"recoverTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"redeemCollateral\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"redemptionRebate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"redemptionSpread\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"newBorrowingSpread\",\"type\":\"uint256\"}],\"name\":\"setBorrowingSpread\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"name\":\"setCollateralEnabled\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newFeeRecipient\",\"type\":\"address\"}],\"name\":\"setFeeRecipient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"newRedemptionRebate\",\"type\":\"uint256\"}],\"name\":\"setRedemptionRebate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"newRedemptionSpread\",\"type\":\"uint256\"}],\"name\":\"setRedemptionSpread\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"contract ISplitLiquidationCollateral\",\"name\":\"newSplitLiquidationCollateral\",\"type\":\"address\"}],\"name\":\"setSplitLiquidationCollateral\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"splitLiquidationCollateral\",\"outputs\":[{\"internalType\":\"contract ISplitLiquidationCollateral\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"delegate\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"whitelisted\",\"type\":\"bool\"}],\"name\":\"whitelistDelegate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - "ContractName": "InterestRatePositionManager", - "CompilerVersion": "v0.8.19+commit.7dd6d404", - "OptimizationUsed": 1, - "Runs": 200000, - "ConstructorArguments": "0x000000000000000000000000183015a9ba6ff60230fdeadc3f43b3d788b13e21", - "EVMVersion": "london", - "Library": "", - "LicenseType": "", - "Proxy": 0, - "SwarmSource": "" - } -] \ No newline at end of file +[{"SourceCode":{"language":"Solidity","sources":{"contracts/InterestRates/InterestRatePositionManager.f.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.19;\n\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\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 /**\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// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n\n/// Parameters for ERC20Permit.permit call\nstruct ERC20PermitSignature {\n IERC20Permit token;\n uint256 value;\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n}\n\nlibrary PermitHelper {\n function applyPermit(\n ERC20PermitSignature calldata p,\n address owner,\n address spender\n ) internal {\n p.token.permit(owner, spender, p.value, p.deadline, p.v, p.r, p.s);\n }\n\n function applyPermits(\n ERC20PermitSignature[] calldata permits,\n address owner,\n address spender\n ) internal {\n for (uint256 i = 0; i < permits.length; i++) {\n applyPermit(permits[i], owner, spender);\n }\n }\n}\n\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC3156FlashLender.sol)\n\n// OpenZeppelin Contracts (last updated v4.7.0) (interfaces/IERC3156FlashBorrower.sol)\n\n/**\n * @dev Interface of the ERC3156 FlashBorrower, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * _Available since v4.1._\n */\ninterface IERC3156FlashBorrower {\n /**\n * @dev Receive a flash loan.\n * @param initiator The initiator of the loan.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @param fee The additional amount of tokens to repay.\n * @param data Arbitrary data structure, intended to contain user-defined parameters.\n * @return The keccak256 hash of \"IERC3156FlashBorrower.onFlashLoan\"\n */\n function onFlashLoan(\n address initiator,\n address token,\n uint256 amount,\n uint256 fee,\n bytes calldata data\n ) external returns (bytes32);\n}\n\n/**\n * @dev Interface of the ERC3156 FlashLender, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * _Available since v4.1._\n */\ninterface IERC3156FlashLender {\n /**\n * @dev The amount of currency available to be lended.\n * @param token The loan currency.\n * @return The amount of `token` that can be borrowed.\n */\n function maxFlashLoan(address token) external view returns (uint256);\n\n /**\n * @dev The fee to be charged for a given loan.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @return The amount of `token` to be charged for the loan, on top of the returned principal.\n */\n function flashFee(address token, uint256 amount) external view returns (uint256);\n\n /**\n * @dev Initiate a flash loan.\n * @param receiver The receiver of the tokens in the loan, and the receiver of the callback.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @param data Arbitrary data structure, intended to contain user-defined parameters.\n */\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n ) external returns (bool);\n}\n\n/// @dev Interface to be used by contracts that collect fees. Contains fee recipient that can be changed by owner.\ninterface IFeeCollector {\n // --- Events ---\n\n /// @dev Fee Recipient is changed to @param feeRecipient address.\n /// @param feeRecipient New fee recipient address.\n event FeeRecipientChanged(address feeRecipient);\n\n // --- Errors ---\n\n /// @dev Invalid fee recipient.\n error InvalidFeeRecipient();\n\n // --- Functions ---\n\n /// @return Address of the current fee recipient.\n function feeRecipient() external view returns (address);\n\n /// @dev Sets new fee recipient address\n /// @param newFeeRecipient Address of the new fee recipient.\n function setFeeRecipient(address newFeeRecipient) external;\n}\n\ninterface IPositionManagerDependent {\n // --- Errors ---\n\n /// @dev Position Manager cannot be zero.\n error PositionManagerCannotBeZero();\n\n /// @dev Caller is not Position Manager.\n error CallerIsNotPositionManager(address caller);\n\n // --- Functions ---\n\n /// @dev Returns address of the PositionManager contract.\n function positionManager() external view returns (address);\n}\n\n/// @dev Interface of R stablecoin token. Implements some standards like IERC20, IERC20Permit, and IERC3156FlashLender.\n/// Raft's specific implementation contains IFeeCollector and IPositionManagerDependent.\n/// PositionManager can mint and burn R when particular actions happen with user's position.\ninterface IRToken is IERC20, IERC20Permit, IERC3156FlashLender, IFeeCollector, IPositionManagerDependent {\n // --- Events ---\n\n /// @dev New R token is deployed\n /// @param positionManager Address of the PositionManager contract that is authorized to mint and burn new tokens.\n /// @param flashMintFeeRecipient Address of flash mint fee recipient.\n event RDeployed(address positionManager, address flashMintFeeRecipient);\n\n /// @dev The Flash Mint Fee Percentage has been changed.\n /// @param flashMintFeePercentage The new Flash Mint Fee Percentage value.\n event FlashMintFeePercentageChanged(uint256 flashMintFeePercentage);\n\n /// --- Errors ---\n\n /// @dev Proposed flash mint fee percentage is too big.\n /// @param feePercentage Proposed flash mint fee percentage.\n error FlashFeePercentageTooBig(uint256 feePercentage);\n\n // --- Functions ---\n\n /// @return Number representing 100 percentage.\n function PERCENTAGE_BASE() external view returns (uint256);\n\n /// @dev Mints new tokens. Callable only by PositionManager contract.\n /// @param to Address that will receive newly minted tokens.\n /// @param amount Amount of tokens to mint.\n function mint(address to, uint256 amount) external;\n\n /// @dev Mints new tokens. Callable only by PositionManager contract.\n /// @param from Address of user whose tokens are burnt.\n /// @param amount Amount of tokens to burn.\n function burn(address from, uint256 amount) external;\n\n /// @return Maximum flash mint fee percentage that can be set by owner.\n function MAX_FLASH_MINT_FEE_PERCENTAGE() external view returns (uint256);\n\n /// @return Current flash mint fee percentage.\n function flashMintFeePercentage() external view returns (uint256);\n\n /// @dev Sets new flash mint fee percentage. Callable only by owner.\n /// @notice The proposed flash mint fee percentage cannot exceed `MAX_FLASH_MINT_FEE_PERCENTAGE`.\n /// @param feePercentage New flash fee percentage.\n function setFlashMintFeePercentage(uint256 feePercentage) external;\n}\n\ninterface IPriceOracle {\n // --- Errors ---\n\n /// @dev Contract initialized with an invalid deviation parameter.\n error InvalidDeviation();\n\n // --- Types ---\n\n struct PriceOracleResponse {\n bool isBrokenOrFrozen;\n bool priceChangeAboveMax;\n uint256 price;\n }\n\n // --- Functions ---\n\n /// @dev Return price oracle response which consists the following information: oracle is broken or frozen, the\n /// price change between two rounds is more than max, and the price.\n function getPriceOracleResponse() external returns (PriceOracleResponse memory);\n\n /// @dev Maximum time period allowed since oracle latest round data timestamp, beyond which oracle is considered\n /// frozen.\n function timeout() external view returns (uint256);\n\n /// @dev Used to convert a price answer to an 18-digit precision uint.\n function TARGET_DIGITS() external view returns (uint256);\n\n /// @dev price deviation for the oracle in percentage.\n function DEVIATION() external view returns (uint256);\n}\n\ninterface IPriceFeed {\n // --- Events ---\n\n /// @dev Last good price has been updated.\n event LastGoodPriceUpdated(uint256 lastGoodPrice);\n\n /// @dev Price difference between oracles has been updated.\n /// @param priceDifferenceBetweenOracles New price difference between oracles.\n event PriceDifferenceBetweenOraclesUpdated(uint256 priceDifferenceBetweenOracles);\n\n /// @dev Primary oracle has been updated.\n /// @param primaryOracle New primary oracle.\n event PrimaryOracleUpdated(IPriceOracle primaryOracle);\n\n /// @dev Secondary oracle has been updated.\n /// @param secondaryOracle New secondary oracle.\n event SecondaryOracleUpdated(IPriceOracle secondaryOracle);\n\n // --- Errors ---\n\n /// @dev Invalid primary oracle.\n error InvalidPrimaryOracle();\n\n /// @dev Invalid secondary oracle.\n error InvalidSecondaryOracle();\n\n /// @dev Primary oracle is broken or frozen or has bad result.\n error PrimaryOracleBrokenOrFrozenOrBadResult();\n\n /// @dev Invalid price difference between oracles.\n error InvalidPriceDifferenceBetweenOracles();\n\n // --- Functions ---\n\n /// @dev Return primary oracle address.\n function primaryOracle() external returns (IPriceOracle);\n\n /// @dev Return secondary oracle address\n function secondaryOracle() external returns (IPriceOracle);\n\n /// @dev The last good price seen from an oracle by Raft.\n function lastGoodPrice() external returns (uint256);\n\n /// @dev The maximum relative price difference between two oracle responses.\n function priceDifferenceBetweenOracles() external returns (uint256);\n\n /// @dev Set primary oracle address.\n /// @param newPrimaryOracle Primary oracle address.\n function setPrimaryOracle(IPriceOracle newPrimaryOracle) external;\n\n /// @dev Set secondary oracle address.\n /// @param newSecondaryOracle Secondary oracle address.\n function setSecondaryOracle(IPriceOracle newSecondaryOracle) external;\n\n /// @dev Set the maximum relative price difference between two oracle responses.\n /// @param newPriceDifferenceBetweenOracles The maximum relative price difference between two oracle responses.\n function setPriceDifferenceBetweenOracles(uint256 newPriceDifferenceBetweenOracles) external;\n\n /// @dev Returns the latest price obtained from the Oracle. Called by Raft functions that require a current price.\n ///\n /// Also callable by anyone externally.\n /// Non-view function - it stores the last good price seen by Raft.\n ///\n /// Uses a primary oracle and a fallback oracle in case primary fails. If both fail,\n /// it uses the last good price seen by Raft.\n ///\n /// @return currentPrice Returned price.\n /// @return deviation Deviation of the reported price in percentage.\n /// @notice Actual returned price is in range `currentPrice` +/- `currentPrice * deviation / ONE`\n function fetchPrice() external returns (uint256 currentPrice, uint256 deviation);\n}\n\ninterface IERC20Indexable is IERC20, IPositionManagerDependent {\n // --- Events ---\n\n /// @dev New token is deployed.\n /// @param positionManager Address of the PositionManager contract that is authorized to mint and burn new tokens.\n event ERC20IndexableDeployed(address positionManager);\n\n /// @dev New index has been set.\n /// @param newIndex Value of the new index.\n event IndexUpdated(uint256 newIndex);\n\n // --- Errors ---\n\n /// @dev Unsupported action for ERC20Indexable contract.\n error NotSupported();\n\n // --- Functions ---\n\n /// @return Precision for token index. Represents index that is equal to 1.\n function INDEX_PRECISION() external view returns (uint256);\n\n /// @return Current index value.\n function currentIndex() external view returns (uint256);\n\n /// @dev Sets new token index. Callable only by PositionManager contract.\n /// @param backingAmount Amount of backing token that is covered by total supply.\n function setIndex(uint256 backingAmount) external;\n\n /// @dev Mints new tokens. Callable only by PositionManager contract.\n /// @param to Address that will receive newly minted tokens.\n /// @param amount Amount of tokens to mint.\n function mint(address to, uint256 amount) external;\n\n /// @dev Mints new tokens. Callable only by PositionManager contract.\n /// @param from Address of user whose tokens are burnt.\n /// @param amount Amount of tokens to burn.\n function burn(address from, uint256 amount) external;\n}\n\ninterface ISplitLiquidationCollateral {\n // --- Functions ---\n\n /// @dev Returns lowest total debt that will be split.\n function LOW_TOTAL_DEBT() external view returns (uint256);\n\n /// @dev Minimum collateralization ratio for position\n function MCR() external view returns (uint256);\n\n /// @dev Splits collateral between protocol and liquidator.\n /// @param totalCollateral Amount of collateral to split.\n /// @param totalDebt Amount of debt to split.\n /// @param price Price of collateral.\n /// @param isRedistribution True if this is a redistribution.\n /// @return collateralToSendToProtocol Amount of collateral to send to protocol.\n /// @return collateralToSentToLiquidator Amount of collateral to send to liquidator.\n function split(\n uint256 totalCollateral,\n uint256 totalDebt,\n uint256 price,\n bool isRedistribution\n )\n external\n view\n returns (uint256 collateralToSendToProtocol, uint256 collateralToSentToLiquidator);\n}\n\n/// @dev Common interface for the Position Manager.\ninterface IPositionManager is IFeeCollector {\n // --- Types ---\n\n /// @dev Information for a Raft indexable collateral token.\n /// @param collateralToken The Raft indexable collateral token.\n /// @param debtToken Corresponding Raft indexable debt token.\n /// @param priceFeed The contract that provides a price for the collateral token.\n /// @param splitLiquidation The contract that calculates collateral split in case of liquidation.\n /// @param isEnabled Whether the token can be used as collateral or not.\n /// @param lastFeeOperationTime Timestamp of the last operation for the collateral token.\n /// @param borrowingSpread The current borrowing spread.\n /// @param baseRate The current base rate.\n /// @param redemptionSpread The current redemption spread.\n /// @param redemptionRebate Percentage of the redemption fee returned to redeemed positions.\n struct CollateralTokenInfo {\n IERC20Indexable collateralToken;\n IERC20Indexable debtToken;\n IPriceFeed priceFeed;\n ISplitLiquidationCollateral splitLiquidation;\n bool isEnabled;\n uint256 lastFeeOperationTime;\n uint256 borrowingSpread;\n uint256 baseRate;\n uint256 redemptionSpread;\n uint256 redemptionRebate;\n }\n\n // --- Events ---\n\n /// @dev New position manager has been token deployed.\n /// @param rToken The R token used by the position manager.\n /// @param feeRecipient The address of fee recipient.\n event PositionManagerDeployed(IRToken rToken, address feeRecipient);\n\n /// @dev New collateral token has been added added to the system.\n /// @param collateralToken The token used as collateral.\n /// @param raftCollateralToken The Raft indexable collateral token for the given collateral token.\n /// @param raftDebtToken The Raft indexable debt token for given collateral token.\n /// @param priceFeed The contract that provides price for the collateral token.\n event CollateralTokenAdded(\n IERC20 collateralToken,\n IERC20Indexable raftCollateralToken,\n IERC20Indexable raftDebtToken,\n IPriceFeed priceFeed\n );\n\n /// @dev Collateral token has been enabled or disabled.\n /// @param collateralToken The token used as collateral.\n /// @param isEnabled True if the token is enabled, false otherwise.\n event CollateralTokenModified(IERC20 collateralToken, bool isEnabled);\n\n /// @dev A delegate has been whitelisted for a certain position.\n /// @param position The position for which the delegate was whitelisted.\n /// @param delegate The delegate which was whitelisted.\n /// @param whitelisted Specifies whether the delegate whitelisting has been enabled (true) or disabled (false).\n event DelegateWhitelisted(address indexed position, address indexed delegate, bool whitelisted);\n\n /// @dev New position has been created.\n /// @param position The address of the user opening new position.\n /// @param collateralToken The token used as collateral for the created position.\n event PositionCreated(address indexed position, IERC20 indexed collateralToken);\n\n /// @dev The position has been closed by either repayment, liquidation, or redemption.\n /// @param position The address of the user whose position is closed.\n event PositionClosed(address indexed position);\n\n /// @dev Collateral amount for the position has been changed.\n /// @param position The address of the user that has opened the position.\n /// @param collateralToken The address of the collateral token being added to position.\n /// @param collateralAmount The amount of collateral added or removed.\n /// @param isCollateralIncrease Whether the collateral is added to the position or removed from it.\n event CollateralChanged(\n address indexed position, IERC20 indexed collateralToken, uint256 collateralAmount, bool isCollateralIncrease\n );\n\n /// @dev Debt amount for position has been changed.\n /// @param position The address of the user that has opened the position.\n /// @param collateralToken The address of the collateral token backing the debt.\n /// @param debtAmount The amount of debt added or removed.\n /// @param isDebtIncrease Whether the debt is added to the position or removed from it.\n event DebtChanged(\n address indexed position, IERC20 indexed collateralToken, uint256 debtAmount, bool isDebtIncrease\n );\n\n /// @dev Borrowing fee has been paid. Emitted only if the actual fee was paid - doesn't happen with no fees are\n /// paid.\n /// @param collateralToken Collateral token used to mint R.\n /// @param position The address of position's owner that triggered the fee payment.\n /// @param feeAmount The amount of tokens paid as the borrowing fee.\n event RBorrowingFeePaid(IERC20 collateralToken, address indexed position, uint256 feeAmount);\n\n /// @dev Liquidation has been executed.\n /// @param liquidator The liquidator that executed the liquidation.\n /// @param position The address of position's owner whose position was liquidated.\n /// @param collateralToken The collateral token used for the liquidation.\n /// @param debtLiquidated The total debt that was liquidated or redistributed.\n /// @param collateralLiquidated The total collateral liquidated.\n /// @param collateralSentToLiquidator The collateral amount sent to the liquidator.\n /// @param collateralLiquidationFeePaid The total collateral paid as the liquidation fee to the fee recipient.\n /// @param isRedistribution Whether the executed liquidation was redistribution or not.\n event Liquidation(\n address indexed liquidator,\n address indexed position,\n IERC20 indexed collateralToken,\n uint256 debtLiquidated,\n uint256 collateralLiquidated,\n uint256 collateralSentToLiquidator,\n uint256 collateralLiquidationFeePaid,\n bool isRedistribution\n );\n\n /// @dev Redemption has been executed.\n /// @param redeemer User that redeemed R.\n /// @param amount Amount of R that was redeemed.\n /// @param collateralSent The amount of collateral sent to the redeemer.\n /// @param fee The amount of fee paid to the fee recipient.\n /// @param rebate Redemption rebate amount.\n event Redemption(address indexed redeemer, uint256 amount, uint256 collateralSent, uint256 fee, uint256 rebate);\n\n /// @dev Borrowing spread has been updated.\n /// @param borrowingSpread The new borrowing spread.\n event BorrowingSpreadUpdated(uint256 borrowingSpread);\n\n /// @dev Redemption rebate has been updated.\n /// @param redemptionRebate The new redemption rebate.\n event RedemptionRebateUpdated(uint256 redemptionRebate);\n\n /// @dev Redemption spread has been updated.\n /// @param collateralToken Collateral token that the spread was set for.\n /// @param redemptionSpread The new redemption spread.\n event RedemptionSpreadUpdated(IERC20 collateralToken, uint256 redemptionSpread);\n\n /// @dev Base rate has been updated.\n /// @param collateralToken Collateral token that the baser rate was updated for.\n /// @param baseRate The new base rate.\n event BaseRateUpdated(IERC20 collateralToken, uint256 baseRate);\n\n /// @dev Last fee operation time has been updated.\n /// @param collateralToken Collateral token that the baser rate was updated for.\n /// @param lastFeeOpTime The new operation time.\n event LastFeeOpTimeUpdated(IERC20 collateralToken, uint256 lastFeeOpTime);\n\n /// @dev Split liquidation collateral has been changed.\n /// @param collateralToken Collateral token whose split liquidation collateral contract is set.\n /// @param newSplitLiquidationCollateral New value that was set to be split liquidation collateral.\n event SplitLiquidationCollateralChanged(\n IERC20 collateralToken, ISplitLiquidationCollateral indexed newSplitLiquidationCollateral\n );\n\n // --- Errors ---\n\n /// @dev Max fee percentage must be between borrowing spread and 100%.\n error InvalidMaxFeePercentage();\n\n /// @dev Max fee percentage must be between 0.5% and 100%.\n error MaxFeePercentageOutOfRange();\n\n /// @dev Amount is zero.\n error AmountIsZero();\n\n /// @dev Nothing to liquidate.\n error NothingToLiquidate();\n\n /// @dev Cannot liquidate last position.\n error CannotLiquidateLastPosition();\n\n /// @dev Cannot redeem collateral below minimum debt threshold.\n /// @param collateralToken Collateral token used to redeem.\n /// @param newTotalDebt New total debt backed by collateral, which is lower than minimum debt.\n error TotalDebtCannotBeLowerThanMinDebt(IERC20 collateralToken, uint256 newTotalDebt);\n\n /// @dev Cannot redeem collateral\n /// @param collateralToken Collateral token used to redeem.\n /// @param newTotalCollateral New total collateral, which is lower than minimum collateral.\n /// @param minimumCollateral Minimum collateral required to complete redeem\n error TotalCollateralCannotBeLowerThanMinCollateral(\n IERC20 collateralToken, uint256 newTotalCollateral, uint256 minimumCollateral\n );\n\n /// @dev Fee would eat up all returned collateral.\n error FeeEatsUpAllReturnedCollateral();\n\n /// @dev Borrowing spread exceeds maximum.\n error BorrowingSpreadExceedsMaximum();\n\n /// @dev Redemption rebate exceeds maximum.\n error RedemptionRebateExceedsMaximum();\n\n /// @dev Redemption spread is out of allowed range.\n error RedemptionSpreadOutOfRange();\n\n /// @dev There must be either a collateral change or a debt change.\n error NoCollateralOrDebtChange();\n\n /// @dev There is some collateral for position that doesn't have debt.\n error InvalidPosition();\n\n /// @dev An operation that would result in ICR < MCR is not permitted.\n /// @param newICR Resulting ICR that is below MCR.\n error NewICRLowerThanMCR(uint256 newICR);\n\n /// @dev Position's net debt must be greater than minimum.\n /// @param netDebt Net debt amount that is below minimum.\n error NetDebtBelowMinimum(uint256 netDebt);\n\n /// @dev The provided delegate address is invalid.\n error InvalidDelegateAddress();\n\n /// @dev A non-whitelisted delegate cannot adjust positions.\n error DelegateNotWhitelisted();\n\n /// @dev Fee exceeded provided maximum fee percentage.\n /// @param fee The fee amount.\n /// @param amount The amount of debt or collateral.\n /// @param maxFeePercentage The maximum fee percentage.\n error FeeExceedsMaxFee(uint256 fee, uint256 amount, uint256 maxFeePercentage);\n\n /// @dev Borrower uses a different collateral token already.\n error PositionCollateralTokenMismatch();\n\n /// @dev Collateral token address cannot be zero.\n error CollateralTokenAddressCannotBeZero();\n\n /// @dev Price feed address cannot be zero.\n error PriceFeedAddressCannotBeZero();\n\n /// @dev Collateral token already added.\n error CollateralTokenAlreadyAdded();\n\n /// @dev Collateral token is not added.\n error CollateralTokenNotAdded();\n\n /// @dev Collateral token is not enabled.\n error CollateralTokenDisabled();\n\n /// @dev Split liquidation collateral cannot be zero.\n error SplitLiquidationCollateralCannotBeZero();\n\n /// @dev Cannot change collateral in case of repaying the whole debt.\n error WrongCollateralParamsForFullRepayment();\n\n // --- Functions ---\n\n /// @return The R token used by position manager.\n function rToken() external view returns (IRToken);\n\n /// @dev Retrieves information about certain collateral type.\n /// @param collateralToken The token used as collateral.\n /// @return raftCollateralToken The Raft indexable collateral token.\n /// @return raftDebtToken The Raft indexable debt token.\n /// @return priceFeed The contract that provides a price for the collateral token.\n /// @return splitLiquidation The contract that calculates collateral split in case of liquidation.\n /// @return isEnabled Whether the collateral token can be used as collateral or not.\n /// @return lastFeeOperationTime Timestamp of the last operation for the collateral token.\n /// @return borrowingSpread The current borrowing spread.\n /// @return baseRate The current base rate.\n /// @return redemptionSpread The current redemption spread.\n /// @return redemptionRebate Percentage of the redemption fee returned to redeemed positions.\n function collateralInfo(IERC20 collateralToken)\n external\n view\n returns (\n IERC20Indexable raftCollateralToken,\n IERC20Indexable raftDebtToken,\n IPriceFeed priceFeed,\n ISplitLiquidationCollateral splitLiquidation,\n bool isEnabled,\n uint256 lastFeeOperationTime,\n uint256 borrowingSpread,\n uint256 baseRate,\n uint256 redemptionSpread,\n uint256 redemptionRebate\n );\n\n /// @param collateralToken Collateral token whose raft collateral indexable token is being queried.\n /// @return Raft collateral token address for given collateral token.\n function raftCollateralToken(IERC20 collateralToken) external view returns (IERC20Indexable);\n\n /// @param collateralToken Collateral token whose raft collateral indexable token is being queried.\n /// @return Raft debt token address for given collateral token.\n function raftDebtToken(IERC20 collateralToken) external view returns (IERC20Indexable);\n\n /// @param collateralToken Collateral token whose price feed contract is being queried.\n /// @return Price feed contract address for given collateral token.\n function priceFeed(IERC20 collateralToken) external view returns (IPriceFeed);\n\n /// @param collateralToken Collateral token whose split liquidation collateral is being queried.\n /// @return Returns address of the split liquidation collateral contract.\n function splitLiquidationCollateral(IERC20 collateralToken) external view returns (ISplitLiquidationCollateral);\n\n /// @param collateralToken Collateral token whose split liquidation collateral is being queried.\n /// @return Returns whether collateral is enabled or nor.\n function collateralEnabled(IERC20 collateralToken) external view returns (bool);\n\n /// @param collateralToken Collateral token we query last operation time fee for.\n /// @return The timestamp of the latest fee operation (redemption or new R issuance).\n function lastFeeOperationTime(IERC20 collateralToken) external view returns (uint256);\n\n /// @param collateralToken Collateral token we query borrowing spread for.\n /// @return The current borrowing spread.\n function borrowingSpread(IERC20 collateralToken) external view returns (uint256);\n\n /// @param collateralToken Collateral token we query base rate for.\n /// @return rate The base rate.\n function baseRate(IERC20 collateralToken) external view returns (uint256 rate);\n\n /// @param collateralToken Collateral token we query redemption spread for.\n /// @return The current redemption spread for collateral token.\n function redemptionSpread(IERC20 collateralToken) external view returns (uint256);\n\n /// @param collateralToken Collateral token we query redemption rebate for.\n /// @return rebate Percentage of the redemption fee returned to redeemed positions.\n function redemptionRebate(IERC20 collateralToken) external view returns (uint256);\n\n /// @param collateralToken Collateral token we query redemption rate for.\n /// @return rate The current redemption rate for collateral token.\n function getRedemptionRate(IERC20 collateralToken) external view returns (uint256 rate);\n\n /// @dev Returns the collateral token that a given position used for their position.\n /// @param position The address of the borrower.\n /// @return collateralToken The collateral token of the borrower's position.\n function collateralTokenForPosition(address position) external view returns (IERC20 collateralToken);\n\n /// @dev Adds a new collateral token to the protocol.\n /// @param collateralToken The new collateral token.\n /// @param priceFeed The price feed for the collateral token.\n /// @param newSplitLiquidationCollateral split liquidation collateral contract address.\n function addCollateralToken(\n IERC20 collateralToken,\n IPriceFeed priceFeed,\n ISplitLiquidationCollateral newSplitLiquidationCollateral\n )\n external;\n\n /// @dev Adds a new collateral token to the protocol.\n /// @param collateralToken The new collateral token.\n /// @param priceFeed The price feed for the collateral token.\n /// @param newSplitLiquidationCollateral split liquidation collateral contract address.\n /// @param raftCollateralToken_ Address of raft collateral token.\n /// @param raftDebtToken_ Address of raft debt token.\n function addCollateralToken(\n IERC20 collateralToken,\n IPriceFeed priceFeed,\n ISplitLiquidationCollateral newSplitLiquidationCollateral,\n IERC20Indexable raftCollateralToken_,\n IERC20Indexable raftDebtToken_\n )\n external;\n\n /// @dev Enables or disables a collateral token. Reverts if the collateral token has not been added.\n /// @param collateralToken The collateral token.\n /// @param isEnabled Whether the collateral token can be used as collateral or not.\n function setCollateralEnabled(IERC20 collateralToken, bool isEnabled) external;\n\n /// @dev Sets the new split liquidation collateral contract.\n /// @param collateralToken Collateral token whose split liquidation collateral is being set.\n /// @param newSplitLiquidationCollateral New split liquidation collateral contract address.\n function setSplitLiquidationCollateral(\n IERC20 collateralToken,\n ISplitLiquidationCollateral newSplitLiquidationCollateral\n )\n external;\n\n /// @dev Liquidates the borrower if its position's ICR is lower than the minimum collateral ratio.\n /// @param position The address of the borrower.\n function liquidate(address position) external;\n\n /// @dev Redeems the collateral token for a given debt amount. It sends @param debtAmount R to the system and\n /// redeems the corresponding amount of collateral from as many positions as are needed to fill the redemption\n /// request.\n /// @param collateralToken The token used as collateral.\n /// @param debtAmount The amount of debt to be redeemed. Must be greater than zero.\n /// @param maxFeePercentage The maximum fee percentage to pay for the redemption.\n function redeemCollateral(IERC20 collateralToken, uint256 debtAmount, uint256 maxFeePercentage) external;\n\n /// @dev Manages the position on behalf of a given borrower.\n /// @param collateralToken The token the borrower used as collateral.\n /// @param position The address of the borrower.\n /// @param collateralChange The amount of collateral to add or remove.\n /// @param isCollateralIncrease True if the collateral is being increased, false otherwise.\n /// @param debtChange The amount of R to add or remove. In case of repayment (isDebtIncrease = false)\n /// `type(uint256).max` value can be used to repay the whole outstanding loan.\n /// @param isDebtIncrease True if the debt is being increased, false otherwise.\n /// @param maxFeePercentage The maximum fee percentage to pay for the position management.\n /// @param permitSignature Optional permit signature for tokens that support IERC20Permit interface.\n /// @notice `permitSignature` it is ignored if permit signature is not for `collateralToken`.\n /// @notice In case of full debt repayment, `isCollateralIncrease` is ignored and `collateralChange` must be 0.\n /// These values are set to `false`(collateral decrease), and the whole collateral balance of the user.\n /// @return actualCollateralChange Actual amount of collateral added/removed.\n /// Can be different to `collateralChange` in case of full repayment.\n /// @return actualDebtChange Actual amount of debt added/removed.\n /// Can be different to `debtChange` in case of passing type(uint256).max as `debtChange`.\n function managePosition(\n IERC20 collateralToken,\n address position,\n uint256 collateralChange,\n bool isCollateralIncrease,\n uint256 debtChange,\n bool isDebtIncrease,\n uint256 maxFeePercentage,\n ERC20PermitSignature calldata permitSignature\n )\n external\n returns (uint256 actualCollateralChange, uint256 actualDebtChange);\n\n /// @return The max borrowing spread.\n function MAX_BORROWING_SPREAD() external view returns (uint256);\n\n /// @return The max borrowing rate.\n function MAX_BORROWING_RATE() external view returns (uint256);\n\n /// @dev Sets the new borrowing spread.\n /// @param collateralToken Collateral token we set borrowing spread for.\n /// @param newBorrowingSpread New borrowing spread to be used.\n function setBorrowingSpread(IERC20 collateralToken, uint256 newBorrowingSpread) external;\n\n /// @param collateralToken Collateral token we query borrowing rate for.\n /// @return The current borrowing rate.\n function getBorrowingRate(IERC20 collateralToken) external view returns (uint256);\n\n /// @param collateralToken Collateral token we query borrowing rate with decay for.\n /// @return The current borrowing rate with decay.\n function getBorrowingRateWithDecay(IERC20 collateralToken) external view returns (uint256);\n\n /// @dev Returns the borrowing fee for a given debt amount.\n /// @param collateralToken Collateral token we query borrowing fee for.\n /// @param debtAmount The amount of debt.\n /// @return The borrowing fee.\n function getBorrowingFee(IERC20 collateralToken, uint256 debtAmount) external view returns (uint256);\n\n /// @dev Sets the new redemption spread.\n /// @param newRedemptionSpread New redemption spread to be used.\n function setRedemptionSpread(IERC20 collateralToken, uint256 newRedemptionSpread) external;\n\n /// @dev Sets new redemption rebate percentage.\n /// @param newRedemptionRebate Value that is being set as a redemption rebate percentage.\n function setRedemptionRebate(IERC20 collateralToken, uint256 newRedemptionRebate) external;\n\n /// @param collateralToken Collateral token we query redemption rate with decay for.\n /// @return The current redemption rate with decay.\n function getRedemptionRateWithDecay(IERC20 collateralToken) external view returns (uint256);\n\n /// @dev Returns the redemption fee for a given collateral amount.\n /// @param collateralToken Collateral token we query redemption fee for.\n /// @param collateralAmount The amount of collateral.\n /// @param priceDeviation Deviation for the reported price by oracle in percentage.\n /// @return The redemption fee.\n function getRedemptionFee(\n IERC20 collateralToken,\n uint256 collateralAmount,\n uint256 priceDeviation\n )\n external\n view\n returns (uint256);\n\n /// @dev Returns the redemption fee with decay for a given collateral amount.\n /// @param collateralToken Collateral token we query redemption fee with decay for.\n /// @param collateralAmount The amount of collateral.\n /// @return The redemption fee with decay.\n function getRedemptionFeeWithDecay(\n IERC20 collateralToken,\n uint256 collateralAmount\n )\n external\n view\n returns (uint256);\n\n /// @return Half-life of 12h (720 min).\n /// @dev (1/2) = d^720 => d = (1/2)^(1/720)\n function MINUTE_DECAY_FACTOR() external view returns (uint256);\n\n /// @dev Returns if a given delegate is whitelisted for a given borrower.\n /// @param position The address of the borrower.\n /// @param delegate The address of the delegate.\n /// @return isWhitelisted True if the delegate is whitelisted for a given borrower, false otherwise.\n function isDelegateWhitelisted(address position, address delegate) external view returns (bool isWhitelisted);\n\n /// @dev Whitelists a delegate.\n /// @param delegate The address of the delegate.\n /// @param whitelisted True if delegate is being whitelisted, false otherwise.\n function whitelistDelegate(address delegate, bool whitelisted) external;\n\n /// @return Parameter by which to divide the redeemed fraction, in order to calc the new base rate from a\n /// redemption. Corresponds to (1 / ALPHA) in the white paper.\n function BETA() external view returns (uint256);\n}\n\n/// @dev Common interface for the Position Manager.\ninterface IInterestRatePositionManager is IPositionManager {\n // --- Events ---\n\n /// @dev Fees coming from accrued interest are minted.\n /// @param collateralToken Collateral token that fees are paid for.\n /// @param amount Amount of R minted.\n event MintedFees(IERC20 collateralToken, uint256 amount);\n\n // --- Errors ---\n\n /// @dev Only registered debt token can be caller.\n /// @param sender Actual caller.\n error InvalidDebtToken(address sender);\n\n // --- Functions ---\n\n /// @dev Mints fees coming from accrued interest. Can be called only from matching debt token.\n /// @param collateralToken Collateral token to mint fees for.\n /// @param amount Amount of R to mint.\n function mintFees(IERC20 collateralToken, uint256 amount) external;\n}\n\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)\n\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\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 functionCallWithValue(target, data, 0, \"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 (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, 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 (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, 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 (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or 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 _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\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 /// @solidity memory-safe-assembly\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/**\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 function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\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\nlibrary Fixed256x18 {\n uint256 internal constant ONE = 1e18; // 18 decimal places\n\n function mulDown(uint256 a, uint256 b) internal pure returns (uint256) {\n return (a * b) / ONE;\n }\n\n function mulUp(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 product = a * b;\n\n if (product == 0) {\n return 0;\n } else {\n return ((product - 1) / ONE) + 1;\n }\n }\n\n function divDown(uint256 a, uint256 b) internal pure returns (uint256) {\n return (a * ONE) / b;\n }\n\n function divUp(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n } else {\n return (((a * ONE) - 1) / b) + 1;\n }\n }\n\n function complement(uint256 x) internal pure returns (uint256) {\n return (x < ONE) ? (ONE - x) : 0;\n }\n}\n\nlibrary MathUtils {\n // --- Constants ---\n\n /// @notice Represents 100%.\n /// @dev 1e18 is the scaling factor (100% == 1e18).\n uint256 public constant _100_PERCENT = Fixed256x18.ONE;\n\n /// @notice Precision for Nominal ICR (independent of price).\n /// @dev Rationale for the value:\n /// - Making it “too high” could lead to overflows.\n /// - Making it “too low” could lead to an ICR equal to zero, due to truncation from floor division.\n ///\n /// This value of 1e20 is chosen for safety: the NICR will only overflow for numerator > ~1e39 collateralToken,\n /// and will only truncate to 0 if the denominator is at least 1e20 times greater than the numerator.\n uint256 internal constant _NICR_PRECISION = 1e20;\n\n /// @notice Number of minutes in 1000 years.\n uint256 internal constant _MINUTES_IN_1000_YEARS = 1000 * 365 days / 1 minutes;\n\n // --- Functions ---\n\n /// @notice Multiplies two decimal numbers and use normal rounding rules:\n /// - round product up if 19'th mantissa digit >= 5\n /// - round product down if 19'th mantissa digit < 5.\n /// @param x First number.\n /// @param y Second number.\n function _decMul(uint256 x, uint256 y) internal pure returns (uint256 decProd) {\n decProd = (x * y + Fixed256x18.ONE / 2) / Fixed256x18.ONE;\n }\n\n /// @notice Exponentiation function for 18-digit decimal base, and integer exponent n.\n ///\n /// @dev Uses the efficient \"exponentiation by squaring\" algorithm. O(log(n)) complexity. The exponent is capped to\n /// avoid reverting due to overflow.\n ///\n /// If a period of > 1000 years is ever used as an exponent in either of the above functions, the result will be\n /// negligibly different from just passing the cap, since the decayed base rate will be 0 for 1000 years or > 1000\n /// years.\n /// @param base The decimal base.\n /// @param exponent The exponent.\n /// @return The result of the exponentiation.\n function _decPow(uint256 base, uint256 exponent) internal pure returns (uint256) {\n if (exponent == 0) {\n return Fixed256x18.ONE;\n }\n\n uint256 y = Fixed256x18.ONE;\n uint256 x = base;\n uint256 n = Math.min(exponent, _MINUTES_IN_1000_YEARS); // cap to avoid overflow\n\n // Exponentiation-by-squaring\n while (n > 1) {\n if (n % 2 != 0) {\n y = _decMul(x, y);\n }\n x = _decMul(x, x);\n n /= 2;\n }\n\n return _decMul(x, y);\n }\n\n /// @notice Computes the Nominal Individual Collateral Ratio (NICR) for given collateral and debt. If debt is zero,\n /// it returns the maximal value for uint256 (represents \"infinite\" CR).\n /// @param collateral Collateral amount.\n /// @param debt Debt amount.\n /// @return NICR.\n function _computeNominalCR(uint256 collateral, uint256 debt) internal pure returns (uint256) {\n return debt > 0 ? collateral * _NICR_PRECISION / debt : type(uint256).max;\n }\n\n /// @notice Computes the Collateral Ratio for given collateral, debt and price. If debt is zero, it returns the\n /// maximal value for uint256 (represents \"infinite\" CR).\n /// @param collateral Collateral amount.\n /// @param debt Debt amount.\n /// @param price Collateral price.\n /// @return Collateral ratio.\n function _computeCR(uint256 collateral, uint256 debt, uint256 price) internal pure returns (uint256) {\n return debt > 0 ? collateral * price / debt : type(uint256).max;\n }\n}\n\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol)\n\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\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\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n\n// OpenZeppelin Contracts (last updated v4.8.0) (access/Ownable2Step.sol)\n\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.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 Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\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 the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\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\n/**\n * @dev Contract module which provides 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} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() external {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n\n/**\n * @dev Extension of {ERC20} that adds a cap to the supply of tokens.\n */\nabstract contract ERC20Capped is ERC20, Ownable2Step {\n uint256 public cap;\n\n /**\n * @dev Total supply cap has been exceeded.\n */\n error ERC20ExceededCap();\n\n /**\n * @dev The supplied cap is not a valid cap.\n */\n error ERC20InvalidCap(uint256 cap);\n\n constructor(uint256 cap_) {\n setCap(cap_);\n }\n\n /**\n * @dev Sets the value of the `cap`.\n */\n function setCap(uint256 cap_) public onlyOwner {\n if (cap_ == 0) {\n revert ERC20InvalidCap(0);\n }\n cap = cap_;\n }\n\n /**\n * @dev See {ERC20-_mint}.\n */\n function _mint(address account, uint256 amount) internal virtual override {\n if (totalSupply() + amount > cap) {\n revert ERC20ExceededCap();\n }\n super._mint(account, amount);\n }\n}\n\nabstract contract PositionManagerDependent is IPositionManagerDependent {\n // --- Immutable variables ---\n\n address public immutable override positionManager;\n\n // --- Modifiers ---\n\n modifier onlyPositionManager() {\n if (msg.sender != positionManager) {\n revert CallerIsNotPositionManager(msg.sender);\n }\n _;\n }\n\n // --- Constructor ---\n\n constructor(address positionManager_) {\n if (positionManager_ == address(0)) {\n revert PositionManagerCannotBeZero();\n }\n positionManager = positionManager_;\n }\n}\n\ncontract ERC20Indexable is IERC20Indexable, ERC20Capped, PositionManagerDependent {\n // --- Types ---\n\n using Fixed256x18 for uint256;\n\n // --- Constants ---\n\n uint256 public constant override INDEX_PRECISION = Fixed256x18.ONE;\n\n // --- Variables ---\n\n uint256 internal storedIndex;\n\n // --- Constructor ---\n\n constructor(\n address positionManager_,\n string memory name_,\n string memory symbol_,\n uint256 cap_\n )\n ERC20(name_, symbol_)\n ERC20Capped(cap_)\n PositionManagerDependent(positionManager_)\n {\n storedIndex = INDEX_PRECISION;\n emit ERC20IndexableDeployed(positionManager_);\n }\n\n // --- Functions ---\n\n function mint(address to, uint256 amount) public virtual override onlyPositionManager {\n _mint(to, amount.divUp(storedIndex));\n }\n\n function burn(address from, uint256 amount) public virtual override onlyPositionManager {\n _burn(from, amount == type(uint256).max ? ERC20.balanceOf(from) : amount.divUp(storedIndex));\n }\n\n function setIndex(uint256 backingAmount) external override onlyPositionManager {\n uint256 supply = ERC20.totalSupply();\n uint256 newIndex = (backingAmount == 0 && supply == 0) ? INDEX_PRECISION : backingAmount.divUp(supply);\n storedIndex = newIndex;\n emit IndexUpdated(newIndex);\n }\n\n function currentIndex() public view virtual override returns (uint256) {\n return storedIndex;\n }\n\n function totalSupply() public view virtual override(IERC20, ERC20) returns (uint256) {\n return ERC20.totalSupply().mulDown(currentIndex());\n }\n\n function balanceOf(address account) public view virtual override(IERC20, ERC20) returns (uint256) {\n return ERC20.balanceOf(account).mulDown(currentIndex());\n }\n\n function transfer(address, uint256) public virtual override(IERC20, ERC20) returns (bool) {\n revert NotSupported();\n }\n\n function allowance(address, address) public view virtual override(IERC20, ERC20) returns (uint256) {\n revert NotSupported();\n }\n\n function approve(address, uint256) public virtual override(IERC20, ERC20) returns (bool) {\n revert NotSupported();\n }\n\n function transferFrom(address, address, uint256) public virtual override(IERC20, ERC20) returns (bool) {\n revert NotSupported();\n }\n\n function increaseAllowance(address, uint256) public virtual override returns (bool) {\n revert NotSupported();\n }\n\n function decreaseAllowance(address, uint256) public virtual override returns (bool) {\n revert NotSupported();\n }\n}\n\nabstract contract FeeCollector is Ownable2Step, IFeeCollector {\n // --- Variables ---\n\n address public override feeRecipient;\n\n // --- Constructor ---\n\n /// @param feeRecipient_ Address of the fee recipient to initialize contract with.\n constructor(address feeRecipient_) {\n if (feeRecipient_ == address(0)) {\n revert InvalidFeeRecipient();\n }\n\n feeRecipient = feeRecipient_;\n }\n\n // --- Functions ---\n\n function setFeeRecipient(address newFeeRecipient) external onlyOwner {\n if (newFeeRecipient == address(0)) {\n revert InvalidFeeRecipient();\n }\n\n feeRecipient = newFeeRecipient;\n emit FeeRecipientChanged(newFeeRecipient);\n }\n}\n\n// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol)\n\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/EIP712.sol)\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n address private immutable _CACHED_THIS;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n );\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = block.chainid;\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _CACHED_THIS = address(this);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n}\n\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) EIP712(name, \"1\") {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n Counters.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n}\n\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/extensions/ERC20FlashMint.sol)\n\n/**\n * @dev Implementation of the ERC3156 Flash loans extension, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * Adds the {flashLoan} method, which provides flash loan support at the token\n * level. By default there is no fee, but this can be changed by overriding {flashFee}.\n *\n * _Available since v4.1._\n */\nabstract contract ERC20FlashMint is ERC20, IERC3156FlashLender {\n bytes32 private constant _RETURN_VALUE = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n /**\n * @dev Returns the maximum amount of tokens available for loan.\n * @param token The address of the token that is requested.\n * @return The amount of token that can be loaned.\n */\n function maxFlashLoan(address token) public view virtual override returns (uint256) {\n return token == address(this) ? type(uint256).max - ERC20.totalSupply() : 0;\n }\n\n /**\n * @dev Returns the fee applied when doing flash loans. This function calls\n * the {_flashFee} function which returns the fee applied when doing flash\n * loans.\n * @param token The token to be flash loaned.\n * @param amount The amount of tokens to be loaned.\n * @return The fees applied to the corresponding flash loan.\n */\n function flashFee(address token, uint256 amount) public view virtual override returns (uint256) {\n require(token == address(this), \"ERC20FlashMint: wrong token\");\n return _flashFee(token, amount);\n }\n\n /**\n * @dev Returns the fee applied when doing flash loans. By default this\n * implementation has 0 fees. This function can be overloaded to make\n * the flash loan mechanism deflationary.\n * @param token The token to be flash loaned.\n * @param amount The amount of tokens to be loaned.\n * @return The fees applied to the corresponding flash loan.\n */\n function _flashFee(address token, uint256 amount) internal view virtual returns (uint256) {\n // silence warning about unused variable without the addition of bytecode.\n token;\n amount;\n return 0;\n }\n\n /**\n * @dev Returns the receiver address of the flash fee. By default this\n * implementation returns the address(0) which means the fee amount will be burnt.\n * This function can be overloaded to change the fee receiver.\n * @return The address for which the flash fee will be sent to.\n */\n function _flashFeeReceiver() internal view virtual returns (address) {\n return address(0);\n }\n\n /**\n * @dev Performs a flash loan. New tokens are minted and sent to the\n * `receiver`, who is required to implement the {IERC3156FlashBorrower}\n * interface. By the end of the flash loan, the receiver is expected to own\n * amount + fee tokens and have them approved back to the token contract itself so\n * they can be burned.\n * @param receiver The receiver of the flash loan. Should implement the\n * {IERC3156FlashBorrower-onFlashLoan} interface.\n * @param token The token to be flash loaned. Only `address(this)` is\n * supported.\n * @param amount The amount of tokens to be loaned.\n * @param data An arbitrary datafield that is passed to the receiver.\n * @return `true` if the flash loan was successful.\n */\n // This function can reenter, but it doesn't pose a risk because it always preserves the property that the amount\n // minted at the beginning is always recovered and burned at the end, or else the entire function will revert.\n // slither-disable-next-line reentrancy-no-eth\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n ) public virtual override returns (bool) {\n require(amount <= maxFlashLoan(token), \"ERC20FlashMint: amount exceeds maxFlashLoan\");\n uint256 fee = flashFee(token, amount);\n _mint(address(receiver), amount);\n require(\n receiver.onFlashLoan(msg.sender, token, amount, fee, data) == _RETURN_VALUE,\n \"ERC20FlashMint: invalid return value\"\n );\n address flashFeeReceiver = _flashFeeReceiver();\n _spendAllowance(address(receiver), address(this), amount + fee);\n if (fee == 0 || flashFeeReceiver == address(0)) {\n _burn(address(receiver), amount + fee);\n } else {\n _burn(address(receiver), amount);\n _transfer(address(receiver), flashFeeReceiver, fee);\n }\n return true;\n }\n}\n\ncontract RToken is ReentrancyGuard, ERC20Permit, ERC20FlashMint, PositionManagerDependent, FeeCollector, IRToken {\n // --- Constants ---\n\n uint256 public constant override PERCENTAGE_BASE = 10_000;\n uint256 public constant override MAX_FLASH_MINT_FEE_PERCENTAGE = 500;\n\n // --- Variables ---\n\n uint256 public override flashMintFeePercentage;\n\n // --- Constructor ---\n\n /// @dev Deploys new R token. Sets flash mint fee percentage to 0. Transfers ownership to @param feeRecipient_.\n /// @param positionManager_ Address of the PositionManager contract that is authorized to mint and burn new tokens.\n /// @param feeRecipient_ Address of flash mint fee recipient.\n constructor(\n address positionManager_,\n address feeRecipient_\n )\n ERC20Permit(\"R Stablecoin\")\n ERC20(\"R Stablecoin\", \"R\")\n PositionManagerDependent(positionManager_)\n FeeCollector(feeRecipient_)\n {\n setFlashMintFeePercentage(PERCENTAGE_BASE / 200); // 0.5%\n\n transferOwnership(feeRecipient_);\n\n emit RDeployed(positionManager_, feeRecipient_);\n }\n\n // --- Functions ---\n\n function mint(address to, uint256 amount) external override onlyPositionManager {\n _mint(to, amount);\n }\n\n function burn(address from, uint256 amount) external override onlyPositionManager {\n _burn(from, amount);\n }\n\n function setFlashMintFeePercentage(uint256 feePercentage) public override onlyOwner {\n if (feePercentage > MAX_FLASH_MINT_FEE_PERCENTAGE) {\n revert FlashFeePercentageTooBig(feePercentage);\n }\n\n flashMintFeePercentage = feePercentage;\n emit FlashMintFeePercentageChanged(flashMintFeePercentage);\n }\n\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n )\n public\n override(ERC20FlashMint, IERC3156FlashLender)\n nonReentrant\n returns (bool)\n {\n return super.flashLoan(receiver, token, amount, data);\n }\n\n /// @dev Inherited from ERC20FlashMint. Defines maximum size of the flash mint.\n /// @param token Token to be flash minted. Returns 0 amount in case of token != address(this).\n function maxFlashLoan(address token)\n public\n view\n virtual\n override(ERC20FlashMint, IERC3156FlashLender)\n returns (uint256)\n {\n return token == address(this) ? Math.min(totalSupply() / 10, ERC20FlashMint.maxFlashLoan(address(this))) : 0;\n }\n\n /// @dev Inherited from ERC20FlashMint. Defines flash mint fee for the flash mint of @param amount tokens.\n /// @param token Token to be flash minted. Returns 0 fee in case of token != address(this).\n /// @param amount Size of the flash mint.\n function _flashFee(address token, uint256 amount) internal view virtual override returns (uint256) {\n return token == address(this) ? amount * flashMintFeePercentage / PERCENTAGE_BASE : 0;\n }\n\n /// @dev Inherited from ERC20FlashMint. Defines flash mint fee receiver.\n /// @return Address that will receive flash mint fees.\n function _flashFeeReceiver() internal view virtual override returns (address) {\n return feeRecipient;\n }\n}\n\n/// @dev Implementation of Position Manager. Current implementation does not support rebasing tokens as collateral.\ncontract PositionManager is FeeCollector, IPositionManager {\n // --- Types ---\n\n using SafeERC20 for IERC20;\n using Fixed256x18 for uint256;\n\n // --- Constants ---\n\n uint256 public constant override MINUTE_DECAY_FACTOR = 999_037_758_833_783_000;\n\n uint256 public constant override MAX_BORROWING_SPREAD = MathUtils._100_PERCENT / 100; // 1%\n uint256 public constant override MAX_BORROWING_RATE = MathUtils._100_PERCENT / 100 * 5; // 5%\n\n uint256 public constant override BETA = 2;\n\n // --- Immutables ---\n\n IRToken public immutable override rToken;\n\n // --- Variables ---\n\n mapping(address position => IERC20 collateralToken) public override collateralTokenForPosition;\n\n mapping(address position => mapping(address delegate => bool isWhitelisted)) public override isDelegateWhitelisted;\n\n mapping(IERC20 collateralToken => CollateralTokenInfo collateralTokenInfo) public override collateralInfo;\n\n // --- Modifiers ---\n\n /// @dev Checks if the collateral token has been added to the position manager, or reverts otherwise.\n /// @param collateralToken The collateral token to check.\n modifier collateralTokenExists(IERC20 collateralToken) {\n if (address(collateralInfo[collateralToken].collateralToken) == address(0)) {\n revert CollateralTokenNotAdded();\n }\n _;\n }\n\n /// @dev Checks if the collateral token has enabled, or reverts otherwise. When the condition is false, the check\n /// is skipped.\n /// @param collateralToken The collateral token to check.\n /// @param condition If true, the check will be performed.\n modifier onlyEnabledCollateralTokenWhen(IERC20 collateralToken, bool condition) {\n if (condition && !collateralInfo[collateralToken].isEnabled) {\n revert CollateralTokenDisabled();\n }\n _;\n }\n\n /// @dev Checks if the borrower has a position with the collateral token or doesn't have a position at all, or\n /// reverts otherwise.\n /// @param position The borrower to check.\n /// @param collateralToken The collateral token to check.\n modifier onlyDepositedCollateralTokenOrNew(address position, IERC20 collateralToken) {\n if (\n collateralTokenForPosition[position] != IERC20(address(0))\n && collateralTokenForPosition[position] != collateralToken\n ) {\n revert PositionCollateralTokenMismatch();\n }\n _;\n }\n\n /// @dev Checks if the max fee percentage is between the borrowing spread and 100%, or reverts otherwise. When the\n /// condition is false, the check is skipped.\n /// @param maxFeePercentage The max fee percentage to check.\n /// @param condition If true, the check will be performed.\n modifier validMaxFeePercentageWhen(uint256 maxFeePercentage, bool condition) {\n if (condition && maxFeePercentage > MathUtils._100_PERCENT) {\n revert InvalidMaxFeePercentage();\n }\n _;\n }\n\n // --- Constructor ---\n\n /// @dev Initializes the position manager.\n constructor(address rToken_) FeeCollector(msg.sender) {\n rToken = rToken_ == address(0) ? new RToken(address(this), msg.sender) : IRToken(rToken_);\n emit PositionManagerDeployed(rToken, msg.sender);\n }\n\n // --- External functions ---\n\n function managePosition(\n IERC20 collateralToken,\n address position,\n uint256 collateralChange,\n bool isCollateralIncrease,\n uint256 debtChange,\n bool isDebtIncrease,\n uint256 maxFeePercentage,\n ERC20PermitSignature calldata permitSignature\n )\n public\n virtual\n override\n collateralTokenExists(collateralToken)\n validMaxFeePercentageWhen(maxFeePercentage, isDebtIncrease)\n onlyDepositedCollateralTokenOrNew(position, collateralToken)\n onlyEnabledCollateralTokenWhen(collateralToken, isDebtIncrease && debtChange > 0)\n returns (uint256 actualCollateralChange, uint256 actualDebtChange)\n {\n if (position != msg.sender && !isDelegateWhitelisted[position][msg.sender]) {\n revert DelegateNotWhitelisted();\n }\n if (collateralChange == 0 && debtChange == 0) {\n revert NoCollateralOrDebtChange();\n }\n if (address(permitSignature.token) == address(collateralToken)) {\n PermitHelper.applyPermit(permitSignature, msg.sender, address(this));\n }\n\n CollateralTokenInfo storage collateralTokenInfo = collateralInfo[collateralToken];\n IERC20Indexable raftCollateralToken = collateralTokenInfo.collateralToken;\n IERC20Indexable raftDebtToken = collateralTokenInfo.debtToken;\n\n uint256 debtBefore = raftDebtToken.balanceOf(position);\n if (!isDebtIncrease && (debtChange == type(uint256).max || (debtBefore != 0 && debtChange == debtBefore))) {\n if (collateralChange != 0 || isCollateralIncrease) {\n revert WrongCollateralParamsForFullRepayment();\n }\n collateralChange = raftCollateralToken.balanceOf(position);\n debtChange = debtBefore;\n }\n\n _adjustDebt(position, collateralToken, raftDebtToken, debtChange, isDebtIncrease, maxFeePercentage);\n _adjustCollateral(collateralToken, raftCollateralToken, position, collateralChange, isCollateralIncrease);\n\n uint256 positionDebt = raftDebtToken.balanceOf(position);\n uint256 positionCollateral = raftCollateralToken.balanceOf(position);\n\n if (positionDebt == 0) {\n if (positionCollateral != 0) {\n revert InvalidPosition();\n }\n // position was closed, remove it\n _closePosition(raftCollateralToken, raftDebtToken, position, false);\n } else {\n _checkValidPosition(collateralToken, positionDebt, positionCollateral);\n\n if (debtBefore == 0) {\n collateralTokenForPosition[position] = collateralToken;\n emit PositionCreated(position, collateralToken);\n }\n }\n return (collateralChange, debtChange);\n }\n\n function liquidate(address position) external override {\n IERC20 collateralToken = collateralTokenForPosition[position];\n CollateralTokenInfo storage collateralTokenInfo = collateralInfo[collateralToken];\n IERC20Indexable raftCollateralToken = collateralTokenInfo.collateralToken;\n IERC20Indexable raftDebtToken = collateralTokenInfo.debtToken;\n ISplitLiquidationCollateral splitLiquidation = collateralTokenInfo.splitLiquidation;\n\n if (address(collateralToken) == address(0)) {\n revert NothingToLiquidate();\n }\n (uint256 price,) = collateralTokenInfo.priceFeed.fetchPrice();\n uint256 entireCollateral = raftCollateralToken.balanceOf(position);\n uint256 entireDebt = raftDebtToken.balanceOf(position);\n uint256 icr = MathUtils._computeCR(entireCollateral, entireDebt, price);\n\n if (icr >= splitLiquidation.MCR()) {\n revert NothingToLiquidate();\n }\n\n uint256 totalDebt = raftDebtToken.totalSupply();\n if (entireDebt == totalDebt) {\n revert CannotLiquidateLastPosition();\n }\n bool isRedistribution = icr <= MathUtils._100_PERCENT;\n\n // prettier: ignore\n (uint256 collateralLiquidationFee, uint256 collateralToSendToLiquidator) =\n splitLiquidation.split(entireCollateral, entireDebt, price, isRedistribution);\n\n if (!isRedistribution) {\n _burnRTokens(msg.sender, entireDebt);\n totalDebt -= entireDebt;\n\n // Collateral is sent to protocol as a fee only in case of liquidation\n collateralToken.safeTransfer(feeRecipient, collateralLiquidationFee);\n }\n\n collateralToken.safeTransfer(msg.sender, collateralToSendToLiquidator);\n\n _closePosition(raftCollateralToken, raftDebtToken, position, true);\n\n _updateDebtAndCollateralIndex(collateralToken, raftCollateralToken, raftDebtToken, totalDebt);\n\n emit Liquidation(\n msg.sender,\n position,\n collateralToken,\n entireDebt,\n entireCollateral,\n collateralToSendToLiquidator,\n collateralLiquidationFee,\n isRedistribution\n );\n }\n\n function redeemCollateral(\n IERC20 collateralToken,\n uint256 debtAmount,\n uint256 maxFeePercentage\n )\n public\n virtual\n override\n {\n if (maxFeePercentage > MathUtils._100_PERCENT) {\n revert MaxFeePercentageOutOfRange();\n }\n if (debtAmount == 0) {\n revert AmountIsZero();\n }\n IERC20Indexable raftDebtToken = collateralInfo[collateralToken].debtToken;\n\n uint256 newTotalDebt = raftDebtToken.totalSupply() - debtAmount;\n uint256 lowTotalDebt = collateralInfo[collateralToken].splitLiquidation.LOW_TOTAL_DEBT();\n if (newTotalDebt < lowTotalDebt) {\n revert TotalDebtCannotBeLowerThanMinDebt(collateralToken, newTotalDebt);\n }\n\n (uint256 price, uint256 deviation) = collateralInfo[collateralToken].priceFeed.fetchPrice();\n uint256 collateralToRedeem = debtAmount.divDown(price);\n uint256 totalCollateral = collateralToken.balanceOf(address(this));\n if (\n totalCollateral - collateralToRedeem == 0\n || totalCollateral - collateralToRedeem < lowTotalDebt.divDown(price)\n ) {\n revert TotalCollateralCannotBeLowerThanMinCollateral(\n collateralToken, totalCollateral - collateralToRedeem, lowTotalDebt.divDown(price)\n );\n }\n\n // Decay the baseRate due to time passed, and then increase it according to the size of this redemption.\n // Use the saved total R supply value, from before it was reduced by the redemption.\n _updateBaseRateFromRedemption(collateralToken, collateralToRedeem, price, rToken.totalSupply());\n\n // Calculate the redemption fee\n uint256 redemptionFee = getRedemptionFee(collateralToken, collateralToRedeem, deviation);\n uint256 rebate = redemptionFee.mulDown(collateralInfo[collateralToken].redemptionRebate);\n\n _checkValidFee(redemptionFee, collateralToRedeem, maxFeePercentage);\n\n // Send the redemption fee to the recipient\n collateralToken.safeTransfer(feeRecipient, redemptionFee - rebate);\n\n // Burn the total R that is cancelled with debt, and send the redeemed collateral to msg.sender\n _burnRTokens(msg.sender, debtAmount);\n\n // Send collateral to account\n collateralToken.safeTransfer(msg.sender, collateralToRedeem - redemptionFee);\n\n _updateDebtAndCollateralIndex(\n collateralToken, collateralInfo[collateralToken].collateralToken, raftDebtToken, newTotalDebt\n );\n\n emit Redemption(msg.sender, debtAmount, collateralToRedeem, redemptionFee, rebate);\n }\n\n function whitelistDelegate(address delegate, bool whitelisted) external override {\n if (delegate == address(0)) {\n revert InvalidDelegateAddress();\n }\n isDelegateWhitelisted[msg.sender][delegate] = whitelisted;\n\n emit DelegateWhitelisted(msg.sender, delegate, whitelisted);\n }\n\n function setBorrowingSpread(IERC20 collateralToken, uint256 newBorrowingSpread) external override onlyOwner {\n if (newBorrowingSpread > MAX_BORROWING_SPREAD) {\n revert BorrowingSpreadExceedsMaximum();\n }\n collateralInfo[collateralToken].borrowingSpread = newBorrowingSpread;\n emit BorrowingSpreadUpdated(newBorrowingSpread);\n }\n\n function setRedemptionRebate(IERC20 collateralToken, uint256 newRedemptionRebate) public override onlyOwner {\n if (newRedemptionRebate > MathUtils._100_PERCENT) {\n revert RedemptionRebateExceedsMaximum();\n }\n collateralInfo[collateralToken].redemptionRebate = newRedemptionRebate;\n emit RedemptionRebateUpdated(newRedemptionRebate);\n }\n\n function getRedemptionFeeWithDecay(\n IERC20 collateralToken,\n uint256 collateralAmount\n )\n external\n view\n override\n returns (uint256 redemptionFee)\n {\n redemptionFee = getRedemptionRateWithDecay(collateralToken).mulDown(collateralAmount);\n if (redemptionFee >= collateralAmount) {\n revert FeeEatsUpAllReturnedCollateral();\n }\n }\n\n // --- Public functions ---\n\n function addCollateralToken(\n IERC20 collateralToken,\n IPriceFeed priceFeed,\n ISplitLiquidationCollateral newSplitLiquidationCollateral\n )\n public\n virtual\n override\n {\n addCollateralToken(\n collateralToken,\n priceFeed,\n newSplitLiquidationCollateral,\n new ERC20Indexable(\n address(this),\n string(bytes.concat(\"Raft \", bytes(IERC20Metadata(address(collateralToken)).name()), \" collateral\")),\n string(bytes.concat(\"r\", bytes(IERC20Metadata(address(collateralToken)).symbol()), \"-c\")),\n type(uint256).max\n ),\n new ERC20Indexable(\n address(this),\n string(bytes.concat(\"Raft \", bytes(IERC20Metadata(address(collateralToken)).name()), \" debt\")),\n string(bytes.concat(\"r\", bytes(IERC20Metadata(address(collateralToken)).symbol()), \"-d\")),\n type(uint256).max\n )\n );\n }\n\n function addCollateralToken(\n IERC20 collateralToken,\n IPriceFeed priceFeed,\n ISplitLiquidationCollateral newSplitLiquidationCollateral,\n IERC20Indexable raftCollateralToken_,\n IERC20Indexable raftDebtToken_\n )\n public\n override\n onlyOwner\n {\n if (address(collateralToken) == address(0)) {\n revert CollateralTokenAddressCannotBeZero();\n }\n if (address(priceFeed) == address(0)) {\n revert PriceFeedAddressCannotBeZero();\n }\n if (address(collateralInfo[collateralToken].collateralToken) != address(0)) {\n revert CollateralTokenAlreadyAdded();\n }\n\n CollateralTokenInfo memory raftCollateralTokenInfo;\n raftCollateralTokenInfo.collateralToken = raftCollateralToken_;\n raftCollateralTokenInfo.debtToken = raftDebtToken_;\n raftCollateralTokenInfo.isEnabled = true;\n raftCollateralTokenInfo.priceFeed = priceFeed;\n\n collateralInfo[collateralToken] = raftCollateralTokenInfo;\n\n setRedemptionSpread(collateralToken, MathUtils._100_PERCENT);\n setRedemptionRebate(collateralToken, MathUtils._100_PERCENT);\n\n setSplitLiquidationCollateral(collateralToken, newSplitLiquidationCollateral);\n\n emit CollateralTokenAdded(\n collateralToken, raftCollateralTokenInfo.collateralToken, raftCollateralTokenInfo.debtToken, priceFeed\n );\n }\n\n function setCollateralEnabled(\n IERC20 collateralToken,\n bool isEnabled\n )\n public\n override\n onlyOwner\n collateralTokenExists(collateralToken)\n {\n bool previousIsEnabled = collateralInfo[collateralToken].isEnabled;\n collateralInfo[collateralToken].isEnabled = isEnabled;\n\n if (previousIsEnabled != isEnabled) {\n emit CollateralTokenModified(collateralToken, isEnabled);\n }\n }\n\n function setSplitLiquidationCollateral(\n IERC20 collateralToken,\n ISplitLiquidationCollateral newSplitLiquidationCollateral\n )\n public\n override\n onlyOwner\n {\n if (address(newSplitLiquidationCollateral) == address(0)) {\n revert SplitLiquidationCollateralCannotBeZero();\n }\n collateralInfo[collateralToken].splitLiquidation = newSplitLiquidationCollateral;\n emit SplitLiquidationCollateralChanged(collateralToken, newSplitLiquidationCollateral);\n }\n\n function setRedemptionSpread(IERC20 collateralToken, uint256 newRedemptionSpread) public override onlyOwner {\n if (newRedemptionSpread > MathUtils._100_PERCENT) {\n revert RedemptionSpreadOutOfRange();\n }\n collateralInfo[collateralToken].redemptionSpread = newRedemptionSpread;\n emit RedemptionSpreadUpdated(collateralToken, newRedemptionSpread);\n }\n\n function getRedemptionRateWithDecay(IERC20 collateralToken) public view override returns (uint256) {\n return _calcRedemptionRate(collateralToken, _calcDecayedBaseRate(collateralToken));\n }\n\n function raftCollateralToken(IERC20 collateralToken) external view override returns (IERC20Indexable) {\n return collateralInfo[collateralToken].collateralToken;\n }\n\n function raftDebtToken(IERC20 collateralToken) external view override returns (IERC20Indexable) {\n return collateralInfo[collateralToken].debtToken;\n }\n\n function priceFeed(IERC20 collateralToken) external view override returns (IPriceFeed) {\n return collateralInfo[collateralToken].priceFeed;\n }\n\n function splitLiquidationCollateral(IERC20 collateralToken) external view returns (ISplitLiquidationCollateral) {\n return collateralInfo[collateralToken].splitLiquidation;\n }\n\n function collateralEnabled(IERC20 collateralToken) external view override returns (bool) {\n return collateralInfo[collateralToken].isEnabled;\n }\n\n function lastFeeOperationTime(IERC20 collateralToken) external view override returns (uint256) {\n return collateralInfo[collateralToken].lastFeeOperationTime;\n }\n\n function borrowingSpread(IERC20 collateralToken) external view override returns (uint256) {\n return collateralInfo[collateralToken].borrowingSpread;\n }\n\n function baseRate(IERC20 collateralToken) external view override returns (uint256) {\n return collateralInfo[collateralToken].baseRate;\n }\n\n function redemptionSpread(IERC20 collateralToken) external view override returns (uint256) {\n return collateralInfo[collateralToken].redemptionSpread;\n }\n\n function redemptionRebate(IERC20 collateralToken) external view override returns (uint256) {\n return collateralInfo[collateralToken].redemptionRebate;\n }\n\n function getRedemptionRate(IERC20 collateralToken) public view override returns (uint256) {\n return _calcRedemptionRate(collateralToken, collateralInfo[collateralToken].baseRate);\n }\n\n function getRedemptionFee(\n IERC20 collateralToken,\n uint256 collateralAmount,\n uint256 priceDeviation\n )\n public\n view\n override\n returns (uint256)\n {\n return Math.min(getRedemptionRate(collateralToken) + priceDeviation, MathUtils._100_PERCENT).mulDown(\n collateralAmount\n );\n }\n\n function getBorrowingRate(IERC20 collateralToken) public view override returns (uint256) {\n return _calcBorrowingRate(collateralToken, collateralInfo[collateralToken].baseRate);\n }\n\n function getBorrowingRateWithDecay(IERC20 collateralToken) public view override returns (uint256) {\n return _calcBorrowingRate(collateralToken, _calcDecayedBaseRate(collateralToken));\n }\n\n function getBorrowingFee(IERC20 collateralToken, uint256 debtAmount) public view override returns (uint256) {\n return getBorrowingRate(collateralToken).mulDown(debtAmount);\n }\n\n // --- Helper functions ---\n\n /// @dev Adjusts the debt of a given borrower by burning or minting the corresponding amount of R and the Raft\n /// debt token. If the debt is being increased, the borrowing fee is also triggered.\n /// @param position The address of the borrower.\n /// @param debtChange The amount of R to add or remove. Must be positive.\n /// @param isDebtIncrease True if the debt is being increased, false otherwise.\n /// @param maxFeePercentage The maximum fee percentage.\n function _adjustDebt(\n address position,\n IERC20 collateralToken,\n IERC20Indexable raftDebtToken,\n uint256 debtChange,\n bool isDebtIncrease,\n uint256 maxFeePercentage\n )\n internal\n {\n if (debtChange == 0) {\n return;\n }\n\n if (isDebtIncrease) {\n uint256 totalDebtChange =\n debtChange + _triggerBorrowingFee(collateralToken, position, debtChange, maxFeePercentage);\n raftDebtToken.mint(position, totalDebtChange);\n _mintRTokens(msg.sender, debtChange);\n } else {\n raftDebtToken.burn(position, debtChange);\n _burnRTokens(msg.sender, debtChange);\n }\n\n emit DebtChanged(position, collateralToken, debtChange, isDebtIncrease);\n }\n\n /// @dev Mints R tokens\n function _mintRTokens(address to, uint256 amount) internal virtual {\n rToken.mint(to, amount);\n }\n\n /// @dev Burns R tokens\n function _burnRTokens(address from, uint256 amount) internal virtual {\n rToken.burn(from, amount);\n }\n\n /// @dev Adjusts the collateral of a given borrower by burning or minting the corresponding amount of Raft\n /// collateral token and transferring the corresponding amount of collateral token.\n /// @param collateralToken The token the borrower used as collateral.\n /// @param position The address of the borrower.\n /// @param collateralChange The amount of collateral to add or remove. Must be positive.\n /// @param isCollateralIncrease True if the collateral is being increased, false otherwise.\n function _adjustCollateral(\n IERC20 collateralToken,\n IERC20Indexable raftCollateralToken,\n address position,\n uint256 collateralChange,\n bool isCollateralIncrease\n )\n internal\n {\n if (collateralChange == 0) {\n return;\n }\n\n if (isCollateralIncrease) {\n raftCollateralToken.mint(position, collateralChange);\n collateralToken.safeTransferFrom(msg.sender, address(this), collateralChange);\n } else {\n raftCollateralToken.burn(position, collateralChange);\n collateralToken.safeTransfer(msg.sender, collateralChange);\n }\n\n emit CollateralChanged(position, collateralToken, collateralChange, isCollateralIncrease);\n }\n\n /// @dev Updates debt and collateral indexes for a given collateral token.\n /// @param collateralToken The collateral token for which to update the indexes.\n /// @param raftCollateralToken The raft collateral indexable token.\n /// @param raftDebtToken The raft debt indexable token.\n /// @param totalDebtForCollateral Totam amount of debt backed by collateral token.\n function _updateDebtAndCollateralIndex(\n IERC20 collateralToken,\n IERC20Indexable raftCollateralToken,\n IERC20Indexable raftDebtToken,\n uint256 totalDebtForCollateral\n )\n internal\n {\n raftDebtToken.setIndex(totalDebtForCollateral);\n raftCollateralToken.setIndex(collateralToken.balanceOf(address(this)));\n }\n\n function _closePosition(\n IERC20Indexable raftCollateralToken,\n IERC20Indexable raftDebtToken,\n address position,\n bool burnTokens\n )\n internal\n {\n collateralTokenForPosition[position] = IERC20(address(0));\n\n if (burnTokens) {\n raftDebtToken.burn(position, type(uint256).max);\n raftCollateralToken.burn(position, type(uint256).max);\n }\n emit PositionClosed(position);\n }\n\n // --- Borrowing & redemption fee helper functions ---\n\n /// @dev Updates the base rate from a redemption operation. Impacts on the base rate:\n /// 1. decays the base rate based on time passed since last redemption or R borrowing operation,\n /// 2. increases the base rate based on the amount redeemed, as a proportion of total supply.\n function _updateBaseRateFromRedemption(\n IERC20 collateralToken,\n uint256 collateralDrawn,\n uint256 price,\n uint256 totalDebtSupply\n )\n internal\n returns (uint256)\n {\n uint256 decayedBaseRate = _calcDecayedBaseRate(collateralToken);\n\n /* Convert the drawn collateral back to R at face value rate (1 R:1 USD), in order to get\n * the fraction of total supply that was redeemed at face value. */\n uint256 redeemedFraction = collateralDrawn * price / totalDebtSupply;\n\n uint256 newBaseRate = decayedBaseRate + redeemedFraction / BETA;\n newBaseRate = Math.min(newBaseRate, MathUtils._100_PERCENT); // cap baseRate at a maximum of 100%\n assert(newBaseRate > 0); // Base rate is always non-zero after redemption\n\n // Update the baseRate state variable\n collateralInfo[collateralToken].baseRate = newBaseRate;\n emit BaseRateUpdated(collateralToken, newBaseRate);\n\n _updateLastFeeOpTime(collateralToken);\n\n return newBaseRate;\n }\n\n function _calcRedemptionRate(IERC20 collateralToken, uint256 baseRate_) internal view returns (uint256) {\n return baseRate_ + collateralInfo[collateralToken].redemptionSpread;\n }\n\n function _calcBorrowingRate(IERC20 collateralToken, uint256 baseRate_) internal view returns (uint256) {\n return Math.min(collateralInfo[collateralToken].borrowingSpread + baseRate_, MAX_BORROWING_RATE);\n }\n\n /// @dev Updates the base rate based on time elapsed since the last redemption or R borrowing operation.\n function _decayBaseRateFromBorrowing(IERC20 collateralToken) internal {\n uint256 decayedBaseRate = _calcDecayedBaseRate(collateralToken);\n assert(decayedBaseRate <= MathUtils._100_PERCENT); // The baseRate can decay to 0\n\n collateralInfo[collateralToken].baseRate = decayedBaseRate;\n emit BaseRateUpdated(collateralToken, decayedBaseRate);\n\n _updateLastFeeOpTime(collateralToken);\n }\n\n /// @dev Update the last fee operation time only if time passed >= decay interval. This prevents base rate\n /// griefing.\n function _updateLastFeeOpTime(IERC20 collateralToken) internal {\n uint256 timePassed = block.timestamp - collateralInfo[collateralToken].lastFeeOperationTime;\n\n if (timePassed >= 1 minutes) {\n collateralInfo[collateralToken].lastFeeOperationTime = block.timestamp;\n emit LastFeeOpTimeUpdated(collateralToken, block.timestamp);\n }\n }\n\n function _calcDecayedBaseRate(IERC20 collateralToken) internal view returns (uint256) {\n uint256 minutesPassed = (block.timestamp - collateralInfo[collateralToken].lastFeeOperationTime) / 1 minutes;\n uint256 decayFactor = MathUtils._decPow(MINUTE_DECAY_FACTOR, minutesPassed);\n\n return collateralInfo[collateralToken].baseRate.mulDown(decayFactor);\n }\n\n function _triggerBorrowingFee(\n IERC20 collateralToken,\n address position,\n uint256 debtAmount,\n uint256 maxFeePercentage\n )\n internal\n virtual\n returns (uint256 borrowingFee)\n {\n _decayBaseRateFromBorrowing(collateralToken); // decay the baseRate state variable\n borrowingFee = getBorrowingFee(collateralToken, debtAmount);\n\n _checkValidFee(borrowingFee, debtAmount, maxFeePercentage);\n\n if (borrowingFee > 0) {\n _mintRTokens(feeRecipient, borrowingFee);\n emit RBorrowingFeePaid(collateralToken, position, borrowingFee);\n }\n }\n\n // --- Validation check helper functions ---\n\n function _checkValidPosition(IERC20 collateralToken, uint256 positionDebt, uint256 positionCollateral) internal {\n ISplitLiquidationCollateral splitCollateral = collateralInfo[collateralToken].splitLiquidation;\n if (positionDebt < splitCollateral.LOW_TOTAL_DEBT()) {\n revert NetDebtBelowMinimum(positionDebt);\n }\n\n (uint256 price,) = collateralInfo[collateralToken].priceFeed.fetchPrice();\n uint256 newICR = MathUtils._computeCR(positionCollateral, positionDebt, price);\n if (newICR < splitCollateral.MCR()) {\n revert NewICRLowerThanMCR(newICR);\n }\n }\n\n function _checkValidFee(uint256 fee, uint256 amount, uint256 maxFeePercentage) internal pure {\n uint256 feePercentage = fee.divDown(amount);\n\n if (feePercentage > maxFeePercentage) {\n revert FeeExceedsMaxFee(fee, amount, maxFeePercentage);\n }\n }\n}\n\ninterface IRMinter {\n /// @dev Emitted when tokens are recovered from the contract.\n /// @param token The address of the token being recovered.\n /// @param to The address receiving the recovered tokens.\n /// @param amount The amount of tokens recovered.\n event TokensRecovered(IERC20 token, address to, uint256 amount);\n\n /// @return Address of the R token.\n function r() external view returns (IRToken);\n\n /// @return Address of the Position manager contract responsible for minting R.\n function positionManager() external view returns (IPositionManager);\n\n /// @dev Recover accidentally sent tokens to the contract\n /// @param token Address of the token contract.\n /// @param to Address of the receiver of the tokens.\n /// @param amount Number of tokens to recover.\n function recoverTokens(IERC20 token, address to, uint256 amount) external;\n}\n\ninterface ILock {\n /// @dev Thrown when contract usage is locked.\n error ContractLocked();\n\n /// @dev Unauthorized call to lock/unlock.\n error Unauthorized();\n\n /// @dev Retrieves if contract is currently locked or not.\n function locked() external view returns (bool);\n\n /// @dev Retrieves address of the locker who can unlock contract.\n function locker() external view returns (address);\n\n /// @dev Unlcoks the usage of the contract.\n function unlock() external;\n\n /// @dev Locks the usage of the contract.\n function lock() external;\n}\n\nabstract contract ERC20RMinter is IRMinter, ERC20, Ownable2Step {\n using SafeERC20 for IERC20;\n\n IRToken public immutable override r;\n IPositionManager public immutable override positionManager;\n\n constructor(IRToken rToken_, string memory name_, string memory symbol_) ERC20(name_, symbol_) {\n r = rToken_;\n positionManager = IPositionManager(rToken_.positionManager());\n\n _approve(address(this), address(positionManager), type(uint256).max);\n }\n\n modifier unlockCall() {\n ILock lockContract = ILock(address(positionManager.priceFeed(IERC20(this))));\n lockContract.unlock();\n _;\n lockContract.lock();\n }\n\n function recoverTokens(IERC20 token, address to, uint256 amount) external override onlyOwner {\n token.safeTransfer(to, amount);\n emit TokensRecovered(token, to, amount);\n }\n\n function _mintR(address to, uint256 amount) internal unlockCall {\n _mint(address(this), amount);\n ERC20PermitSignature memory emptySignature;\n positionManager.managePosition(\n IERC20(address(this)),\n address(this),\n amount,\n true, // collateral increase\n amount,\n true, // debt increase\n 1e18, // 100%\n emptySignature\n );\n r.transfer(to, amount);\n }\n\n function _burnR(address from, uint256 amount) internal unlockCall {\n r.transferFrom(from, address(this), amount);\n ERC20PermitSignature memory emptySignature;\n positionManager.managePosition(\n IERC20(address(this)),\n address(this),\n amount,\n false, // collateral decrease\n amount,\n false, // debt decrease\n 1e18, // 100%\n emptySignature\n );\n _burn(address(this), amount);\n }\n}\n\ncontract InterestRateDebtToken is ERC20Indexable {\n // --- Types ---\n\n using Fixed256x18 for uint256;\n\n // --- Events ---\n\n event IndexIncreasePerSecondSet(uint256 indexIncreasePerSecond);\n\n // --- Immutables ---\n\n IERC20 immutable collateralToken;\n\n // --- Variables ---\n\n uint256 internal storedIndexUpdatedAt;\n\n uint256 public indexIncreasePerSecond;\n\n // --- Constructor ---\n\n constructor(\n address positionManager_,\n string memory name_,\n string memory symbol_,\n IERC20 collateralToken_,\n uint256 cap_,\n uint256 indexIncreasePerSecond_\n )\n ERC20Indexable(positionManager_, name_, symbol_, cap_)\n {\n storedIndexUpdatedAt = block.timestamp;\n collateralToken = collateralToken_;\n setIndexIncreasePerSecond(indexIncreasePerSecond_);\n }\n\n // --- Functions ---\n\n function mint(address to, uint256 amount) public virtual override {\n updateIndexAndPayFees();\n super.mint(to, amount);\n }\n\n function burn(address from, uint256 amount) public virtual override {\n updateIndexAndPayFees();\n super.burn(from, amount);\n }\n\n function currentIndex() public view virtual override returns (uint256) {\n return storedIndex.mulUp(INDEX_PRECISION + indexIncreasePerSecond * (block.timestamp - storedIndexUpdatedAt));\n }\n\n function updateIndexAndPayFees() public {\n uint256 currentIndex_ = currentIndex();\n _payFees(currentIndex_);\n storedIndexUpdatedAt = block.timestamp;\n storedIndex = currentIndex_;\n emit IndexUpdated(currentIndex_);\n }\n\n function setIndexIncreasePerSecond(uint256 indexIncreasePerSecond_) public onlyOwner {\n updateIndexAndPayFees();\n indexIncreasePerSecond = indexIncreasePerSecond_;\n emit IndexIncreasePerSecondSet(indexIncreasePerSecond_);\n }\n\n function unpaidFees() external view returns (uint256) {\n return _unpaidFees(currentIndex());\n }\n\n function _unpaidFees(uint256 currentIndex_) private view returns (uint256) {\n return totalSupply().mulDown(currentIndex_ - storedIndex);\n }\n\n function _payFees(uint256 currentIndex_) private {\n uint256 unpaidFees = _unpaidFees(currentIndex_);\n if (unpaidFees > 0) {\n IInterestRatePositionManager(positionManager).mintFees(collateralToken, unpaidFees);\n }\n }\n}\n\n/// @dev Implementation of Position Manager. Current implementation does not support rebasing tokens as collateral.\ncontract InterestRatePositionManager is ERC20RMinter, PositionManager, IInterestRatePositionManager {\n // --- Errors ---\n\n error Unsupported();\n\n // --- Constructor ---\n\n /// @dev Initializes the position manager.\n constructor(IRToken rToken_)\n PositionManager(address(rToken_))\n ERC20RMinter(rToken_, \"Interest Rate Posman\", \"IRPM\")\n { }\n\n // --- External functions ---\n\n function managePosition(\n IERC20 collateralToken,\n address position,\n uint256 collateralChange,\n bool isCollateralIncrease,\n uint256 debtChange,\n bool isDebtIncrease,\n uint256 maxFeePercentage,\n ERC20PermitSignature calldata permitSignature\n )\n public\n virtual\n override(IPositionManager, PositionManager)\n returns (uint256 actualCollateralChange, uint256 actualDebtChange)\n {\n if (address(permitSignature.token) == address(r)) {\n PermitHelper.applyPermit(permitSignature, msg.sender, address(this));\n }\n return super.managePosition(\n collateralToken,\n position,\n collateralChange,\n isCollateralIncrease,\n debtChange,\n isDebtIncrease,\n maxFeePercentage,\n permitSignature\n );\n }\n\n function mintFees(IERC20 collateralToken, uint256 amount) external {\n if (msg.sender != address(collateralInfo[collateralToken].debtToken)) {\n revert InvalidDebtToken(msg.sender);\n }\n _mintR(feeRecipient, amount);\n\n emit MintedFees(collateralToken, amount);\n }\n\n function redeemCollateral(IERC20, uint256, uint256) public virtual override(IPositionManager, PositionManager) {\n revert Unsupported();\n }\n\n function addCollateralToken(\n IERC20,\n IPriceFeed,\n ISplitLiquidationCollateral\n )\n public\n override(IPositionManager, PositionManager)\n {\n revert Unsupported();\n }\n\n // --- Helper functions ---\n\n function _mintRTokens(address to, uint256 amount) internal virtual override {\n _mintR(to, amount);\n }\n\n function _burnRTokens(address from, uint256 amount) internal virtual override {\n _burnR(from, amount);\n }\n\n function _triggerBorrowingFee(\n IERC20,\n address,\n uint256,\n uint256\n )\n internal\n pure\n virtual\n override\n returns (uint256)\n {\n return 0;\n }\n}\n"}},"settings":{"remappings":["@balancer-labs/=node_modules/@balancer-labs/","@balancer-labs/v2-interfaces/contracts/=lib/balancer-v2-monorepo/pkg/interfaces/contracts/","@chainlink/=node_modules/@chainlink/","@eth-optimism/=node_modules/@eth-optimism/","@openzeppelin/=node_modules/@openzeppelin/","@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/","@redstone-finance/=node_modules/@redstone-finance/","@smartcontractkit/chainlink/=lib/chainlink/contracts/src/v0.8/","@tempusfinance/=node_modules/@tempusfinance/","@tempusfinance/tempus-utils/contracts/=lib/tempus-utils/contracts/","balancer-v2-monorepo/=lib/balancer-v2-monorepo/","chainlink/=lib/chainlink/","ds-test/=lib/forge-std/lib/ds-test/src/","erc4626-tests/=lib/chainlink/contracts/foundry-lib/openzeppelin-contracts/lib/erc4626-tests/","eth-gas-reporter/=node_modules/eth-gas-reporter/","forge-std/=lib/forge-std/src/","hardhat/=node_modules/hardhat/","openzeppelin-contracts/=lib/openzeppelin-contracts/","tempus-utils/=lib/tempus-utils/contracts/"],"optimizer":{"enabled":true,"runs":200000},"metadata":{"bytecodeHash":"ipfs","appendCBOR":true},"outputSelection":{"*":{"*":["evm.bytecode","evm.deployedBytecode","devdoc","userdoc","metadata","abi"]}},"evmVersion":"london","viaIR":true,"libraries":{}}},"ABI":"[{\"inputs\":[{\"internalType\":\"contract IRToken\",\"name\":\"rToken_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AmountIsZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BorrowingSpreadExceedsMaximum\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotLiquidateLastPosition\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CollateralTokenAddressCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CollateralTokenAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CollateralTokenDisabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CollateralTokenNotAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DelegateNotWhitelisted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FeeEatsUpAllReturnedCollateral\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePercentage\",\"type\":\"uint256\"}],\"name\":\"FeeExceedsMaxFee\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"InvalidDebtToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDelegateAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidFeeRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMaxFeePercentage\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPosition\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxFeePercentageOutOfRange\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"netDebt\",\"type\":\"uint256\"}],\"name\":\"NetDebtBelowMinimum\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newICR\",\"type\":\"uint256\"}],\"name\":\"NewICRLowerThanMCR\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoCollateralOrDebtChange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NothingToLiquidate\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PositionCollateralTokenMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PriceFeedAddressCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RedemptionRebateExceedsMaximum\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RedemptionSpreadOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SplitLiquidationCollateralCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"newTotalCollateral\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minimumCollateral\",\"type\":\"uint256\"}],\"name\":\"TotalCollateralCannotBeLowerThanMinCollateral\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"newTotalDebt\",\"type\":\"uint256\"}],\"name\":\"TotalDebtCannotBeLowerThanMinDebt\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unsupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongCollateralParamsForFullRepayment\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"baseRate\",\"type\":\"uint256\"}],\"name\":\"BaseRateUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"borrowingSpread\",\"type\":\"uint256\"}],\"name\":\"BorrowingSpreadUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"position\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"collateralAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isCollateralIncrease\",\"type\":\"bool\"}],\"name\":\"CollateralChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contract IERC20Indexable\",\"name\":\"raftCollateralToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contract IERC20Indexable\",\"name\":\"raftDebtToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contract IPriceFeed\",\"name\":\"priceFeed\",\"type\":\"address\"}],\"name\":\"CollateralTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"name\":\"CollateralTokenModified\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"position\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"debtAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isDebtIncrease\",\"type\":\"bool\"}],\"name\":\"DebtChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"position\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"delegate\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"whitelisted\",\"type\":\"bool\"}],\"name\":\"DelegateWhitelisted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeRecipient\",\"type\":\"address\"}],\"name\":\"FeeRecipientChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"lastFeeOpTime\",\"type\":\"uint256\"}],\"name\":\"LastFeeOpTimeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"liquidator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"position\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"debtLiquidated\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"collateralLiquidated\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"collateralSentToLiquidator\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"collateralLiquidationFeePaid\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isRedistribution\",\"type\":\"bool\"}],\"name\":\"Liquidation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"MintedFees\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferStarted\",\"type\":\"event\"},{\"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\":\"position\",\"type\":\"address\"}],\"name\":\"PositionClosed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"position\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"PositionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IRToken\",\"name\":\"rToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeRecipient\",\"type\":\"address\"}],\"name\":\"PositionManagerDeployed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"position\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeAmount\",\"type\":\"uint256\"}],\"name\":\"RBorrowingFeePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"redeemer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"collateralSent\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"rebate\",\"type\":\"uint256\"}],\"name\":\"Redemption\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"redemptionRebate\",\"type\":\"uint256\"}],\"name\":\"RedemptionRebateUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"redemptionSpread\",\"type\":\"uint256\"}],\"name\":\"RedemptionSpreadUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"contract ISplitLiquidationCollateral\",\"name\":\"newSplitLiquidationCollateral\",\"type\":\"address\"}],\"name\":\"SplitLiquidationCollateralChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IERC20\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensRecovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BETA\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_BORROWING_RATE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_BORROWING_SPREAD\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MINUTE_DECAY_FACTOR\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"contract IPriceFeed\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"contract ISplitLiquidationCollateral\",\"name\":\"newSplitLiquidationCollateral\",\"type\":\"address\"},{\"internalType\":\"contract IERC20Indexable\",\"name\":\"raftCollateralToken_\",\"type\":\"address\"},{\"internalType\":\"contract IERC20Indexable\",\"name\":\"raftDebtToken_\",\"type\":\"address\"}],\"name\":\"addCollateralToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"contract IPriceFeed\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"contract ISplitLiquidationCollateral\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"addCollateralToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"baseRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"borrowingSpread\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"collateralEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"collateralInfo\",\"outputs\":[{\"internalType\":\"contract IERC20Indexable\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"contract IERC20Indexable\",\"name\":\"debtToken\",\"type\":\"address\"},{\"internalType\":\"contract IPriceFeed\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"contract ISplitLiquidationCollateral\",\"name\":\"splitLiquidation\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"lastFeeOperationTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"borrowingSpread\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseRate\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"redemptionSpread\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"redemptionRebate\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"position\",\"type\":\"address\"}],\"name\":\"collateralTokenForPosition\",\"outputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feeRecipient\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"debtAmount\",\"type\":\"uint256\"}],\"name\":\"getBorrowingFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"getBorrowingRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"getBorrowingRateWithDecay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"collateralAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"priceDeviation\",\"type\":\"uint256\"}],\"name\":\"getRedemptionFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"collateralAmount\",\"type\":\"uint256\"}],\"name\":\"getRedemptionFeeWithDecay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"redemptionFee\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"getRedemptionRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"getRedemptionRateWithDecay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"position\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"delegate\",\"type\":\"address\"}],\"name\":\"isDelegateWhitelisted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isWhitelisted\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"lastFeeOperationTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"position\",\"type\":\"address\"}],\"name\":\"liquidate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"position\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"collateralChange\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isCollateralIncrease\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"debtChange\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isDebtIncrease\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePercentage\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"contract IERC20Permit\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"struct ERC20PermitSignature\",\"name\":\"permitSignature\",\"type\":\"tuple\"}],\"name\":\"managePosition\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"actualCollateralChange\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualDebtChange\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mintFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"positionManager\",\"outputs\":[{\"internalType\":\"contract IPositionManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"priceFeed\",\"outputs\":[{\"internalType\":\"contract IPriceFeed\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"r\",\"outputs\":[{\"internalType\":\"contract IRToken\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rToken\",\"outputs\":[{\"internalType\":\"contract IRToken\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"raftCollateralToken\",\"outputs\":[{\"internalType\":\"contract IERC20Indexable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"raftDebtToken\",\"outputs\":[{\"internalType\":\"contract IERC20Indexable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"recoverTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"redeemCollateral\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"redemptionRebate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"redemptionSpread\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"newBorrowingSpread\",\"type\":\"uint256\"}],\"name\":\"setBorrowingSpread\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"name\":\"setCollateralEnabled\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newFeeRecipient\",\"type\":\"address\"}],\"name\":\"setFeeRecipient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"newRedemptionRebate\",\"type\":\"uint256\"}],\"name\":\"setRedemptionRebate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"newRedemptionSpread\",\"type\":\"uint256\"}],\"name\":\"setRedemptionSpread\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"},{\"internalType\":\"contract ISplitLiquidationCollateral\",\"name\":\"newSplitLiquidationCollateral\",\"type\":\"address\"}],\"name\":\"setSplitLiquidationCollateral\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"collateralToken\",\"type\":\"address\"}],\"name\":\"splitLiquidationCollateral\",\"outputs\":[{\"internalType\":\"contract ISplitLiquidationCollateral\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"delegate\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"whitelisted\",\"type\":\"bool\"}],\"name\":\"whitelistDelegate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]","ContractName":"InterestRatePositionManager","CompilerVersion":"v0.8.19+commit.7dd6d404","OptimizationUsed":1,"Runs":200000,"ConstructorArguments":"0x000000000000000000000000183015a9ba6ff60230fdeadc3f43b3d788b13e21","EVMVersion":"london","Library":"","LicenseType":"","Proxy":0,"SwarmSource":""}] \ No newline at end of file diff --git a/testdata/etherscan/0xDb53f47aC61FE54F456A4eb3E09832D08Dd7BEec/creation_data.json b/testdata/etherscan/0xDb53f47aC61FE54F456A4eb3E09832D08Dd7BEec/creation_data.json index 6a1311bb4258..646ea065a473 100644 --- a/testdata/etherscan/0xDb53f47aC61FE54F456A4eb3E09832D08Dd7BEec/creation_data.json +++ b/testdata/etherscan/0xDb53f47aC61FE54F456A4eb3E09832D08Dd7BEec/creation_data.json @@ -1,5 +1 @@ -{ - "contractAddress": "0xdb53f47ac61fe54f456a4eb3e09832d08dd7beec", - "contractCreator": "0xc7f8d87734ab2cbf70030ac8aa82abfe3e8126cb", - "txHash": "0x196898c69f6b1944f1011120b15c0903329d46259c8cdc0fbcad71da1fe58245" -} \ No newline at end of file +{"contractAddress":"0xdb53f47ac61fe54f456a4eb3e09832d08dd7beec","contractCreator":"0xc7f8d87734ab2cbf70030ac8aa82abfe3e8126cb","txHash":"0x196898c69f6b1944f1011120b15c0903329d46259c8cdc0fbcad71da1fe58245"} \ No newline at end of file diff --git a/testdata/etherscan/0xDb53f47aC61FE54F456A4eb3E09832D08Dd7BEec/metadata.json b/testdata/etherscan/0xDb53f47aC61FE54F456A4eb3E09832D08Dd7BEec/metadata.json index 83c1a063596f..df45d9be39c9 100644 --- a/testdata/etherscan/0xDb53f47aC61FE54F456A4eb3E09832D08Dd7BEec/metadata.json +++ b/testdata/etherscan/0xDb53f47aC61FE54F456A4eb3E09832D08Dd7BEec/metadata.json @@ -1,148 +1 @@ -[ - { - "SourceCode": { - "language": "Solidity", - "sources": { - "@solidstate/contracts/token/ERC1155/base/ERC1155Base.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IERC1155 } from '../IERC1155.sol';\nimport { IERC1155Receiver } from '../IERC1155Receiver.sol';\nimport { ERC1155BaseInternal, ERC1155BaseStorage } from './ERC1155BaseInternal.sol';\n\n/**\n * @title Base ERC1155 contract\n * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts/ (MIT license)\n */\nabstract contract ERC1155Base is IERC1155, ERC1155BaseInternal {\n /**\n * @inheritdoc IERC1155\n */\n function balanceOf(address account, uint256 id)\n public\n view\n virtual\n override\n returns (uint256)\n {\n return _balanceOf(account, id);\n }\n\n /**\n * @inheritdoc IERC1155\n */\n function balanceOfBatch(address[] memory accounts, uint256[] memory ids)\n public\n view\n virtual\n override\n returns (uint256[] memory)\n {\n require(\n accounts.length == ids.length,\n 'ERC1155: accounts and ids length mismatch'\n );\n\n mapping(uint256 => mapping(address => uint256))\n storage balances = ERC1155BaseStorage.layout().balances;\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n unchecked {\n for (uint256 i; i < accounts.length; i++) {\n require(\n accounts[i] != address(0),\n 'ERC1155: batch balance query for the zero address'\n );\n batchBalances[i] = balances[ids[i]][accounts[i]];\n }\n }\n\n return batchBalances;\n }\n\n /**\n * @inheritdoc IERC1155\n */\n function isApprovedForAll(address account, address operator)\n public\n view\n virtual\n override\n returns (bool)\n {\n return ERC1155BaseStorage.layout().operatorApprovals[account][operator];\n }\n\n /**\n * @inheritdoc IERC1155\n */\n function setApprovalForAll(address operator, bool status)\n public\n virtual\n override\n {\n require(\n msg.sender != operator,\n 'ERC1155: setting approval status for self'\n );\n ERC1155BaseStorage.layout().operatorApprovals[msg.sender][\n operator\n ] = status;\n emit ApprovalForAll(msg.sender, operator, status);\n }\n\n /**\n * @inheritdoc IERC1155\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == msg.sender || isApprovedForAll(from, msg.sender),\n 'ERC1155: caller is not owner nor approved'\n );\n _safeTransfer(msg.sender, from, to, id, amount, data);\n }\n\n /**\n * @inheritdoc IERC1155\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == msg.sender || isApprovedForAll(from, msg.sender),\n 'ERC1155: caller is not owner nor approved'\n );\n _safeTransferBatch(msg.sender, from, to, ids, amounts, data);\n }\n}\n" - }, - "@solidstate/contracts/introspection/IERC165.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC165 interface registration interface\n * @dev see https://eips.ethereum.org/EIPS/eip-165\n */\ninterface IERC165 {\n /**\n * @notice query whether contract has registered support for given interface\n * @param interfaceId interface id\n * @return bool whether interface is supported\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" - }, - "abdk-libraries-solidity/ABDKMath64x64.sol": { - "content": "// SPDX-License-Identifier: BSD-4-Clause\n/*\n * ABDK Math 64.64 Smart Contract Library. Copyright © 2019 by ABDK Consulting.\n * Author: Mikhail Vladimirov \n */\npragma solidity ^0.8.0;\n\n/**\n * Smart contract library of mathematical functions operating with signed\n * 64.64-bit fixed point numbers. Signed 64.64-bit fixed point number is\n * basically a simple fraction whose numerator is signed 128-bit integer and\n * denominator is 2^64. As long as denominator is always the same, there is no\n * need to store it, thus in Solidity signed 64.64-bit fixed point numbers are\n * represented by int128 type holding only the numerator.\n */\nlibrary ABDKMath64x64 {\n /*\n * Minimum value signed 64.64-bit fixed point number may have. \n */\n int128 private constant MIN_64x64 = -0x80000000000000000000000000000000;\n\n /*\n * Maximum value signed 64.64-bit fixed point number may have. \n */\n int128 private constant MAX_64x64 = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n\n /**\n * Convert signed 256-bit integer number into signed 64.64-bit fixed point\n * number. Revert on overflow.\n *\n * @param x signed 256-bit integer number\n * @return signed 64.64-bit fixed point number\n */\n function fromInt (int256 x) internal pure returns (int128) {\n unchecked {\n require (x >= -0x8000000000000000 && x <= 0x7FFFFFFFFFFFFFFF);\n return int128 (x << 64);\n }\n }\n\n /**\n * Convert signed 64.64 fixed point number into signed 64-bit integer number\n * rounding down.\n *\n * @param x signed 64.64-bit fixed point number\n * @return signed 64-bit integer number\n */\n function toInt (int128 x) internal pure returns (int64) {\n unchecked {\n return int64 (x >> 64);\n }\n }\n\n /**\n * Convert unsigned 256-bit integer number into signed 64.64-bit fixed point\n * number. Revert on overflow.\n *\n * @param x unsigned 256-bit integer number\n * @return signed 64.64-bit fixed point number\n */\n function fromUInt (uint256 x) internal pure returns (int128) {\n unchecked {\n require (x <= 0x7FFFFFFFFFFFFFFF);\n return int128 (int256 (x << 64));\n }\n }\n\n /**\n * Convert signed 64.64 fixed point number into unsigned 64-bit integer\n * number rounding down. Revert on underflow.\n *\n * @param x signed 64.64-bit fixed point number\n * @return unsigned 64-bit integer number\n */\n function toUInt (int128 x) internal pure returns (uint64) {\n unchecked {\n require (x >= 0);\n return uint64 (uint128 (x >> 64));\n }\n }\n\n /**\n * Convert signed 128.128 fixed point number into signed 64.64-bit fixed point\n * number rounding down. Revert on overflow.\n *\n * @param x signed 128.128-bin fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function from128x128 (int256 x) internal pure returns (int128) {\n unchecked {\n int256 result = x >> 64;\n require (result >= MIN_64x64 && result <= MAX_64x64);\n return int128 (result);\n }\n }\n\n /**\n * Convert signed 64.64 fixed point number into signed 128.128 fixed point\n * number.\n *\n * @param x signed 64.64-bit fixed point number\n * @return signed 128.128 fixed point number\n */\n function to128x128 (int128 x) internal pure returns (int256) {\n unchecked {\n return int256 (x) << 64;\n }\n }\n\n /**\n * Calculate x + y. Revert on overflow.\n *\n * @param x signed 64.64-bit fixed point number\n * @param y signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function add (int128 x, int128 y) internal pure returns (int128) {\n unchecked {\n int256 result = int256(x) + y;\n require (result >= MIN_64x64 && result <= MAX_64x64);\n return int128 (result);\n }\n }\n\n /**\n * Calculate x - y. Revert on overflow.\n *\n * @param x signed 64.64-bit fixed point number\n * @param y signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function sub (int128 x, int128 y) internal pure returns (int128) {\n unchecked {\n int256 result = int256(x) - y;\n require (result >= MIN_64x64 && result <= MAX_64x64);\n return int128 (result);\n }\n }\n\n /**\n * Calculate x * y rounding down. Revert on overflow.\n *\n * @param x signed 64.64-bit fixed point number\n * @param y signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function mul (int128 x, int128 y) internal pure returns (int128) {\n unchecked {\n int256 result = int256(x) * y >> 64;\n require (result >= MIN_64x64 && result <= MAX_64x64);\n return int128 (result);\n }\n }\n\n /**\n * Calculate x * y rounding towards zero, where x is signed 64.64 fixed point\n * number and y is signed 256-bit integer number. Revert on overflow.\n *\n * @param x signed 64.64 fixed point number\n * @param y signed 256-bit integer number\n * @return signed 256-bit integer number\n */\n function muli (int128 x, int256 y) internal pure returns (int256) {\n unchecked {\n if (x == MIN_64x64) {\n require (y >= -0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF &&\n y <= 0x1000000000000000000000000000000000000000000000000);\n return -y << 63;\n } else {\n bool negativeResult = false;\n if (x < 0) {\n x = -x;\n negativeResult = true;\n }\n if (y < 0) {\n y = -y; // We rely on overflow behavior here\n negativeResult = !negativeResult;\n }\n uint256 absoluteResult = mulu (x, uint256 (y));\n if (negativeResult) {\n require (absoluteResult <=\n 0x8000000000000000000000000000000000000000000000000000000000000000);\n return -int256 (absoluteResult); // We rely on overflow behavior here\n } else {\n require (absoluteResult <=\n 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);\n return int256 (absoluteResult);\n }\n }\n }\n }\n\n /**\n * Calculate x * y rounding down, where x is signed 64.64 fixed point number\n * and y is unsigned 256-bit integer number. Revert on overflow.\n *\n * @param x signed 64.64 fixed point number\n * @param y unsigned 256-bit integer number\n * @return unsigned 256-bit integer number\n */\n function mulu (int128 x, uint256 y) internal pure returns (uint256) {\n unchecked {\n if (y == 0) return 0;\n\n require (x >= 0);\n\n uint256 lo = (uint256 (int256 (x)) * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) >> 64;\n uint256 hi = uint256 (int256 (x)) * (y >> 128);\n\n require (hi <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);\n hi <<= 64;\n\n require (hi <=\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - lo);\n return hi + lo;\n }\n }\n\n /**\n * Calculate x / y rounding towards zero. Revert on overflow or when y is\n * zero.\n *\n * @param x signed 64.64-bit fixed point number\n * @param y signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function div (int128 x, int128 y) internal pure returns (int128) {\n unchecked {\n require (y != 0);\n int256 result = (int256 (x) << 64) / y;\n require (result >= MIN_64x64 && result <= MAX_64x64);\n return int128 (result);\n }\n }\n\n /**\n * Calculate x / y rounding towards zero, where x and y are signed 256-bit\n * integer numbers. Revert on overflow or when y is zero.\n *\n * @param x signed 256-bit integer number\n * @param y signed 256-bit integer number\n * @return signed 64.64-bit fixed point number\n */\n function divi (int256 x, int256 y) internal pure returns (int128) {\n unchecked {\n require (y != 0);\n\n bool negativeResult = false;\n if (x < 0) {\n x = -x; // We rely on overflow behavior here\n negativeResult = true;\n }\n if (y < 0) {\n y = -y; // We rely on overflow behavior here\n negativeResult = !negativeResult;\n }\n uint128 absoluteResult = divuu (uint256 (x), uint256 (y));\n if (negativeResult) {\n require (absoluteResult <= 0x80000000000000000000000000000000);\n return -int128 (absoluteResult); // We rely on overflow behavior here\n } else {\n require (absoluteResult <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);\n return int128 (absoluteResult); // We rely on overflow behavior here\n }\n }\n }\n\n /**\n * Calculate x / y rounding towards zero, where x and y are unsigned 256-bit\n * integer numbers. Revert on overflow or when y is zero.\n *\n * @param x unsigned 256-bit integer number\n * @param y unsigned 256-bit integer number\n * @return signed 64.64-bit fixed point number\n */\n function divu (uint256 x, uint256 y) internal pure returns (int128) {\n unchecked {\n require (y != 0);\n uint128 result = divuu (x, y);\n require (result <= uint128 (MAX_64x64));\n return int128 (result);\n }\n }\n\n /**\n * Calculate -x. Revert on overflow.\n *\n * @param x signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function neg (int128 x) internal pure returns (int128) {\n unchecked {\n require (x != MIN_64x64);\n return -x;\n }\n }\n\n /**\n * Calculate |x|. Revert on overflow.\n *\n * @param x signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function abs (int128 x) internal pure returns (int128) {\n unchecked {\n require (x != MIN_64x64);\n return x < 0 ? -x : x;\n }\n }\n\n /**\n * Calculate 1 / x rounding towards zero. Revert on overflow or when x is\n * zero.\n *\n * @param x signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function inv (int128 x) internal pure returns (int128) {\n unchecked {\n require (x != 0);\n int256 result = int256 (0x100000000000000000000000000000000) / x;\n require (result >= MIN_64x64 && result <= MAX_64x64);\n return int128 (result);\n }\n }\n\n /**\n * Calculate arithmetics average of x and y, i.e. (x + y) / 2 rounding down.\n *\n * @param x signed 64.64-bit fixed point number\n * @param y signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function avg (int128 x, int128 y) internal pure returns (int128) {\n unchecked {\n return int128 ((int256 (x) + int256 (y)) >> 1);\n }\n }\n\n /**\n * Calculate geometric average of x and y, i.e. sqrt (x * y) rounding down.\n * Revert on overflow or in case x * y is negative.\n *\n * @param x signed 64.64-bit fixed point number\n * @param y signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function gavg (int128 x, int128 y) internal pure returns (int128) {\n unchecked {\n int256 m = int256 (x) * int256 (y);\n require (m >= 0);\n require (m <\n 0x4000000000000000000000000000000000000000000000000000000000000000);\n return int128 (sqrtu (uint256 (m)));\n }\n }\n\n /**\n * Calculate x^y assuming 0^0 is 1, where x is signed 64.64 fixed point number\n * and y is unsigned 256-bit integer number. Revert on overflow.\n *\n * @param x signed 64.64-bit fixed point number\n * @param y uint256 value\n * @return signed 64.64-bit fixed point number\n */\n function pow (int128 x, uint256 y) internal pure returns (int128) {\n unchecked {\n bool negative = x < 0 && y & 1 == 1;\n\n uint256 absX = uint128 (x < 0 ? -x : x);\n uint256 absResult;\n absResult = 0x100000000000000000000000000000000;\n\n if (absX <= 0x10000000000000000) {\n absX <<= 63;\n while (y != 0) {\n if (y & 0x1 != 0) {\n absResult = absResult * absX >> 127;\n }\n absX = absX * absX >> 127;\n\n if (y & 0x2 != 0) {\n absResult = absResult * absX >> 127;\n }\n absX = absX * absX >> 127;\n\n if (y & 0x4 != 0) {\n absResult = absResult * absX >> 127;\n }\n absX = absX * absX >> 127;\n\n if (y & 0x8 != 0) {\n absResult = absResult * absX >> 127;\n }\n absX = absX * absX >> 127;\n\n y >>= 4;\n }\n\n absResult >>= 64;\n } else {\n uint256 absXShift = 63;\n if (absX < 0x1000000000000000000000000) { absX <<= 32; absXShift -= 32; }\n if (absX < 0x10000000000000000000000000000) { absX <<= 16; absXShift -= 16; }\n if (absX < 0x1000000000000000000000000000000) { absX <<= 8; absXShift -= 8; }\n if (absX < 0x10000000000000000000000000000000) { absX <<= 4; absXShift -= 4; }\n if (absX < 0x40000000000000000000000000000000) { absX <<= 2; absXShift -= 2; }\n if (absX < 0x80000000000000000000000000000000) { absX <<= 1; absXShift -= 1; }\n\n uint256 resultShift = 0;\n while (y != 0) {\n require (absXShift < 64);\n\n if (y & 0x1 != 0) {\n absResult = absResult * absX >> 127;\n resultShift += absXShift;\n if (absResult > 0x100000000000000000000000000000000) {\n absResult >>= 1;\n resultShift += 1;\n }\n }\n absX = absX * absX >> 127;\n absXShift <<= 1;\n if (absX >= 0x100000000000000000000000000000000) {\n absX >>= 1;\n absXShift += 1;\n }\n\n y >>= 1;\n }\n\n require (resultShift < 64);\n absResult >>= 64 - resultShift;\n }\n int256 result = negative ? -int256 (absResult) : int256 (absResult);\n require (result >= MIN_64x64 && result <= MAX_64x64);\n return int128 (result);\n }\n }\n\n /**\n * Calculate sqrt (x) rounding down. Revert if x < 0.\n *\n * @param x signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function sqrt (int128 x) internal pure returns (int128) {\n unchecked {\n require (x >= 0);\n return int128 (sqrtu (uint256 (int256 (x)) << 64));\n }\n }\n\n /**\n * Calculate binary logarithm of x. Revert if x <= 0.\n *\n * @param x signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function log_2 (int128 x) internal pure returns (int128) {\n unchecked {\n require (x > 0);\n\n int256 msb = 0;\n int256 xc = x;\n if (xc >= 0x10000000000000000) { xc >>= 64; msb += 64; }\n if (xc >= 0x100000000) { xc >>= 32; msb += 32; }\n if (xc >= 0x10000) { xc >>= 16; msb += 16; }\n if (xc >= 0x100) { xc >>= 8; msb += 8; }\n if (xc >= 0x10) { xc >>= 4; msb += 4; }\n if (xc >= 0x4) { xc >>= 2; msb += 2; }\n if (xc >= 0x2) msb += 1; // No need to shift xc anymore\n\n int256 result = msb - 64 << 64;\n uint256 ux = uint256 (int256 (x)) << uint256 (127 - msb);\n for (int256 bit = 0x8000000000000000; bit > 0; bit >>= 1) {\n ux *= ux;\n uint256 b = ux >> 255;\n ux >>= 127 + b;\n result += bit * int256 (b);\n }\n\n return int128 (result);\n }\n }\n\n /**\n * Calculate natural logarithm of x. Revert if x <= 0.\n *\n * @param x signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function ln (int128 x) internal pure returns (int128) {\n unchecked {\n require (x > 0);\n\n return int128 (int256 (\n uint256 (int256 (log_2 (x))) * 0xB17217F7D1CF79ABC9E3B39803F2F6AF >> 128));\n }\n }\n\n /**\n * Calculate binary exponent of x. Revert on overflow.\n *\n * @param x signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function exp_2 (int128 x) internal pure returns (int128) {\n unchecked {\n require (x < 0x400000000000000000); // Overflow\n\n if (x < -0x400000000000000000) return 0; // Underflow\n\n uint256 result = 0x80000000000000000000000000000000;\n\n if (x & 0x8000000000000000 > 0)\n result = result * 0x16A09E667F3BCC908B2FB1366EA957D3E >> 128;\n if (x & 0x4000000000000000 > 0)\n result = result * 0x1306FE0A31B7152DE8D5A46305C85EDEC >> 128;\n if (x & 0x2000000000000000 > 0)\n result = result * 0x1172B83C7D517ADCDF7C8C50EB14A791F >> 128;\n if (x & 0x1000000000000000 > 0)\n result = result * 0x10B5586CF9890F6298B92B71842A98363 >> 128;\n if (x & 0x800000000000000 > 0)\n result = result * 0x1059B0D31585743AE7C548EB68CA417FD >> 128;\n if (x & 0x400000000000000 > 0)\n result = result * 0x102C9A3E778060EE6F7CACA4F7A29BDE8 >> 128;\n if (x & 0x200000000000000 > 0)\n result = result * 0x10163DA9FB33356D84A66AE336DCDFA3F >> 128;\n if (x & 0x100000000000000 > 0)\n result = result * 0x100B1AFA5ABCBED6129AB13EC11DC9543 >> 128;\n if (x & 0x80000000000000 > 0)\n result = result * 0x10058C86DA1C09EA1FF19D294CF2F679B >> 128;\n if (x & 0x40000000000000 > 0)\n result = result * 0x1002C605E2E8CEC506D21BFC89A23A00F >> 128;\n if (x & 0x20000000000000 > 0)\n result = result * 0x100162F3904051FA128BCA9C55C31E5DF >> 128;\n if (x & 0x10000000000000 > 0)\n result = result * 0x1000B175EFFDC76BA38E31671CA939725 >> 128;\n if (x & 0x8000000000000 > 0)\n result = result * 0x100058BA01FB9F96D6CACD4B180917C3D >> 128;\n if (x & 0x4000000000000 > 0)\n result = result * 0x10002C5CC37DA9491D0985C348C68E7B3 >> 128;\n if (x & 0x2000000000000 > 0)\n result = result * 0x1000162E525EE054754457D5995292026 >> 128;\n if (x & 0x1000000000000 > 0)\n result = result * 0x10000B17255775C040618BF4A4ADE83FC >> 128;\n if (x & 0x800000000000 > 0)\n result = result * 0x1000058B91B5BC9AE2EED81E9B7D4CFAB >> 128;\n if (x & 0x400000000000 > 0)\n result = result * 0x100002C5C89D5EC6CA4D7C8ACC017B7C9 >> 128;\n if (x & 0x200000000000 > 0)\n result = result * 0x10000162E43F4F831060E02D839A9D16D >> 128;\n if (x & 0x100000000000 > 0)\n result = result * 0x100000B1721BCFC99D9F890EA06911763 >> 128;\n if (x & 0x80000000000 > 0)\n result = result * 0x10000058B90CF1E6D97F9CA14DBCC1628 >> 128;\n if (x & 0x40000000000 > 0)\n result = result * 0x1000002C5C863B73F016468F6BAC5CA2B >> 128;\n if (x & 0x20000000000 > 0)\n result = result * 0x100000162E430E5A18F6119E3C02282A5 >> 128;\n if (x & 0x10000000000 > 0)\n result = result * 0x1000000B1721835514B86E6D96EFD1BFE >> 128;\n if (x & 0x8000000000 > 0)\n result = result * 0x100000058B90C0B48C6BE5DF846C5B2EF >> 128;\n if (x & 0x4000000000 > 0)\n result = result * 0x10000002C5C8601CC6B9E94213C72737A >> 128;\n if (x & 0x2000000000 > 0)\n result = result * 0x1000000162E42FFF037DF38AA2B219F06 >> 128;\n if (x & 0x1000000000 > 0)\n result = result * 0x10000000B17217FBA9C739AA5819F44F9 >> 128;\n if (x & 0x800000000 > 0)\n result = result * 0x1000000058B90BFCDEE5ACD3C1CEDC823 >> 128;\n if (x & 0x400000000 > 0)\n result = result * 0x100000002C5C85FE31F35A6A30DA1BE50 >> 128;\n if (x & 0x200000000 > 0)\n result = result * 0x10000000162E42FF0999CE3541B9FFFCF >> 128;\n if (x & 0x100000000 > 0)\n result = result * 0x100000000B17217F80F4EF5AADDA45554 >> 128;\n if (x & 0x80000000 > 0)\n result = result * 0x10000000058B90BFBF8479BD5A81B51AD >> 128;\n if (x & 0x40000000 > 0)\n result = result * 0x1000000002C5C85FDF84BD62AE30A74CC >> 128;\n if (x & 0x20000000 > 0)\n result = result * 0x100000000162E42FEFB2FED257559BDAA >> 128;\n if (x & 0x10000000 > 0)\n result = result * 0x1000000000B17217F7D5A7716BBA4A9AE >> 128;\n if (x & 0x8000000 > 0)\n result = result * 0x100000000058B90BFBE9DDBAC5E109CCE >> 128;\n if (x & 0x4000000 > 0)\n result = result * 0x10000000002C5C85FDF4B15DE6F17EB0D >> 128;\n if (x & 0x2000000 > 0)\n result = result * 0x1000000000162E42FEFA494F1478FDE05 >> 128;\n if (x & 0x1000000 > 0)\n result = result * 0x10000000000B17217F7D20CF927C8E94C >> 128;\n if (x & 0x800000 > 0)\n result = result * 0x1000000000058B90BFBE8F71CB4E4B33D >> 128;\n if (x & 0x400000 > 0)\n result = result * 0x100000000002C5C85FDF477B662B26945 >> 128;\n if (x & 0x200000 > 0)\n result = result * 0x10000000000162E42FEFA3AE53369388C >> 128;\n if (x & 0x100000 > 0)\n result = result * 0x100000000000B17217F7D1D351A389D40 >> 128;\n if (x & 0x80000 > 0)\n result = result * 0x10000000000058B90BFBE8E8B2D3D4EDE >> 128;\n if (x & 0x40000 > 0)\n result = result * 0x1000000000002C5C85FDF4741BEA6E77E >> 128;\n if (x & 0x20000 > 0)\n result = result * 0x100000000000162E42FEFA39FE95583C2 >> 128;\n if (x & 0x10000 > 0)\n result = result * 0x1000000000000B17217F7D1CFB72B45E1 >> 128;\n if (x & 0x8000 > 0)\n result = result * 0x100000000000058B90BFBE8E7CC35C3F0 >> 128;\n if (x & 0x4000 > 0)\n result = result * 0x10000000000002C5C85FDF473E242EA38 >> 128;\n if (x & 0x2000 > 0)\n result = result * 0x1000000000000162E42FEFA39F02B772C >> 128;\n if (x & 0x1000 > 0)\n result = result * 0x10000000000000B17217F7D1CF7D83C1A >> 128;\n if (x & 0x800 > 0)\n result = result * 0x1000000000000058B90BFBE8E7BDCBE2E >> 128;\n if (x & 0x400 > 0)\n result = result * 0x100000000000002C5C85FDF473DEA871F >> 128;\n if (x & 0x200 > 0)\n result = result * 0x10000000000000162E42FEFA39EF44D91 >> 128;\n if (x & 0x100 > 0)\n result = result * 0x100000000000000B17217F7D1CF79E949 >> 128;\n if (x & 0x80 > 0)\n result = result * 0x10000000000000058B90BFBE8E7BCE544 >> 128;\n if (x & 0x40 > 0)\n result = result * 0x1000000000000002C5C85FDF473DE6ECA >> 128;\n if (x & 0x20 > 0)\n result = result * 0x100000000000000162E42FEFA39EF366F >> 128;\n if (x & 0x10 > 0)\n result = result * 0x1000000000000000B17217F7D1CF79AFA >> 128;\n if (x & 0x8 > 0)\n result = result * 0x100000000000000058B90BFBE8E7BCD6D >> 128;\n if (x & 0x4 > 0)\n result = result * 0x10000000000000002C5C85FDF473DE6B2 >> 128;\n if (x & 0x2 > 0)\n result = result * 0x1000000000000000162E42FEFA39EF358 >> 128;\n if (x & 0x1 > 0)\n result = result * 0x10000000000000000B17217F7D1CF79AB >> 128;\n\n result >>= uint256 (int256 (63 - (x >> 64)));\n require (result <= uint256 (int256 (MAX_64x64)));\n\n return int128 (int256 (result));\n }\n }\n\n /**\n * Calculate natural exponent of x. Revert on overflow.\n *\n * @param x signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function exp (int128 x) internal pure returns (int128) {\n unchecked {\n require (x < 0x400000000000000000); // Overflow\n\n if (x < -0x400000000000000000) return 0; // Underflow\n\n return exp_2 (\n int128 (int256 (x) * 0x171547652B82FE1777D0FFDA0D23A7D12 >> 128));\n }\n }\n\n /**\n * Calculate x / y rounding towards zero, where x and y are unsigned 256-bit\n * integer numbers. Revert on overflow or when y is zero.\n *\n * @param x unsigned 256-bit integer number\n * @param y unsigned 256-bit integer number\n * @return unsigned 64.64-bit fixed point number\n */\n function divuu (uint256 x, uint256 y) private pure returns (uint128) {\n unchecked {\n require (y != 0);\n\n uint256 result;\n\n if (x <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n result = (x << 64) / y;\n else {\n uint256 msb = 192;\n uint256 xc = x >> 192;\n if (xc >= 0x100000000) { xc >>= 32; msb += 32; }\n if (xc >= 0x10000) { xc >>= 16; msb += 16; }\n if (xc >= 0x100) { xc >>= 8; msb += 8; }\n if (xc >= 0x10) { xc >>= 4; msb += 4; }\n if (xc >= 0x4) { xc >>= 2; msb += 2; }\n if (xc >= 0x2) msb += 1; // No need to shift xc anymore\n\n result = (x << 255 - msb) / ((y - 1 >> msb - 191) + 1);\n require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);\n\n uint256 hi = result * (y >> 128);\n uint256 lo = result * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);\n\n uint256 xh = x >> 192;\n uint256 xl = x << 64;\n\n if (xl < lo) xh -= 1;\n xl -= lo; // We rely on overflow behavior here\n lo = hi << 128;\n if (xl < lo) xh -= 1;\n xl -= lo; // We rely on overflow behavior here\n\n assert (xh == hi >> 128);\n\n result += xl / y;\n }\n\n require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);\n return uint128 (result);\n }\n }\n\n /**\n * Calculate sqrt (x) rounding down, where x is unsigned 256-bit integer\n * number.\n *\n * @param x unsigned 256-bit integer number\n * @return unsigned 128-bit integer number\n */\n function sqrtu (uint256 x) private pure returns (uint128) {\n unchecked {\n if (x == 0) return 0;\n else {\n uint256 xx = x;\n uint256 r = 1;\n if (xx >= 0x100000000000000000000000000000000) { xx >>= 128; r <<= 64; }\n if (xx >= 0x10000000000000000) { xx >>= 64; r <<= 32; }\n if (xx >= 0x100000000) { xx >>= 32; r <<= 16; }\n if (xx >= 0x10000) { xx >>= 16; r <<= 8; }\n if (xx >= 0x100) { xx >>= 8; r <<= 4; }\n if (xx >= 0x10) { xx >>= 4; r <<= 2; }\n if (xx >= 0x8) { r <<= 1; }\n r = (r + x / r) >> 1;\n r = (r + x / r) >> 1;\n r = (r + x / r) >> 1;\n r = (r + x / r) >> 1;\n r = (r + x / r) >> 1;\n r = (r + x / r) >> 1;\n r = (r + x / r) >> 1; // Seven iterations should be enough\n uint256 r1 = x / r;\n return uint128 (r < r1 ? r : r1);\n }\n }\n }\n}\n" - }, - "@solidstate/contracts/token/ERC20/metadata/IERC20Metadata.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC20 metadata interface\n */\ninterface IERC20Metadata {\n /**\n * @notice return token name\n * @return token name\n */\n function name() external view returns (string memory);\n\n /**\n * @notice return token symbol\n * @return token symbol\n */\n function symbol() external view returns (string memory);\n\n /**\n * @notice return token decimals, generally used only for display purposes\n * @return token decimals\n */\n function decimals() external view returns (uint8);\n}\n" - }, - "contracts/staking/FeeDiscountStorage.sol": { - "content": "// SPDX-License-Identifier: BUSL-1.1\r\n// For further clarification please see https://license.premia.legal\r\n\r\npragma solidity ^0.8.0;\r\n\r\nlibrary FeeDiscountStorage {\r\n bytes32 internal constant STORAGE_SLOT =\r\n keccak256(\"premia.contracts.staking.PremiaFeeDiscount\");\r\n\r\n struct UserInfo {\r\n uint256 balance; // Balance staked by user\r\n uint64 stakePeriod; // Stake period selected by user\r\n uint64 lockedUntil; // Timestamp at which the lock ends\r\n }\r\n\r\n struct Layout {\r\n // User data with xPREMIA balance staked and date at which lock ends\r\n mapping(address => UserInfo) userInfo;\r\n }\r\n\r\n function layout() internal pure returns (Layout storage l) {\r\n bytes32 slot = STORAGE_SLOT;\r\n assembly {\r\n l.slot := slot\r\n }\r\n }\r\n}\r\n" - }, - "contracts/libraries/OptionMath.sol": { - "content": "// SPDX-License-Identifier: BUSL-1.1\r\n// For further clarification please see https://license.premia.legal\r\n\r\npragma solidity ^0.8.0;\r\n\r\nimport {ABDKMath64x64} from \"abdk-libraries-solidity/ABDKMath64x64.sol\";\r\n\r\nlibrary OptionMath {\r\n using ABDKMath64x64 for int128;\r\n\r\n struct QuoteArgs {\r\n int128 varianceAnnualized64x64; // 64x64 fixed point representation of annualized variance\r\n int128 strike64x64; // 64x64 fixed point representation of strike price\r\n int128 spot64x64; // 64x64 fixed point representation of spot price\r\n int128 timeToMaturity64x64; // 64x64 fixed point representation of duration of option contract (in years)\r\n int128 oldCLevel64x64; // 64x64 fixed point representation of C-Level of Pool before purchase\r\n int128 oldPoolState; // 64x64 fixed point representation of current state of the pool\r\n int128 newPoolState; // 64x64 fixed point representation of state of the pool after trade\r\n int128 steepness64x64; // 64x64 fixed point representation of Pool state delta multiplier\r\n int128 minAPY64x64; // 64x64 fixed point representation of minimum APY for capital locked up to underwrite options\r\n bool isCall; // whether to price \"call\" or \"put\" option\r\n }\r\n\r\n struct CalculateCLevelDecayArgs {\r\n int128 timeIntervalsElapsed64x64; // 64x64 fixed point representation of quantity of discrete arbitrary intervals elapsed since last update\r\n int128 oldCLevel64x64; // 64x64 fixed point representation of C-Level prior to accounting for decay\r\n int128 utilization64x64; // 64x64 fixed point representation of pool capital utilization rate\r\n int128 utilizationLowerBound64x64;\r\n int128 utilizationUpperBound64x64;\r\n int128 cLevelLowerBound64x64;\r\n int128 cLevelUpperBound64x64;\r\n int128 cConvergenceULowerBound64x64;\r\n int128 cConvergenceUUpperBound64x64;\r\n }\r\n\r\n // 64x64 fixed point integer constants\r\n int128 internal constant ONE_64x64 = 0x10000000000000000;\r\n int128 internal constant THREE_64x64 = 0x30000000000000000;\r\n\r\n // 64x64 fixed point constants used in Choudhury’s approximation of the Black-Scholes CDF\r\n int128 private constant CDF_CONST_0 = 0x09109f285df452394; // 2260 / 3989\r\n int128 private constant CDF_CONST_1 = 0x19abac0ea1da65036; // 6400 / 3989\r\n int128 private constant CDF_CONST_2 = 0x0d3c84b78b749bd6b; // 3300 / 3989\r\n\r\n /**\r\n * @notice recalculate C-Level based on change in liquidity\r\n * @param initialCLevel64x64 64x64 fixed point representation of C-Level of Pool before update\r\n * @param oldPoolState64x64 64x64 fixed point representation of liquidity in pool before update\r\n * @param newPoolState64x64 64x64 fixed point representation of liquidity in pool after update\r\n * @param steepness64x64 64x64 fixed point representation of steepness coefficient\r\n * @return 64x64 fixed point representation of new C-Level\r\n */\r\n function calculateCLevel(\r\n int128 initialCLevel64x64,\r\n int128 oldPoolState64x64,\r\n int128 newPoolState64x64,\r\n int128 steepness64x64\r\n ) external pure returns (int128) {\r\n return\r\n newPoolState64x64\r\n .sub(oldPoolState64x64)\r\n .div(\r\n oldPoolState64x64 > newPoolState64x64\r\n ? oldPoolState64x64\r\n : newPoolState64x64\r\n )\r\n .mul(steepness64x64)\r\n .neg()\r\n .exp()\r\n .mul(initialCLevel64x64);\r\n }\r\n\r\n /**\r\n * @notice calculate the price of an option using the Premia Finance model\r\n * @param args arguments of quotePrice\r\n * @return premiaPrice64x64 64x64 fixed point representation of Premia option price\r\n * @return cLevel64x64 64x64 fixed point representation of C-Level of Pool after purchase\r\n */\r\n function quotePrice(QuoteArgs memory args)\r\n external\r\n pure\r\n returns (\r\n int128 premiaPrice64x64,\r\n int128 cLevel64x64,\r\n int128 slippageCoefficient64x64\r\n )\r\n {\r\n int128 deltaPoolState64x64 = args\r\n .newPoolState\r\n .sub(args.oldPoolState)\r\n .div(args.oldPoolState)\r\n .mul(args.steepness64x64);\r\n int128 tradingDelta64x64 = deltaPoolState64x64.neg().exp();\r\n\r\n int128 blackScholesPrice64x64 = _blackScholesPrice(\r\n args.varianceAnnualized64x64,\r\n args.strike64x64,\r\n args.spot64x64,\r\n args.timeToMaturity64x64,\r\n args.isCall\r\n );\r\n\r\n cLevel64x64 = tradingDelta64x64.mul(args.oldCLevel64x64);\r\n slippageCoefficient64x64 = ONE_64x64.sub(tradingDelta64x64).div(\r\n deltaPoolState64x64\r\n );\r\n\r\n premiaPrice64x64 = blackScholesPrice64x64.mul(cLevel64x64).mul(\r\n slippageCoefficient64x64\r\n );\r\n\r\n int128 intrinsicValue64x64;\r\n\r\n if (args.isCall && args.strike64x64 < args.spot64x64) {\r\n intrinsicValue64x64 = args.spot64x64.sub(args.strike64x64);\r\n } else if (!args.isCall && args.strike64x64 > args.spot64x64) {\r\n intrinsicValue64x64 = args.strike64x64.sub(args.spot64x64);\r\n }\r\n\r\n int128 collateralValue64x64 = args.isCall\r\n ? args.spot64x64\r\n : args.strike64x64;\r\n\r\n int128 minPrice64x64 = intrinsicValue64x64.add(\r\n collateralValue64x64.mul(args.minAPY64x64).mul(\r\n args.timeToMaturity64x64\r\n )\r\n );\r\n\r\n if (minPrice64x64 > premiaPrice64x64) {\r\n premiaPrice64x64 = minPrice64x64;\r\n }\r\n }\r\n\r\n /**\r\n * @notice calculate the decay of C-Level based on heat diffusion function\r\n * @param args structured CalculateCLevelDecayArgs\r\n * @return cLevelDecayed64x64 C-Level after accounting for decay\r\n */\r\n function calculateCLevelDecay(CalculateCLevelDecayArgs memory args)\r\n external\r\n pure\r\n returns (int128 cLevelDecayed64x64)\r\n {\r\n int128 convFHighU64x64 = (args.utilization64x64 >=\r\n args.utilizationUpperBound64x64 &&\r\n args.oldCLevel64x64 <= args.cLevelLowerBound64x64)\r\n ? ONE_64x64\r\n : int128(0);\r\n\r\n int128 convFLowU64x64 = (args.utilization64x64 <=\r\n args.utilizationLowerBound64x64 &&\r\n args.oldCLevel64x64 >= args.cLevelUpperBound64x64)\r\n ? ONE_64x64\r\n : int128(0);\r\n\r\n cLevelDecayed64x64 = args\r\n .oldCLevel64x64\r\n .sub(args.cConvergenceULowerBound64x64.mul(convFLowU64x64))\r\n .sub(args.cConvergenceUUpperBound64x64.mul(convFHighU64x64))\r\n .mul(\r\n convFLowU64x64\r\n .mul(ONE_64x64.sub(args.utilization64x64))\r\n .add(convFHighU64x64.mul(args.utilization64x64))\r\n .mul(args.timeIntervalsElapsed64x64)\r\n .neg()\r\n .exp()\r\n )\r\n .add(\r\n args.cConvergenceULowerBound64x64.mul(convFLowU64x64).add(\r\n args.cConvergenceUUpperBound64x64.mul(convFHighU64x64)\r\n )\r\n );\r\n }\r\n\r\n /**\r\n * @notice calculate the exponential decay coefficient for a given interval\r\n * @param oldTimestamp timestamp of previous update\r\n * @param newTimestamp current timestamp\r\n * @return 64x64 fixed point representation of exponential decay coefficient\r\n */\r\n function _decay(uint256 oldTimestamp, uint256 newTimestamp)\r\n internal\r\n pure\r\n returns (int128)\r\n {\r\n return\r\n ONE_64x64.sub(\r\n (-ABDKMath64x64.divu(newTimestamp - oldTimestamp, 7 days)).exp()\r\n );\r\n }\r\n\r\n /**\r\n * @notice calculate Choudhury’s approximation of the Black-Scholes CDF\r\n * @param input64x64 64x64 fixed point representation of random variable\r\n * @return 64x64 fixed point representation of the approximated CDF of x\r\n */\r\n function _N(int128 input64x64) internal pure returns (int128) {\r\n // squaring via mul is cheaper than via pow\r\n int128 inputSquared64x64 = input64x64.mul(input64x64);\r\n\r\n int128 value64x64 = (-inputSquared64x64 >> 1).exp().div(\r\n CDF_CONST_0.add(CDF_CONST_1.mul(input64x64.abs())).add(\r\n CDF_CONST_2.mul(inputSquared64x64.add(THREE_64x64).sqrt())\r\n )\r\n );\r\n\r\n return input64x64 > 0 ? ONE_64x64.sub(value64x64) : value64x64;\r\n }\r\n\r\n /**\r\n * @notice calculate the price of an option using the Black-Scholes model\r\n * @param varianceAnnualized64x64 64x64 fixed point representation of annualized variance\r\n * @param strike64x64 64x64 fixed point representation of strike price\r\n * @param spot64x64 64x64 fixed point representation of spot price\r\n * @param timeToMaturity64x64 64x64 fixed point representation of duration of option contract (in years)\r\n * @param isCall whether to price \"call\" or \"put\" option\r\n * @return 64x64 fixed point representation of Black-Scholes option price\r\n */\r\n function _blackScholesPrice(\r\n int128 varianceAnnualized64x64,\r\n int128 strike64x64,\r\n int128 spot64x64,\r\n int128 timeToMaturity64x64,\r\n bool isCall\r\n ) internal pure returns (int128) {\r\n int128 cumulativeVariance64x64 = timeToMaturity64x64.mul(\r\n varianceAnnualized64x64\r\n );\r\n int128 cumulativeVarianceSqrt64x64 = cumulativeVariance64x64.sqrt();\r\n\r\n int128 d1_64x64 = spot64x64\r\n .div(strike64x64)\r\n .ln()\r\n .add(cumulativeVariance64x64 >> 1)\r\n .div(cumulativeVarianceSqrt64x64);\r\n int128 d2_64x64 = d1_64x64.sub(cumulativeVarianceSqrt64x64);\r\n\r\n if (isCall) {\r\n return\r\n spot64x64.mul(_N(d1_64x64)).sub(strike64x64.mul(_N(d2_64x64)));\r\n } else {\r\n return\r\n -spot64x64.mul(_N(-d1_64x64)).sub(\r\n strike64x64.mul(_N(-d2_64x64))\r\n );\r\n }\r\n }\r\n}\r\n" - }, - "@solidstate/contracts/access/IERC173.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title Contract ownership standard interface\n * @dev see https://eips.ethereum.org/EIPS/eip-173\n */\ninterface IERC173 {\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /**\n * @notice get the ERC173 contract owner\n * @return conract owner\n */\n function owner() external view returns (address);\n\n /**\n * @notice transfer contract ownership to new account\n * @param account address of new owner\n */\n function transferOwnership(address account) external;\n}\n" - }, - "contracts/libraries/ABDKMath64x64Token.sol": { - "content": "// SPDX-License-Identifier: BUSL-1.1\r\n// For further clarification please see https://license.premia.legal\r\n\r\npragma solidity ^0.8.0;\r\n\r\nimport {ABDKMath64x64} from \"abdk-libraries-solidity/ABDKMath64x64.sol\";\r\n\r\nlibrary ABDKMath64x64Token {\r\n using ABDKMath64x64 for int128;\r\n\r\n /**\r\n * @notice convert 64x64 fixed point representation of token amount to decimal\r\n * @param value64x64 64x64 fixed point representation of token amount\r\n * @param decimals token display decimals\r\n * @return value decimal representation of token amount\r\n */\r\n function toDecimals(int128 value64x64, uint8 decimals)\r\n internal\r\n pure\r\n returns (uint256 value)\r\n {\r\n value = value64x64.mulu(10**decimals);\r\n }\r\n\r\n /**\r\n * @notice convert decimal representation of token amount to 64x64 fixed point\r\n * @param value decimal representation of token amount\r\n * @param decimals token display decimals\r\n * @return value64x64 64x64 fixed point representation of token amount\r\n */\r\n function fromDecimals(uint256 value, uint8 decimals)\r\n internal\r\n pure\r\n returns (int128 value64x64)\r\n {\r\n value64x64 = ABDKMath64x64.divu(value, 10**decimals);\r\n }\r\n\r\n /**\r\n * @notice convert 64x64 fixed point representation of token amount to wei (18 decimals)\r\n * @param value64x64 64x64 fixed point representation of token amount\r\n * @return value wei representation of token amount\r\n */\r\n function toWei(int128 value64x64) internal pure returns (uint256 value) {\r\n value = toDecimals(value64x64, 18);\r\n }\r\n\r\n /**\r\n * @notice convert wei representation (18 decimals) of token amount to 64x64 fixed point\r\n * @param value wei representation of token amount\r\n * @return value64x64 64x64 fixed point representation of token amount\r\n */\r\n function fromWei(uint256 value) internal pure returns (int128 value64x64) {\r\n value64x64 = fromDecimals(value, 18);\r\n }\r\n}\r\n" - }, - "@solidstate/contracts/token/ERC1155/IERC1155.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IERC1155Internal } from './IERC1155Internal.sol';\nimport { IERC165 } from '../../introspection/IERC165.sol';\n\n/**\n * @notice ERC1155 interface\n * @dev see https://github.com/ethereum/EIPs/issues/1155\n */\ninterface IERC1155 is IERC1155Internal, IERC165 {\n /**\n * @notice query the balance of given token held by given address\n * @param account address to query\n * @param id token to query\n * @return token balance\n */\n function balanceOf(address account, uint256 id)\n external\n view\n returns (uint256);\n\n /**\n * @notice query the balances of given tokens held by given addresses\n * @param accounts addresss to query\n * @param ids tokens to query\n * @return token balances\n */\n function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)\n external\n view\n returns (uint256[] memory);\n\n /**\n * @notice query approval status of given operator with respect to given address\n * @param account address to query for approval granted\n * @param operator address to query for approval received\n * @return whether operator is approved to spend tokens held by account\n */\n function isApprovedForAll(address account, address operator)\n external\n view\n returns (bool);\n\n /**\n * @notice grant approval to or revoke approval from given operator to spend held tokens\n * @param operator address whose approval status to update\n * @param status whether operator should be considered approved\n */\n function setApprovalForAll(address operator, bool status) external;\n\n /**\n * @notice transfer tokens between given addresses, checking for ERC1155Receiver implementation if applicable\n * @param from sender of tokens\n * @param to receiver of tokens\n * @param id token ID\n * @param amount quantity of tokens to transfer\n * @param data data payload\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @notice transfer batch of tokens between given addresses, checking for ERC1155Receiver implementation if applicable\n * @param from sender of tokens\n * @param to receiver of tokens\n * @param ids list of token IDs\n * @param amounts list of quantities of tokens to transfer\n * @param data data payload\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" - }, - "contracts/staking/IFeeDiscount.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-or-later\r\n\r\npragma solidity ^0.8.0;\r\n\r\nimport {FeeDiscountStorage} from \"./FeeDiscountStorage.sol\";\r\n\r\ninterface IFeeDiscount {\r\n event Staked(\r\n address indexed user,\r\n uint256 amount,\r\n uint256 stakePeriod,\r\n uint256 lockedUntil\r\n );\r\n event Unstaked(address indexed user, uint256 amount);\r\n\r\n struct StakeLevel {\r\n uint256 amount; // Amount to stake\r\n uint256 discount; // Discount when amount is reached\r\n }\r\n\r\n /**\r\n * @notice Stake using IERC2612 permit\r\n * @param amount The amount of xPremia to stake\r\n * @param period The lockup period (in seconds)\r\n * @param deadline Deadline after which permit will fail\r\n * @param v V\r\n * @param r R\r\n * @param s S\r\n */\r\n function stakeWithPermit(\r\n uint256 amount,\r\n uint256 period,\r\n uint256 deadline,\r\n uint8 v,\r\n bytes32 r,\r\n bytes32 s\r\n ) external;\r\n\r\n /**\r\n * @notice Lockup xPremia for protocol fee discounts\r\n * Longer period of locking will apply a multiplier on the amount staked, in the fee discount calculation\r\n * @param amount The amount of xPremia to stake\r\n * @param period The lockup period (in seconds)\r\n */\r\n function stake(uint256 amount, uint256 period) external;\r\n\r\n /**\r\n * @notice Unstake xPremia (If lockup period has ended)\r\n * @param amount The amount of xPremia to unstake\r\n */\r\n function unstake(uint256 amount) external;\r\n\r\n //////////\r\n // View //\r\n //////////\r\n\r\n /**\r\n * Calculate the stake amount of a user, after applying the bonus from the lockup period chosen\r\n * @param user The user from which to query the stake amount\r\n * @return The user stake amount after applying the bonus\r\n */\r\n function getStakeAmountWithBonus(address user)\r\n external\r\n view\r\n returns (uint256);\r\n\r\n /**\r\n * @notice Calculate the % of fee discount for user, based on his stake\r\n * @param user The _user for which the discount is for\r\n * @return Percentage of protocol fee discount (in basis point)\r\n * Ex : 1000 = 10% fee discount\r\n */\r\n function getDiscount(address user) external view returns (uint256);\r\n\r\n /**\r\n * @notice Get stake levels\r\n * @return Stake levels\r\n * Ex : 2500 = -25%\r\n */\r\n function getStakeLevels() external returns (StakeLevel[] memory);\r\n\r\n /**\r\n * @notice Get stake period multiplier\r\n * @param period The duration (in seconds) for which tokens are locked\r\n * @return The multiplier for this staking period\r\n * Ex : 20000 = x2\r\n */\r\n function getStakePeriodMultiplier(uint256 period)\r\n external\r\n returns (uint256);\r\n\r\n /**\r\n * @notice Get staking infos of a user\r\n * @param user The user address for which to get staking infos\r\n * @return The staking infos of the user\r\n */\r\n function getUserInfo(address user)\r\n external\r\n view\r\n returns (FeeDiscountStorage.UserInfo memory);\r\n}\r\n" - }, - "@solidstate/contracts/token/ERC1155/base/ERC1155BaseInternal.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { AddressUtils } from '../../../utils/AddressUtils.sol';\nimport { IERC1155Internal } from '../IERC1155Internal.sol';\nimport { IERC1155Receiver } from '../IERC1155Receiver.sol';\nimport { ERC1155BaseStorage } from './ERC1155BaseStorage.sol';\n\n/**\n * @title Base ERC1155 internal functions\n * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts/ (MIT license)\n */\nabstract contract ERC1155BaseInternal is IERC1155Internal {\n using AddressUtils for address;\n\n /**\n * @notice query the balance of given token held by given address\n * @param account address to query\n * @param id token to query\n * @return token balance\n */\n function _balanceOf(address account, uint256 id)\n internal\n view\n virtual\n returns (uint256)\n {\n require(\n account != address(0),\n 'ERC1155: balance query for the zero address'\n );\n return ERC1155BaseStorage.layout().balances[id][account];\n }\n\n /**\n * @notice mint given quantity of tokens for given address\n * @dev ERC1155Receiver implementation is not checked\n * @param account beneficiary of minting\n * @param id token ID\n * @param amount quantity of tokens to mint\n * @param data data payload\n */\n function _mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(account != address(0), 'ERC1155: mint to the zero address');\n\n _beforeTokenTransfer(\n msg.sender,\n address(0),\n account,\n _asSingletonArray(id),\n _asSingletonArray(amount),\n data\n );\n\n mapping(address => uint256) storage balances = ERC1155BaseStorage\n .layout()\n .balances[id];\n balances[account] += amount;\n\n emit TransferSingle(msg.sender, address(0), account, id, amount);\n }\n\n /**\n * @notice mint given quantity of tokens for given address\n * @param account beneficiary of minting\n * @param id token ID\n * @param amount quantity of tokens to mint\n * @param data data payload\n */\n function _safeMint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n _mint(account, id, amount, data);\n\n _doSafeTransferAcceptanceCheck(\n msg.sender,\n address(0),\n account,\n id,\n amount,\n data\n );\n }\n\n /**\n * @notice mint batch of tokens for given address\n * @dev ERC1155Receiver implementation is not checked\n * @param account beneficiary of minting\n * @param ids list of token IDs\n * @param amounts list of quantities of tokens to mint\n * @param data data payload\n */\n function _mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(account != address(0), 'ERC1155: mint to the zero address');\n require(\n ids.length == amounts.length,\n 'ERC1155: ids and amounts length mismatch'\n );\n\n _beforeTokenTransfer(\n msg.sender,\n address(0),\n account,\n ids,\n amounts,\n data\n );\n\n mapping(uint256 => mapping(address => uint256))\n storage balances = ERC1155BaseStorage.layout().balances;\n\n for (uint256 i; i < ids.length; i++) {\n balances[ids[i]][account] += amounts[i];\n }\n\n emit TransferBatch(msg.sender, address(0), account, ids, amounts);\n }\n\n /**\n * @notice mint batch of tokens for given address\n * @param account beneficiary of minting\n * @param ids list of token IDs\n * @param amounts list of quantities of tokens to mint\n * @param data data payload\n */\n function _safeMintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n _mintBatch(account, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(\n msg.sender,\n address(0),\n account,\n ids,\n amounts,\n data\n );\n }\n\n /**\n * @notice burn given quantity of tokens held by given address\n * @param account holder of tokens to burn\n * @param id token ID\n * @param amount quantity of tokens to burn\n */\n function _burn(\n address account,\n uint256 id,\n uint256 amount\n ) internal virtual {\n require(account != address(0), 'ERC1155: burn from the zero address');\n\n _beforeTokenTransfer(\n msg.sender,\n account,\n address(0),\n _asSingletonArray(id),\n _asSingletonArray(amount),\n ''\n );\n\n mapping(address => uint256) storage balances = ERC1155BaseStorage\n .layout()\n .balances[id];\n\n unchecked {\n require(\n balances[account] >= amount,\n 'ERC1155: burn amount exceeds balances'\n );\n balances[account] -= amount;\n }\n\n emit TransferSingle(msg.sender, account, address(0), id, amount);\n }\n\n /**\n * @notice burn given batch of tokens held by given address\n * @param account holder of tokens to burn\n * @param ids token IDs\n * @param amounts quantities of tokens to burn\n */\n function _burnBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal virtual {\n require(account != address(0), 'ERC1155: burn from the zero address');\n require(\n ids.length == amounts.length,\n 'ERC1155: ids and amounts length mismatch'\n );\n\n _beforeTokenTransfer(msg.sender, account, address(0), ids, amounts, '');\n\n mapping(uint256 => mapping(address => uint256))\n storage balances = ERC1155BaseStorage.layout().balances;\n\n unchecked {\n for (uint256 i; i < ids.length; i++) {\n uint256 id = ids[i];\n require(\n balances[id][account] >= amounts[i],\n 'ERC1155: burn amount exceeds balance'\n );\n balances[id][account] -= amounts[i];\n }\n }\n\n emit TransferBatch(msg.sender, account, address(0), ids, amounts);\n }\n\n /**\n * @notice transfer tokens between given addresses\n * @dev ERC1155Receiver implementation is not checked\n * @param operator executor of transfer\n * @param sender sender of tokens\n * @param recipient receiver of tokens\n * @param id token ID\n * @param amount quantity of tokens to transfer\n * @param data data payload\n */\n function _transfer(\n address operator,\n address sender,\n address recipient,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(\n recipient != address(0),\n 'ERC1155: transfer to the zero address'\n );\n\n _beforeTokenTransfer(\n operator,\n sender,\n recipient,\n _asSingletonArray(id),\n _asSingletonArray(amount),\n data\n );\n\n mapping(uint256 => mapping(address => uint256))\n storage balances = ERC1155BaseStorage.layout().balances;\n\n unchecked {\n uint256 senderBalance = balances[id][sender];\n require(\n senderBalance >= amount,\n 'ERC1155: insufficient balances for transfer'\n );\n balances[id][sender] = senderBalance - amount;\n }\n\n balances[id][recipient] += amount;\n\n emit TransferSingle(operator, sender, recipient, id, amount);\n }\n\n /**\n * @notice transfer tokens between given addresses\n * @param operator executor of transfer\n * @param sender sender of tokens\n * @param recipient receiver of tokens\n * @param id token ID\n * @param amount quantity of tokens to transfer\n * @param data data payload\n */\n function _safeTransfer(\n address operator,\n address sender,\n address recipient,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n _transfer(operator, sender, recipient, id, amount, data);\n\n _doSafeTransferAcceptanceCheck(\n operator,\n sender,\n recipient,\n id,\n amount,\n data\n );\n }\n\n /**\n * @notice transfer batch of tokens between given addresses\n * @dev ERC1155Receiver implementation is not checked\n * @param operator executor of transfer\n * @param sender sender of tokens\n * @param recipient receiver of tokens\n * @param ids token IDs\n * @param amounts quantities of tokens to transfer\n * @param data data payload\n */\n function _transferBatch(\n address operator,\n address sender,\n address recipient,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(\n recipient != address(0),\n 'ERC1155: transfer to the zero address'\n );\n require(\n ids.length == amounts.length,\n 'ERC1155: ids and amounts length mismatch'\n );\n\n _beforeTokenTransfer(operator, sender, recipient, ids, amounts, data);\n\n mapping(uint256 => mapping(address => uint256))\n storage balances = ERC1155BaseStorage.layout().balances;\n\n for (uint256 i; i < ids.length; i++) {\n uint256 token = ids[i];\n uint256 amount = amounts[i];\n\n unchecked {\n uint256 senderBalance = balances[token][sender];\n require(\n senderBalance >= amount,\n 'ERC1155: insufficient balances for transfer'\n );\n balances[token][sender] = senderBalance - amount;\n }\n\n balances[token][recipient] += amount;\n }\n\n emit TransferBatch(operator, sender, recipient, ids, amounts);\n }\n\n /**\n * @notice transfer batch of tokens between given addresses\n * @param operator executor of transfer\n * @param sender sender of tokens\n * @param recipient receiver of tokens\n * @param ids token IDs\n * @param amounts quantities of tokens to transfer\n * @param data data payload\n */\n function _safeTransferBatch(\n address operator,\n address sender,\n address recipient,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n _transferBatch(operator, sender, recipient, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(\n operator,\n sender,\n recipient,\n ids,\n amounts,\n data\n );\n }\n\n /**\n * @notice wrap given element in array of length 1\n * @param element element to wrap\n * @return singleton array\n */\n function _asSingletonArray(uint256 element)\n private\n pure\n returns (uint256[] memory)\n {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n return array;\n }\n\n /**\n * @notice revert if applicable transfer recipient is not valid ERC1155Receiver\n * @param operator executor of transfer\n * @param from sender of tokens\n * @param to receiver of tokens\n * @param id token ID\n * @param amount quantity of tokens to transfer\n * @param data data payload\n */\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try\n IERC1155Receiver(to).onERC1155Received(\n operator,\n from,\n id,\n amount,\n data\n )\n returns (bytes4 response) {\n require(\n response == IERC1155Receiver.onERC1155Received.selector,\n 'ERC1155: ERC1155Receiver rejected tokens'\n );\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert('ERC1155: transfer to non ERC1155Receiver implementer');\n }\n }\n }\n\n /**\n * @notice revert if applicable transfer recipient is not valid ERC1155Receiver\n * @param operator executor of transfer\n * @param from sender of tokens\n * @param to receiver of tokens\n * @param ids token IDs\n * @param amounts quantities of tokens to transfer\n * @param data data payload\n */\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try\n IERC1155Receiver(to).onERC1155BatchReceived(\n operator,\n from,\n ids,\n amounts,\n data\n )\n returns (bytes4 response) {\n require(\n response ==\n IERC1155Receiver.onERC1155BatchReceived.selector,\n 'ERC1155: ERC1155Receiver rejected tokens'\n );\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert('ERC1155: transfer to non ERC1155Receiver implementer');\n }\n }\n }\n\n /**\n * @notice ERC1155 hook, called before all transfers including mint and burn\n * @dev function should be overridden and new implementation must call super\n * @dev called for both single and batch transfers\n * @param operator executor of transfer\n * @param from sender of tokens\n * @param to receiver of tokens\n * @param ids token IDs\n * @param amounts quantities of tokens to transfer\n * @param data data payload\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n}\n" - }, - "@solidstate/contracts/token/ERC20/IERC20Internal.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title Partial ERC20 interface needed by internal functions\n */\ninterface IERC20Internal {\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n}\n" - }, - "@chainlink/contracts/src/v0.8/interfaces/AggregatorInterface.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorInterface {\n function latestAnswer()\n external\n view\n returns (\n int256\n );\n \n function latestTimestamp()\n external\n view\n returns (\n uint256\n );\n\n function latestRound()\n external\n view\n returns (\n uint256\n );\n\n function getAnswer(\n uint256 roundId\n )\n external\n view\n returns (\n int256\n );\n\n function getTimestamp(\n uint256 roundId\n )\n external\n view\n returns (\n uint256\n );\n\n event AnswerUpdated(\n int256 indexed current,\n uint256 indexed roundId,\n uint256 updatedAt\n );\n\n event NewRound(\n uint256 indexed roundId,\n address indexed startedBy,\n uint256 startedAt\n );\n}\n" - }, - "contracts/pool/PoolExercise.sol": { - "content": "// SPDX-License-Identifier: BUSL-1.1\r\n// For further clarification please see https://license.premia.legal\r\n\r\npragma solidity ^0.8.0;\r\n\r\nimport {ERC1155BaseStorage} from \"@solidstate/contracts/token/ERC1155/base/ERC1155BaseStorage.sol\";\r\n\r\nimport {PoolInternal} from \"./PoolInternal.sol\";\r\nimport {IPoolExercise} from \"./IPoolExercise.sol\";\r\n\r\n/**\r\n * @title Premia option pool\r\n * @dev deployed standalone and referenced by PoolProxy\r\n */\r\ncontract PoolExercise is IPoolExercise, PoolInternal {\r\n constructor(\r\n address ivolOracle,\r\n address weth,\r\n address premiaMining,\r\n address feeReceiver,\r\n address feeDiscountAddress,\r\n int128 fee64x64\r\n )\r\n PoolInternal(\r\n ivolOracle,\r\n weth,\r\n premiaMining,\r\n feeReceiver,\r\n feeDiscountAddress,\r\n fee64x64\r\n )\r\n {}\r\n\r\n /**\r\n * @inheritdoc IPoolExercise\r\n */\r\n function exerciseFrom(\r\n address holder,\r\n uint256 longTokenId,\r\n uint256 contractSize\r\n ) external override {\r\n if (msg.sender != holder) {\r\n require(\r\n ERC1155BaseStorage.layout().operatorApprovals[holder][\r\n msg.sender\r\n ],\r\n \"not approved\"\r\n );\r\n }\r\n\r\n _exercise(holder, longTokenId, contractSize);\r\n }\r\n\r\n /**\r\n * @inheritdoc IPoolExercise\r\n */\r\n function processExpired(uint256 longTokenId, uint256 contractSize)\r\n external\r\n override\r\n {\r\n _exercise(address(0), longTokenId, contractSize);\r\n }\r\n}\r\n" - }, - "contracts/pool/IPoolExercise.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-or-later\r\n\r\npragma solidity ^0.8.0;\r\n\r\n/**\r\n * @notice Pool interface for exercising and processing of expired options\r\n */\r\ninterface IPoolExercise {\r\n /**\r\n * @notice exercise option on behalf of holder\r\n * @param holder owner of long option tokens to exercise\r\n * @param longTokenId long option token id\r\n * @param contractSize quantity of tokens to exercise\r\n */\r\n function exerciseFrom(\r\n address holder,\r\n uint256 longTokenId,\r\n uint256 contractSize\r\n ) external;\r\n\r\n /**\r\n * @notice process expired option, freeing liquidity and distributing profits\r\n * @param longTokenId long option token id\r\n * @param contractSize quantity of tokens to process\r\n */\r\n function processExpired(uint256 longTokenId, uint256 contractSize) external;\r\n}\r\n" - }, - "contracts/pool/PoolStorage.sol": { - "content": "// SPDX-License-Identifier: BUSL-1.1\r\n// For further clarification please see https://license.premia.legal\r\n\r\npragma solidity ^0.8.0;\r\n\r\nimport {AggregatorInterface} from \"@chainlink/contracts/src/v0.8/interfaces/AggregatorInterface.sol\";\r\nimport {AggregatorV3Interface} from \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\r\nimport {EnumerableSet, ERC1155EnumerableStorage} from \"@solidstate/contracts/token/ERC1155/enumerable/ERC1155EnumerableStorage.sol\";\r\n\r\nimport {ABDKMath64x64} from \"abdk-libraries-solidity/ABDKMath64x64.sol\";\r\nimport {ABDKMath64x64Token} from \"../libraries/ABDKMath64x64Token.sol\";\r\nimport {OptionMath} from \"../libraries/OptionMath.sol\";\r\n\r\nlibrary PoolStorage {\r\n using ABDKMath64x64 for int128;\r\n using PoolStorage for PoolStorage.Layout;\r\n\r\n enum TokenType {\r\n UNDERLYING_FREE_LIQ,\r\n BASE_FREE_LIQ,\r\n UNDERLYING_RESERVED_LIQ,\r\n BASE_RESERVED_LIQ,\r\n LONG_CALL,\r\n SHORT_CALL,\r\n LONG_PUT,\r\n SHORT_PUT\r\n }\r\n\r\n struct PoolSettings {\r\n address underlying;\r\n address base;\r\n address underlyingOracle;\r\n address baseOracle;\r\n }\r\n\r\n struct QuoteArgsInternal {\r\n address feePayer; // address of the fee payer\r\n uint64 maturity; // timestamp of option maturity\r\n int128 strike64x64; // 64x64 fixed point representation of strike price\r\n int128 spot64x64; // 64x64 fixed point representation of spot price\r\n uint256 contractSize; // size of option contract\r\n bool isCall; // true for call, false for put\r\n }\r\n\r\n struct QuoteResultInternal {\r\n int128 baseCost64x64; // 64x64 fixed point representation of option cost denominated in underlying currency (without fee)\r\n int128 feeCost64x64; // 64x64 fixed point representation of option fee cost denominated in underlying currency for call, or base currency for put\r\n int128 cLevel64x64; // 64x64 fixed point representation of C-Level of Pool after purchase\r\n int128 slippageCoefficient64x64; // 64x64 fixed point representation of slippage coefficient for given order size\r\n }\r\n\r\n struct BatchData {\r\n uint256 eta;\r\n uint256 totalPendingDeposits;\r\n }\r\n\r\n bytes32 internal constant STORAGE_SLOT =\r\n keccak256(\"premia.contracts.storage.Pool\");\r\n\r\n uint256 private constant C_DECAY_BUFFER = 12 hours;\r\n uint256 private constant C_DECAY_INTERVAL = 4 hours;\r\n\r\n struct Layout {\r\n // ERC20 token addresses\r\n address base;\r\n address underlying;\r\n // AggregatorV3Interface oracle addresses\r\n address baseOracle;\r\n address underlyingOracle;\r\n // token metadata\r\n uint8 underlyingDecimals;\r\n uint8 baseDecimals;\r\n // minimum amounts\r\n uint256 baseMinimum;\r\n uint256 underlyingMinimum;\r\n // deposit caps\r\n uint256 basePoolCap;\r\n uint256 underlyingPoolCap;\r\n // market state\r\n int128 _deprecated_steepness64x64;\r\n int128 cLevelBase64x64;\r\n int128 cLevelUnderlying64x64;\r\n uint256 cLevelBaseUpdatedAt;\r\n uint256 cLevelUnderlyingUpdatedAt;\r\n uint256 updatedAt;\r\n // User -> isCall -> depositedAt\r\n mapping(address => mapping(bool => uint256)) depositedAt;\r\n mapping(address => mapping(bool => uint256)) divestmentTimestamps;\r\n // doubly linked list of free liquidity intervals\r\n // isCall -> User -> User\r\n mapping(bool => mapping(address => address)) liquidityQueueAscending;\r\n mapping(bool => mapping(address => address)) liquidityQueueDescending;\r\n // minimum resolution price bucket => price\r\n mapping(uint256 => int128) bucketPrices64x64;\r\n // sequence id (minimum resolution price bucket / 256) => price update sequence\r\n mapping(uint256 => uint256) priceUpdateSequences;\r\n // isCall -> batch data\r\n mapping(bool => BatchData) nextDeposits;\r\n // user -> batch timestamp -> isCall -> pending amount\r\n mapping(address => mapping(uint256 => mapping(bool => uint256))) pendingDeposits;\r\n EnumerableSet.UintSet tokenIds;\r\n // user -> isCallPool -> total value locked of user (Used for liquidity mining)\r\n mapping(address => mapping(bool => uint256)) userTVL;\r\n // isCallPool -> total value locked\r\n mapping(bool => uint256) totalTVL;\r\n // steepness values\r\n int128 steepnessBase64x64;\r\n int128 steepnessUnderlying64x64;\r\n }\r\n\r\n function layout() internal pure returns (Layout storage l) {\r\n bytes32 slot = STORAGE_SLOT;\r\n assembly {\r\n l.slot := slot\r\n }\r\n }\r\n\r\n /**\r\n * @notice calculate ERC1155 token id for given option parameters\r\n * @param tokenType TokenType enum\r\n * @param maturity timestamp of option maturity\r\n * @param strike64x64 64x64 fixed point representation of strike price\r\n * @return tokenId token id\r\n */\r\n function formatTokenId(\r\n TokenType tokenType,\r\n uint64 maturity,\r\n int128 strike64x64\r\n ) internal pure returns (uint256 tokenId) {\r\n tokenId =\r\n (uint256(tokenType) << 248) +\r\n (uint256(maturity) << 128) +\r\n uint256(int256(strike64x64));\r\n }\r\n\r\n /**\r\n * @notice derive option maturity and strike price from ERC1155 token id\r\n * @param tokenId token id\r\n * @return tokenType TokenType enum\r\n * @return maturity timestamp of option maturity\r\n * @return strike64x64 option strike price\r\n */\r\n function parseTokenId(uint256 tokenId)\r\n internal\r\n pure\r\n returns (\r\n TokenType tokenType,\r\n uint64 maturity,\r\n int128 strike64x64\r\n )\r\n {\r\n assembly {\r\n tokenType := shr(248, tokenId)\r\n maturity := shr(128, tokenId)\r\n strike64x64 := tokenId\r\n }\r\n }\r\n\r\n function getTokenDecimals(Layout storage l, bool isCall)\r\n internal\r\n view\r\n returns (uint8 decimals)\r\n {\r\n decimals = isCall ? l.underlyingDecimals : l.baseDecimals;\r\n }\r\n\r\n /**\r\n * @notice get the total supply of free liquidity tokens, minus pending deposits\r\n * @param l storage layout struct\r\n * @param isCall whether query is for call or put pool\r\n * @return 64x64 fixed point representation of total free liquidity\r\n */\r\n function totalFreeLiquiditySupply64x64(Layout storage l, bool isCall)\r\n internal\r\n view\r\n returns (int128)\r\n {\r\n uint256 tokenId = formatTokenId(\r\n isCall ? TokenType.UNDERLYING_FREE_LIQ : TokenType.BASE_FREE_LIQ,\r\n 0,\r\n 0\r\n );\r\n\r\n return\r\n ABDKMath64x64Token.fromDecimals(\r\n ERC1155EnumerableStorage.layout().totalSupply[tokenId] -\r\n l.nextDeposits[isCall].totalPendingDeposits,\r\n l.getTokenDecimals(isCall)\r\n );\r\n }\r\n\r\n function getReinvestmentStatus(\r\n Layout storage l,\r\n address account,\r\n bool isCallPool\r\n ) internal view returns (bool) {\r\n uint256 timestamp = l.divestmentTimestamps[account][isCallPool];\r\n return timestamp == 0 || timestamp > block.timestamp;\r\n }\r\n\r\n function addUnderwriter(\r\n Layout storage l,\r\n address account,\r\n bool isCallPool\r\n ) internal {\r\n require(account != address(0));\r\n\r\n mapping(address => address) storage asc = l.liquidityQueueAscending[\r\n isCallPool\r\n ];\r\n mapping(address => address) storage desc = l.liquidityQueueDescending[\r\n isCallPool\r\n ];\r\n\r\n if (_isInQueue(account, asc, desc)) return;\r\n\r\n address last = desc[address(0)];\r\n\r\n asc[last] = account;\r\n desc[account] = last;\r\n desc[address(0)] = account;\r\n }\r\n\r\n function removeUnderwriter(\r\n Layout storage l,\r\n address account,\r\n bool isCallPool\r\n ) internal {\r\n require(account != address(0));\r\n\r\n mapping(address => address) storage asc = l.liquidityQueueAscending[\r\n isCallPool\r\n ];\r\n mapping(address => address) storage desc = l.liquidityQueueDescending[\r\n isCallPool\r\n ];\r\n\r\n if (!_isInQueue(account, asc, desc)) return;\r\n\r\n address prev = desc[account];\r\n address next = asc[account];\r\n asc[prev] = next;\r\n desc[next] = prev;\r\n delete asc[account];\r\n delete desc[account];\r\n }\r\n\r\n function isInQueue(\r\n Layout storage l,\r\n address account,\r\n bool isCallPool\r\n ) internal view returns (bool) {\r\n mapping(address => address) storage asc = l.liquidityQueueAscending[\r\n isCallPool\r\n ];\r\n mapping(address => address) storage desc = l.liquidityQueueDescending[\r\n isCallPool\r\n ];\r\n\r\n return _isInQueue(account, asc, desc);\r\n }\r\n\r\n function _isInQueue(\r\n address account,\r\n mapping(address => address) storage asc,\r\n mapping(address => address) storage desc\r\n ) private view returns (bool) {\r\n return asc[account] != address(0) || desc[address(0)] == account;\r\n }\r\n\r\n /**\r\n * @notice get current C-Level, without accounting for pending adjustments\r\n * @param l storage layout struct\r\n * @param isCall whether query is for call or put pool\r\n * @return cLevel64x64 64x64 fixed point representation of C-Level\r\n */\r\n function getRawCLevel64x64(Layout storage l, bool isCall)\r\n internal\r\n view\r\n returns (int128 cLevel64x64)\r\n {\r\n cLevel64x64 = isCall ? l.cLevelUnderlying64x64 : l.cLevelBase64x64;\r\n }\r\n\r\n /**\r\n * @notice get current C-Level, accounting for unrealized decay\r\n * @param l storage layout struct\r\n * @param isCall whether query is for call or put pool\r\n * @return cLevel64x64 64x64 fixed point representation of C-Level\r\n */\r\n function getDecayAdjustedCLevel64x64(Layout storage l, bool isCall)\r\n internal\r\n view\r\n returns (int128 cLevel64x64)\r\n {\r\n // get raw C-Level from storage\r\n cLevel64x64 = l.getRawCLevel64x64(isCall);\r\n\r\n // account for C-Level decay\r\n cLevel64x64 = l.applyCLevelDecayAdjustment(cLevel64x64, isCall);\r\n }\r\n\r\n /**\r\n * @notice calculate updated C-Level, accounting for unrealized decay\r\n * @param l storage layout struct\r\n * @param oldCLevel64x64 64x64 fixed point representation pool C-Level before accounting for decay\r\n * @param isCall whether query is for call or put pool\r\n * @return cLevel64x64 64x64 fixed point representation of C-Level of Pool after accounting for decay\r\n */\r\n function applyCLevelDecayAdjustment(\r\n Layout storage l,\r\n int128 oldCLevel64x64,\r\n bool isCall\r\n ) internal view returns (int128 cLevel64x64) {\r\n uint256 timeElapsed = block.timestamp -\r\n (isCall ? l.cLevelUnderlyingUpdatedAt : l.cLevelBaseUpdatedAt);\r\n\r\n // do not apply C decay if less than 24 hours have elapsed\r\n\r\n if (timeElapsed > C_DECAY_BUFFER) {\r\n timeElapsed -= C_DECAY_BUFFER;\r\n } else {\r\n return oldCLevel64x64;\r\n }\r\n\r\n int128 timeIntervalsElapsed64x64 = ABDKMath64x64.divu(\r\n timeElapsed,\r\n C_DECAY_INTERVAL\r\n );\r\n\r\n uint256 tokenId = formatTokenId(\r\n isCall ? TokenType.UNDERLYING_FREE_LIQ : TokenType.BASE_FREE_LIQ,\r\n 0,\r\n 0\r\n );\r\n\r\n uint256 tvl = l.totalTVL[isCall];\r\n\r\n int128 utilization = ABDKMath64x64.divu(\r\n tvl -\r\n (ERC1155EnumerableStorage.layout().totalSupply[tokenId] -\r\n l.nextDeposits[isCall].totalPendingDeposits),\r\n tvl\r\n );\r\n\r\n return\r\n OptionMath.calculateCLevelDecay(\r\n OptionMath.CalculateCLevelDecayArgs(\r\n timeIntervalsElapsed64x64,\r\n oldCLevel64x64,\r\n utilization,\r\n 0xb333333333333333, // 0.7\r\n 0xe666666666666666, // 0.9\r\n 0x10000000000000000, // 1.0\r\n 0x10000000000000000, // 1.0\r\n 0xe666666666666666, // 0.9\r\n 0x56fc2a2c515da32ea // 2e\r\n )\r\n );\r\n }\r\n\r\n /**\r\n * @notice calculate updated C-Level, accounting for pending deposits\r\n * @param l storage layout struct\r\n * @param oldCLevel64x64 64x64 fixed point representation pool C-Level before accounting for liquidity change\r\n * @param oldLiquidity64x64 64x64 fixed point representation of previous liquidity\r\n * @param isCall whether to update C-Level for call or put pool\r\n * @return cLevel64x64 64x64 fixed point representation of C-Level\r\n * @return liquidity64x64 64x64 fixed point representation of new liquidity amount\r\n */\r\n function applyCLevelPendingDepositAdjustment(\r\n Layout storage l,\r\n int128 oldCLevel64x64,\r\n int128 oldLiquidity64x64,\r\n bool isCall\r\n ) internal view returns (int128 cLevel64x64, int128 liquidity64x64) {\r\n PoolStorage.BatchData storage batchData = l.nextDeposits[isCall];\r\n int128 pendingDeposits64x64;\r\n\r\n if (\r\n batchData.totalPendingDeposits > 0 &&\r\n batchData.eta != 0 &&\r\n block.timestamp >= batchData.eta\r\n ) {\r\n pendingDeposits64x64 = ABDKMath64x64Token.fromDecimals(\r\n batchData.totalPendingDeposits,\r\n l.getTokenDecimals(isCall)\r\n );\r\n\r\n liquidity64x64 = oldLiquidity64x64.add(pendingDeposits64x64);\r\n\r\n cLevel64x64 = l.applyCLevelLiquidityChangeAdjustment(\r\n oldCLevel64x64,\r\n oldLiquidity64x64,\r\n liquidity64x64,\r\n isCall\r\n );\r\n } else {\r\n cLevel64x64 = oldCLevel64x64;\r\n liquidity64x64 = oldLiquidity64x64;\r\n }\r\n }\r\n\r\n /**\r\n * @notice calculate updated C-Level, accounting for change in liquidity\r\n * @param l storage layout struct\r\n * @param oldCLevel64x64 64x64 fixed point representation pool C-Level before accounting for liquidity change\r\n * @param oldLiquidity64x64 64x64 fixed point representation of previous liquidity\r\n * @param newLiquidity64x64 64x64 fixed point representation of current liquidity\r\n * @param isCallPool whether to update C-Level for call or put pool\r\n * @return cLevel64x64 64x64 fixed point representation of C-Level\r\n */\r\n function applyCLevelLiquidityChangeAdjustment(\r\n Layout storage l,\r\n int128 oldCLevel64x64,\r\n int128 oldLiquidity64x64,\r\n int128 newLiquidity64x64,\r\n bool isCallPool\r\n ) internal view returns (int128 cLevel64x64) {\r\n int128 steepness64x64 = isCallPool\r\n ? l.steepnessUnderlying64x64\r\n : l.steepnessBase64x64;\r\n\r\n // fallback to deprecated storage value if side-specific value is not set\r\n if (steepness64x64 == 0) steepness64x64 = l._deprecated_steepness64x64;\r\n\r\n cLevel64x64 = OptionMath.calculateCLevel(\r\n oldCLevel64x64,\r\n oldLiquidity64x64,\r\n newLiquidity64x64,\r\n steepness64x64\r\n );\r\n\r\n if (cLevel64x64 < 0xb333333333333333) {\r\n cLevel64x64 = int128(0xb333333333333333); // 64x64 fixed point representation of 0.7\r\n }\r\n }\r\n\r\n /**\r\n * @notice set C-Level to arbitrary pre-calculated value\r\n * @param cLevel64x64 new C-Level of pool\r\n * @param isCallPool whether to update C-Level for call or put pool\r\n */\r\n function setCLevel(\r\n Layout storage l,\r\n int128 cLevel64x64,\r\n bool isCallPool\r\n ) internal {\r\n if (isCallPool) {\r\n l.cLevelUnderlying64x64 = cLevel64x64;\r\n l.cLevelUnderlyingUpdatedAt = block.timestamp;\r\n } else {\r\n l.cLevelBase64x64 = cLevel64x64;\r\n l.cLevelBaseUpdatedAt = block.timestamp;\r\n }\r\n }\r\n\r\n function setOracles(\r\n Layout storage l,\r\n address baseOracle,\r\n address underlyingOracle\r\n ) internal {\r\n require(\r\n AggregatorV3Interface(baseOracle).decimals() ==\r\n AggregatorV3Interface(underlyingOracle).decimals(),\r\n \"Pool: oracle decimals must match\"\r\n );\r\n\r\n l.baseOracle = baseOracle;\r\n l.underlyingOracle = underlyingOracle;\r\n }\r\n\r\n function fetchPriceUpdate(Layout storage l)\r\n internal\r\n view\r\n returns (int128 price64x64)\r\n {\r\n int256 priceUnderlying = AggregatorInterface(l.underlyingOracle)\r\n .latestAnswer();\r\n int256 priceBase = AggregatorInterface(l.baseOracle).latestAnswer();\r\n\r\n return ABDKMath64x64.divi(priceUnderlying, priceBase);\r\n }\r\n\r\n /**\r\n * @notice set price update for hourly bucket corresponding to given timestamp\r\n * @param l storage layout struct\r\n * @param timestamp timestamp to update\r\n * @param price64x64 64x64 fixed point representation of price\r\n */\r\n function setPriceUpdate(\r\n Layout storage l,\r\n uint256 timestamp,\r\n int128 price64x64\r\n ) internal {\r\n uint256 bucket = timestamp / (1 hours);\r\n l.bucketPrices64x64[bucket] = price64x64;\r\n l.priceUpdateSequences[bucket >> 8] += 1 << (255 - (bucket & 255));\r\n }\r\n\r\n /**\r\n * @notice get price update for hourly bucket corresponding to given timestamp\r\n * @param l storage layout struct\r\n * @param timestamp timestamp to query\r\n * @return 64x64 fixed point representation of price\r\n */\r\n function getPriceUpdate(Layout storage l, uint256 timestamp)\r\n internal\r\n view\r\n returns (int128)\r\n {\r\n return l.bucketPrices64x64[timestamp / (1 hours)];\r\n }\r\n\r\n /**\r\n * @notice get first price update available following given timestamp\r\n * @param l storage layout struct\r\n * @param timestamp timestamp to query\r\n * @return 64x64 fixed point representation of price\r\n */\r\n function getPriceUpdateAfter(Layout storage l, uint256 timestamp)\r\n internal\r\n view\r\n returns (int128)\r\n {\r\n // price updates are grouped into hourly buckets\r\n uint256 bucket = timestamp / (1 hours);\r\n // divide by 256 to get the index of the relevant price update sequence\r\n uint256 sequenceId = bucket >> 8;\r\n\r\n // get position within sequence relevant to current price update\r\n\r\n uint256 offset = bucket & 255;\r\n // shift to skip buckets from earlier in sequence\r\n uint256 sequence = (l.priceUpdateSequences[sequenceId] << offset) >>\r\n offset;\r\n\r\n // iterate through future sequences until a price update is found\r\n // sequence corresponding to current timestamp used as upper bound\r\n\r\n uint256 currentPriceUpdateSequenceId = block.timestamp / (256 hours);\r\n\r\n while (sequence == 0 && sequenceId <= currentPriceUpdateSequenceId) {\r\n sequence = l.priceUpdateSequences[++sequenceId];\r\n }\r\n\r\n // if no price update is found (sequence == 0) function will return 0\r\n // this should never occur, as each relevant external function triggers a price update\r\n\r\n // the most significant bit of the sequence corresponds to the offset of the relevant bucket\r\n\r\n uint256 msb;\r\n\r\n for (uint256 i = 128; i > 0; i >>= 1) {\r\n if (sequence >> i > 0) {\r\n msb += i;\r\n sequence >>= i;\r\n }\r\n }\r\n\r\n return l.bucketPrices64x64[((sequenceId + 1) << 8) - msb - 1];\r\n }\r\n\r\n function fromBaseToUnderlyingDecimals(Layout storage l, uint256 value)\r\n internal\r\n view\r\n returns (uint256)\r\n {\r\n int128 valueFixed64x64 = ABDKMath64x64Token.fromDecimals(\r\n value,\r\n l.baseDecimals\r\n );\r\n return\r\n ABDKMath64x64Token.toDecimals(\r\n valueFixed64x64,\r\n l.underlyingDecimals\r\n );\r\n }\r\n\r\n function fromUnderlyingToBaseDecimals(Layout storage l, uint256 value)\r\n internal\r\n view\r\n returns (uint256)\r\n {\r\n int128 valueFixed64x64 = ABDKMath64x64Token.fromDecimals(\r\n value,\r\n l.underlyingDecimals\r\n );\r\n return ABDKMath64x64Token.toDecimals(valueFixed64x64, l.baseDecimals);\r\n }\r\n}\r\n" - }, - "@solidstate/contracts/utils/AddressUtils.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nlibrary AddressUtils {\n function toString(address account) internal pure returns (string memory) {\n bytes32 value = bytes32(uint256(uint160(account)));\n bytes memory alphabet = '0123456789abcdef';\n bytes memory chars = new bytes(42);\n\n chars[0] = '0';\n chars[1] = 'x';\n\n for (uint256 i = 0; i < 20; i++) {\n chars[2 + i * 2] = alphabet[uint8(value[i + 12] >> 4)];\n chars[3 + i * 2] = alphabet[uint8(value[i + 12] & 0x0f)];\n }\n\n return string(chars);\n }\n\n function isContract(address account) internal view returns (bool) {\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size > 0;\n }\n\n function sendValue(address payable account, uint256 amount) internal {\n (bool success, ) = account.call{ value: amount }('');\n require(success, 'AddressUtils: failed to send value');\n }\n\n function functionCall(address target, bytes memory data)\n internal\n returns (bytes memory)\n {\n return\n functionCall(target, data, 'AddressUtils: failed low-level call');\n }\n\n function functionCall(\n address target,\n bytes memory data,\n string memory error\n ) internal returns (bytes memory) {\n return _functionCallWithValue(target, data, 0, error);\n }\n\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return\n functionCallWithValue(\n target,\n data,\n value,\n 'AddressUtils: failed low-level call with value'\n );\n }\n\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory error\n ) internal returns (bytes memory) {\n require(\n address(this).balance >= value,\n 'AddressUtils: insufficient balance for call'\n );\n return _functionCallWithValue(target, data, value, error);\n }\n\n function _functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory error\n ) private returns (bytes memory) {\n require(\n isContract(target),\n 'AddressUtils: function call to non-contract'\n );\n\n (bool success, bytes memory returnData) = target.call{ value: value }(\n data\n );\n\n if (success) {\n return returnData;\n } else if (returnData.length > 0) {\n assembly {\n let returnData_size := mload(returnData)\n revert(add(32, returnData), returnData_size)\n }\n } else {\n revert(error);\n }\n }\n}\n" - }, - "@solidstate/contracts/token/ERC1155/enumerable/ERC1155Enumerable.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { EnumerableSet } from '../../../utils/EnumerableSet.sol';\nimport { ERC1155Base, ERC1155BaseInternal } from '../base/ERC1155Base.sol';\nimport { IERC1155Enumerable } from './IERC1155Enumerable.sol';\nimport { ERC1155EnumerableInternal, ERC1155EnumerableStorage } from './ERC1155EnumerableInternal.sol';\n\n/**\n * @title ERC1155 implementation including enumerable and aggregate functions\n */\nabstract contract ERC1155Enumerable is\n IERC1155Enumerable,\n ERC1155Base,\n ERC1155EnumerableInternal\n{\n using EnumerableSet for EnumerableSet.AddressSet;\n using EnumerableSet for EnumerableSet.UintSet;\n\n /**\n * @inheritdoc IERC1155Enumerable\n */\n function totalSupply(uint256 id)\n public\n view\n virtual\n override\n returns (uint256)\n {\n return ERC1155EnumerableStorage.layout().totalSupply[id];\n }\n\n /**\n * @inheritdoc IERC1155Enumerable\n */\n function totalHolders(uint256 id)\n public\n view\n virtual\n override\n returns (uint256)\n {\n return ERC1155EnumerableStorage.layout().accountsByToken[id].length();\n }\n\n /**\n * @inheritdoc IERC1155Enumerable\n */\n function accountsByToken(uint256 id)\n public\n view\n virtual\n override\n returns (address[] memory)\n {\n EnumerableSet.AddressSet storage accounts = ERC1155EnumerableStorage\n .layout()\n .accountsByToken[id];\n\n address[] memory addresses = new address[](accounts.length());\n\n for (uint256 i; i < accounts.length(); i++) {\n addresses[i] = accounts.at(i);\n }\n\n return addresses;\n }\n\n /**\n * @inheritdoc IERC1155Enumerable\n */\n function tokensByAccount(address account)\n public\n view\n virtual\n override\n returns (uint256[] memory)\n {\n EnumerableSet.UintSet storage tokens = ERC1155EnumerableStorage\n .layout()\n .tokensByAccount[account];\n\n uint256[] memory ids = new uint256[](tokens.length());\n\n for (uint256 i; i < tokens.length(); i++) {\n ids[i] = tokens.at(i);\n }\n\n return ids;\n }\n\n /**\n * @notice ERC1155 hook: update aggregate values\n * @inheritdoc ERC1155EnumerableInternal\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n override(ERC1155BaseInternal, ERC1155EnumerableInternal)\n {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n }\n}\n" - }, - "@solidstate/contracts/token/ERC1155/IERC1155Receiver.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IERC165 } from '../../introspection/IERC165.sol';\n\n/**\n * @title ERC1155 transfer receiver interface\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @notice validate receipt of ERC1155 transfer\n * @param operator executor of transfer\n * @param from sender of tokens\n * @param id token ID received\n * @param value quantity of tokens received\n * @param data data payload\n * @return function's own selector if transfer is accepted\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @notice validate receipt of ERC1155 batch transfer\n * @param operator executor of transfer\n * @param from sender of tokens\n * @param ids token IDs received\n * @param values quantities of tokens received\n * @param data data payload\n * @return function's own selector if transfer is accepted\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" - }, - "contracts/pool/IPoolEvents.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-or-later\r\n\r\npragma solidity ^0.8.0;\r\n\r\ninterface IPoolEvents {\r\n event Purchase(\r\n address indexed user,\r\n uint256 longTokenId,\r\n uint256 contractSize,\r\n uint256 baseCost,\r\n uint256 feeCost,\r\n int128 spot64x64\r\n );\r\n\r\n event Exercise(\r\n address indexed user,\r\n uint256 longTokenId,\r\n uint256 contractSize,\r\n uint256 exerciseValue,\r\n uint256 fee\r\n );\r\n\r\n event Underwrite(\r\n address indexed underwriter,\r\n address indexed longReceiver,\r\n uint256 shortTokenId,\r\n uint256 intervalContractSize,\r\n uint256 intervalPremium,\r\n bool isManualUnderwrite\r\n );\r\n\r\n event AssignExercise(\r\n address indexed underwriter,\r\n uint256 shortTokenId,\r\n uint256 freedAmount,\r\n uint256 intervalContractSize,\r\n uint256 fee\r\n );\r\n\r\n event Deposit(address indexed user, bool isCallPool, uint256 amount);\r\n\r\n event Withdrawal(\r\n address indexed user,\r\n bool isCallPool,\r\n uint256 depositedAt,\r\n uint256 amount\r\n );\r\n\r\n event FeeWithdrawal(bool indexed isCallPool, uint256 amount);\r\n\r\n event Annihilate(uint256 shortTokenId, uint256 amount);\r\n\r\n event UpdateCLevel(\r\n bool indexed isCall,\r\n int128 cLevel64x64,\r\n int128 oldLiquidity64x64,\r\n int128 newLiquidity64x64\r\n );\r\n\r\n event UpdateSteepness(int128 steepness64x64, bool isCallPool);\r\n}\r\n" - }, - "contracts/oracle/VolatilitySurfaceOracleStorage.sol": { - "content": "// SPDX-License-Identifier: BUSL-1.1\r\n// For further clarification please see https://license.premia.legal\r\n\r\npragma solidity ^0.8.0;\r\n\r\nimport {EnumerableSet} from \"@solidstate/contracts/utils/EnumerableSet.sol\";\r\n\r\nlibrary VolatilitySurfaceOracleStorage {\r\n bytes32 internal constant STORAGE_SLOT =\r\n keccak256(\"premia.contracts.storage.VolatilitySurfaceOracle\");\r\n\r\n uint256 internal constant COEFF_BITS = 51;\r\n uint256 internal constant COEFF_BITS_MINUS_ONE = 50;\r\n uint256 internal constant COEFF_AMOUNT = 5;\r\n // START_BIT = COEFF_BITS * (COEFF_AMOUNT - 1)\r\n uint256 internal constant START_BIT = 204;\r\n\r\n struct Update {\r\n uint256 updatedAt;\r\n bytes32 callCoefficients;\r\n bytes32 putCoefficients;\r\n }\r\n\r\n struct Layout {\r\n // Base token -> Underlying token -> Update\r\n mapping(address => mapping(address => Update)) volatilitySurfaces;\r\n // Relayer addresses which can be trusted to provide accurate option trades\r\n EnumerableSet.AddressSet whitelistedRelayers;\r\n }\r\n\r\n function layout() internal pure returns (Layout storage l) {\r\n bytes32 slot = STORAGE_SLOT;\r\n assembly {\r\n l.slot := slot\r\n }\r\n }\r\n\r\n function getCoefficients(\r\n Layout storage l,\r\n address baseToken,\r\n address underlyingToken,\r\n bool isCall\r\n ) internal view returns (bytes32) {\r\n Update storage u = l.volatilitySurfaces[baseToken][underlyingToken];\r\n return isCall ? u.callCoefficients : u.putCoefficients;\r\n }\r\n\r\n function parseVolatilitySurfaceCoefficients(bytes32 input)\r\n internal\r\n pure\r\n returns (int256[] memory coefficients)\r\n {\r\n coefficients = new int256[](COEFF_AMOUNT);\r\n\r\n // Value to add to negative numbers to cast them to int256\r\n int256 toAdd = (int256(-1) >> COEFF_BITS) << COEFF_BITS;\r\n\r\n assembly {\r\n let i := 0\r\n // Value equal to -1\r\n let mid := shl(COEFF_BITS_MINUS_ONE, 1)\r\n\r\n for {\r\n\r\n } lt(i, COEFF_AMOUNT) {\r\n\r\n } {\r\n let offset := sub(START_BIT, mul(COEFF_BITS, i))\r\n let coeff := shr(\r\n offset,\r\n sub(\r\n input,\r\n shl(\r\n add(offset, COEFF_BITS),\r\n shr(add(offset, COEFF_BITS), input)\r\n )\r\n )\r\n )\r\n\r\n // Check if value is a negative number and needs casting\r\n if or(eq(coeff, mid), gt(coeff, mid)) {\r\n coeff := add(coeff, toAdd)\r\n }\r\n\r\n // Store result in the coefficients array\r\n mstore(add(coefficients, add(0x20, mul(0x20, i))), coeff)\r\n\r\n i := add(i, 1)\r\n }\r\n }\r\n }\r\n\r\n function formatVolatilitySurfaceCoefficients(int256[5] memory coefficients)\r\n internal\r\n pure\r\n returns (bytes32 result)\r\n {\r\n for (uint256 i = 0; i < COEFF_AMOUNT; i++) {\r\n int256 max = int256(1 << COEFF_BITS_MINUS_ONE);\r\n require(\r\n coefficients[i] < max && coefficients[i] > -max,\r\n \"Out of bounds\"\r\n );\r\n }\r\n\r\n assembly {\r\n let i := 0\r\n\r\n for {\r\n\r\n } lt(i, COEFF_AMOUNT) {\r\n\r\n } {\r\n let offset := sub(START_BIT, mul(COEFF_BITS, i))\r\n let coeff := mload(add(coefficients, mul(0x20, i)))\r\n\r\n result := add(\r\n result,\r\n shl(\r\n offset,\r\n sub(coeff, shl(COEFF_BITS, shr(COEFF_BITS, coeff)))\r\n )\r\n )\r\n\r\n i := add(i, 1)\r\n }\r\n }\r\n }\r\n}\r\n" - }, - "@solidstate/contracts/token/ERC1155/enumerable/IERC1155Enumerable.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC1155 enumerable and aggregate function interface\n */\ninterface IERC1155Enumerable {\n /**\n * @notice query total minted supply of given token\n * @param id token id to query\n * @return token supply\n */\n function totalSupply(uint256 id) external view returns (uint256);\n\n /**\n * @notice query total number of holders for given token\n * @param id token id to query\n * @return quantity of holders\n */\n function totalHolders(uint256 id) external view returns (uint256);\n\n /**\n * @notice query holders of given token\n * @param id token id to query\n * @return list of holder addresses\n */\n function accountsByToken(uint256 id)\n external\n view\n returns (address[] memory);\n\n /**\n * @notice query tokens held by given address\n * @param account address to query\n * @return list of token ids\n */\n function tokensByAccount(address account)\n external\n view\n returns (uint256[] memory);\n}\n" - }, - "@solidstate/contracts/token/ERC20/IERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IERC20Internal } from './IERC20Internal.sol';\n\n/**\n * @title ERC20 interface\n * @dev see https://github.com/ethereum/EIPs/issues/20\n */\ninterface IERC20 is IERC20Internal {\n /**\n * @notice query the total minted token supply\n * @return token supply\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @notice query the token balance of given account\n * @param account address to query\n * @return token balance\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @notice query the allowance granted from given holder to given spender\n * @param holder approver of allowance\n * @param spender recipient of allowance\n * @return token allowance\n */\n function allowance(address holder, address spender)\n external\n view\n returns (uint256);\n\n /**\n * @notice grant approval to spender to spend tokens\n * @dev prefer ERC20Extended functions to avoid transaction-ordering vulnerability (see https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729)\n * @param spender recipient of allowance\n * @param amount quantity of tokens approved for spending\n * @return success status (always true; otherwise function should revert)\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @notice transfer tokens to given recipient\n * @param recipient beneficiary of token transfer\n * @param amount quantity of tokens to transfer\n * @return success status (always true; otherwise function should revert)\n */\n function transfer(address recipient, uint256 amount)\n external\n returns (bool);\n\n /**\n * @notice transfer tokens to given recipient on behalf of given holder\n * @param holder holder of tokens prior to transfer\n * @param recipient beneficiary of token transfer\n * @param amount quantity of tokens to transfer\n * @return success status (always true; otherwise function should revert)\n */\n function transferFrom(\n address holder,\n address recipient,\n uint256 amount\n ) external returns (bool);\n}\n" - }, - "contracts/mining/IPremiaMining.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-or-later\r\n\r\npragma solidity ^0.8.0;\r\n\r\nimport {PremiaMiningStorage} from \"./PremiaMiningStorage.sol\";\r\n\r\ninterface IPremiaMining {\r\n function addPremiaRewards(uint256 _amount) external;\r\n\r\n function premiaRewardsAvailable() external view returns (uint256);\r\n\r\n function getTotalAllocationPoints() external view returns (uint256);\r\n\r\n function getPoolInfo(address pool, bool isCallPool)\r\n external\r\n view\r\n returns (PremiaMiningStorage.PoolInfo memory);\r\n\r\n function getPremiaPerYear() external view returns (uint256);\r\n\r\n function addPool(address _pool, uint256 _allocPoints) external;\r\n\r\n function setPoolAllocPoints(\r\n address[] memory _pools,\r\n uint256[] memory _allocPoints\r\n ) external;\r\n\r\n function pendingPremia(\r\n address _pool,\r\n bool _isCallPool,\r\n address _user\r\n ) external view returns (uint256);\r\n\r\n function updatePool(\r\n address _pool,\r\n bool _isCallPool,\r\n uint256 _totalTVL\r\n ) external;\r\n\r\n function allocatePending(\r\n address _user,\r\n address _pool,\r\n bool _isCallPool,\r\n uint256 _userTVLOld,\r\n uint256 _userTVLNew,\r\n uint256 _totalTVL\r\n ) external;\r\n\r\n function claim(\r\n address _user,\r\n address _pool,\r\n bool _isCallPool,\r\n uint256 _userTVLOld,\r\n uint256 _userTVLNew,\r\n uint256 _totalTVL\r\n ) external;\r\n}\r\n" - }, - "@solidstate/contracts/token/ERC1155/enumerable/ERC1155EnumerableStorage.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { EnumerableSet } from '../../../utils/EnumerableSet.sol';\n\nlibrary ERC1155EnumerableStorage {\n struct Layout {\n mapping(uint256 => uint256) totalSupply;\n mapping(uint256 => EnumerableSet.AddressSet) accountsByToken;\n mapping(address => EnumerableSet.UintSet) tokensByAccount;\n }\n\n bytes32 internal constant STORAGE_SLOT =\n keccak256('solidstate.contracts.storage.ERC1155Enumerable');\n\n function layout() internal pure returns (Layout storage l) {\n bytes32 slot = STORAGE_SLOT;\n assembly {\n l.slot := slot\n }\n }\n}\n" - }, - "@solidstate/contracts/token/ERC1155/enumerable/ERC1155EnumerableInternal.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { EnumerableSet } from '../../../utils/EnumerableSet.sol';\nimport { ERC1155BaseInternal, ERC1155BaseStorage } from '../base/ERC1155BaseInternal.sol';\nimport { ERC1155EnumerableStorage } from './ERC1155EnumerableStorage.sol';\n\n/**\n * @title ERC1155Enumerable internal functions\n */\nabstract contract ERC1155EnumerableInternal is ERC1155BaseInternal {\n using EnumerableSet for EnumerableSet.AddressSet;\n using EnumerableSet for EnumerableSet.UintSet;\n\n /**\n * @notice ERC1155 hook: update aggregate values\n * @inheritdoc ERC1155BaseInternal\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual override {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n if (from != to) {\n ERC1155EnumerableStorage.Layout storage l = ERC1155EnumerableStorage\n .layout();\n mapping(uint256 => EnumerableSet.AddressSet)\n storage tokenAccounts = l.accountsByToken;\n EnumerableSet.UintSet storage fromTokens = l.tokensByAccount[from];\n EnumerableSet.UintSet storage toTokens = l.tokensByAccount[to];\n\n for (uint256 i; i < ids.length; i++) {\n uint256 amount = amounts[i];\n\n if (amount > 0) {\n uint256 id = ids[i];\n\n if (from == address(0)) {\n l.totalSupply[id] += amount;\n } else if (_balanceOf(from, id) == amount) {\n tokenAccounts[id].remove(from);\n fromTokens.remove(id);\n }\n\n if (to == address(0)) {\n l.totalSupply[id] -= amount;\n } else if (_balanceOf(to, id) == 0) {\n tokenAccounts[id].add(to);\n toTokens.add(id);\n }\n }\n }\n }\n }\n}\n" - }, - "contracts/oracle/IVolatilitySurfaceOracle.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-or-later\r\n\r\npragma solidity ^0.8.0;\r\n\r\nimport {VolatilitySurfaceOracleStorage} from \"./VolatilitySurfaceOracleStorage.sol\";\r\n\r\ninterface IVolatilitySurfaceOracle {\r\n function getWhitelistedRelayers() external view returns (address[] memory);\r\n\r\n function getVolatilitySurface(address baseToken, address underlyingToken)\r\n external\r\n view\r\n returns (VolatilitySurfaceOracleStorage.Update memory);\r\n\r\n function getVolatilitySurfaceCoefficientsUnpacked(\r\n address baseToken,\r\n address underlyingToken,\r\n bool isCall\r\n ) external view returns (int256[] memory);\r\n\r\n function getTimeToMaturity64x64(uint64 maturity)\r\n external\r\n view\r\n returns (int128);\r\n\r\n function getAnnualizedVolatility64x64(\r\n address baseToken,\r\n address underlyingToken,\r\n int128 spot64x64,\r\n int128 strike64x64,\r\n int128 timeToMaturity64x64,\r\n bool isCall\r\n ) external view returns (int128);\r\n\r\n function getBlackScholesPrice64x64(\r\n address baseToken,\r\n address underlyingToken,\r\n int128 strike64x64,\r\n int128 spot64x64,\r\n int128 timeToMaturity64x64,\r\n bool isCall\r\n ) external view returns (int128);\r\n\r\n function getBlackScholesPrice(\r\n address baseToken,\r\n address underlyingToken,\r\n int128 strike64x64,\r\n int128 spot64x64,\r\n int128 timeToMaturity64x64,\r\n bool isCall\r\n ) external view returns (uint256);\r\n}\r\n" - }, - "contracts/pool/PoolInternal.sol": { - "content": "// SPDX-License-Identifier: BUSL-1.1\r\n// For further clarification please see https://license.premia.legal\r\n\r\npragma solidity ^0.8.0;\r\n\r\nimport {IERC173} from \"@solidstate/contracts/access/IERC173.sol\";\r\nimport {OwnableStorage} from \"@solidstate/contracts/access/OwnableStorage.sol\";\r\nimport {IERC20} from \"@solidstate/contracts/token/ERC20/IERC20.sol\";\r\nimport {ERC1155EnumerableInternal, ERC1155EnumerableStorage, EnumerableSet} from \"@solidstate/contracts/token/ERC1155/enumerable/ERC1155Enumerable.sol\";\r\nimport {IWETH} from \"@solidstate/contracts/utils/IWETH.sol\";\r\n\r\nimport {PoolStorage} from \"./PoolStorage.sol\";\r\n\r\nimport {ABDKMath64x64} from \"abdk-libraries-solidity/ABDKMath64x64.sol\";\r\nimport {ABDKMath64x64Token} from \"../libraries/ABDKMath64x64Token.sol\";\r\nimport {OptionMath} from \"../libraries/OptionMath.sol\";\r\nimport {IFeeDiscount} from \"../staking/IFeeDiscount.sol\";\r\nimport {IPoolEvents} from \"./IPoolEvents.sol\";\r\nimport {IPremiaMining} from \"../mining/IPremiaMining.sol\";\r\nimport {IVolatilitySurfaceOracle} from \"../oracle/IVolatilitySurfaceOracle.sol\";\r\n\r\n/**\r\n * @title Premia option pool\r\n * @dev deployed standalone and referenced by PoolProxy\r\n */\r\ncontract PoolInternal is IPoolEvents, ERC1155EnumerableInternal {\r\n using ABDKMath64x64 for int128;\r\n using EnumerableSet for EnumerableSet.AddressSet;\r\n using EnumerableSet for EnumerableSet.UintSet;\r\n using PoolStorage for PoolStorage.Layout;\r\n\r\n address internal immutable WETH_ADDRESS;\r\n address internal immutable PREMIA_MINING_ADDRESS;\r\n address internal immutable FEE_RECEIVER_ADDRESS;\r\n address internal immutable FEE_DISCOUNT_ADDRESS;\r\n address internal immutable IVOL_ORACLE_ADDRESS;\r\n\r\n int128 internal immutable FEE_64x64;\r\n\r\n uint256 internal immutable UNDERLYING_FREE_LIQ_TOKEN_ID;\r\n uint256 internal immutable BASE_FREE_LIQ_TOKEN_ID;\r\n\r\n uint256 internal immutable UNDERLYING_RESERVED_LIQ_TOKEN_ID;\r\n uint256 internal immutable BASE_RESERVED_LIQ_TOKEN_ID;\r\n\r\n uint256 internal constant INVERSE_BASIS_POINT = 1e4;\r\n uint256 internal constant BATCHING_PERIOD = 260;\r\n\r\n // Minimum APY for capital locked up to underwrite options.\r\n // The quote will return a minimum price corresponding to this APY\r\n int128 internal constant MIN_APY_64x64 = 0x4ccccccccccccccd; // 0.3\r\n\r\n constructor(\r\n address ivolOracle,\r\n address weth,\r\n address premiaMining,\r\n address feeReceiver,\r\n address feeDiscountAddress,\r\n int128 fee64x64\r\n ) {\r\n IVOL_ORACLE_ADDRESS = ivolOracle;\r\n WETH_ADDRESS = weth;\r\n PREMIA_MINING_ADDRESS = premiaMining;\r\n FEE_RECEIVER_ADDRESS = feeReceiver;\r\n // PremiaFeeDiscount contract address\r\n FEE_DISCOUNT_ADDRESS = feeDiscountAddress;\r\n FEE_64x64 = fee64x64;\r\n\r\n UNDERLYING_FREE_LIQ_TOKEN_ID = PoolStorage.formatTokenId(\r\n PoolStorage.TokenType.UNDERLYING_FREE_LIQ,\r\n 0,\r\n 0\r\n );\r\n BASE_FREE_LIQ_TOKEN_ID = PoolStorage.formatTokenId(\r\n PoolStorage.TokenType.BASE_FREE_LIQ,\r\n 0,\r\n 0\r\n );\r\n\r\n UNDERLYING_RESERVED_LIQ_TOKEN_ID = PoolStorage.formatTokenId(\r\n PoolStorage.TokenType.UNDERLYING_RESERVED_LIQ,\r\n 0,\r\n 0\r\n );\r\n BASE_RESERVED_LIQ_TOKEN_ID = PoolStorage.formatTokenId(\r\n PoolStorage.TokenType.BASE_RESERVED_LIQ,\r\n 0,\r\n 0\r\n );\r\n }\r\n\r\n modifier onlyProtocolOwner() {\r\n require(\r\n msg.sender == IERC173(OwnableStorage.layout().owner).owner(),\r\n \"Not protocol owner\"\r\n );\r\n _;\r\n }\r\n\r\n function _getFeeDiscount(address feePayer)\r\n internal\r\n view\r\n returns (uint256 discount)\r\n {\r\n if (FEE_DISCOUNT_ADDRESS != address(0)) {\r\n discount = IFeeDiscount(FEE_DISCOUNT_ADDRESS).getDiscount(feePayer);\r\n }\r\n }\r\n\r\n function _getFeeWithDiscount(address feePayer, uint256 fee)\r\n internal\r\n view\r\n returns (uint256)\r\n {\r\n uint256 discount = _getFeeDiscount(feePayer);\r\n return fee - ((fee * discount) / INVERSE_BASIS_POINT);\r\n }\r\n\r\n function _withdrawFees(bool isCall) internal returns (uint256 amount) {\r\n uint256 tokenId = _getReservedLiquidityTokenId(isCall);\r\n amount = _balanceOf(FEE_RECEIVER_ADDRESS, tokenId);\r\n\r\n if (amount > 0) {\r\n _burn(FEE_RECEIVER_ADDRESS, tokenId, amount);\r\n emit FeeWithdrawal(isCall, amount);\r\n }\r\n }\r\n\r\n /**\r\n * @notice calculate price of option contract\r\n * @param args structured quote arguments\r\n * @return result quote result\r\n */\r\n function _quote(PoolStorage.QuoteArgsInternal memory args)\r\n internal\r\n view\r\n returns (PoolStorage.QuoteResultInternal memory result)\r\n {\r\n require(\r\n args.strike64x64 > 0 && args.spot64x64 > 0 && args.maturity > 0,\r\n \"invalid args\"\r\n );\r\n PoolStorage.Layout storage l = PoolStorage.layout();\r\n\r\n int128 contractSize64x64 = ABDKMath64x64Token.fromDecimals(\r\n args.contractSize,\r\n l.underlyingDecimals\r\n );\r\n bool isCall = args.isCall;\r\n\r\n (int128 adjustedCLevel64x64, int128 oldLiquidity64x64) = l\r\n .applyCLevelPendingDepositAdjustment(\r\n l.getDecayAdjustedCLevel64x64(isCall),\r\n l.totalFreeLiquiditySupply64x64(isCall),\r\n isCall\r\n );\r\n\r\n require(oldLiquidity64x64 > 0, \"no liq\");\r\n\r\n int128 timeToMaturity64x64 = ABDKMath64x64.divu(\r\n args.maturity - block.timestamp,\r\n 365 days\r\n );\r\n\r\n int128 annualizedVolatility64x64 = IVolatilitySurfaceOracle(\r\n IVOL_ORACLE_ADDRESS\r\n ).getAnnualizedVolatility64x64(\r\n l.base,\r\n l.underlying,\r\n args.spot64x64,\r\n args.strike64x64,\r\n timeToMaturity64x64,\r\n isCall\r\n );\r\n\r\n require(annualizedVolatility64x64 > 0, \"vol = 0\");\r\n\r\n (\r\n int128 price64x64,\r\n int128 cLevel64x64,\r\n int128 slippageCoefficient64x64\r\n ) = OptionMath.quotePrice(\r\n OptionMath.QuoteArgs(\r\n annualizedVolatility64x64.mul(annualizedVolatility64x64),\r\n args.strike64x64,\r\n args.spot64x64,\r\n timeToMaturity64x64,\r\n adjustedCLevel64x64,\r\n oldLiquidity64x64,\r\n oldLiquidity64x64.sub(contractSize64x64),\r\n 0x10000000000000000, // 64x64 fixed point representation of 1\r\n MIN_APY_64x64,\r\n isCall\r\n )\r\n );\r\n\r\n result.baseCost64x64 = isCall\r\n ? price64x64.mul(contractSize64x64).div(args.spot64x64)\r\n : price64x64.mul(contractSize64x64);\r\n result.feeCost64x64 = result.baseCost64x64.mul(FEE_64x64);\r\n result.cLevel64x64 = cLevel64x64;\r\n result.slippageCoefficient64x64 = slippageCoefficient64x64;\r\n\r\n int128 discount = ABDKMath64x64.divu(\r\n _getFeeDiscount(args.feePayer),\r\n INVERSE_BASIS_POINT\r\n );\r\n result.feeCost64x64 -= result.feeCost64x64.mul(discount);\r\n }\r\n\r\n /**\r\n * @notice burn corresponding long and short option tokens\r\n * @param account holder of tokens to annihilate\r\n * @param maturity timestamp of option maturity\r\n * @param strike64x64 64x64 fixed point representation of strike price\r\n * @param isCall true for call, false for put\r\n * @param contractSize quantity of option contract tokens to annihilate\r\n */\r\n function _annihilate(\r\n address account,\r\n uint64 maturity,\r\n int128 strike64x64,\r\n bool isCall,\r\n uint256 contractSize\r\n ) internal {\r\n uint256 longTokenId = PoolStorage.formatTokenId(\r\n _getTokenType(isCall, true),\r\n maturity,\r\n strike64x64\r\n );\r\n uint256 shortTokenId = PoolStorage.formatTokenId(\r\n _getTokenType(isCall, false),\r\n maturity,\r\n strike64x64\r\n );\r\n\r\n _burn(account, longTokenId, contractSize);\r\n _burn(account, shortTokenId, contractSize);\r\n\r\n emit Annihilate(shortTokenId, contractSize);\r\n }\r\n\r\n /**\r\n * @notice purchase option\r\n * @param l storage layout struct\r\n * @param account recipient of purchased option\r\n * @param maturity timestamp of option maturity\r\n * @param strike64x64 64x64 fixed point representation of strike price\r\n * @param isCall true for call, false for put\r\n * @param contractSize size of option contract\r\n * @param newPrice64x64 64x64 fixed point representation of current spot price\r\n * @return baseCost quantity of tokens required to purchase long position\r\n * @return feeCost quantity of tokens required to pay fees\r\n */\r\n function _purchase(\r\n PoolStorage.Layout storage l,\r\n address account,\r\n uint64 maturity,\r\n int128 strike64x64,\r\n bool isCall,\r\n uint256 contractSize,\r\n int128 newPrice64x64\r\n ) internal returns (uint256 baseCost, uint256 feeCost) {\r\n require(maturity > block.timestamp, \"expired\");\r\n require(contractSize >= l.underlyingMinimum, \"too small\");\r\n\r\n {\r\n uint256 size = isCall\r\n ? contractSize\r\n : l.fromUnderlyingToBaseDecimals(\r\n strike64x64.mulu(contractSize)\r\n );\r\n\r\n require(\r\n size <=\r\n ERC1155EnumerableStorage.layout().totalSupply[\r\n _getFreeLiquidityTokenId(isCall)\r\n ] -\r\n l.nextDeposits[isCall].totalPendingDeposits,\r\n \"insuf liq\"\r\n );\r\n }\r\n\r\n PoolStorage.QuoteResultInternal memory quote = _quote(\r\n PoolStorage.QuoteArgsInternal(\r\n account,\r\n maturity,\r\n strike64x64,\r\n newPrice64x64,\r\n contractSize,\r\n isCall\r\n )\r\n );\r\n\r\n baseCost = ABDKMath64x64Token.toDecimals(\r\n quote.baseCost64x64,\r\n l.getTokenDecimals(isCall)\r\n );\r\n\r\n feeCost = ABDKMath64x64Token.toDecimals(\r\n quote.feeCost64x64,\r\n l.getTokenDecimals(isCall)\r\n );\r\n\r\n uint256 longTokenId = PoolStorage.formatTokenId(\r\n _getTokenType(isCall, true),\r\n maturity,\r\n strike64x64\r\n );\r\n\r\n uint256 shortTokenId = PoolStorage.formatTokenId(\r\n _getTokenType(isCall, false),\r\n maturity,\r\n strike64x64\r\n );\r\n\r\n // mint long option token for buyer\r\n _mint(account, longTokenId, contractSize);\r\n\r\n int128 oldLiquidity64x64 = l.totalFreeLiquiditySupply64x64(isCall);\r\n // burn free liquidity tokens from other underwriters\r\n _mintShortTokenLoop(\r\n l,\r\n account,\r\n contractSize,\r\n baseCost,\r\n shortTokenId,\r\n isCall\r\n );\r\n int128 newLiquidity64x64 = l.totalFreeLiquiditySupply64x64(isCall);\r\n\r\n _setCLevel(l, oldLiquidity64x64, newLiquidity64x64, isCall);\r\n\r\n // mint reserved liquidity tokens for fee receiver\r\n _mint(\r\n FEE_RECEIVER_ADDRESS,\r\n _getReservedLiquidityTokenId(isCall),\r\n feeCost\r\n );\r\n\r\n emit Purchase(\r\n account,\r\n longTokenId,\r\n contractSize,\r\n baseCost,\r\n feeCost,\r\n newPrice64x64\r\n );\r\n }\r\n\r\n /**\r\n * @notice reassign short position to new underwriter\r\n * @param l storage layout struct\r\n * @param account holder of positions to be reassigned\r\n * @param maturity timestamp of option maturity\r\n * @param strike64x64 64x64 fixed point representation of strike price\r\n * @param isCall true for call, false for put\r\n * @param contractSize quantity of option contract tokens to reassign\r\n * @param newPrice64x64 64x64 fixed point representation of current spot price\r\n * @return baseCost quantity of tokens required to reassign short position\r\n * @return feeCost quantity of tokens required to pay fees\r\n * @return amountOut quantity of liquidity freed\r\n */\r\n function _reassign(\r\n PoolStorage.Layout storage l,\r\n address account,\r\n uint64 maturity,\r\n int128 strike64x64,\r\n bool isCall,\r\n uint256 contractSize,\r\n int128 newPrice64x64\r\n )\r\n internal\r\n returns (\r\n uint256 baseCost,\r\n uint256 feeCost,\r\n uint256 amountOut\r\n )\r\n {\r\n (baseCost, feeCost) = _purchase(\r\n l,\r\n account,\r\n maturity,\r\n strike64x64,\r\n isCall,\r\n contractSize,\r\n newPrice64x64\r\n );\r\n\r\n _annihilate(account, maturity, strike64x64, isCall, contractSize);\r\n\r\n uint256 annihilateAmount = isCall\r\n ? contractSize\r\n : l.fromUnderlyingToBaseDecimals(strike64x64.mulu(contractSize));\r\n\r\n amountOut = annihilateAmount - baseCost - feeCost;\r\n }\r\n\r\n /**\r\n * @notice exercise option on behalf of holder\r\n * @dev used for processing of expired options if passed holder is zero address\r\n * @param holder owner of long option tokens to exercise\r\n * @param longTokenId long option token id\r\n * @param contractSize quantity of tokens to exercise\r\n */\r\n function _exercise(\r\n address holder,\r\n uint256 longTokenId,\r\n uint256 contractSize\r\n ) internal {\r\n uint64 maturity;\r\n int128 strike64x64;\r\n bool isCall;\r\n\r\n bool onlyExpired = holder == address(0);\r\n\r\n {\r\n PoolStorage.TokenType tokenType;\r\n (tokenType, maturity, strike64x64) = PoolStorage.parseTokenId(\r\n longTokenId\r\n );\r\n require(\r\n tokenType == PoolStorage.TokenType.LONG_CALL ||\r\n tokenType == PoolStorage.TokenType.LONG_PUT,\r\n \"invalid type\"\r\n );\r\n require(!onlyExpired || maturity < block.timestamp, \"not expired\");\r\n isCall = tokenType == PoolStorage.TokenType.LONG_CALL;\r\n }\r\n\r\n PoolStorage.Layout storage l = PoolStorage.layout();\r\n\r\n int128 spot64x64 = _update(l);\r\n\r\n if (maturity < block.timestamp) {\r\n spot64x64 = l.getPriceUpdateAfter(maturity);\r\n }\r\n\r\n require(\r\n onlyExpired ||\r\n (\r\n isCall\r\n ? (spot64x64 > strike64x64)\r\n : (spot64x64 < strike64x64)\r\n ),\r\n \"not ITM\"\r\n );\r\n\r\n uint256 exerciseValue;\r\n // option has a non-zero exercise value\r\n if (isCall) {\r\n if (spot64x64 > strike64x64) {\r\n exerciseValue = spot64x64.sub(strike64x64).div(spot64x64).mulu(\r\n contractSize\r\n );\r\n }\r\n } else {\r\n if (spot64x64 < strike64x64) {\r\n exerciseValue = l.fromUnderlyingToBaseDecimals(\r\n strike64x64.sub(spot64x64).mulu(contractSize)\r\n );\r\n }\r\n }\r\n\r\n uint256 totalFee;\r\n\r\n if (onlyExpired) {\r\n totalFee += _burnLongTokenLoop(\r\n contractSize,\r\n exerciseValue,\r\n longTokenId,\r\n isCall\r\n );\r\n } else {\r\n // burn long option tokens from sender\r\n _burn(holder, longTokenId, contractSize);\r\n\r\n uint256 fee;\r\n\r\n if (exerciseValue > 0) {\r\n fee = _getFeeWithDiscount(\r\n holder,\r\n FEE_64x64.mulu(exerciseValue)\r\n );\r\n totalFee += fee;\r\n\r\n _pushTo(holder, _getPoolToken(isCall), exerciseValue - fee);\r\n }\r\n\r\n emit Exercise(\r\n holder,\r\n longTokenId,\r\n contractSize,\r\n exerciseValue,\r\n fee\r\n );\r\n }\r\n\r\n totalFee += _burnShortTokenLoop(\r\n contractSize,\r\n exerciseValue,\r\n PoolStorage.formatTokenId(\r\n _getTokenType(isCall, false),\r\n maturity,\r\n strike64x64\r\n ),\r\n isCall\r\n );\r\n\r\n _mint(\r\n FEE_RECEIVER_ADDRESS,\r\n _getReservedLiquidityTokenId(isCall),\r\n totalFee\r\n );\r\n }\r\n\r\n function _mintShortTokenLoop(\r\n PoolStorage.Layout storage l,\r\n address buyer,\r\n uint256 contractSize,\r\n uint256 premium,\r\n uint256 shortTokenId,\r\n bool isCall\r\n ) internal {\r\n uint256 freeLiqTokenId = _getFreeLiquidityTokenId(isCall);\r\n (, , int128 strike64x64) = PoolStorage.parseTokenId(shortTokenId);\r\n\r\n uint256 toPay = isCall\r\n ? contractSize\r\n : l.fromUnderlyingToBaseDecimals(strike64x64.mulu(contractSize));\r\n\r\n while (toPay > 0) {\r\n address underwriter = l.liquidityQueueAscending[isCall][address(0)];\r\n uint256 balance = _balanceOf(underwriter, freeLiqTokenId);\r\n\r\n // If dust left, we remove underwriter and skip to next\r\n if (balance < _getMinimumAmount(l, isCall)) {\r\n l.removeUnderwriter(underwriter, isCall);\r\n continue;\r\n }\r\n\r\n if (!l.getReinvestmentStatus(underwriter, isCall)) {\r\n _burn(underwriter, freeLiqTokenId, balance);\r\n _mint(\r\n underwriter,\r\n _getReservedLiquidityTokenId(isCall),\r\n balance\r\n );\r\n _subUserTVL(l, underwriter, isCall, balance);\r\n continue;\r\n }\r\n\r\n // amount of liquidity provided by underwriter, accounting for reinvested premium\r\n uint256 intervalContractSize = ((balance -\r\n l.pendingDeposits[underwriter][l.nextDeposits[isCall].eta][\r\n isCall\r\n ]) * (toPay + premium)) / toPay;\r\n if (intervalContractSize == 0) continue;\r\n if (intervalContractSize > toPay) intervalContractSize = toPay;\r\n\r\n // amount of premium paid to underwriter\r\n uint256 intervalPremium = (premium * intervalContractSize) / toPay;\r\n premium -= intervalPremium;\r\n toPay -= intervalContractSize;\r\n _addUserTVL(l, underwriter, isCall, intervalPremium);\r\n\r\n // burn free liquidity tokens from underwriter\r\n _burn(\r\n underwriter,\r\n freeLiqTokenId,\r\n intervalContractSize - intervalPremium\r\n );\r\n\r\n if (isCall == false) {\r\n // For PUT, conversion to contract amount is done here (Prior to this line, it is token amount)\r\n intervalContractSize = l.fromBaseToUnderlyingDecimals(\r\n strike64x64.inv().mulu(intervalContractSize)\r\n );\r\n }\r\n\r\n // mint short option tokens for underwriter\r\n // toPay == 0 ? contractSize : intervalContractSize : To prevent minting less than amount,\r\n // because of rounding (Can happen for put, because of fixed point precision)\r\n _mint(\r\n underwriter,\r\n shortTokenId,\r\n toPay == 0 ? contractSize : intervalContractSize\r\n );\r\n\r\n emit Underwrite(\r\n underwriter,\r\n buyer,\r\n shortTokenId,\r\n toPay == 0 ? contractSize : intervalContractSize,\r\n intervalPremium,\r\n false\r\n );\r\n\r\n contractSize -= intervalContractSize;\r\n }\r\n }\r\n\r\n function _burnLongTokenLoop(\r\n uint256 contractSize,\r\n uint256 exerciseValue,\r\n uint256 longTokenId,\r\n bool isCall\r\n ) internal returns (uint256 totalFee) {\r\n EnumerableSet.AddressSet storage holders = ERC1155EnumerableStorage\r\n .layout()\r\n .accountsByToken[longTokenId];\r\n\r\n while (contractSize > 0) {\r\n address longTokenHolder = holders.at(holders.length() - 1);\r\n\r\n uint256 intervalContractSize = _balanceOf(\r\n longTokenHolder,\r\n longTokenId\r\n );\r\n if (intervalContractSize > contractSize)\r\n intervalContractSize = contractSize;\r\n\r\n uint256 intervalExerciseValue;\r\n\r\n uint256 fee;\r\n if (exerciseValue > 0) {\r\n intervalExerciseValue =\r\n (exerciseValue * intervalContractSize) /\r\n contractSize;\r\n\r\n fee = _getFeeWithDiscount(\r\n longTokenHolder,\r\n FEE_64x64.mulu(intervalExerciseValue)\r\n );\r\n totalFee += fee;\r\n\r\n exerciseValue -= intervalExerciseValue;\r\n _pushTo(\r\n longTokenHolder,\r\n _getPoolToken(isCall),\r\n intervalExerciseValue - fee\r\n );\r\n }\r\n\r\n contractSize -= intervalContractSize;\r\n\r\n emit Exercise(\r\n longTokenHolder,\r\n longTokenId,\r\n intervalContractSize,\r\n intervalExerciseValue - fee,\r\n fee\r\n );\r\n\r\n _burn(longTokenHolder, longTokenId, intervalContractSize);\r\n }\r\n }\r\n\r\n function _burnShortTokenLoop(\r\n uint256 contractSize,\r\n uint256 exerciseValue,\r\n uint256 shortTokenId,\r\n bool isCall\r\n ) internal returns (uint256 totalFee) {\r\n EnumerableSet.AddressSet storage underwriters = ERC1155EnumerableStorage\r\n .layout()\r\n .accountsByToken[shortTokenId];\r\n (, , int128 strike64x64) = PoolStorage.parseTokenId(shortTokenId);\r\n\r\n while (contractSize > 0) {\r\n address underwriter = underwriters.at(underwriters.length() - 1);\r\n\r\n // amount of liquidity provided by underwriter\r\n uint256 intervalContractSize = _balanceOf(\r\n underwriter,\r\n shortTokenId\r\n );\r\n if (intervalContractSize > contractSize)\r\n intervalContractSize = contractSize;\r\n\r\n // amount of value claimed by buyer\r\n uint256 intervalExerciseValue = (exerciseValue *\r\n intervalContractSize) / contractSize;\r\n exerciseValue -= intervalExerciseValue;\r\n contractSize -= intervalContractSize;\r\n\r\n uint256 freeLiq = isCall\r\n ? intervalContractSize - intervalExerciseValue\r\n : PoolStorage.layout().fromUnderlyingToBaseDecimals(\r\n strike64x64.mulu(intervalContractSize)\r\n ) - intervalExerciseValue;\r\n\r\n uint256 fee = _getFeeWithDiscount(\r\n underwriter,\r\n FEE_64x64.mulu(freeLiq)\r\n );\r\n totalFee += fee;\r\n\r\n uint256 tvlToSubtract = intervalExerciseValue;\r\n\r\n // mint free liquidity tokens for underwriter\r\n if (\r\n PoolStorage.layout().getReinvestmentStatus(underwriter, isCall)\r\n ) {\r\n _addToDepositQueue(underwriter, freeLiq - fee, isCall);\r\n tvlToSubtract += fee;\r\n } else {\r\n _mint(\r\n underwriter,\r\n _getReservedLiquidityTokenId(isCall),\r\n freeLiq - fee\r\n );\r\n tvlToSubtract += freeLiq;\r\n }\r\n\r\n _subUserTVL(\r\n PoolStorage.layout(),\r\n underwriter,\r\n isCall,\r\n tvlToSubtract\r\n );\r\n\r\n // burn short option tokens from underwriter\r\n _burn(underwriter, shortTokenId, intervalContractSize);\r\n\r\n emit AssignExercise(\r\n underwriter,\r\n shortTokenId,\r\n freeLiq - fee,\r\n intervalContractSize,\r\n fee\r\n );\r\n }\r\n }\r\n\r\n function _addToDepositQueue(\r\n address account,\r\n uint256 amount,\r\n bool isCallPool\r\n ) internal {\r\n PoolStorage.Layout storage l = PoolStorage.layout();\r\n\r\n _mint(account, _getFreeLiquidityTokenId(isCallPool), amount);\r\n\r\n uint256 nextBatch = (block.timestamp / BATCHING_PERIOD) *\r\n BATCHING_PERIOD +\r\n BATCHING_PERIOD;\r\n l.pendingDeposits[account][nextBatch][isCallPool] += amount;\r\n\r\n PoolStorage.BatchData storage batchData = l.nextDeposits[isCallPool];\r\n batchData.totalPendingDeposits += amount;\r\n batchData.eta = nextBatch;\r\n }\r\n\r\n function _processPendingDeposits(PoolStorage.Layout storage l, bool isCall)\r\n internal\r\n {\r\n PoolStorage.BatchData storage data = l.nextDeposits[isCall];\r\n\r\n if (data.eta == 0 || block.timestamp < data.eta) return;\r\n\r\n int128 oldLiquidity64x64 = l.totalFreeLiquiditySupply64x64(isCall);\r\n\r\n _setCLevel(\r\n l,\r\n oldLiquidity64x64,\r\n oldLiquidity64x64.add(\r\n ABDKMath64x64Token.fromDecimals(\r\n data.totalPendingDeposits,\r\n l.getTokenDecimals(isCall)\r\n )\r\n ),\r\n isCall\r\n );\r\n\r\n delete l.nextDeposits[isCall];\r\n }\r\n\r\n function _getFreeLiquidityTokenId(bool isCall)\r\n internal\r\n view\r\n returns (uint256 freeLiqTokenId)\r\n {\r\n freeLiqTokenId = isCall\r\n ? UNDERLYING_FREE_LIQ_TOKEN_ID\r\n : BASE_FREE_LIQ_TOKEN_ID;\r\n }\r\n\r\n function _getReservedLiquidityTokenId(bool isCall)\r\n internal\r\n view\r\n returns (uint256 reservedLiqTokenId)\r\n {\r\n reservedLiqTokenId = isCall\r\n ? UNDERLYING_RESERVED_LIQ_TOKEN_ID\r\n : BASE_RESERVED_LIQ_TOKEN_ID;\r\n }\r\n\r\n function _getPoolToken(bool isCall) internal view returns (address token) {\r\n token = isCall\r\n ? PoolStorage.layout().underlying\r\n : PoolStorage.layout().base;\r\n }\r\n\r\n function _getTokenType(bool isCall, bool isLong)\r\n internal\r\n pure\r\n returns (PoolStorage.TokenType tokenType)\r\n {\r\n if (isCall) {\r\n tokenType = isLong\r\n ? PoolStorage.TokenType.LONG_CALL\r\n : PoolStorage.TokenType.SHORT_CALL;\r\n } else {\r\n tokenType = isLong\r\n ? PoolStorage.TokenType.LONG_PUT\r\n : PoolStorage.TokenType.SHORT_PUT;\r\n }\r\n }\r\n\r\n function _getMinimumAmount(PoolStorage.Layout storage l, bool isCall)\r\n internal\r\n view\r\n returns (uint256 minimumAmount)\r\n {\r\n minimumAmount = isCall ? l.underlyingMinimum : l.baseMinimum;\r\n }\r\n\r\n function _getPoolCapAmount(PoolStorage.Layout storage l, bool isCall)\r\n internal\r\n view\r\n returns (uint256 poolCapAmount)\r\n {\r\n poolCapAmount = isCall ? l.underlyingPoolCap : l.basePoolCap;\r\n }\r\n\r\n function _setCLevel(\r\n PoolStorage.Layout storage l,\r\n int128 oldLiquidity64x64,\r\n int128 newLiquidity64x64,\r\n bool isCallPool\r\n ) internal {\r\n int128 oldCLevel64x64 = l.getDecayAdjustedCLevel64x64(isCallPool);\r\n\r\n int128 cLevel64x64 = l.applyCLevelLiquidityChangeAdjustment(\r\n oldCLevel64x64,\r\n oldLiquidity64x64,\r\n newLiquidity64x64,\r\n isCallPool\r\n );\r\n\r\n l.setCLevel(cLevel64x64, isCallPool);\r\n\r\n emit UpdateCLevel(\r\n isCallPool,\r\n cLevel64x64,\r\n oldLiquidity64x64,\r\n newLiquidity64x64\r\n );\r\n }\r\n\r\n /**\r\n * @notice calculate and store updated market state\r\n * @param l storage layout struct\r\n * @return newPrice64x64 64x64 fixed point representation of current spot price\r\n */\r\n function _update(PoolStorage.Layout storage l)\r\n internal\r\n returns (int128 newPrice64x64)\r\n {\r\n if (l.updatedAt == block.timestamp) {\r\n return (l.getPriceUpdate(block.timestamp));\r\n }\r\n\r\n newPrice64x64 = l.fetchPriceUpdate();\r\n\r\n if (l.getPriceUpdate(block.timestamp) == 0) {\r\n l.setPriceUpdate(block.timestamp, newPrice64x64);\r\n }\r\n\r\n l.updatedAt = block.timestamp;\r\n\r\n _processPendingDeposits(l, true);\r\n _processPendingDeposits(l, false);\r\n }\r\n\r\n /**\r\n * @notice transfer ERC20 tokens to message sender\r\n * @param token ERC20 token address\r\n * @param amount quantity of token to transfer\r\n */\r\n function _pushTo(\r\n address to,\r\n address token,\r\n uint256 amount\r\n ) internal {\r\n if (amount == 0) return;\r\n\r\n require(IERC20(token).transfer(to, amount), \"ERC20 transfer failed\");\r\n }\r\n\r\n /**\r\n * @notice transfer ERC20 tokens from message sender\r\n * @param from address from which tokens are pulled from\r\n * @param token ERC20 token address\r\n * @param amount quantity of token to transfer\r\n * @param skipWethDeposit if false, will not try to deposit weth from attach eth\r\n */\r\n function _pullFrom(\r\n address from,\r\n address token,\r\n uint256 amount,\r\n bool skipWethDeposit\r\n ) internal {\r\n if (!skipWethDeposit) {\r\n if (token == WETH_ADDRESS) {\r\n if (msg.value > 0) {\r\n if (msg.value > amount) {\r\n IWETH(WETH_ADDRESS).deposit{value: amount}();\r\n\r\n (bool success, ) = payable(msg.sender).call{\r\n value: msg.value - amount\r\n }(\"\");\r\n\r\n require(success, \"ETH refund failed\");\r\n\r\n amount = 0;\r\n } else {\r\n unchecked {\r\n amount -= msg.value;\r\n }\r\n\r\n IWETH(WETH_ADDRESS).deposit{value: msg.value}();\r\n }\r\n }\r\n } else {\r\n require(msg.value == 0, \"not WETH deposit\");\r\n }\r\n }\r\n\r\n if (amount > 0) {\r\n require(\r\n IERC20(token).transferFrom(from, address(this), amount),\r\n \"ERC20 transfer failed\"\r\n );\r\n }\r\n }\r\n\r\n function _mint(\r\n address account,\r\n uint256 tokenId,\r\n uint256 amount\r\n ) internal {\r\n _mint(account, tokenId, amount, \"\");\r\n }\r\n\r\n function _addUserTVL(\r\n PoolStorage.Layout storage l,\r\n address user,\r\n bool isCallPool,\r\n uint256 amount\r\n ) internal {\r\n uint256 userTVL = l.userTVL[user][isCallPool];\r\n uint256 totalTVL = l.totalTVL[isCallPool];\r\n\r\n IPremiaMining(PREMIA_MINING_ADDRESS).allocatePending(\r\n user,\r\n address(this),\r\n isCallPool,\r\n userTVL,\r\n userTVL + amount,\r\n totalTVL\r\n );\r\n\r\n l.userTVL[user][isCallPool] = userTVL + amount;\r\n l.totalTVL[isCallPool] = totalTVL + amount;\r\n }\r\n\r\n function _subUserTVL(\r\n PoolStorage.Layout storage l,\r\n address user,\r\n bool isCallPool,\r\n uint256 amount\r\n ) internal {\r\n uint256 userTVL = l.userTVL[user][isCallPool];\r\n uint256 totalTVL = l.totalTVL[isCallPool];\r\n\r\n IPremiaMining(PREMIA_MINING_ADDRESS).allocatePending(\r\n user,\r\n address(this),\r\n isCallPool,\r\n userTVL,\r\n userTVL - amount,\r\n totalTVL\r\n );\r\n l.userTVL[user][isCallPool] = userTVL - amount;\r\n l.totalTVL[isCallPool] = totalTVL - amount;\r\n }\r\n\r\n /**\r\n * @notice ERC1155 hook: track eligible underwriters\r\n * @param operator transaction sender\r\n * @param from token sender\r\n * @param to token receiver\r\n * @param ids token ids transferred\r\n * @param amounts token quantities transferred\r\n * @param data data payload\r\n */\r\n function _beforeTokenTransfer(\r\n address operator,\r\n address from,\r\n address to,\r\n uint256[] memory ids,\r\n uint256[] memory amounts,\r\n bytes memory data\r\n ) internal virtual override {\r\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\r\n\r\n PoolStorage.Layout storage l = PoolStorage.layout();\r\n\r\n for (uint256 i; i < ids.length; i++) {\r\n uint256 id = ids[i];\r\n uint256 amount = amounts[i];\r\n\r\n if (amount == 0) continue;\r\n\r\n if (from == address(0)) {\r\n l.tokenIds.add(id);\r\n }\r\n\r\n if (\r\n to == address(0) &&\r\n ERC1155EnumerableStorage.layout().totalSupply[id] == 0\r\n ) {\r\n l.tokenIds.remove(id);\r\n }\r\n\r\n // prevent transfer of free and reserved liquidity during waiting period\r\n\r\n if (\r\n id == UNDERLYING_FREE_LIQ_TOKEN_ID ||\r\n id == BASE_FREE_LIQ_TOKEN_ID ||\r\n id == UNDERLYING_RESERVED_LIQ_TOKEN_ID ||\r\n id == BASE_RESERVED_LIQ_TOKEN_ID\r\n ) {\r\n if (from != address(0) && to != address(0)) {\r\n bool isCallPool = id == UNDERLYING_FREE_LIQ_TOKEN_ID ||\r\n id == UNDERLYING_RESERVED_LIQ_TOKEN_ID;\r\n\r\n require(\r\n l.depositedAt[from][isCallPool] + (1 days) <\r\n block.timestamp,\r\n \"liq lock 1d\"\r\n );\r\n }\r\n }\r\n\r\n if (\r\n id == UNDERLYING_FREE_LIQ_TOKEN_ID ||\r\n id == BASE_FREE_LIQ_TOKEN_ID\r\n ) {\r\n bool isCallPool = id == UNDERLYING_FREE_LIQ_TOKEN_ID;\r\n uint256 minimum = _getMinimumAmount(l, isCallPool);\r\n\r\n if (from != address(0)) {\r\n uint256 balance = _balanceOf(from, id);\r\n\r\n if (balance > minimum && balance <= amount + minimum) {\r\n require(\r\n balance -\r\n l.pendingDeposits[from][\r\n l.nextDeposits[isCallPool].eta\r\n ][isCallPool] >=\r\n amount,\r\n \"Insuf balance\"\r\n );\r\n l.removeUnderwriter(from, isCallPool);\r\n }\r\n\r\n if (to != address(0)) {\r\n _subUserTVL(l, from, isCallPool, amounts[i]);\r\n _addUserTVL(l, to, isCallPool, amounts[i]);\r\n }\r\n }\r\n\r\n if (to != address(0)) {\r\n uint256 balance = _balanceOf(to, id);\r\n\r\n if (balance <= minimum && balance + amount > minimum) {\r\n l.addUnderwriter(to, isCallPool);\r\n }\r\n }\r\n }\r\n\r\n // Update userTVL on SHORT options transfers\r\n (\r\n PoolStorage.TokenType tokenType,\r\n ,\r\n int128 strike64x64\r\n ) = PoolStorage.parseTokenId(id);\r\n\r\n if (\r\n (from != address(0) && to != address(0)) &&\r\n (tokenType == PoolStorage.TokenType.SHORT_CALL ||\r\n tokenType == PoolStorage.TokenType.SHORT_PUT)\r\n ) {\r\n bool isCall = tokenType == PoolStorage.TokenType.SHORT_CALL;\r\n uint256 collateral = isCall\r\n ? amount\r\n : l.fromUnderlyingToBaseDecimals(strike64x64.mulu(amount));\r\n\r\n _subUserTVL(l, from, isCall, collateral);\r\n _addUserTVL(l, to, isCall, collateral);\r\n }\r\n }\r\n }\r\n}\r\n" - }, - "@solidstate/contracts/token/ERC1155/base/ERC1155BaseStorage.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nlibrary ERC1155BaseStorage {\n struct Layout {\n mapping(uint256 => mapping(address => uint256)) balances;\n mapping(address => mapping(address => bool)) operatorApprovals;\n }\n\n bytes32 internal constant STORAGE_SLOT =\n keccak256('solidstate.contracts.storage.ERC1155Base');\n\n function layout() internal pure returns (Layout storage l) {\n bytes32 slot = STORAGE_SLOT;\n assembly {\n l.slot := slot\n }\n }\n}\n" - }, - "@solidstate/contracts/utils/EnumerableSet.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title Set implementation with enumeration functions\n * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts (MIT license)\n */\nlibrary EnumerableSet {\n struct Set {\n bytes32[] _values;\n // 1-indexed to allow 0 to signify nonexistence\n mapping(bytes32 => uint256) _indexes;\n }\n\n struct Bytes32Set {\n Set _inner;\n }\n\n struct AddressSet {\n Set _inner;\n }\n\n struct UintSet {\n Set _inner;\n }\n\n function at(Bytes32Set storage set, uint256 index)\n internal\n view\n returns (bytes32)\n {\n return _at(set._inner, index);\n }\n\n function at(AddressSet storage set, uint256 index)\n internal\n view\n returns (address)\n {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n function at(UintSet storage set, uint256 index)\n internal\n view\n returns (uint256)\n {\n return uint256(_at(set._inner, index));\n }\n\n function contains(Bytes32Set storage set, bytes32 value)\n internal\n view\n returns (bool)\n {\n return _contains(set._inner, value);\n }\n\n function contains(AddressSet storage set, address value)\n internal\n view\n returns (bool)\n {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n function contains(UintSet storage set, uint256 value)\n internal\n view\n returns (bool)\n {\n return _contains(set._inner, bytes32(value));\n }\n\n function indexOf(Bytes32Set storage set, bytes32 value)\n internal\n view\n returns (uint256)\n {\n return _indexOf(set._inner, value);\n }\n\n function indexOf(AddressSet storage set, address value)\n internal\n view\n returns (uint256)\n {\n return _indexOf(set._inner, bytes32(uint256(uint160(value))));\n }\n\n function indexOf(UintSet storage set, uint256 value)\n internal\n view\n returns (uint256)\n {\n return _indexOf(set._inner, bytes32(value));\n }\n\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n function add(Bytes32Set storage set, bytes32 value)\n internal\n returns (bool)\n {\n return _add(set._inner, value);\n }\n\n function add(AddressSet storage set, address value)\n internal\n returns (bool)\n {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n function remove(Bytes32Set storage set, bytes32 value)\n internal\n returns (bool)\n {\n return _remove(set._inner, value);\n }\n\n function remove(AddressSet storage set, address value)\n internal\n returns (bool)\n {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n function remove(UintSet storage set, uint256 value)\n internal\n returns (bool)\n {\n return _remove(set._inner, bytes32(value));\n }\n\n function _at(Set storage set, uint256 index)\n private\n view\n returns (bytes32)\n {\n require(\n set._values.length > index,\n 'EnumerableSet: index out of bounds'\n );\n return set._values[index];\n }\n\n function _contains(Set storage set, bytes32 value)\n private\n view\n returns (bool)\n {\n return set._indexes[value] != 0;\n }\n\n function _indexOf(Set storage set, bytes32 value)\n private\n view\n returns (uint256)\n {\n unchecked {\n return set._indexes[value] - 1;\n }\n }\n\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n uint256 index = valueIndex - 1;\n bytes32 last = set._values[set._values.length - 1];\n\n // move last value to now-vacant index\n\n set._values[index] = last;\n set._indexes[last] = index + 1;\n\n // clear last index\n\n set._values.pop();\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n}\n" - }, - "contracts/mining/PremiaMiningStorage.sol": { - "content": "// SPDX-License-Identifier: BUSL-1.1\r\n// For further clarification please see https://license.premia.legal\r\n\r\npragma solidity ^0.8.0;\r\n\r\nlibrary PremiaMiningStorage {\r\n bytes32 internal constant STORAGE_SLOT =\r\n keccak256(\"premia.contracts.storage.PremiaMining\");\r\n\r\n // Info of each pool.\r\n struct PoolInfo {\r\n uint256 allocPoint; // How many allocation points assigned to this pool. PREMIA to distribute per block.\r\n uint256 lastRewardTimestamp; // Last timestamp that PREMIA distribution occurs\r\n uint256 accPremiaPerShare; // Accumulated PREMIA per share, times 1e12. See below.\r\n }\r\n\r\n // Info of each user.\r\n struct UserInfo {\r\n uint256 reward; // Total allocated unclaimed reward\r\n uint256 rewardDebt; // Reward debt. See explanation below.\r\n //\r\n // We do some fancy math here. Basically, any point in time, the amount of PREMIA\r\n // entitled to a user but is pending to be distributed is:\r\n //\r\n // pending reward = (user.amount * pool.accPremiaPerShare) - user.rewardDebt\r\n //\r\n // Whenever a user deposits or withdraws LP tokens to a pool. Here's what happens:\r\n // 1. The pool's `accPremiaPerShare` (and `lastRewardBlock`) gets updated.\r\n // 2. User receives the pending reward sent to his/her address.\r\n // 3. User's `amount` gets updated.\r\n // 4. User's `rewardDebt` gets updated.\r\n }\r\n\r\n struct Layout {\r\n // Total PREMIA left to distribute\r\n uint256 premiaAvailable;\r\n // Amount of premia distributed per year\r\n uint256 premiaPerYear;\r\n // pool -> isCallPool -> PoolInfo\r\n mapping(address => mapping(bool => PoolInfo)) poolInfo;\r\n // pool -> isCallPool -> user -> UserInfo\r\n mapping(address => mapping(bool => mapping(address => UserInfo))) userInfo;\r\n // Total allocation points. Must be the sum of all allocation points in all pools.\r\n uint256 totalAllocPoint;\r\n }\r\n\r\n function layout() internal pure returns (Layout storage l) {\r\n bytes32 slot = STORAGE_SLOT;\r\n assembly {\r\n l.slot := slot\r\n }\r\n }\r\n}\r\n" - }, - "@solidstate/contracts/utils/IWETH.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IERC20 } from '../token/ERC20/IERC20.sol';\nimport { IERC20Metadata } from '../token/ERC20/metadata/IERC20Metadata.sol';\n\n/**\n * @title WETH (Wrapped ETH) interface\n */\ninterface IWETH is IERC20, IERC20Metadata {\n /**\n * @notice convert ETH to WETH\n */\n function deposit() external payable;\n\n /**\n * @notice convert WETH to ETH\n * @dev if caller is a contract, it should have a fallback or receive function\n * @param amount quantity of WETH to convert, denominated in wei\n */\n function withdraw(uint256 amount) external;\n}\n" - }, - "@solidstate/contracts/token/ERC1155/IERC1155Internal.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IERC165 } from '../../introspection/IERC165.sol';\n\n/**\n * @notice Partial ERC1155 interface needed by internal functions\n */\ninterface IERC1155Internal {\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 value\n );\n\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n event ApprovalForAll(\n address indexed account,\n address indexed operator,\n bool approved\n );\n}\n" - }, - "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorV3Interface {\n\n function decimals()\n external\n view\n returns (\n uint8\n );\n\n function description()\n external\n view\n returns (\n string memory\n );\n\n function version()\n external\n view\n returns (\n uint256\n );\n\n // getRoundData and latestRoundData should both raise \"No data present\"\n // if they do not have data to report, instead of returning unset values\n // which could be misinterpreted as actual reported values.\n function getRoundData(\n uint80 _roundId\n )\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n function latestRoundData()\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n}\n" - }, - "@solidstate/contracts/access/OwnableStorage.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nlibrary OwnableStorage {\n struct Layout {\n address owner;\n }\n\n bytes32 internal constant STORAGE_SLOT =\n keccak256('solidstate.contracts.storage.Ownable');\n\n function layout() internal pure returns (Layout storage l) {\n bytes32 slot = STORAGE_SLOT;\n assembly {\n l.slot := slot\n }\n }\n\n function setOwner(Layout storage l, address owner) internal {\n l.owner = owner;\n }\n}\n" - } - }, - "settings": { - "optimizer": { - "enabled": true, - "runs": 200 - }, - "outputSelection": { - "*": { - "*": [ - "evm.bytecode", - "evm.deployedBytecode", - "devdoc", - "userdoc", - "metadata", - "abi" - ] - } - }, - "libraries": { - "contracts/libraries/OptionMath.sol": { - "OptionMath": "0x0f6e8ef18fb5bb61d545fee60f779d8aed60408f" - } - } - } - }, - "ABI": "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"ivolOracle\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"weth\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"premiaMining\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeReceiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeDiscountAddress\",\"type\":\"address\"},{\"internalType\":\"int128\",\"name\":\"fee64x64\",\"type\":\"int128\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"shortTokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Annihilate\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"underwriter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"shortTokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"freedAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"intervalContractSize\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"name\":\"AssignExercise\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isCallPool\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"longTokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"contractSize\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"exerciseValue\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"name\":\"Exercise\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"isCallPool\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeeWithdrawal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"longTokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"contractSize\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"baseCost\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeCost\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"int128\",\"name\":\"spot64x64\",\"type\":\"int128\"}],\"name\":\"Purchase\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"}],\"name\":\"TransferBatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"TransferSingle\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"underwriter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"longReceiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"shortTokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"intervalContractSize\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"intervalPremium\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isManualUnderwrite\",\"type\":\"bool\"}],\"name\":\"Underwrite\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"isCall\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"int128\",\"name\":\"cLevel64x64\",\"type\":\"int128\"},{\"indexed\":false,\"internalType\":\"int128\",\"name\":\"oldLiquidity64x64\",\"type\":\"int128\"},{\"indexed\":false,\"internalType\":\"int128\",\"name\":\"newLiquidity64x64\",\"type\":\"int128\"}],\"name\":\"UpdateCLevel\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"int128\",\"name\":\"steepness64x64\",\"type\":\"int128\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isCallPool\",\"type\":\"bool\"}],\"name\":\"UpdateSteepness\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isCallPool\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"depositedAt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"holder\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"longTokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"contractSize\",\"type\":\"uint256\"}],\"name\":\"exerciseFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"longTokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"contractSize\",\"type\":\"uint256\"}],\"name\":\"processExpired\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - "ContractName": "PoolExercise", - "CompilerVersion": "v0.8.9+commit.e5eed63a", - "OptimizationUsed": 1, - "Runs": 200, - "ConstructorArguments": "0x0000000000000000000000003a87bb29b984d672664aa1dd2d19d2e8b24f0f2a000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000009abb27581c2e46a114f8c367355851e0580e9703000000000000000000000000c4b2c51f969e0713e799de73b7f130fb7bb604cf000000000000000000000000f1bb87563a122211d40d393ebf1c633c330377f900000000000000000000000000000000000000000000000007ae147ae147ae14", - "EVMVersion": "Default", - "Library": "", - "LicenseType": "", - "Proxy": 0, - "SwarmSource": "" - } -] \ No newline at end of file +[{"SourceCode":{"language":"Solidity","sources":{"@solidstate/contracts/token/ERC1155/base/ERC1155Base.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IERC1155 } from '../IERC1155.sol';\nimport { IERC1155Receiver } from '../IERC1155Receiver.sol';\nimport { ERC1155BaseInternal, ERC1155BaseStorage } from './ERC1155BaseInternal.sol';\n\n/**\n * @title Base ERC1155 contract\n * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts/ (MIT license)\n */\nabstract contract ERC1155Base is IERC1155, ERC1155BaseInternal {\n /**\n * @inheritdoc IERC1155\n */\n function balanceOf(address account, uint256 id)\n public\n view\n virtual\n override\n returns (uint256)\n {\n return _balanceOf(account, id);\n }\n\n /**\n * @inheritdoc IERC1155\n */\n function balanceOfBatch(address[] memory accounts, uint256[] memory ids)\n public\n view\n virtual\n override\n returns (uint256[] memory)\n {\n require(\n accounts.length == ids.length,\n 'ERC1155: accounts and ids length mismatch'\n );\n\n mapping(uint256 => mapping(address => uint256))\n storage balances = ERC1155BaseStorage.layout().balances;\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n unchecked {\n for (uint256 i; i < accounts.length; i++) {\n require(\n accounts[i] != address(0),\n 'ERC1155: batch balance query for the zero address'\n );\n batchBalances[i] = balances[ids[i]][accounts[i]];\n }\n }\n\n return batchBalances;\n }\n\n /**\n * @inheritdoc IERC1155\n */\n function isApprovedForAll(address account, address operator)\n public\n view\n virtual\n override\n returns (bool)\n {\n return ERC1155BaseStorage.layout().operatorApprovals[account][operator];\n }\n\n /**\n * @inheritdoc IERC1155\n */\n function setApprovalForAll(address operator, bool status)\n public\n virtual\n override\n {\n require(\n msg.sender != operator,\n 'ERC1155: setting approval status for self'\n );\n ERC1155BaseStorage.layout().operatorApprovals[msg.sender][\n operator\n ] = status;\n emit ApprovalForAll(msg.sender, operator, status);\n }\n\n /**\n * @inheritdoc IERC1155\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == msg.sender || isApprovedForAll(from, msg.sender),\n 'ERC1155: caller is not owner nor approved'\n );\n _safeTransfer(msg.sender, from, to, id, amount, data);\n }\n\n /**\n * @inheritdoc IERC1155\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == msg.sender || isApprovedForAll(from, msg.sender),\n 'ERC1155: caller is not owner nor approved'\n );\n _safeTransferBatch(msg.sender, from, to, ids, amounts, data);\n }\n}\n"},"@solidstate/contracts/introspection/IERC165.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC165 interface registration interface\n * @dev see https://eips.ethereum.org/EIPS/eip-165\n */\ninterface IERC165 {\n /**\n * @notice query whether contract has registered support for given interface\n * @param interfaceId interface id\n * @return bool whether interface is supported\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"},"abdk-libraries-solidity/ABDKMath64x64.sol":{"content":"// SPDX-License-Identifier: BSD-4-Clause\n/*\n * ABDK Math 64.64 Smart Contract Library. Copyright © 2019 by ABDK Consulting.\n * Author: Mikhail Vladimirov \n */\npragma solidity ^0.8.0;\n\n/**\n * Smart contract library of mathematical functions operating with signed\n * 64.64-bit fixed point numbers. Signed 64.64-bit fixed point number is\n * basically a simple fraction whose numerator is signed 128-bit integer and\n * denominator is 2^64. As long as denominator is always the same, there is no\n * need to store it, thus in Solidity signed 64.64-bit fixed point numbers are\n * represented by int128 type holding only the numerator.\n */\nlibrary ABDKMath64x64 {\n /*\n * Minimum value signed 64.64-bit fixed point number may have. \n */\n int128 private constant MIN_64x64 = -0x80000000000000000000000000000000;\n\n /*\n * Maximum value signed 64.64-bit fixed point number may have. \n */\n int128 private constant MAX_64x64 = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n\n /**\n * Convert signed 256-bit integer number into signed 64.64-bit fixed point\n * number. Revert on overflow.\n *\n * @param x signed 256-bit integer number\n * @return signed 64.64-bit fixed point number\n */\n function fromInt (int256 x) internal pure returns (int128) {\n unchecked {\n require (x >= -0x8000000000000000 && x <= 0x7FFFFFFFFFFFFFFF);\n return int128 (x << 64);\n }\n }\n\n /**\n * Convert signed 64.64 fixed point number into signed 64-bit integer number\n * rounding down.\n *\n * @param x signed 64.64-bit fixed point number\n * @return signed 64-bit integer number\n */\n function toInt (int128 x) internal pure returns (int64) {\n unchecked {\n return int64 (x >> 64);\n }\n }\n\n /**\n * Convert unsigned 256-bit integer number into signed 64.64-bit fixed point\n * number. Revert on overflow.\n *\n * @param x unsigned 256-bit integer number\n * @return signed 64.64-bit fixed point number\n */\n function fromUInt (uint256 x) internal pure returns (int128) {\n unchecked {\n require (x <= 0x7FFFFFFFFFFFFFFF);\n return int128 (int256 (x << 64));\n }\n }\n\n /**\n * Convert signed 64.64 fixed point number into unsigned 64-bit integer\n * number rounding down. Revert on underflow.\n *\n * @param x signed 64.64-bit fixed point number\n * @return unsigned 64-bit integer number\n */\n function toUInt (int128 x) internal pure returns (uint64) {\n unchecked {\n require (x >= 0);\n return uint64 (uint128 (x >> 64));\n }\n }\n\n /**\n * Convert signed 128.128 fixed point number into signed 64.64-bit fixed point\n * number rounding down. Revert on overflow.\n *\n * @param x signed 128.128-bin fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function from128x128 (int256 x) internal pure returns (int128) {\n unchecked {\n int256 result = x >> 64;\n require (result >= MIN_64x64 && result <= MAX_64x64);\n return int128 (result);\n }\n }\n\n /**\n * Convert signed 64.64 fixed point number into signed 128.128 fixed point\n * number.\n *\n * @param x signed 64.64-bit fixed point number\n * @return signed 128.128 fixed point number\n */\n function to128x128 (int128 x) internal pure returns (int256) {\n unchecked {\n return int256 (x) << 64;\n }\n }\n\n /**\n * Calculate x + y. Revert on overflow.\n *\n * @param x signed 64.64-bit fixed point number\n * @param y signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function add (int128 x, int128 y) internal pure returns (int128) {\n unchecked {\n int256 result = int256(x) + y;\n require (result >= MIN_64x64 && result <= MAX_64x64);\n return int128 (result);\n }\n }\n\n /**\n * Calculate x - y. Revert on overflow.\n *\n * @param x signed 64.64-bit fixed point number\n * @param y signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function sub (int128 x, int128 y) internal pure returns (int128) {\n unchecked {\n int256 result = int256(x) - y;\n require (result >= MIN_64x64 && result <= MAX_64x64);\n return int128 (result);\n }\n }\n\n /**\n * Calculate x * y rounding down. Revert on overflow.\n *\n * @param x signed 64.64-bit fixed point number\n * @param y signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function mul (int128 x, int128 y) internal pure returns (int128) {\n unchecked {\n int256 result = int256(x) * y >> 64;\n require (result >= MIN_64x64 && result <= MAX_64x64);\n return int128 (result);\n }\n }\n\n /**\n * Calculate x * y rounding towards zero, where x is signed 64.64 fixed point\n * number and y is signed 256-bit integer number. Revert on overflow.\n *\n * @param x signed 64.64 fixed point number\n * @param y signed 256-bit integer number\n * @return signed 256-bit integer number\n */\n function muli (int128 x, int256 y) internal pure returns (int256) {\n unchecked {\n if (x == MIN_64x64) {\n require (y >= -0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF &&\n y <= 0x1000000000000000000000000000000000000000000000000);\n return -y << 63;\n } else {\n bool negativeResult = false;\n if (x < 0) {\n x = -x;\n negativeResult = true;\n }\n if (y < 0) {\n y = -y; // We rely on overflow behavior here\n negativeResult = !negativeResult;\n }\n uint256 absoluteResult = mulu (x, uint256 (y));\n if (negativeResult) {\n require (absoluteResult <=\n 0x8000000000000000000000000000000000000000000000000000000000000000);\n return -int256 (absoluteResult); // We rely on overflow behavior here\n } else {\n require (absoluteResult <=\n 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);\n return int256 (absoluteResult);\n }\n }\n }\n }\n\n /**\n * Calculate x * y rounding down, where x is signed 64.64 fixed point number\n * and y is unsigned 256-bit integer number. Revert on overflow.\n *\n * @param x signed 64.64 fixed point number\n * @param y unsigned 256-bit integer number\n * @return unsigned 256-bit integer number\n */\n function mulu (int128 x, uint256 y) internal pure returns (uint256) {\n unchecked {\n if (y == 0) return 0;\n\n require (x >= 0);\n\n uint256 lo = (uint256 (int256 (x)) * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) >> 64;\n uint256 hi = uint256 (int256 (x)) * (y >> 128);\n\n require (hi <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);\n hi <<= 64;\n\n require (hi <=\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - lo);\n return hi + lo;\n }\n }\n\n /**\n * Calculate x / y rounding towards zero. Revert on overflow or when y is\n * zero.\n *\n * @param x signed 64.64-bit fixed point number\n * @param y signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function div (int128 x, int128 y) internal pure returns (int128) {\n unchecked {\n require (y != 0);\n int256 result = (int256 (x) << 64) / y;\n require (result >= MIN_64x64 && result <= MAX_64x64);\n return int128 (result);\n }\n }\n\n /**\n * Calculate x / y rounding towards zero, where x and y are signed 256-bit\n * integer numbers. Revert on overflow or when y is zero.\n *\n * @param x signed 256-bit integer number\n * @param y signed 256-bit integer number\n * @return signed 64.64-bit fixed point number\n */\n function divi (int256 x, int256 y) internal pure returns (int128) {\n unchecked {\n require (y != 0);\n\n bool negativeResult = false;\n if (x < 0) {\n x = -x; // We rely on overflow behavior here\n negativeResult = true;\n }\n if (y < 0) {\n y = -y; // We rely on overflow behavior here\n negativeResult = !negativeResult;\n }\n uint128 absoluteResult = divuu (uint256 (x), uint256 (y));\n if (negativeResult) {\n require (absoluteResult <= 0x80000000000000000000000000000000);\n return -int128 (absoluteResult); // We rely on overflow behavior here\n } else {\n require (absoluteResult <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);\n return int128 (absoluteResult); // We rely on overflow behavior here\n }\n }\n }\n\n /**\n * Calculate x / y rounding towards zero, where x and y are unsigned 256-bit\n * integer numbers. Revert on overflow or when y is zero.\n *\n * @param x unsigned 256-bit integer number\n * @param y unsigned 256-bit integer number\n * @return signed 64.64-bit fixed point number\n */\n function divu (uint256 x, uint256 y) internal pure returns (int128) {\n unchecked {\n require (y != 0);\n uint128 result = divuu (x, y);\n require (result <= uint128 (MAX_64x64));\n return int128 (result);\n }\n }\n\n /**\n * Calculate -x. Revert on overflow.\n *\n * @param x signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function neg (int128 x) internal pure returns (int128) {\n unchecked {\n require (x != MIN_64x64);\n return -x;\n }\n }\n\n /**\n * Calculate |x|. Revert on overflow.\n *\n * @param x signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function abs (int128 x) internal pure returns (int128) {\n unchecked {\n require (x != MIN_64x64);\n return x < 0 ? -x : x;\n }\n }\n\n /**\n * Calculate 1 / x rounding towards zero. Revert on overflow or when x is\n * zero.\n *\n * @param x signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function inv (int128 x) internal pure returns (int128) {\n unchecked {\n require (x != 0);\n int256 result = int256 (0x100000000000000000000000000000000) / x;\n require (result >= MIN_64x64 && result <= MAX_64x64);\n return int128 (result);\n }\n }\n\n /**\n * Calculate arithmetics average of x and y, i.e. (x + y) / 2 rounding down.\n *\n * @param x signed 64.64-bit fixed point number\n * @param y signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function avg (int128 x, int128 y) internal pure returns (int128) {\n unchecked {\n return int128 ((int256 (x) + int256 (y)) >> 1);\n }\n }\n\n /**\n * Calculate geometric average of x and y, i.e. sqrt (x * y) rounding down.\n * Revert on overflow or in case x * y is negative.\n *\n * @param x signed 64.64-bit fixed point number\n * @param y signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function gavg (int128 x, int128 y) internal pure returns (int128) {\n unchecked {\n int256 m = int256 (x) * int256 (y);\n require (m >= 0);\n require (m <\n 0x4000000000000000000000000000000000000000000000000000000000000000);\n return int128 (sqrtu (uint256 (m)));\n }\n }\n\n /**\n * Calculate x^y assuming 0^0 is 1, where x is signed 64.64 fixed point number\n * and y is unsigned 256-bit integer number. Revert on overflow.\n *\n * @param x signed 64.64-bit fixed point number\n * @param y uint256 value\n * @return signed 64.64-bit fixed point number\n */\n function pow (int128 x, uint256 y) internal pure returns (int128) {\n unchecked {\n bool negative = x < 0 && y & 1 == 1;\n\n uint256 absX = uint128 (x < 0 ? -x : x);\n uint256 absResult;\n absResult = 0x100000000000000000000000000000000;\n\n if (absX <= 0x10000000000000000) {\n absX <<= 63;\n while (y != 0) {\n if (y & 0x1 != 0) {\n absResult = absResult * absX >> 127;\n }\n absX = absX * absX >> 127;\n\n if (y & 0x2 != 0) {\n absResult = absResult * absX >> 127;\n }\n absX = absX * absX >> 127;\n\n if (y & 0x4 != 0) {\n absResult = absResult * absX >> 127;\n }\n absX = absX * absX >> 127;\n\n if (y & 0x8 != 0) {\n absResult = absResult * absX >> 127;\n }\n absX = absX * absX >> 127;\n\n y >>= 4;\n }\n\n absResult >>= 64;\n } else {\n uint256 absXShift = 63;\n if (absX < 0x1000000000000000000000000) { absX <<= 32; absXShift -= 32; }\n if (absX < 0x10000000000000000000000000000) { absX <<= 16; absXShift -= 16; }\n if (absX < 0x1000000000000000000000000000000) { absX <<= 8; absXShift -= 8; }\n if (absX < 0x10000000000000000000000000000000) { absX <<= 4; absXShift -= 4; }\n if (absX < 0x40000000000000000000000000000000) { absX <<= 2; absXShift -= 2; }\n if (absX < 0x80000000000000000000000000000000) { absX <<= 1; absXShift -= 1; }\n\n uint256 resultShift = 0;\n while (y != 0) {\n require (absXShift < 64);\n\n if (y & 0x1 != 0) {\n absResult = absResult * absX >> 127;\n resultShift += absXShift;\n if (absResult > 0x100000000000000000000000000000000) {\n absResult >>= 1;\n resultShift += 1;\n }\n }\n absX = absX * absX >> 127;\n absXShift <<= 1;\n if (absX >= 0x100000000000000000000000000000000) {\n absX >>= 1;\n absXShift += 1;\n }\n\n y >>= 1;\n }\n\n require (resultShift < 64);\n absResult >>= 64 - resultShift;\n }\n int256 result = negative ? -int256 (absResult) : int256 (absResult);\n require (result >= MIN_64x64 && result <= MAX_64x64);\n return int128 (result);\n }\n }\n\n /**\n * Calculate sqrt (x) rounding down. Revert if x < 0.\n *\n * @param x signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function sqrt (int128 x) internal pure returns (int128) {\n unchecked {\n require (x >= 0);\n return int128 (sqrtu (uint256 (int256 (x)) << 64));\n }\n }\n\n /**\n * Calculate binary logarithm of x. Revert if x <= 0.\n *\n * @param x signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function log_2 (int128 x) internal pure returns (int128) {\n unchecked {\n require (x > 0);\n\n int256 msb = 0;\n int256 xc = x;\n if (xc >= 0x10000000000000000) { xc >>= 64; msb += 64; }\n if (xc >= 0x100000000) { xc >>= 32; msb += 32; }\n if (xc >= 0x10000) { xc >>= 16; msb += 16; }\n if (xc >= 0x100) { xc >>= 8; msb += 8; }\n if (xc >= 0x10) { xc >>= 4; msb += 4; }\n if (xc >= 0x4) { xc >>= 2; msb += 2; }\n if (xc >= 0x2) msb += 1; // No need to shift xc anymore\n\n int256 result = msb - 64 << 64;\n uint256 ux = uint256 (int256 (x)) << uint256 (127 - msb);\n for (int256 bit = 0x8000000000000000; bit > 0; bit >>= 1) {\n ux *= ux;\n uint256 b = ux >> 255;\n ux >>= 127 + b;\n result += bit * int256 (b);\n }\n\n return int128 (result);\n }\n }\n\n /**\n * Calculate natural logarithm of x. Revert if x <= 0.\n *\n * @param x signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function ln (int128 x) internal pure returns (int128) {\n unchecked {\n require (x > 0);\n\n return int128 (int256 (\n uint256 (int256 (log_2 (x))) * 0xB17217F7D1CF79ABC9E3B39803F2F6AF >> 128));\n }\n }\n\n /**\n * Calculate binary exponent of x. Revert on overflow.\n *\n * @param x signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function exp_2 (int128 x) internal pure returns (int128) {\n unchecked {\n require (x < 0x400000000000000000); // Overflow\n\n if (x < -0x400000000000000000) return 0; // Underflow\n\n uint256 result = 0x80000000000000000000000000000000;\n\n if (x & 0x8000000000000000 > 0)\n result = result * 0x16A09E667F3BCC908B2FB1366EA957D3E >> 128;\n if (x & 0x4000000000000000 > 0)\n result = result * 0x1306FE0A31B7152DE8D5A46305C85EDEC >> 128;\n if (x & 0x2000000000000000 > 0)\n result = result * 0x1172B83C7D517ADCDF7C8C50EB14A791F >> 128;\n if (x & 0x1000000000000000 > 0)\n result = result * 0x10B5586CF9890F6298B92B71842A98363 >> 128;\n if (x & 0x800000000000000 > 0)\n result = result * 0x1059B0D31585743AE7C548EB68CA417FD >> 128;\n if (x & 0x400000000000000 > 0)\n result = result * 0x102C9A3E778060EE6F7CACA4F7A29BDE8 >> 128;\n if (x & 0x200000000000000 > 0)\n result = result * 0x10163DA9FB33356D84A66AE336DCDFA3F >> 128;\n if (x & 0x100000000000000 > 0)\n result = result * 0x100B1AFA5ABCBED6129AB13EC11DC9543 >> 128;\n if (x & 0x80000000000000 > 0)\n result = result * 0x10058C86DA1C09EA1FF19D294CF2F679B >> 128;\n if (x & 0x40000000000000 > 0)\n result = result * 0x1002C605E2E8CEC506D21BFC89A23A00F >> 128;\n if (x & 0x20000000000000 > 0)\n result = result * 0x100162F3904051FA128BCA9C55C31E5DF >> 128;\n if (x & 0x10000000000000 > 0)\n result = result * 0x1000B175EFFDC76BA38E31671CA939725 >> 128;\n if (x & 0x8000000000000 > 0)\n result = result * 0x100058BA01FB9F96D6CACD4B180917C3D >> 128;\n if (x & 0x4000000000000 > 0)\n result = result * 0x10002C5CC37DA9491D0985C348C68E7B3 >> 128;\n if (x & 0x2000000000000 > 0)\n result = result * 0x1000162E525EE054754457D5995292026 >> 128;\n if (x & 0x1000000000000 > 0)\n result = result * 0x10000B17255775C040618BF4A4ADE83FC >> 128;\n if (x & 0x800000000000 > 0)\n result = result * 0x1000058B91B5BC9AE2EED81E9B7D4CFAB >> 128;\n if (x & 0x400000000000 > 0)\n result = result * 0x100002C5C89D5EC6CA4D7C8ACC017B7C9 >> 128;\n if (x & 0x200000000000 > 0)\n result = result * 0x10000162E43F4F831060E02D839A9D16D >> 128;\n if (x & 0x100000000000 > 0)\n result = result * 0x100000B1721BCFC99D9F890EA06911763 >> 128;\n if (x & 0x80000000000 > 0)\n result = result * 0x10000058B90CF1E6D97F9CA14DBCC1628 >> 128;\n if (x & 0x40000000000 > 0)\n result = result * 0x1000002C5C863B73F016468F6BAC5CA2B >> 128;\n if (x & 0x20000000000 > 0)\n result = result * 0x100000162E430E5A18F6119E3C02282A5 >> 128;\n if (x & 0x10000000000 > 0)\n result = result * 0x1000000B1721835514B86E6D96EFD1BFE >> 128;\n if (x & 0x8000000000 > 0)\n result = result * 0x100000058B90C0B48C6BE5DF846C5B2EF >> 128;\n if (x & 0x4000000000 > 0)\n result = result * 0x10000002C5C8601CC6B9E94213C72737A >> 128;\n if (x & 0x2000000000 > 0)\n result = result * 0x1000000162E42FFF037DF38AA2B219F06 >> 128;\n if (x & 0x1000000000 > 0)\n result = result * 0x10000000B17217FBA9C739AA5819F44F9 >> 128;\n if (x & 0x800000000 > 0)\n result = result * 0x1000000058B90BFCDEE5ACD3C1CEDC823 >> 128;\n if (x & 0x400000000 > 0)\n result = result * 0x100000002C5C85FE31F35A6A30DA1BE50 >> 128;\n if (x & 0x200000000 > 0)\n result = result * 0x10000000162E42FF0999CE3541B9FFFCF >> 128;\n if (x & 0x100000000 > 0)\n result = result * 0x100000000B17217F80F4EF5AADDA45554 >> 128;\n if (x & 0x80000000 > 0)\n result = result * 0x10000000058B90BFBF8479BD5A81B51AD >> 128;\n if (x & 0x40000000 > 0)\n result = result * 0x1000000002C5C85FDF84BD62AE30A74CC >> 128;\n if (x & 0x20000000 > 0)\n result = result * 0x100000000162E42FEFB2FED257559BDAA >> 128;\n if (x & 0x10000000 > 0)\n result = result * 0x1000000000B17217F7D5A7716BBA4A9AE >> 128;\n if (x & 0x8000000 > 0)\n result = result * 0x100000000058B90BFBE9DDBAC5E109CCE >> 128;\n if (x & 0x4000000 > 0)\n result = result * 0x10000000002C5C85FDF4B15DE6F17EB0D >> 128;\n if (x & 0x2000000 > 0)\n result = result * 0x1000000000162E42FEFA494F1478FDE05 >> 128;\n if (x & 0x1000000 > 0)\n result = result * 0x10000000000B17217F7D20CF927C8E94C >> 128;\n if (x & 0x800000 > 0)\n result = result * 0x1000000000058B90BFBE8F71CB4E4B33D >> 128;\n if (x & 0x400000 > 0)\n result = result * 0x100000000002C5C85FDF477B662B26945 >> 128;\n if (x & 0x200000 > 0)\n result = result * 0x10000000000162E42FEFA3AE53369388C >> 128;\n if (x & 0x100000 > 0)\n result = result * 0x100000000000B17217F7D1D351A389D40 >> 128;\n if (x & 0x80000 > 0)\n result = result * 0x10000000000058B90BFBE8E8B2D3D4EDE >> 128;\n if (x & 0x40000 > 0)\n result = result * 0x1000000000002C5C85FDF4741BEA6E77E >> 128;\n if (x & 0x20000 > 0)\n result = result * 0x100000000000162E42FEFA39FE95583C2 >> 128;\n if (x & 0x10000 > 0)\n result = result * 0x1000000000000B17217F7D1CFB72B45E1 >> 128;\n if (x & 0x8000 > 0)\n result = result * 0x100000000000058B90BFBE8E7CC35C3F0 >> 128;\n if (x & 0x4000 > 0)\n result = result * 0x10000000000002C5C85FDF473E242EA38 >> 128;\n if (x & 0x2000 > 0)\n result = result * 0x1000000000000162E42FEFA39F02B772C >> 128;\n if (x & 0x1000 > 0)\n result = result * 0x10000000000000B17217F7D1CF7D83C1A >> 128;\n if (x & 0x800 > 0)\n result = result * 0x1000000000000058B90BFBE8E7BDCBE2E >> 128;\n if (x & 0x400 > 0)\n result = result * 0x100000000000002C5C85FDF473DEA871F >> 128;\n if (x & 0x200 > 0)\n result = result * 0x10000000000000162E42FEFA39EF44D91 >> 128;\n if (x & 0x100 > 0)\n result = result * 0x100000000000000B17217F7D1CF79E949 >> 128;\n if (x & 0x80 > 0)\n result = result * 0x10000000000000058B90BFBE8E7BCE544 >> 128;\n if (x & 0x40 > 0)\n result = result * 0x1000000000000002C5C85FDF473DE6ECA >> 128;\n if (x & 0x20 > 0)\n result = result * 0x100000000000000162E42FEFA39EF366F >> 128;\n if (x & 0x10 > 0)\n result = result * 0x1000000000000000B17217F7D1CF79AFA >> 128;\n if (x & 0x8 > 0)\n result = result * 0x100000000000000058B90BFBE8E7BCD6D >> 128;\n if (x & 0x4 > 0)\n result = result * 0x10000000000000002C5C85FDF473DE6B2 >> 128;\n if (x & 0x2 > 0)\n result = result * 0x1000000000000000162E42FEFA39EF358 >> 128;\n if (x & 0x1 > 0)\n result = result * 0x10000000000000000B17217F7D1CF79AB >> 128;\n\n result >>= uint256 (int256 (63 - (x >> 64)));\n require (result <= uint256 (int256 (MAX_64x64)));\n\n return int128 (int256 (result));\n }\n }\n\n /**\n * Calculate natural exponent of x. Revert on overflow.\n *\n * @param x signed 64.64-bit fixed point number\n * @return signed 64.64-bit fixed point number\n */\n function exp (int128 x) internal pure returns (int128) {\n unchecked {\n require (x < 0x400000000000000000); // Overflow\n\n if (x < -0x400000000000000000) return 0; // Underflow\n\n return exp_2 (\n int128 (int256 (x) * 0x171547652B82FE1777D0FFDA0D23A7D12 >> 128));\n }\n }\n\n /**\n * Calculate x / y rounding towards zero, where x and y are unsigned 256-bit\n * integer numbers. Revert on overflow or when y is zero.\n *\n * @param x unsigned 256-bit integer number\n * @param y unsigned 256-bit integer number\n * @return unsigned 64.64-bit fixed point number\n */\n function divuu (uint256 x, uint256 y) private pure returns (uint128) {\n unchecked {\n require (y != 0);\n\n uint256 result;\n\n if (x <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n result = (x << 64) / y;\n else {\n uint256 msb = 192;\n uint256 xc = x >> 192;\n if (xc >= 0x100000000) { xc >>= 32; msb += 32; }\n if (xc >= 0x10000) { xc >>= 16; msb += 16; }\n if (xc >= 0x100) { xc >>= 8; msb += 8; }\n if (xc >= 0x10) { xc >>= 4; msb += 4; }\n if (xc >= 0x4) { xc >>= 2; msb += 2; }\n if (xc >= 0x2) msb += 1; // No need to shift xc anymore\n\n result = (x << 255 - msb) / ((y - 1 >> msb - 191) + 1);\n require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);\n\n uint256 hi = result * (y >> 128);\n uint256 lo = result * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);\n\n uint256 xh = x >> 192;\n uint256 xl = x << 64;\n\n if (xl < lo) xh -= 1;\n xl -= lo; // We rely on overflow behavior here\n lo = hi << 128;\n if (xl < lo) xh -= 1;\n xl -= lo; // We rely on overflow behavior here\n\n assert (xh == hi >> 128);\n\n result += xl / y;\n }\n\n require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);\n return uint128 (result);\n }\n }\n\n /**\n * Calculate sqrt (x) rounding down, where x is unsigned 256-bit integer\n * number.\n *\n * @param x unsigned 256-bit integer number\n * @return unsigned 128-bit integer number\n */\n function sqrtu (uint256 x) private pure returns (uint128) {\n unchecked {\n if (x == 0) return 0;\n else {\n uint256 xx = x;\n uint256 r = 1;\n if (xx >= 0x100000000000000000000000000000000) { xx >>= 128; r <<= 64; }\n if (xx >= 0x10000000000000000) { xx >>= 64; r <<= 32; }\n if (xx >= 0x100000000) { xx >>= 32; r <<= 16; }\n if (xx >= 0x10000) { xx >>= 16; r <<= 8; }\n if (xx >= 0x100) { xx >>= 8; r <<= 4; }\n if (xx >= 0x10) { xx >>= 4; r <<= 2; }\n if (xx >= 0x8) { r <<= 1; }\n r = (r + x / r) >> 1;\n r = (r + x / r) >> 1;\n r = (r + x / r) >> 1;\n r = (r + x / r) >> 1;\n r = (r + x / r) >> 1;\n r = (r + x / r) >> 1;\n r = (r + x / r) >> 1; // Seven iterations should be enough\n uint256 r1 = x / r;\n return uint128 (r < r1 ? r : r1);\n }\n }\n }\n}\n"},"@solidstate/contracts/token/ERC20/metadata/IERC20Metadata.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC20 metadata interface\n */\ninterface IERC20Metadata {\n /**\n * @notice return token name\n * @return token name\n */\n function name() external view returns (string memory);\n\n /**\n * @notice return token symbol\n * @return token symbol\n */\n function symbol() external view returns (string memory);\n\n /**\n * @notice return token decimals, generally used only for display purposes\n * @return token decimals\n */\n function decimals() external view returns (uint8);\n}\n"},"contracts/staking/FeeDiscountStorage.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\r\n// For further clarification please see https://license.premia.legal\r\n\r\npragma solidity ^0.8.0;\r\n\r\nlibrary FeeDiscountStorage {\r\n bytes32 internal constant STORAGE_SLOT =\r\n keccak256(\"premia.contracts.staking.PremiaFeeDiscount\");\r\n\r\n struct UserInfo {\r\n uint256 balance; // Balance staked by user\r\n uint64 stakePeriod; // Stake period selected by user\r\n uint64 lockedUntil; // Timestamp at which the lock ends\r\n }\r\n\r\n struct Layout {\r\n // User data with xPREMIA balance staked and date at which lock ends\r\n mapping(address => UserInfo) userInfo;\r\n }\r\n\r\n function layout() internal pure returns (Layout storage l) {\r\n bytes32 slot = STORAGE_SLOT;\r\n assembly {\r\n l.slot := slot\r\n }\r\n }\r\n}\r\n"},"contracts/libraries/OptionMath.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\r\n// For further clarification please see https://license.premia.legal\r\n\r\npragma solidity ^0.8.0;\r\n\r\nimport {ABDKMath64x64} from \"abdk-libraries-solidity/ABDKMath64x64.sol\";\r\n\r\nlibrary OptionMath {\r\n using ABDKMath64x64 for int128;\r\n\r\n struct QuoteArgs {\r\n int128 varianceAnnualized64x64; // 64x64 fixed point representation of annualized variance\r\n int128 strike64x64; // 64x64 fixed point representation of strike price\r\n int128 spot64x64; // 64x64 fixed point representation of spot price\r\n int128 timeToMaturity64x64; // 64x64 fixed point representation of duration of option contract (in years)\r\n int128 oldCLevel64x64; // 64x64 fixed point representation of C-Level of Pool before purchase\r\n int128 oldPoolState; // 64x64 fixed point representation of current state of the pool\r\n int128 newPoolState; // 64x64 fixed point representation of state of the pool after trade\r\n int128 steepness64x64; // 64x64 fixed point representation of Pool state delta multiplier\r\n int128 minAPY64x64; // 64x64 fixed point representation of minimum APY for capital locked up to underwrite options\r\n bool isCall; // whether to price \"call\" or \"put\" option\r\n }\r\n\r\n struct CalculateCLevelDecayArgs {\r\n int128 timeIntervalsElapsed64x64; // 64x64 fixed point representation of quantity of discrete arbitrary intervals elapsed since last update\r\n int128 oldCLevel64x64; // 64x64 fixed point representation of C-Level prior to accounting for decay\r\n int128 utilization64x64; // 64x64 fixed point representation of pool capital utilization rate\r\n int128 utilizationLowerBound64x64;\r\n int128 utilizationUpperBound64x64;\r\n int128 cLevelLowerBound64x64;\r\n int128 cLevelUpperBound64x64;\r\n int128 cConvergenceULowerBound64x64;\r\n int128 cConvergenceUUpperBound64x64;\r\n }\r\n\r\n // 64x64 fixed point integer constants\r\n int128 internal constant ONE_64x64 = 0x10000000000000000;\r\n int128 internal constant THREE_64x64 = 0x30000000000000000;\r\n\r\n // 64x64 fixed point constants used in Choudhury’s approximation of the Black-Scholes CDF\r\n int128 private constant CDF_CONST_0 = 0x09109f285df452394; // 2260 / 3989\r\n int128 private constant CDF_CONST_1 = 0x19abac0ea1da65036; // 6400 / 3989\r\n int128 private constant CDF_CONST_2 = 0x0d3c84b78b749bd6b; // 3300 / 3989\r\n\r\n /**\r\n * @notice recalculate C-Level based on change in liquidity\r\n * @param initialCLevel64x64 64x64 fixed point representation of C-Level of Pool before update\r\n * @param oldPoolState64x64 64x64 fixed point representation of liquidity in pool before update\r\n * @param newPoolState64x64 64x64 fixed point representation of liquidity in pool after update\r\n * @param steepness64x64 64x64 fixed point representation of steepness coefficient\r\n * @return 64x64 fixed point representation of new C-Level\r\n */\r\n function calculateCLevel(\r\n int128 initialCLevel64x64,\r\n int128 oldPoolState64x64,\r\n int128 newPoolState64x64,\r\n int128 steepness64x64\r\n ) external pure returns (int128) {\r\n return\r\n newPoolState64x64\r\n .sub(oldPoolState64x64)\r\n .div(\r\n oldPoolState64x64 > newPoolState64x64\r\n ? oldPoolState64x64\r\n : newPoolState64x64\r\n )\r\n .mul(steepness64x64)\r\n .neg()\r\n .exp()\r\n .mul(initialCLevel64x64);\r\n }\r\n\r\n /**\r\n * @notice calculate the price of an option using the Premia Finance model\r\n * @param args arguments of quotePrice\r\n * @return premiaPrice64x64 64x64 fixed point representation of Premia option price\r\n * @return cLevel64x64 64x64 fixed point representation of C-Level of Pool after purchase\r\n */\r\n function quotePrice(QuoteArgs memory args)\r\n external\r\n pure\r\n returns (\r\n int128 premiaPrice64x64,\r\n int128 cLevel64x64,\r\n int128 slippageCoefficient64x64\r\n )\r\n {\r\n int128 deltaPoolState64x64 = args\r\n .newPoolState\r\n .sub(args.oldPoolState)\r\n .div(args.oldPoolState)\r\n .mul(args.steepness64x64);\r\n int128 tradingDelta64x64 = deltaPoolState64x64.neg().exp();\r\n\r\n int128 blackScholesPrice64x64 = _blackScholesPrice(\r\n args.varianceAnnualized64x64,\r\n args.strike64x64,\r\n args.spot64x64,\r\n args.timeToMaturity64x64,\r\n args.isCall\r\n );\r\n\r\n cLevel64x64 = tradingDelta64x64.mul(args.oldCLevel64x64);\r\n slippageCoefficient64x64 = ONE_64x64.sub(tradingDelta64x64).div(\r\n deltaPoolState64x64\r\n );\r\n\r\n premiaPrice64x64 = blackScholesPrice64x64.mul(cLevel64x64).mul(\r\n slippageCoefficient64x64\r\n );\r\n\r\n int128 intrinsicValue64x64;\r\n\r\n if (args.isCall && args.strike64x64 < args.spot64x64) {\r\n intrinsicValue64x64 = args.spot64x64.sub(args.strike64x64);\r\n } else if (!args.isCall && args.strike64x64 > args.spot64x64) {\r\n intrinsicValue64x64 = args.strike64x64.sub(args.spot64x64);\r\n }\r\n\r\n int128 collateralValue64x64 = args.isCall\r\n ? args.spot64x64\r\n : args.strike64x64;\r\n\r\n int128 minPrice64x64 = intrinsicValue64x64.add(\r\n collateralValue64x64.mul(args.minAPY64x64).mul(\r\n args.timeToMaturity64x64\r\n )\r\n );\r\n\r\n if (minPrice64x64 > premiaPrice64x64) {\r\n premiaPrice64x64 = minPrice64x64;\r\n }\r\n }\r\n\r\n /**\r\n * @notice calculate the decay of C-Level based on heat diffusion function\r\n * @param args structured CalculateCLevelDecayArgs\r\n * @return cLevelDecayed64x64 C-Level after accounting for decay\r\n */\r\n function calculateCLevelDecay(CalculateCLevelDecayArgs memory args)\r\n external\r\n pure\r\n returns (int128 cLevelDecayed64x64)\r\n {\r\n int128 convFHighU64x64 = (args.utilization64x64 >=\r\n args.utilizationUpperBound64x64 &&\r\n args.oldCLevel64x64 <= args.cLevelLowerBound64x64)\r\n ? ONE_64x64\r\n : int128(0);\r\n\r\n int128 convFLowU64x64 = (args.utilization64x64 <=\r\n args.utilizationLowerBound64x64 &&\r\n args.oldCLevel64x64 >= args.cLevelUpperBound64x64)\r\n ? ONE_64x64\r\n : int128(0);\r\n\r\n cLevelDecayed64x64 = args\r\n .oldCLevel64x64\r\n .sub(args.cConvergenceULowerBound64x64.mul(convFLowU64x64))\r\n .sub(args.cConvergenceUUpperBound64x64.mul(convFHighU64x64))\r\n .mul(\r\n convFLowU64x64\r\n .mul(ONE_64x64.sub(args.utilization64x64))\r\n .add(convFHighU64x64.mul(args.utilization64x64))\r\n .mul(args.timeIntervalsElapsed64x64)\r\n .neg()\r\n .exp()\r\n )\r\n .add(\r\n args.cConvergenceULowerBound64x64.mul(convFLowU64x64).add(\r\n args.cConvergenceUUpperBound64x64.mul(convFHighU64x64)\r\n )\r\n );\r\n }\r\n\r\n /**\r\n * @notice calculate the exponential decay coefficient for a given interval\r\n * @param oldTimestamp timestamp of previous update\r\n * @param newTimestamp current timestamp\r\n * @return 64x64 fixed point representation of exponential decay coefficient\r\n */\r\n function _decay(uint256 oldTimestamp, uint256 newTimestamp)\r\n internal\r\n pure\r\n returns (int128)\r\n {\r\n return\r\n ONE_64x64.sub(\r\n (-ABDKMath64x64.divu(newTimestamp - oldTimestamp, 7 days)).exp()\r\n );\r\n }\r\n\r\n /**\r\n * @notice calculate Choudhury’s approximation of the Black-Scholes CDF\r\n * @param input64x64 64x64 fixed point representation of random variable\r\n * @return 64x64 fixed point representation of the approximated CDF of x\r\n */\r\n function _N(int128 input64x64) internal pure returns (int128) {\r\n // squaring via mul is cheaper than via pow\r\n int128 inputSquared64x64 = input64x64.mul(input64x64);\r\n\r\n int128 value64x64 = (-inputSquared64x64 >> 1).exp().div(\r\n CDF_CONST_0.add(CDF_CONST_1.mul(input64x64.abs())).add(\r\n CDF_CONST_2.mul(inputSquared64x64.add(THREE_64x64).sqrt())\r\n )\r\n );\r\n\r\n return input64x64 > 0 ? ONE_64x64.sub(value64x64) : value64x64;\r\n }\r\n\r\n /**\r\n * @notice calculate the price of an option using the Black-Scholes model\r\n * @param varianceAnnualized64x64 64x64 fixed point representation of annualized variance\r\n * @param strike64x64 64x64 fixed point representation of strike price\r\n * @param spot64x64 64x64 fixed point representation of spot price\r\n * @param timeToMaturity64x64 64x64 fixed point representation of duration of option contract (in years)\r\n * @param isCall whether to price \"call\" or \"put\" option\r\n * @return 64x64 fixed point representation of Black-Scholes option price\r\n */\r\n function _blackScholesPrice(\r\n int128 varianceAnnualized64x64,\r\n int128 strike64x64,\r\n int128 spot64x64,\r\n int128 timeToMaturity64x64,\r\n bool isCall\r\n ) internal pure returns (int128) {\r\n int128 cumulativeVariance64x64 = timeToMaturity64x64.mul(\r\n varianceAnnualized64x64\r\n );\r\n int128 cumulativeVarianceSqrt64x64 = cumulativeVariance64x64.sqrt();\r\n\r\n int128 d1_64x64 = spot64x64\r\n .div(strike64x64)\r\n .ln()\r\n .add(cumulativeVariance64x64 >> 1)\r\n .div(cumulativeVarianceSqrt64x64);\r\n int128 d2_64x64 = d1_64x64.sub(cumulativeVarianceSqrt64x64);\r\n\r\n if (isCall) {\r\n return\r\n spot64x64.mul(_N(d1_64x64)).sub(strike64x64.mul(_N(d2_64x64)));\r\n } else {\r\n return\r\n -spot64x64.mul(_N(-d1_64x64)).sub(\r\n strike64x64.mul(_N(-d2_64x64))\r\n );\r\n }\r\n }\r\n}\r\n"},"@solidstate/contracts/access/IERC173.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title Contract ownership standard interface\n * @dev see https://eips.ethereum.org/EIPS/eip-173\n */\ninterface IERC173 {\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /**\n * @notice get the ERC173 contract owner\n * @return conract owner\n */\n function owner() external view returns (address);\n\n /**\n * @notice transfer contract ownership to new account\n * @param account address of new owner\n */\n function transferOwnership(address account) external;\n}\n"},"contracts/libraries/ABDKMath64x64Token.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\r\n// For further clarification please see https://license.premia.legal\r\n\r\npragma solidity ^0.8.0;\r\n\r\nimport {ABDKMath64x64} from \"abdk-libraries-solidity/ABDKMath64x64.sol\";\r\n\r\nlibrary ABDKMath64x64Token {\r\n using ABDKMath64x64 for int128;\r\n\r\n /**\r\n * @notice convert 64x64 fixed point representation of token amount to decimal\r\n * @param value64x64 64x64 fixed point representation of token amount\r\n * @param decimals token display decimals\r\n * @return value decimal representation of token amount\r\n */\r\n function toDecimals(int128 value64x64, uint8 decimals)\r\n internal\r\n pure\r\n returns (uint256 value)\r\n {\r\n value = value64x64.mulu(10**decimals);\r\n }\r\n\r\n /**\r\n * @notice convert decimal representation of token amount to 64x64 fixed point\r\n * @param value decimal representation of token amount\r\n * @param decimals token display decimals\r\n * @return value64x64 64x64 fixed point representation of token amount\r\n */\r\n function fromDecimals(uint256 value, uint8 decimals)\r\n internal\r\n pure\r\n returns (int128 value64x64)\r\n {\r\n value64x64 = ABDKMath64x64.divu(value, 10**decimals);\r\n }\r\n\r\n /**\r\n * @notice convert 64x64 fixed point representation of token amount to wei (18 decimals)\r\n * @param value64x64 64x64 fixed point representation of token amount\r\n * @return value wei representation of token amount\r\n */\r\n function toWei(int128 value64x64) internal pure returns (uint256 value) {\r\n value = toDecimals(value64x64, 18);\r\n }\r\n\r\n /**\r\n * @notice convert wei representation (18 decimals) of token amount to 64x64 fixed point\r\n * @param value wei representation of token amount\r\n * @return value64x64 64x64 fixed point representation of token amount\r\n */\r\n function fromWei(uint256 value) internal pure returns (int128 value64x64) {\r\n value64x64 = fromDecimals(value, 18);\r\n }\r\n}\r\n"},"@solidstate/contracts/token/ERC1155/IERC1155.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IERC1155Internal } from './IERC1155Internal.sol';\nimport { IERC165 } from '../../introspection/IERC165.sol';\n\n/**\n * @notice ERC1155 interface\n * @dev see https://github.com/ethereum/EIPs/issues/1155\n */\ninterface IERC1155 is IERC1155Internal, IERC165 {\n /**\n * @notice query the balance of given token held by given address\n * @param account address to query\n * @param id token to query\n * @return token balance\n */\n function balanceOf(address account, uint256 id)\n external\n view\n returns (uint256);\n\n /**\n * @notice query the balances of given tokens held by given addresses\n * @param accounts addresss to query\n * @param ids tokens to query\n * @return token balances\n */\n function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)\n external\n view\n returns (uint256[] memory);\n\n /**\n * @notice query approval status of given operator with respect to given address\n * @param account address to query for approval granted\n * @param operator address to query for approval received\n * @return whether operator is approved to spend tokens held by account\n */\n function isApprovedForAll(address account, address operator)\n external\n view\n returns (bool);\n\n /**\n * @notice grant approval to or revoke approval from given operator to spend held tokens\n * @param operator address whose approval status to update\n * @param status whether operator should be considered approved\n */\n function setApprovalForAll(address operator, bool status) external;\n\n /**\n * @notice transfer tokens between given addresses, checking for ERC1155Receiver implementation if applicable\n * @param from sender of tokens\n * @param to receiver of tokens\n * @param id token ID\n * @param amount quantity of tokens to transfer\n * @param data data payload\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @notice transfer batch of tokens between given addresses, checking for ERC1155Receiver implementation if applicable\n * @param from sender of tokens\n * @param to receiver of tokens\n * @param ids list of token IDs\n * @param amounts list of quantities of tokens to transfer\n * @param data data payload\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n"},"contracts/staking/IFeeDiscount.sol":{"content":"// SPDX-License-Identifier: LGPL-3.0-or-later\r\n\r\npragma solidity ^0.8.0;\r\n\r\nimport {FeeDiscountStorage} from \"./FeeDiscountStorage.sol\";\r\n\r\ninterface IFeeDiscount {\r\n event Staked(\r\n address indexed user,\r\n uint256 amount,\r\n uint256 stakePeriod,\r\n uint256 lockedUntil\r\n );\r\n event Unstaked(address indexed user, uint256 amount);\r\n\r\n struct StakeLevel {\r\n uint256 amount; // Amount to stake\r\n uint256 discount; // Discount when amount is reached\r\n }\r\n\r\n /**\r\n * @notice Stake using IERC2612 permit\r\n * @param amount The amount of xPremia to stake\r\n * @param period The lockup period (in seconds)\r\n * @param deadline Deadline after which permit will fail\r\n * @param v V\r\n * @param r R\r\n * @param s S\r\n */\r\n function stakeWithPermit(\r\n uint256 amount,\r\n uint256 period,\r\n uint256 deadline,\r\n uint8 v,\r\n bytes32 r,\r\n bytes32 s\r\n ) external;\r\n\r\n /**\r\n * @notice Lockup xPremia for protocol fee discounts\r\n * Longer period of locking will apply a multiplier on the amount staked, in the fee discount calculation\r\n * @param amount The amount of xPremia to stake\r\n * @param period The lockup period (in seconds)\r\n */\r\n function stake(uint256 amount, uint256 period) external;\r\n\r\n /**\r\n * @notice Unstake xPremia (If lockup period has ended)\r\n * @param amount The amount of xPremia to unstake\r\n */\r\n function unstake(uint256 amount) external;\r\n\r\n //////////\r\n // View //\r\n //////////\r\n\r\n /**\r\n * Calculate the stake amount of a user, after applying the bonus from the lockup period chosen\r\n * @param user The user from which to query the stake amount\r\n * @return The user stake amount after applying the bonus\r\n */\r\n function getStakeAmountWithBonus(address user)\r\n external\r\n view\r\n returns (uint256);\r\n\r\n /**\r\n * @notice Calculate the % of fee discount for user, based on his stake\r\n * @param user The _user for which the discount is for\r\n * @return Percentage of protocol fee discount (in basis point)\r\n * Ex : 1000 = 10% fee discount\r\n */\r\n function getDiscount(address user) external view returns (uint256);\r\n\r\n /**\r\n * @notice Get stake levels\r\n * @return Stake levels\r\n * Ex : 2500 = -25%\r\n */\r\n function getStakeLevels() external returns (StakeLevel[] memory);\r\n\r\n /**\r\n * @notice Get stake period multiplier\r\n * @param period The duration (in seconds) for which tokens are locked\r\n * @return The multiplier for this staking period\r\n * Ex : 20000 = x2\r\n */\r\n function getStakePeriodMultiplier(uint256 period)\r\n external\r\n returns (uint256);\r\n\r\n /**\r\n * @notice Get staking infos of a user\r\n * @param user The user address for which to get staking infos\r\n * @return The staking infos of the user\r\n */\r\n function getUserInfo(address user)\r\n external\r\n view\r\n returns (FeeDiscountStorage.UserInfo memory);\r\n}\r\n"},"@solidstate/contracts/token/ERC1155/base/ERC1155BaseInternal.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { AddressUtils } from '../../../utils/AddressUtils.sol';\nimport { IERC1155Internal } from '../IERC1155Internal.sol';\nimport { IERC1155Receiver } from '../IERC1155Receiver.sol';\nimport { ERC1155BaseStorage } from './ERC1155BaseStorage.sol';\n\n/**\n * @title Base ERC1155 internal functions\n * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts/ (MIT license)\n */\nabstract contract ERC1155BaseInternal is IERC1155Internal {\n using AddressUtils for address;\n\n /**\n * @notice query the balance of given token held by given address\n * @param account address to query\n * @param id token to query\n * @return token balance\n */\n function _balanceOf(address account, uint256 id)\n internal\n view\n virtual\n returns (uint256)\n {\n require(\n account != address(0),\n 'ERC1155: balance query for the zero address'\n );\n return ERC1155BaseStorage.layout().balances[id][account];\n }\n\n /**\n * @notice mint given quantity of tokens for given address\n * @dev ERC1155Receiver implementation is not checked\n * @param account beneficiary of minting\n * @param id token ID\n * @param amount quantity of tokens to mint\n * @param data data payload\n */\n function _mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(account != address(0), 'ERC1155: mint to the zero address');\n\n _beforeTokenTransfer(\n msg.sender,\n address(0),\n account,\n _asSingletonArray(id),\n _asSingletonArray(amount),\n data\n );\n\n mapping(address => uint256) storage balances = ERC1155BaseStorage\n .layout()\n .balances[id];\n balances[account] += amount;\n\n emit TransferSingle(msg.sender, address(0), account, id, amount);\n }\n\n /**\n * @notice mint given quantity of tokens for given address\n * @param account beneficiary of minting\n * @param id token ID\n * @param amount quantity of tokens to mint\n * @param data data payload\n */\n function _safeMint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n _mint(account, id, amount, data);\n\n _doSafeTransferAcceptanceCheck(\n msg.sender,\n address(0),\n account,\n id,\n amount,\n data\n );\n }\n\n /**\n * @notice mint batch of tokens for given address\n * @dev ERC1155Receiver implementation is not checked\n * @param account beneficiary of minting\n * @param ids list of token IDs\n * @param amounts list of quantities of tokens to mint\n * @param data data payload\n */\n function _mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(account != address(0), 'ERC1155: mint to the zero address');\n require(\n ids.length == amounts.length,\n 'ERC1155: ids and amounts length mismatch'\n );\n\n _beforeTokenTransfer(\n msg.sender,\n address(0),\n account,\n ids,\n amounts,\n data\n );\n\n mapping(uint256 => mapping(address => uint256))\n storage balances = ERC1155BaseStorage.layout().balances;\n\n for (uint256 i; i < ids.length; i++) {\n balances[ids[i]][account] += amounts[i];\n }\n\n emit TransferBatch(msg.sender, address(0), account, ids, amounts);\n }\n\n /**\n * @notice mint batch of tokens for given address\n * @param account beneficiary of minting\n * @param ids list of token IDs\n * @param amounts list of quantities of tokens to mint\n * @param data data payload\n */\n function _safeMintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n _mintBatch(account, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(\n msg.sender,\n address(0),\n account,\n ids,\n amounts,\n data\n );\n }\n\n /**\n * @notice burn given quantity of tokens held by given address\n * @param account holder of tokens to burn\n * @param id token ID\n * @param amount quantity of tokens to burn\n */\n function _burn(\n address account,\n uint256 id,\n uint256 amount\n ) internal virtual {\n require(account != address(0), 'ERC1155: burn from the zero address');\n\n _beforeTokenTransfer(\n msg.sender,\n account,\n address(0),\n _asSingletonArray(id),\n _asSingletonArray(amount),\n ''\n );\n\n mapping(address => uint256) storage balances = ERC1155BaseStorage\n .layout()\n .balances[id];\n\n unchecked {\n require(\n balances[account] >= amount,\n 'ERC1155: burn amount exceeds balances'\n );\n balances[account] -= amount;\n }\n\n emit TransferSingle(msg.sender, account, address(0), id, amount);\n }\n\n /**\n * @notice burn given batch of tokens held by given address\n * @param account holder of tokens to burn\n * @param ids token IDs\n * @param amounts quantities of tokens to burn\n */\n function _burnBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal virtual {\n require(account != address(0), 'ERC1155: burn from the zero address');\n require(\n ids.length == amounts.length,\n 'ERC1155: ids and amounts length mismatch'\n );\n\n _beforeTokenTransfer(msg.sender, account, address(0), ids, amounts, '');\n\n mapping(uint256 => mapping(address => uint256))\n storage balances = ERC1155BaseStorage.layout().balances;\n\n unchecked {\n for (uint256 i; i < ids.length; i++) {\n uint256 id = ids[i];\n require(\n balances[id][account] >= amounts[i],\n 'ERC1155: burn amount exceeds balance'\n );\n balances[id][account] -= amounts[i];\n }\n }\n\n emit TransferBatch(msg.sender, account, address(0), ids, amounts);\n }\n\n /**\n * @notice transfer tokens between given addresses\n * @dev ERC1155Receiver implementation is not checked\n * @param operator executor of transfer\n * @param sender sender of tokens\n * @param recipient receiver of tokens\n * @param id token ID\n * @param amount quantity of tokens to transfer\n * @param data data payload\n */\n function _transfer(\n address operator,\n address sender,\n address recipient,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(\n recipient != address(0),\n 'ERC1155: transfer to the zero address'\n );\n\n _beforeTokenTransfer(\n operator,\n sender,\n recipient,\n _asSingletonArray(id),\n _asSingletonArray(amount),\n data\n );\n\n mapping(uint256 => mapping(address => uint256))\n storage balances = ERC1155BaseStorage.layout().balances;\n\n unchecked {\n uint256 senderBalance = balances[id][sender];\n require(\n senderBalance >= amount,\n 'ERC1155: insufficient balances for transfer'\n );\n balances[id][sender] = senderBalance - amount;\n }\n\n balances[id][recipient] += amount;\n\n emit TransferSingle(operator, sender, recipient, id, amount);\n }\n\n /**\n * @notice transfer tokens between given addresses\n * @param operator executor of transfer\n * @param sender sender of tokens\n * @param recipient receiver of tokens\n * @param id token ID\n * @param amount quantity of tokens to transfer\n * @param data data payload\n */\n function _safeTransfer(\n address operator,\n address sender,\n address recipient,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n _transfer(operator, sender, recipient, id, amount, data);\n\n _doSafeTransferAcceptanceCheck(\n operator,\n sender,\n recipient,\n id,\n amount,\n data\n );\n }\n\n /**\n * @notice transfer batch of tokens between given addresses\n * @dev ERC1155Receiver implementation is not checked\n * @param operator executor of transfer\n * @param sender sender of tokens\n * @param recipient receiver of tokens\n * @param ids token IDs\n * @param amounts quantities of tokens to transfer\n * @param data data payload\n */\n function _transferBatch(\n address operator,\n address sender,\n address recipient,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(\n recipient != address(0),\n 'ERC1155: transfer to the zero address'\n );\n require(\n ids.length == amounts.length,\n 'ERC1155: ids and amounts length mismatch'\n );\n\n _beforeTokenTransfer(operator, sender, recipient, ids, amounts, data);\n\n mapping(uint256 => mapping(address => uint256))\n storage balances = ERC1155BaseStorage.layout().balances;\n\n for (uint256 i; i < ids.length; i++) {\n uint256 token = ids[i];\n uint256 amount = amounts[i];\n\n unchecked {\n uint256 senderBalance = balances[token][sender];\n require(\n senderBalance >= amount,\n 'ERC1155: insufficient balances for transfer'\n );\n balances[token][sender] = senderBalance - amount;\n }\n\n balances[token][recipient] += amount;\n }\n\n emit TransferBatch(operator, sender, recipient, ids, amounts);\n }\n\n /**\n * @notice transfer batch of tokens between given addresses\n * @param operator executor of transfer\n * @param sender sender of tokens\n * @param recipient receiver of tokens\n * @param ids token IDs\n * @param amounts quantities of tokens to transfer\n * @param data data payload\n */\n function _safeTransferBatch(\n address operator,\n address sender,\n address recipient,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n _transferBatch(operator, sender, recipient, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(\n operator,\n sender,\n recipient,\n ids,\n amounts,\n data\n );\n }\n\n /**\n * @notice wrap given element in array of length 1\n * @param element element to wrap\n * @return singleton array\n */\n function _asSingletonArray(uint256 element)\n private\n pure\n returns (uint256[] memory)\n {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n return array;\n }\n\n /**\n * @notice revert if applicable transfer recipient is not valid ERC1155Receiver\n * @param operator executor of transfer\n * @param from sender of tokens\n * @param to receiver of tokens\n * @param id token ID\n * @param amount quantity of tokens to transfer\n * @param data data payload\n */\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try\n IERC1155Receiver(to).onERC1155Received(\n operator,\n from,\n id,\n amount,\n data\n )\n returns (bytes4 response) {\n require(\n response == IERC1155Receiver.onERC1155Received.selector,\n 'ERC1155: ERC1155Receiver rejected tokens'\n );\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert('ERC1155: transfer to non ERC1155Receiver implementer');\n }\n }\n }\n\n /**\n * @notice revert if applicable transfer recipient is not valid ERC1155Receiver\n * @param operator executor of transfer\n * @param from sender of tokens\n * @param to receiver of tokens\n * @param ids token IDs\n * @param amounts quantities of tokens to transfer\n * @param data data payload\n */\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try\n IERC1155Receiver(to).onERC1155BatchReceived(\n operator,\n from,\n ids,\n amounts,\n data\n )\n returns (bytes4 response) {\n require(\n response ==\n IERC1155Receiver.onERC1155BatchReceived.selector,\n 'ERC1155: ERC1155Receiver rejected tokens'\n );\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert('ERC1155: transfer to non ERC1155Receiver implementer');\n }\n }\n }\n\n /**\n * @notice ERC1155 hook, called before all transfers including mint and burn\n * @dev function should be overridden and new implementation must call super\n * @dev called for both single and batch transfers\n * @param operator executor of transfer\n * @param from sender of tokens\n * @param to receiver of tokens\n * @param ids token IDs\n * @param amounts quantities of tokens to transfer\n * @param data data payload\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n}\n"},"@solidstate/contracts/token/ERC20/IERC20Internal.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title Partial ERC20 interface needed by internal functions\n */\ninterface IERC20Internal {\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n}\n"},"@chainlink/contracts/src/v0.8/interfaces/AggregatorInterface.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorInterface {\n function latestAnswer()\n external\n view\n returns (\n int256\n );\n \n function latestTimestamp()\n external\n view\n returns (\n uint256\n );\n\n function latestRound()\n external\n view\n returns (\n uint256\n );\n\n function getAnswer(\n uint256 roundId\n )\n external\n view\n returns (\n int256\n );\n\n function getTimestamp(\n uint256 roundId\n )\n external\n view\n returns (\n uint256\n );\n\n event AnswerUpdated(\n int256 indexed current,\n uint256 indexed roundId,\n uint256 updatedAt\n );\n\n event NewRound(\n uint256 indexed roundId,\n address indexed startedBy,\n uint256 startedAt\n );\n}\n"},"contracts/pool/PoolExercise.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\r\n// For further clarification please see https://license.premia.legal\r\n\r\npragma solidity ^0.8.0;\r\n\r\nimport {ERC1155BaseStorage} from \"@solidstate/contracts/token/ERC1155/base/ERC1155BaseStorage.sol\";\r\n\r\nimport {PoolInternal} from \"./PoolInternal.sol\";\r\nimport {IPoolExercise} from \"./IPoolExercise.sol\";\r\n\r\n/**\r\n * @title Premia option pool\r\n * @dev deployed standalone and referenced by PoolProxy\r\n */\r\ncontract PoolExercise is IPoolExercise, PoolInternal {\r\n constructor(\r\n address ivolOracle,\r\n address weth,\r\n address premiaMining,\r\n address feeReceiver,\r\n address feeDiscountAddress,\r\n int128 fee64x64\r\n )\r\n PoolInternal(\r\n ivolOracle,\r\n weth,\r\n premiaMining,\r\n feeReceiver,\r\n feeDiscountAddress,\r\n fee64x64\r\n )\r\n {}\r\n\r\n /**\r\n * @inheritdoc IPoolExercise\r\n */\r\n function exerciseFrom(\r\n address holder,\r\n uint256 longTokenId,\r\n uint256 contractSize\r\n ) external override {\r\n if (msg.sender != holder) {\r\n require(\r\n ERC1155BaseStorage.layout().operatorApprovals[holder][\r\n msg.sender\r\n ],\r\n \"not approved\"\r\n );\r\n }\r\n\r\n _exercise(holder, longTokenId, contractSize);\r\n }\r\n\r\n /**\r\n * @inheritdoc IPoolExercise\r\n */\r\n function processExpired(uint256 longTokenId, uint256 contractSize)\r\n external\r\n override\r\n {\r\n _exercise(address(0), longTokenId, contractSize);\r\n }\r\n}\r\n"},"contracts/pool/IPoolExercise.sol":{"content":"// SPDX-License-Identifier: LGPL-3.0-or-later\r\n\r\npragma solidity ^0.8.0;\r\n\r\n/**\r\n * @notice Pool interface for exercising and processing of expired options\r\n */\r\ninterface IPoolExercise {\r\n /**\r\n * @notice exercise option on behalf of holder\r\n * @param holder owner of long option tokens to exercise\r\n * @param longTokenId long option token id\r\n * @param contractSize quantity of tokens to exercise\r\n */\r\n function exerciseFrom(\r\n address holder,\r\n uint256 longTokenId,\r\n uint256 contractSize\r\n ) external;\r\n\r\n /**\r\n * @notice process expired option, freeing liquidity and distributing profits\r\n * @param longTokenId long option token id\r\n * @param contractSize quantity of tokens to process\r\n */\r\n function processExpired(uint256 longTokenId, uint256 contractSize) external;\r\n}\r\n"},"contracts/pool/PoolStorage.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\r\n// For further clarification please see https://license.premia.legal\r\n\r\npragma solidity ^0.8.0;\r\n\r\nimport {AggregatorInterface} from \"@chainlink/contracts/src/v0.8/interfaces/AggregatorInterface.sol\";\r\nimport {AggregatorV3Interface} from \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\r\nimport {EnumerableSet, ERC1155EnumerableStorage} from \"@solidstate/contracts/token/ERC1155/enumerable/ERC1155EnumerableStorage.sol\";\r\n\r\nimport {ABDKMath64x64} from \"abdk-libraries-solidity/ABDKMath64x64.sol\";\r\nimport {ABDKMath64x64Token} from \"../libraries/ABDKMath64x64Token.sol\";\r\nimport {OptionMath} from \"../libraries/OptionMath.sol\";\r\n\r\nlibrary PoolStorage {\r\n using ABDKMath64x64 for int128;\r\n using PoolStorage for PoolStorage.Layout;\r\n\r\n enum TokenType {\r\n UNDERLYING_FREE_LIQ,\r\n BASE_FREE_LIQ,\r\n UNDERLYING_RESERVED_LIQ,\r\n BASE_RESERVED_LIQ,\r\n LONG_CALL,\r\n SHORT_CALL,\r\n LONG_PUT,\r\n SHORT_PUT\r\n }\r\n\r\n struct PoolSettings {\r\n address underlying;\r\n address base;\r\n address underlyingOracle;\r\n address baseOracle;\r\n }\r\n\r\n struct QuoteArgsInternal {\r\n address feePayer; // address of the fee payer\r\n uint64 maturity; // timestamp of option maturity\r\n int128 strike64x64; // 64x64 fixed point representation of strike price\r\n int128 spot64x64; // 64x64 fixed point representation of spot price\r\n uint256 contractSize; // size of option contract\r\n bool isCall; // true for call, false for put\r\n }\r\n\r\n struct QuoteResultInternal {\r\n int128 baseCost64x64; // 64x64 fixed point representation of option cost denominated in underlying currency (without fee)\r\n int128 feeCost64x64; // 64x64 fixed point representation of option fee cost denominated in underlying currency for call, or base currency for put\r\n int128 cLevel64x64; // 64x64 fixed point representation of C-Level of Pool after purchase\r\n int128 slippageCoefficient64x64; // 64x64 fixed point representation of slippage coefficient for given order size\r\n }\r\n\r\n struct BatchData {\r\n uint256 eta;\r\n uint256 totalPendingDeposits;\r\n }\r\n\r\n bytes32 internal constant STORAGE_SLOT =\r\n keccak256(\"premia.contracts.storage.Pool\");\r\n\r\n uint256 private constant C_DECAY_BUFFER = 12 hours;\r\n uint256 private constant C_DECAY_INTERVAL = 4 hours;\r\n\r\n struct Layout {\r\n // ERC20 token addresses\r\n address base;\r\n address underlying;\r\n // AggregatorV3Interface oracle addresses\r\n address baseOracle;\r\n address underlyingOracle;\r\n // token metadata\r\n uint8 underlyingDecimals;\r\n uint8 baseDecimals;\r\n // minimum amounts\r\n uint256 baseMinimum;\r\n uint256 underlyingMinimum;\r\n // deposit caps\r\n uint256 basePoolCap;\r\n uint256 underlyingPoolCap;\r\n // market state\r\n int128 _deprecated_steepness64x64;\r\n int128 cLevelBase64x64;\r\n int128 cLevelUnderlying64x64;\r\n uint256 cLevelBaseUpdatedAt;\r\n uint256 cLevelUnderlyingUpdatedAt;\r\n uint256 updatedAt;\r\n // User -> isCall -> depositedAt\r\n mapping(address => mapping(bool => uint256)) depositedAt;\r\n mapping(address => mapping(bool => uint256)) divestmentTimestamps;\r\n // doubly linked list of free liquidity intervals\r\n // isCall -> User -> User\r\n mapping(bool => mapping(address => address)) liquidityQueueAscending;\r\n mapping(bool => mapping(address => address)) liquidityQueueDescending;\r\n // minimum resolution price bucket => price\r\n mapping(uint256 => int128) bucketPrices64x64;\r\n // sequence id (minimum resolution price bucket / 256) => price update sequence\r\n mapping(uint256 => uint256) priceUpdateSequences;\r\n // isCall -> batch data\r\n mapping(bool => BatchData) nextDeposits;\r\n // user -> batch timestamp -> isCall -> pending amount\r\n mapping(address => mapping(uint256 => mapping(bool => uint256))) pendingDeposits;\r\n EnumerableSet.UintSet tokenIds;\r\n // user -> isCallPool -> total value locked of user (Used for liquidity mining)\r\n mapping(address => mapping(bool => uint256)) userTVL;\r\n // isCallPool -> total value locked\r\n mapping(bool => uint256) totalTVL;\r\n // steepness values\r\n int128 steepnessBase64x64;\r\n int128 steepnessUnderlying64x64;\r\n }\r\n\r\n function layout() internal pure returns (Layout storage l) {\r\n bytes32 slot = STORAGE_SLOT;\r\n assembly {\r\n l.slot := slot\r\n }\r\n }\r\n\r\n /**\r\n * @notice calculate ERC1155 token id for given option parameters\r\n * @param tokenType TokenType enum\r\n * @param maturity timestamp of option maturity\r\n * @param strike64x64 64x64 fixed point representation of strike price\r\n * @return tokenId token id\r\n */\r\n function formatTokenId(\r\n TokenType tokenType,\r\n uint64 maturity,\r\n int128 strike64x64\r\n ) internal pure returns (uint256 tokenId) {\r\n tokenId =\r\n (uint256(tokenType) << 248) +\r\n (uint256(maturity) << 128) +\r\n uint256(int256(strike64x64));\r\n }\r\n\r\n /**\r\n * @notice derive option maturity and strike price from ERC1155 token id\r\n * @param tokenId token id\r\n * @return tokenType TokenType enum\r\n * @return maturity timestamp of option maturity\r\n * @return strike64x64 option strike price\r\n */\r\n function parseTokenId(uint256 tokenId)\r\n internal\r\n pure\r\n returns (\r\n TokenType tokenType,\r\n uint64 maturity,\r\n int128 strike64x64\r\n )\r\n {\r\n assembly {\r\n tokenType := shr(248, tokenId)\r\n maturity := shr(128, tokenId)\r\n strike64x64 := tokenId\r\n }\r\n }\r\n\r\n function getTokenDecimals(Layout storage l, bool isCall)\r\n internal\r\n view\r\n returns (uint8 decimals)\r\n {\r\n decimals = isCall ? l.underlyingDecimals : l.baseDecimals;\r\n }\r\n\r\n /**\r\n * @notice get the total supply of free liquidity tokens, minus pending deposits\r\n * @param l storage layout struct\r\n * @param isCall whether query is for call or put pool\r\n * @return 64x64 fixed point representation of total free liquidity\r\n */\r\n function totalFreeLiquiditySupply64x64(Layout storage l, bool isCall)\r\n internal\r\n view\r\n returns (int128)\r\n {\r\n uint256 tokenId = formatTokenId(\r\n isCall ? TokenType.UNDERLYING_FREE_LIQ : TokenType.BASE_FREE_LIQ,\r\n 0,\r\n 0\r\n );\r\n\r\n return\r\n ABDKMath64x64Token.fromDecimals(\r\n ERC1155EnumerableStorage.layout().totalSupply[tokenId] -\r\n l.nextDeposits[isCall].totalPendingDeposits,\r\n l.getTokenDecimals(isCall)\r\n );\r\n }\r\n\r\n function getReinvestmentStatus(\r\n Layout storage l,\r\n address account,\r\n bool isCallPool\r\n ) internal view returns (bool) {\r\n uint256 timestamp = l.divestmentTimestamps[account][isCallPool];\r\n return timestamp == 0 || timestamp > block.timestamp;\r\n }\r\n\r\n function addUnderwriter(\r\n Layout storage l,\r\n address account,\r\n bool isCallPool\r\n ) internal {\r\n require(account != address(0));\r\n\r\n mapping(address => address) storage asc = l.liquidityQueueAscending[\r\n isCallPool\r\n ];\r\n mapping(address => address) storage desc = l.liquidityQueueDescending[\r\n isCallPool\r\n ];\r\n\r\n if (_isInQueue(account, asc, desc)) return;\r\n\r\n address last = desc[address(0)];\r\n\r\n asc[last] = account;\r\n desc[account] = last;\r\n desc[address(0)] = account;\r\n }\r\n\r\n function removeUnderwriter(\r\n Layout storage l,\r\n address account,\r\n bool isCallPool\r\n ) internal {\r\n require(account != address(0));\r\n\r\n mapping(address => address) storage asc = l.liquidityQueueAscending[\r\n isCallPool\r\n ];\r\n mapping(address => address) storage desc = l.liquidityQueueDescending[\r\n isCallPool\r\n ];\r\n\r\n if (!_isInQueue(account, asc, desc)) return;\r\n\r\n address prev = desc[account];\r\n address next = asc[account];\r\n asc[prev] = next;\r\n desc[next] = prev;\r\n delete asc[account];\r\n delete desc[account];\r\n }\r\n\r\n function isInQueue(\r\n Layout storage l,\r\n address account,\r\n bool isCallPool\r\n ) internal view returns (bool) {\r\n mapping(address => address) storage asc = l.liquidityQueueAscending[\r\n isCallPool\r\n ];\r\n mapping(address => address) storage desc = l.liquidityQueueDescending[\r\n isCallPool\r\n ];\r\n\r\n return _isInQueue(account, asc, desc);\r\n }\r\n\r\n function _isInQueue(\r\n address account,\r\n mapping(address => address) storage asc,\r\n mapping(address => address) storage desc\r\n ) private view returns (bool) {\r\n return asc[account] != address(0) || desc[address(0)] == account;\r\n }\r\n\r\n /**\r\n * @notice get current C-Level, without accounting for pending adjustments\r\n * @param l storage layout struct\r\n * @param isCall whether query is for call or put pool\r\n * @return cLevel64x64 64x64 fixed point representation of C-Level\r\n */\r\n function getRawCLevel64x64(Layout storage l, bool isCall)\r\n internal\r\n view\r\n returns (int128 cLevel64x64)\r\n {\r\n cLevel64x64 = isCall ? l.cLevelUnderlying64x64 : l.cLevelBase64x64;\r\n }\r\n\r\n /**\r\n * @notice get current C-Level, accounting for unrealized decay\r\n * @param l storage layout struct\r\n * @param isCall whether query is for call or put pool\r\n * @return cLevel64x64 64x64 fixed point representation of C-Level\r\n */\r\n function getDecayAdjustedCLevel64x64(Layout storage l, bool isCall)\r\n internal\r\n view\r\n returns (int128 cLevel64x64)\r\n {\r\n // get raw C-Level from storage\r\n cLevel64x64 = l.getRawCLevel64x64(isCall);\r\n\r\n // account for C-Level decay\r\n cLevel64x64 = l.applyCLevelDecayAdjustment(cLevel64x64, isCall);\r\n }\r\n\r\n /**\r\n * @notice calculate updated C-Level, accounting for unrealized decay\r\n * @param l storage layout struct\r\n * @param oldCLevel64x64 64x64 fixed point representation pool C-Level before accounting for decay\r\n * @param isCall whether query is for call or put pool\r\n * @return cLevel64x64 64x64 fixed point representation of C-Level of Pool after accounting for decay\r\n */\r\n function applyCLevelDecayAdjustment(\r\n Layout storage l,\r\n int128 oldCLevel64x64,\r\n bool isCall\r\n ) internal view returns (int128 cLevel64x64) {\r\n uint256 timeElapsed = block.timestamp -\r\n (isCall ? l.cLevelUnderlyingUpdatedAt : l.cLevelBaseUpdatedAt);\r\n\r\n // do not apply C decay if less than 24 hours have elapsed\r\n\r\n if (timeElapsed > C_DECAY_BUFFER) {\r\n timeElapsed -= C_DECAY_BUFFER;\r\n } else {\r\n return oldCLevel64x64;\r\n }\r\n\r\n int128 timeIntervalsElapsed64x64 = ABDKMath64x64.divu(\r\n timeElapsed,\r\n C_DECAY_INTERVAL\r\n );\r\n\r\n uint256 tokenId = formatTokenId(\r\n isCall ? TokenType.UNDERLYING_FREE_LIQ : TokenType.BASE_FREE_LIQ,\r\n 0,\r\n 0\r\n );\r\n\r\n uint256 tvl = l.totalTVL[isCall];\r\n\r\n int128 utilization = ABDKMath64x64.divu(\r\n tvl -\r\n (ERC1155EnumerableStorage.layout().totalSupply[tokenId] -\r\n l.nextDeposits[isCall].totalPendingDeposits),\r\n tvl\r\n );\r\n\r\n return\r\n OptionMath.calculateCLevelDecay(\r\n OptionMath.CalculateCLevelDecayArgs(\r\n timeIntervalsElapsed64x64,\r\n oldCLevel64x64,\r\n utilization,\r\n 0xb333333333333333, // 0.7\r\n 0xe666666666666666, // 0.9\r\n 0x10000000000000000, // 1.0\r\n 0x10000000000000000, // 1.0\r\n 0xe666666666666666, // 0.9\r\n 0x56fc2a2c515da32ea // 2e\r\n )\r\n );\r\n }\r\n\r\n /**\r\n * @notice calculate updated C-Level, accounting for pending deposits\r\n * @param l storage layout struct\r\n * @param oldCLevel64x64 64x64 fixed point representation pool C-Level before accounting for liquidity change\r\n * @param oldLiquidity64x64 64x64 fixed point representation of previous liquidity\r\n * @param isCall whether to update C-Level for call or put pool\r\n * @return cLevel64x64 64x64 fixed point representation of C-Level\r\n * @return liquidity64x64 64x64 fixed point representation of new liquidity amount\r\n */\r\n function applyCLevelPendingDepositAdjustment(\r\n Layout storage l,\r\n int128 oldCLevel64x64,\r\n int128 oldLiquidity64x64,\r\n bool isCall\r\n ) internal view returns (int128 cLevel64x64, int128 liquidity64x64) {\r\n PoolStorage.BatchData storage batchData = l.nextDeposits[isCall];\r\n int128 pendingDeposits64x64;\r\n\r\n if (\r\n batchData.totalPendingDeposits > 0 &&\r\n batchData.eta != 0 &&\r\n block.timestamp >= batchData.eta\r\n ) {\r\n pendingDeposits64x64 = ABDKMath64x64Token.fromDecimals(\r\n batchData.totalPendingDeposits,\r\n l.getTokenDecimals(isCall)\r\n );\r\n\r\n liquidity64x64 = oldLiquidity64x64.add(pendingDeposits64x64);\r\n\r\n cLevel64x64 = l.applyCLevelLiquidityChangeAdjustment(\r\n oldCLevel64x64,\r\n oldLiquidity64x64,\r\n liquidity64x64,\r\n isCall\r\n );\r\n } else {\r\n cLevel64x64 = oldCLevel64x64;\r\n liquidity64x64 = oldLiquidity64x64;\r\n }\r\n }\r\n\r\n /**\r\n * @notice calculate updated C-Level, accounting for change in liquidity\r\n * @param l storage layout struct\r\n * @param oldCLevel64x64 64x64 fixed point representation pool C-Level before accounting for liquidity change\r\n * @param oldLiquidity64x64 64x64 fixed point representation of previous liquidity\r\n * @param newLiquidity64x64 64x64 fixed point representation of current liquidity\r\n * @param isCallPool whether to update C-Level for call or put pool\r\n * @return cLevel64x64 64x64 fixed point representation of C-Level\r\n */\r\n function applyCLevelLiquidityChangeAdjustment(\r\n Layout storage l,\r\n int128 oldCLevel64x64,\r\n int128 oldLiquidity64x64,\r\n int128 newLiquidity64x64,\r\n bool isCallPool\r\n ) internal view returns (int128 cLevel64x64) {\r\n int128 steepness64x64 = isCallPool\r\n ? l.steepnessUnderlying64x64\r\n : l.steepnessBase64x64;\r\n\r\n // fallback to deprecated storage value if side-specific value is not set\r\n if (steepness64x64 == 0) steepness64x64 = l._deprecated_steepness64x64;\r\n\r\n cLevel64x64 = OptionMath.calculateCLevel(\r\n oldCLevel64x64,\r\n oldLiquidity64x64,\r\n newLiquidity64x64,\r\n steepness64x64\r\n );\r\n\r\n if (cLevel64x64 < 0xb333333333333333) {\r\n cLevel64x64 = int128(0xb333333333333333); // 64x64 fixed point representation of 0.7\r\n }\r\n }\r\n\r\n /**\r\n * @notice set C-Level to arbitrary pre-calculated value\r\n * @param cLevel64x64 new C-Level of pool\r\n * @param isCallPool whether to update C-Level for call or put pool\r\n */\r\n function setCLevel(\r\n Layout storage l,\r\n int128 cLevel64x64,\r\n bool isCallPool\r\n ) internal {\r\n if (isCallPool) {\r\n l.cLevelUnderlying64x64 = cLevel64x64;\r\n l.cLevelUnderlyingUpdatedAt = block.timestamp;\r\n } else {\r\n l.cLevelBase64x64 = cLevel64x64;\r\n l.cLevelBaseUpdatedAt = block.timestamp;\r\n }\r\n }\r\n\r\n function setOracles(\r\n Layout storage l,\r\n address baseOracle,\r\n address underlyingOracle\r\n ) internal {\r\n require(\r\n AggregatorV3Interface(baseOracle).decimals() ==\r\n AggregatorV3Interface(underlyingOracle).decimals(),\r\n \"Pool: oracle decimals must match\"\r\n );\r\n\r\n l.baseOracle = baseOracle;\r\n l.underlyingOracle = underlyingOracle;\r\n }\r\n\r\n function fetchPriceUpdate(Layout storage l)\r\n internal\r\n view\r\n returns (int128 price64x64)\r\n {\r\n int256 priceUnderlying = AggregatorInterface(l.underlyingOracle)\r\n .latestAnswer();\r\n int256 priceBase = AggregatorInterface(l.baseOracle).latestAnswer();\r\n\r\n return ABDKMath64x64.divi(priceUnderlying, priceBase);\r\n }\r\n\r\n /**\r\n * @notice set price update for hourly bucket corresponding to given timestamp\r\n * @param l storage layout struct\r\n * @param timestamp timestamp to update\r\n * @param price64x64 64x64 fixed point representation of price\r\n */\r\n function setPriceUpdate(\r\n Layout storage l,\r\n uint256 timestamp,\r\n int128 price64x64\r\n ) internal {\r\n uint256 bucket = timestamp / (1 hours);\r\n l.bucketPrices64x64[bucket] = price64x64;\r\n l.priceUpdateSequences[bucket >> 8] += 1 << (255 - (bucket & 255));\r\n }\r\n\r\n /**\r\n * @notice get price update for hourly bucket corresponding to given timestamp\r\n * @param l storage layout struct\r\n * @param timestamp timestamp to query\r\n * @return 64x64 fixed point representation of price\r\n */\r\n function getPriceUpdate(Layout storage l, uint256 timestamp)\r\n internal\r\n view\r\n returns (int128)\r\n {\r\n return l.bucketPrices64x64[timestamp / (1 hours)];\r\n }\r\n\r\n /**\r\n * @notice get first price update available following given timestamp\r\n * @param l storage layout struct\r\n * @param timestamp timestamp to query\r\n * @return 64x64 fixed point representation of price\r\n */\r\n function getPriceUpdateAfter(Layout storage l, uint256 timestamp)\r\n internal\r\n view\r\n returns (int128)\r\n {\r\n // price updates are grouped into hourly buckets\r\n uint256 bucket = timestamp / (1 hours);\r\n // divide by 256 to get the index of the relevant price update sequence\r\n uint256 sequenceId = bucket >> 8;\r\n\r\n // get position within sequence relevant to current price update\r\n\r\n uint256 offset = bucket & 255;\r\n // shift to skip buckets from earlier in sequence\r\n uint256 sequence = (l.priceUpdateSequences[sequenceId] << offset) >>\r\n offset;\r\n\r\n // iterate through future sequences until a price update is found\r\n // sequence corresponding to current timestamp used as upper bound\r\n\r\n uint256 currentPriceUpdateSequenceId = block.timestamp / (256 hours);\r\n\r\n while (sequence == 0 && sequenceId <= currentPriceUpdateSequenceId) {\r\n sequence = l.priceUpdateSequences[++sequenceId];\r\n }\r\n\r\n // if no price update is found (sequence == 0) function will return 0\r\n // this should never occur, as each relevant external function triggers a price update\r\n\r\n // the most significant bit of the sequence corresponds to the offset of the relevant bucket\r\n\r\n uint256 msb;\r\n\r\n for (uint256 i = 128; i > 0; i >>= 1) {\r\n if (sequence >> i > 0) {\r\n msb += i;\r\n sequence >>= i;\r\n }\r\n }\r\n\r\n return l.bucketPrices64x64[((sequenceId + 1) << 8) - msb - 1];\r\n }\r\n\r\n function fromBaseToUnderlyingDecimals(Layout storage l, uint256 value)\r\n internal\r\n view\r\n returns (uint256)\r\n {\r\n int128 valueFixed64x64 = ABDKMath64x64Token.fromDecimals(\r\n value,\r\n l.baseDecimals\r\n );\r\n return\r\n ABDKMath64x64Token.toDecimals(\r\n valueFixed64x64,\r\n l.underlyingDecimals\r\n );\r\n }\r\n\r\n function fromUnderlyingToBaseDecimals(Layout storage l, uint256 value)\r\n internal\r\n view\r\n returns (uint256)\r\n {\r\n int128 valueFixed64x64 = ABDKMath64x64Token.fromDecimals(\r\n value,\r\n l.underlyingDecimals\r\n );\r\n return ABDKMath64x64Token.toDecimals(valueFixed64x64, l.baseDecimals);\r\n }\r\n}\r\n"},"@solidstate/contracts/utils/AddressUtils.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nlibrary AddressUtils {\n function toString(address account) internal pure returns (string memory) {\n bytes32 value = bytes32(uint256(uint160(account)));\n bytes memory alphabet = '0123456789abcdef';\n bytes memory chars = new bytes(42);\n\n chars[0] = '0';\n chars[1] = 'x';\n\n for (uint256 i = 0; i < 20; i++) {\n chars[2 + i * 2] = alphabet[uint8(value[i + 12] >> 4)];\n chars[3 + i * 2] = alphabet[uint8(value[i + 12] & 0x0f)];\n }\n\n return string(chars);\n }\n\n function isContract(address account) internal view returns (bool) {\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size > 0;\n }\n\n function sendValue(address payable account, uint256 amount) internal {\n (bool success, ) = account.call{ value: amount }('');\n require(success, 'AddressUtils: failed to send value');\n }\n\n function functionCall(address target, bytes memory data)\n internal\n returns (bytes memory)\n {\n return\n functionCall(target, data, 'AddressUtils: failed low-level call');\n }\n\n function functionCall(\n address target,\n bytes memory data,\n string memory error\n ) internal returns (bytes memory) {\n return _functionCallWithValue(target, data, 0, error);\n }\n\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return\n functionCallWithValue(\n target,\n data,\n value,\n 'AddressUtils: failed low-level call with value'\n );\n }\n\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory error\n ) internal returns (bytes memory) {\n require(\n address(this).balance >= value,\n 'AddressUtils: insufficient balance for call'\n );\n return _functionCallWithValue(target, data, value, error);\n }\n\n function _functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory error\n ) private returns (bytes memory) {\n require(\n isContract(target),\n 'AddressUtils: function call to non-contract'\n );\n\n (bool success, bytes memory returnData) = target.call{ value: value }(\n data\n );\n\n if (success) {\n return returnData;\n } else if (returnData.length > 0) {\n assembly {\n let returnData_size := mload(returnData)\n revert(add(32, returnData), returnData_size)\n }\n } else {\n revert(error);\n }\n }\n}\n"},"@solidstate/contracts/token/ERC1155/enumerable/ERC1155Enumerable.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { EnumerableSet } from '../../../utils/EnumerableSet.sol';\nimport { ERC1155Base, ERC1155BaseInternal } from '../base/ERC1155Base.sol';\nimport { IERC1155Enumerable } from './IERC1155Enumerable.sol';\nimport { ERC1155EnumerableInternal, ERC1155EnumerableStorage } from './ERC1155EnumerableInternal.sol';\n\n/**\n * @title ERC1155 implementation including enumerable and aggregate functions\n */\nabstract contract ERC1155Enumerable is\n IERC1155Enumerable,\n ERC1155Base,\n ERC1155EnumerableInternal\n{\n using EnumerableSet for EnumerableSet.AddressSet;\n using EnumerableSet for EnumerableSet.UintSet;\n\n /**\n * @inheritdoc IERC1155Enumerable\n */\n function totalSupply(uint256 id)\n public\n view\n virtual\n override\n returns (uint256)\n {\n return ERC1155EnumerableStorage.layout().totalSupply[id];\n }\n\n /**\n * @inheritdoc IERC1155Enumerable\n */\n function totalHolders(uint256 id)\n public\n view\n virtual\n override\n returns (uint256)\n {\n return ERC1155EnumerableStorage.layout().accountsByToken[id].length();\n }\n\n /**\n * @inheritdoc IERC1155Enumerable\n */\n function accountsByToken(uint256 id)\n public\n view\n virtual\n override\n returns (address[] memory)\n {\n EnumerableSet.AddressSet storage accounts = ERC1155EnumerableStorage\n .layout()\n .accountsByToken[id];\n\n address[] memory addresses = new address[](accounts.length());\n\n for (uint256 i; i < accounts.length(); i++) {\n addresses[i] = accounts.at(i);\n }\n\n return addresses;\n }\n\n /**\n * @inheritdoc IERC1155Enumerable\n */\n function tokensByAccount(address account)\n public\n view\n virtual\n override\n returns (uint256[] memory)\n {\n EnumerableSet.UintSet storage tokens = ERC1155EnumerableStorage\n .layout()\n .tokensByAccount[account];\n\n uint256[] memory ids = new uint256[](tokens.length());\n\n for (uint256 i; i < tokens.length(); i++) {\n ids[i] = tokens.at(i);\n }\n\n return ids;\n }\n\n /**\n * @notice ERC1155 hook: update aggregate values\n * @inheritdoc ERC1155EnumerableInternal\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n override(ERC1155BaseInternal, ERC1155EnumerableInternal)\n {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n }\n}\n"},"@solidstate/contracts/token/ERC1155/IERC1155Receiver.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IERC165 } from '../../introspection/IERC165.sol';\n\n/**\n * @title ERC1155 transfer receiver interface\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @notice validate receipt of ERC1155 transfer\n * @param operator executor of transfer\n * @param from sender of tokens\n * @param id token ID received\n * @param value quantity of tokens received\n * @param data data payload\n * @return function's own selector if transfer is accepted\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @notice validate receipt of ERC1155 batch transfer\n * @param operator executor of transfer\n * @param from sender of tokens\n * @param ids token IDs received\n * @param values quantities of tokens received\n * @param data data payload\n * @return function's own selector if transfer is accepted\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n"},"contracts/pool/IPoolEvents.sol":{"content":"// SPDX-License-Identifier: LGPL-3.0-or-later\r\n\r\npragma solidity ^0.8.0;\r\n\r\ninterface IPoolEvents {\r\n event Purchase(\r\n address indexed user,\r\n uint256 longTokenId,\r\n uint256 contractSize,\r\n uint256 baseCost,\r\n uint256 feeCost,\r\n int128 spot64x64\r\n );\r\n\r\n event Exercise(\r\n address indexed user,\r\n uint256 longTokenId,\r\n uint256 contractSize,\r\n uint256 exerciseValue,\r\n uint256 fee\r\n );\r\n\r\n event Underwrite(\r\n address indexed underwriter,\r\n address indexed longReceiver,\r\n uint256 shortTokenId,\r\n uint256 intervalContractSize,\r\n uint256 intervalPremium,\r\n bool isManualUnderwrite\r\n );\r\n\r\n event AssignExercise(\r\n address indexed underwriter,\r\n uint256 shortTokenId,\r\n uint256 freedAmount,\r\n uint256 intervalContractSize,\r\n uint256 fee\r\n );\r\n\r\n event Deposit(address indexed user, bool isCallPool, uint256 amount);\r\n\r\n event Withdrawal(\r\n address indexed user,\r\n bool isCallPool,\r\n uint256 depositedAt,\r\n uint256 amount\r\n );\r\n\r\n event FeeWithdrawal(bool indexed isCallPool, uint256 amount);\r\n\r\n event Annihilate(uint256 shortTokenId, uint256 amount);\r\n\r\n event UpdateCLevel(\r\n bool indexed isCall,\r\n int128 cLevel64x64,\r\n int128 oldLiquidity64x64,\r\n int128 newLiquidity64x64\r\n );\r\n\r\n event UpdateSteepness(int128 steepness64x64, bool isCallPool);\r\n}\r\n"},"contracts/oracle/VolatilitySurfaceOracleStorage.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\r\n// For further clarification please see https://license.premia.legal\r\n\r\npragma solidity ^0.8.0;\r\n\r\nimport {EnumerableSet} from \"@solidstate/contracts/utils/EnumerableSet.sol\";\r\n\r\nlibrary VolatilitySurfaceOracleStorage {\r\n bytes32 internal constant STORAGE_SLOT =\r\n keccak256(\"premia.contracts.storage.VolatilitySurfaceOracle\");\r\n\r\n uint256 internal constant COEFF_BITS = 51;\r\n uint256 internal constant COEFF_BITS_MINUS_ONE = 50;\r\n uint256 internal constant COEFF_AMOUNT = 5;\r\n // START_BIT = COEFF_BITS * (COEFF_AMOUNT - 1)\r\n uint256 internal constant START_BIT = 204;\r\n\r\n struct Update {\r\n uint256 updatedAt;\r\n bytes32 callCoefficients;\r\n bytes32 putCoefficients;\r\n }\r\n\r\n struct Layout {\r\n // Base token -> Underlying token -> Update\r\n mapping(address => mapping(address => Update)) volatilitySurfaces;\r\n // Relayer addresses which can be trusted to provide accurate option trades\r\n EnumerableSet.AddressSet whitelistedRelayers;\r\n }\r\n\r\n function layout() internal pure returns (Layout storage l) {\r\n bytes32 slot = STORAGE_SLOT;\r\n assembly {\r\n l.slot := slot\r\n }\r\n }\r\n\r\n function getCoefficients(\r\n Layout storage l,\r\n address baseToken,\r\n address underlyingToken,\r\n bool isCall\r\n ) internal view returns (bytes32) {\r\n Update storage u = l.volatilitySurfaces[baseToken][underlyingToken];\r\n return isCall ? u.callCoefficients : u.putCoefficients;\r\n }\r\n\r\n function parseVolatilitySurfaceCoefficients(bytes32 input)\r\n internal\r\n pure\r\n returns (int256[] memory coefficients)\r\n {\r\n coefficients = new int256[](COEFF_AMOUNT);\r\n\r\n // Value to add to negative numbers to cast them to int256\r\n int256 toAdd = (int256(-1) >> COEFF_BITS) << COEFF_BITS;\r\n\r\n assembly {\r\n let i := 0\r\n // Value equal to -1\r\n let mid := shl(COEFF_BITS_MINUS_ONE, 1)\r\n\r\n for {\r\n\r\n } lt(i, COEFF_AMOUNT) {\r\n\r\n } {\r\n let offset := sub(START_BIT, mul(COEFF_BITS, i))\r\n let coeff := shr(\r\n offset,\r\n sub(\r\n input,\r\n shl(\r\n add(offset, COEFF_BITS),\r\n shr(add(offset, COEFF_BITS), input)\r\n )\r\n )\r\n )\r\n\r\n // Check if value is a negative number and needs casting\r\n if or(eq(coeff, mid), gt(coeff, mid)) {\r\n coeff := add(coeff, toAdd)\r\n }\r\n\r\n // Store result in the coefficients array\r\n mstore(add(coefficients, add(0x20, mul(0x20, i))), coeff)\r\n\r\n i := add(i, 1)\r\n }\r\n }\r\n }\r\n\r\n function formatVolatilitySurfaceCoefficients(int256[5] memory coefficients)\r\n internal\r\n pure\r\n returns (bytes32 result)\r\n {\r\n for (uint256 i = 0; i < COEFF_AMOUNT; i++) {\r\n int256 max = int256(1 << COEFF_BITS_MINUS_ONE);\r\n require(\r\n coefficients[i] < max && coefficients[i] > -max,\r\n \"Out of bounds\"\r\n );\r\n }\r\n\r\n assembly {\r\n let i := 0\r\n\r\n for {\r\n\r\n } lt(i, COEFF_AMOUNT) {\r\n\r\n } {\r\n let offset := sub(START_BIT, mul(COEFF_BITS, i))\r\n let coeff := mload(add(coefficients, mul(0x20, i)))\r\n\r\n result := add(\r\n result,\r\n shl(\r\n offset,\r\n sub(coeff, shl(COEFF_BITS, shr(COEFF_BITS, coeff)))\r\n )\r\n )\r\n\r\n i := add(i, 1)\r\n }\r\n }\r\n }\r\n}\r\n"},"@solidstate/contracts/token/ERC1155/enumerable/IERC1155Enumerable.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC1155 enumerable and aggregate function interface\n */\ninterface IERC1155Enumerable {\n /**\n * @notice query total minted supply of given token\n * @param id token id to query\n * @return token supply\n */\n function totalSupply(uint256 id) external view returns (uint256);\n\n /**\n * @notice query total number of holders for given token\n * @param id token id to query\n * @return quantity of holders\n */\n function totalHolders(uint256 id) external view returns (uint256);\n\n /**\n * @notice query holders of given token\n * @param id token id to query\n * @return list of holder addresses\n */\n function accountsByToken(uint256 id)\n external\n view\n returns (address[] memory);\n\n /**\n * @notice query tokens held by given address\n * @param account address to query\n * @return list of token ids\n */\n function tokensByAccount(address account)\n external\n view\n returns (uint256[] memory);\n}\n"},"@solidstate/contracts/token/ERC20/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IERC20Internal } from './IERC20Internal.sol';\n\n/**\n * @title ERC20 interface\n * @dev see https://github.com/ethereum/EIPs/issues/20\n */\ninterface IERC20 is IERC20Internal {\n /**\n * @notice query the total minted token supply\n * @return token supply\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @notice query the token balance of given account\n * @param account address to query\n * @return token balance\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @notice query the allowance granted from given holder to given spender\n * @param holder approver of allowance\n * @param spender recipient of allowance\n * @return token allowance\n */\n function allowance(address holder, address spender)\n external\n view\n returns (uint256);\n\n /**\n * @notice grant approval to spender to spend tokens\n * @dev prefer ERC20Extended functions to avoid transaction-ordering vulnerability (see https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729)\n * @param spender recipient of allowance\n * @param amount quantity of tokens approved for spending\n * @return success status (always true; otherwise function should revert)\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @notice transfer tokens to given recipient\n * @param recipient beneficiary of token transfer\n * @param amount quantity of tokens to transfer\n * @return success status (always true; otherwise function should revert)\n */\n function transfer(address recipient, uint256 amount)\n external\n returns (bool);\n\n /**\n * @notice transfer tokens to given recipient on behalf of given holder\n * @param holder holder of tokens prior to transfer\n * @param recipient beneficiary of token transfer\n * @param amount quantity of tokens to transfer\n * @return success status (always true; otherwise function should revert)\n */\n function transferFrom(\n address holder,\n address recipient,\n uint256 amount\n ) external returns (bool);\n}\n"},"contracts/mining/IPremiaMining.sol":{"content":"// SPDX-License-Identifier: LGPL-3.0-or-later\r\n\r\npragma solidity ^0.8.0;\r\n\r\nimport {PremiaMiningStorage} from \"./PremiaMiningStorage.sol\";\r\n\r\ninterface IPremiaMining {\r\n function addPremiaRewards(uint256 _amount) external;\r\n\r\n function premiaRewardsAvailable() external view returns (uint256);\r\n\r\n function getTotalAllocationPoints() external view returns (uint256);\r\n\r\n function getPoolInfo(address pool, bool isCallPool)\r\n external\r\n view\r\n returns (PremiaMiningStorage.PoolInfo memory);\r\n\r\n function getPremiaPerYear() external view returns (uint256);\r\n\r\n function addPool(address _pool, uint256 _allocPoints) external;\r\n\r\n function setPoolAllocPoints(\r\n address[] memory _pools,\r\n uint256[] memory _allocPoints\r\n ) external;\r\n\r\n function pendingPremia(\r\n address _pool,\r\n bool _isCallPool,\r\n address _user\r\n ) external view returns (uint256);\r\n\r\n function updatePool(\r\n address _pool,\r\n bool _isCallPool,\r\n uint256 _totalTVL\r\n ) external;\r\n\r\n function allocatePending(\r\n address _user,\r\n address _pool,\r\n bool _isCallPool,\r\n uint256 _userTVLOld,\r\n uint256 _userTVLNew,\r\n uint256 _totalTVL\r\n ) external;\r\n\r\n function claim(\r\n address _user,\r\n address _pool,\r\n bool _isCallPool,\r\n uint256 _userTVLOld,\r\n uint256 _userTVLNew,\r\n uint256 _totalTVL\r\n ) external;\r\n}\r\n"},"@solidstate/contracts/token/ERC1155/enumerable/ERC1155EnumerableStorage.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { EnumerableSet } from '../../../utils/EnumerableSet.sol';\n\nlibrary ERC1155EnumerableStorage {\n struct Layout {\n mapping(uint256 => uint256) totalSupply;\n mapping(uint256 => EnumerableSet.AddressSet) accountsByToken;\n mapping(address => EnumerableSet.UintSet) tokensByAccount;\n }\n\n bytes32 internal constant STORAGE_SLOT =\n keccak256('solidstate.contracts.storage.ERC1155Enumerable');\n\n function layout() internal pure returns (Layout storage l) {\n bytes32 slot = STORAGE_SLOT;\n assembly {\n l.slot := slot\n }\n }\n}\n"},"@solidstate/contracts/token/ERC1155/enumerable/ERC1155EnumerableInternal.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { EnumerableSet } from '../../../utils/EnumerableSet.sol';\nimport { ERC1155BaseInternal, ERC1155BaseStorage } from '../base/ERC1155BaseInternal.sol';\nimport { ERC1155EnumerableStorage } from './ERC1155EnumerableStorage.sol';\n\n/**\n * @title ERC1155Enumerable internal functions\n */\nabstract contract ERC1155EnumerableInternal is ERC1155BaseInternal {\n using EnumerableSet for EnumerableSet.AddressSet;\n using EnumerableSet for EnumerableSet.UintSet;\n\n /**\n * @notice ERC1155 hook: update aggregate values\n * @inheritdoc ERC1155BaseInternal\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual override {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n if (from != to) {\n ERC1155EnumerableStorage.Layout storage l = ERC1155EnumerableStorage\n .layout();\n mapping(uint256 => EnumerableSet.AddressSet)\n storage tokenAccounts = l.accountsByToken;\n EnumerableSet.UintSet storage fromTokens = l.tokensByAccount[from];\n EnumerableSet.UintSet storage toTokens = l.tokensByAccount[to];\n\n for (uint256 i; i < ids.length; i++) {\n uint256 amount = amounts[i];\n\n if (amount > 0) {\n uint256 id = ids[i];\n\n if (from == address(0)) {\n l.totalSupply[id] += amount;\n } else if (_balanceOf(from, id) == amount) {\n tokenAccounts[id].remove(from);\n fromTokens.remove(id);\n }\n\n if (to == address(0)) {\n l.totalSupply[id] -= amount;\n } else if (_balanceOf(to, id) == 0) {\n tokenAccounts[id].add(to);\n toTokens.add(id);\n }\n }\n }\n }\n }\n}\n"},"contracts/oracle/IVolatilitySurfaceOracle.sol":{"content":"// SPDX-License-Identifier: LGPL-3.0-or-later\r\n\r\npragma solidity ^0.8.0;\r\n\r\nimport {VolatilitySurfaceOracleStorage} from \"./VolatilitySurfaceOracleStorage.sol\";\r\n\r\ninterface IVolatilitySurfaceOracle {\r\n function getWhitelistedRelayers() external view returns (address[] memory);\r\n\r\n function getVolatilitySurface(address baseToken, address underlyingToken)\r\n external\r\n view\r\n returns (VolatilitySurfaceOracleStorage.Update memory);\r\n\r\n function getVolatilitySurfaceCoefficientsUnpacked(\r\n address baseToken,\r\n address underlyingToken,\r\n bool isCall\r\n ) external view returns (int256[] memory);\r\n\r\n function getTimeToMaturity64x64(uint64 maturity)\r\n external\r\n view\r\n returns (int128);\r\n\r\n function getAnnualizedVolatility64x64(\r\n address baseToken,\r\n address underlyingToken,\r\n int128 spot64x64,\r\n int128 strike64x64,\r\n int128 timeToMaturity64x64,\r\n bool isCall\r\n ) external view returns (int128);\r\n\r\n function getBlackScholesPrice64x64(\r\n address baseToken,\r\n address underlyingToken,\r\n int128 strike64x64,\r\n int128 spot64x64,\r\n int128 timeToMaturity64x64,\r\n bool isCall\r\n ) external view returns (int128);\r\n\r\n function getBlackScholesPrice(\r\n address baseToken,\r\n address underlyingToken,\r\n int128 strike64x64,\r\n int128 spot64x64,\r\n int128 timeToMaturity64x64,\r\n bool isCall\r\n ) external view returns (uint256);\r\n}\r\n"},"contracts/pool/PoolInternal.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\r\n// For further clarification please see https://license.premia.legal\r\n\r\npragma solidity ^0.8.0;\r\n\r\nimport {IERC173} from \"@solidstate/contracts/access/IERC173.sol\";\r\nimport {OwnableStorage} from \"@solidstate/contracts/access/OwnableStorage.sol\";\r\nimport {IERC20} from \"@solidstate/contracts/token/ERC20/IERC20.sol\";\r\nimport {ERC1155EnumerableInternal, ERC1155EnumerableStorage, EnumerableSet} from \"@solidstate/contracts/token/ERC1155/enumerable/ERC1155Enumerable.sol\";\r\nimport {IWETH} from \"@solidstate/contracts/utils/IWETH.sol\";\r\n\r\nimport {PoolStorage} from \"./PoolStorage.sol\";\r\n\r\nimport {ABDKMath64x64} from \"abdk-libraries-solidity/ABDKMath64x64.sol\";\r\nimport {ABDKMath64x64Token} from \"../libraries/ABDKMath64x64Token.sol\";\r\nimport {OptionMath} from \"../libraries/OptionMath.sol\";\r\nimport {IFeeDiscount} from \"../staking/IFeeDiscount.sol\";\r\nimport {IPoolEvents} from \"./IPoolEvents.sol\";\r\nimport {IPremiaMining} from \"../mining/IPremiaMining.sol\";\r\nimport {IVolatilitySurfaceOracle} from \"../oracle/IVolatilitySurfaceOracle.sol\";\r\n\r\n/**\r\n * @title Premia option pool\r\n * @dev deployed standalone and referenced by PoolProxy\r\n */\r\ncontract PoolInternal is IPoolEvents, ERC1155EnumerableInternal {\r\n using ABDKMath64x64 for int128;\r\n using EnumerableSet for EnumerableSet.AddressSet;\r\n using EnumerableSet for EnumerableSet.UintSet;\r\n using PoolStorage for PoolStorage.Layout;\r\n\r\n address internal immutable WETH_ADDRESS;\r\n address internal immutable PREMIA_MINING_ADDRESS;\r\n address internal immutable FEE_RECEIVER_ADDRESS;\r\n address internal immutable FEE_DISCOUNT_ADDRESS;\r\n address internal immutable IVOL_ORACLE_ADDRESS;\r\n\r\n int128 internal immutable FEE_64x64;\r\n\r\n uint256 internal immutable UNDERLYING_FREE_LIQ_TOKEN_ID;\r\n uint256 internal immutable BASE_FREE_LIQ_TOKEN_ID;\r\n\r\n uint256 internal immutable UNDERLYING_RESERVED_LIQ_TOKEN_ID;\r\n uint256 internal immutable BASE_RESERVED_LIQ_TOKEN_ID;\r\n\r\n uint256 internal constant INVERSE_BASIS_POINT = 1e4;\r\n uint256 internal constant BATCHING_PERIOD = 260;\r\n\r\n // Minimum APY for capital locked up to underwrite options.\r\n // The quote will return a minimum price corresponding to this APY\r\n int128 internal constant MIN_APY_64x64 = 0x4ccccccccccccccd; // 0.3\r\n\r\n constructor(\r\n address ivolOracle,\r\n address weth,\r\n address premiaMining,\r\n address feeReceiver,\r\n address feeDiscountAddress,\r\n int128 fee64x64\r\n ) {\r\n IVOL_ORACLE_ADDRESS = ivolOracle;\r\n WETH_ADDRESS = weth;\r\n PREMIA_MINING_ADDRESS = premiaMining;\r\n FEE_RECEIVER_ADDRESS = feeReceiver;\r\n // PremiaFeeDiscount contract address\r\n FEE_DISCOUNT_ADDRESS = feeDiscountAddress;\r\n FEE_64x64 = fee64x64;\r\n\r\n UNDERLYING_FREE_LIQ_TOKEN_ID = PoolStorage.formatTokenId(\r\n PoolStorage.TokenType.UNDERLYING_FREE_LIQ,\r\n 0,\r\n 0\r\n );\r\n BASE_FREE_LIQ_TOKEN_ID = PoolStorage.formatTokenId(\r\n PoolStorage.TokenType.BASE_FREE_LIQ,\r\n 0,\r\n 0\r\n );\r\n\r\n UNDERLYING_RESERVED_LIQ_TOKEN_ID = PoolStorage.formatTokenId(\r\n PoolStorage.TokenType.UNDERLYING_RESERVED_LIQ,\r\n 0,\r\n 0\r\n );\r\n BASE_RESERVED_LIQ_TOKEN_ID = PoolStorage.formatTokenId(\r\n PoolStorage.TokenType.BASE_RESERVED_LIQ,\r\n 0,\r\n 0\r\n );\r\n }\r\n\r\n modifier onlyProtocolOwner() {\r\n require(\r\n msg.sender == IERC173(OwnableStorage.layout().owner).owner(),\r\n \"Not protocol owner\"\r\n );\r\n _;\r\n }\r\n\r\n function _getFeeDiscount(address feePayer)\r\n internal\r\n view\r\n returns (uint256 discount)\r\n {\r\n if (FEE_DISCOUNT_ADDRESS != address(0)) {\r\n discount = IFeeDiscount(FEE_DISCOUNT_ADDRESS).getDiscount(feePayer);\r\n }\r\n }\r\n\r\n function _getFeeWithDiscount(address feePayer, uint256 fee)\r\n internal\r\n view\r\n returns (uint256)\r\n {\r\n uint256 discount = _getFeeDiscount(feePayer);\r\n return fee - ((fee * discount) / INVERSE_BASIS_POINT);\r\n }\r\n\r\n function _withdrawFees(bool isCall) internal returns (uint256 amount) {\r\n uint256 tokenId = _getReservedLiquidityTokenId(isCall);\r\n amount = _balanceOf(FEE_RECEIVER_ADDRESS, tokenId);\r\n\r\n if (amount > 0) {\r\n _burn(FEE_RECEIVER_ADDRESS, tokenId, amount);\r\n emit FeeWithdrawal(isCall, amount);\r\n }\r\n }\r\n\r\n /**\r\n * @notice calculate price of option contract\r\n * @param args structured quote arguments\r\n * @return result quote result\r\n */\r\n function _quote(PoolStorage.QuoteArgsInternal memory args)\r\n internal\r\n view\r\n returns (PoolStorage.QuoteResultInternal memory result)\r\n {\r\n require(\r\n args.strike64x64 > 0 && args.spot64x64 > 0 && args.maturity > 0,\r\n \"invalid args\"\r\n );\r\n PoolStorage.Layout storage l = PoolStorage.layout();\r\n\r\n int128 contractSize64x64 = ABDKMath64x64Token.fromDecimals(\r\n args.contractSize,\r\n l.underlyingDecimals\r\n );\r\n bool isCall = args.isCall;\r\n\r\n (int128 adjustedCLevel64x64, int128 oldLiquidity64x64) = l\r\n .applyCLevelPendingDepositAdjustment(\r\n l.getDecayAdjustedCLevel64x64(isCall),\r\n l.totalFreeLiquiditySupply64x64(isCall),\r\n isCall\r\n );\r\n\r\n require(oldLiquidity64x64 > 0, \"no liq\");\r\n\r\n int128 timeToMaturity64x64 = ABDKMath64x64.divu(\r\n args.maturity - block.timestamp,\r\n 365 days\r\n );\r\n\r\n int128 annualizedVolatility64x64 = IVolatilitySurfaceOracle(\r\n IVOL_ORACLE_ADDRESS\r\n ).getAnnualizedVolatility64x64(\r\n l.base,\r\n l.underlying,\r\n args.spot64x64,\r\n args.strike64x64,\r\n timeToMaturity64x64,\r\n isCall\r\n );\r\n\r\n require(annualizedVolatility64x64 > 0, \"vol = 0\");\r\n\r\n (\r\n int128 price64x64,\r\n int128 cLevel64x64,\r\n int128 slippageCoefficient64x64\r\n ) = OptionMath.quotePrice(\r\n OptionMath.QuoteArgs(\r\n annualizedVolatility64x64.mul(annualizedVolatility64x64),\r\n args.strike64x64,\r\n args.spot64x64,\r\n timeToMaturity64x64,\r\n adjustedCLevel64x64,\r\n oldLiquidity64x64,\r\n oldLiquidity64x64.sub(contractSize64x64),\r\n 0x10000000000000000, // 64x64 fixed point representation of 1\r\n MIN_APY_64x64,\r\n isCall\r\n )\r\n );\r\n\r\n result.baseCost64x64 = isCall\r\n ? price64x64.mul(contractSize64x64).div(args.spot64x64)\r\n : price64x64.mul(contractSize64x64);\r\n result.feeCost64x64 = result.baseCost64x64.mul(FEE_64x64);\r\n result.cLevel64x64 = cLevel64x64;\r\n result.slippageCoefficient64x64 = slippageCoefficient64x64;\r\n\r\n int128 discount = ABDKMath64x64.divu(\r\n _getFeeDiscount(args.feePayer),\r\n INVERSE_BASIS_POINT\r\n );\r\n result.feeCost64x64 -= result.feeCost64x64.mul(discount);\r\n }\r\n\r\n /**\r\n * @notice burn corresponding long and short option tokens\r\n * @param account holder of tokens to annihilate\r\n * @param maturity timestamp of option maturity\r\n * @param strike64x64 64x64 fixed point representation of strike price\r\n * @param isCall true for call, false for put\r\n * @param contractSize quantity of option contract tokens to annihilate\r\n */\r\n function _annihilate(\r\n address account,\r\n uint64 maturity,\r\n int128 strike64x64,\r\n bool isCall,\r\n uint256 contractSize\r\n ) internal {\r\n uint256 longTokenId = PoolStorage.formatTokenId(\r\n _getTokenType(isCall, true),\r\n maturity,\r\n strike64x64\r\n );\r\n uint256 shortTokenId = PoolStorage.formatTokenId(\r\n _getTokenType(isCall, false),\r\n maturity,\r\n strike64x64\r\n );\r\n\r\n _burn(account, longTokenId, contractSize);\r\n _burn(account, shortTokenId, contractSize);\r\n\r\n emit Annihilate(shortTokenId, contractSize);\r\n }\r\n\r\n /**\r\n * @notice purchase option\r\n * @param l storage layout struct\r\n * @param account recipient of purchased option\r\n * @param maturity timestamp of option maturity\r\n * @param strike64x64 64x64 fixed point representation of strike price\r\n * @param isCall true for call, false for put\r\n * @param contractSize size of option contract\r\n * @param newPrice64x64 64x64 fixed point representation of current spot price\r\n * @return baseCost quantity of tokens required to purchase long position\r\n * @return feeCost quantity of tokens required to pay fees\r\n */\r\n function _purchase(\r\n PoolStorage.Layout storage l,\r\n address account,\r\n uint64 maturity,\r\n int128 strike64x64,\r\n bool isCall,\r\n uint256 contractSize,\r\n int128 newPrice64x64\r\n ) internal returns (uint256 baseCost, uint256 feeCost) {\r\n require(maturity > block.timestamp, \"expired\");\r\n require(contractSize >= l.underlyingMinimum, \"too small\");\r\n\r\n {\r\n uint256 size = isCall\r\n ? contractSize\r\n : l.fromUnderlyingToBaseDecimals(\r\n strike64x64.mulu(contractSize)\r\n );\r\n\r\n require(\r\n size <=\r\n ERC1155EnumerableStorage.layout().totalSupply[\r\n _getFreeLiquidityTokenId(isCall)\r\n ] -\r\n l.nextDeposits[isCall].totalPendingDeposits,\r\n \"insuf liq\"\r\n );\r\n }\r\n\r\n PoolStorage.QuoteResultInternal memory quote = _quote(\r\n PoolStorage.QuoteArgsInternal(\r\n account,\r\n maturity,\r\n strike64x64,\r\n newPrice64x64,\r\n contractSize,\r\n isCall\r\n )\r\n );\r\n\r\n baseCost = ABDKMath64x64Token.toDecimals(\r\n quote.baseCost64x64,\r\n l.getTokenDecimals(isCall)\r\n );\r\n\r\n feeCost = ABDKMath64x64Token.toDecimals(\r\n quote.feeCost64x64,\r\n l.getTokenDecimals(isCall)\r\n );\r\n\r\n uint256 longTokenId = PoolStorage.formatTokenId(\r\n _getTokenType(isCall, true),\r\n maturity,\r\n strike64x64\r\n );\r\n\r\n uint256 shortTokenId = PoolStorage.formatTokenId(\r\n _getTokenType(isCall, false),\r\n maturity,\r\n strike64x64\r\n );\r\n\r\n // mint long option token for buyer\r\n _mint(account, longTokenId, contractSize);\r\n\r\n int128 oldLiquidity64x64 = l.totalFreeLiquiditySupply64x64(isCall);\r\n // burn free liquidity tokens from other underwriters\r\n _mintShortTokenLoop(\r\n l,\r\n account,\r\n contractSize,\r\n baseCost,\r\n shortTokenId,\r\n isCall\r\n );\r\n int128 newLiquidity64x64 = l.totalFreeLiquiditySupply64x64(isCall);\r\n\r\n _setCLevel(l, oldLiquidity64x64, newLiquidity64x64, isCall);\r\n\r\n // mint reserved liquidity tokens for fee receiver\r\n _mint(\r\n FEE_RECEIVER_ADDRESS,\r\n _getReservedLiquidityTokenId(isCall),\r\n feeCost\r\n );\r\n\r\n emit Purchase(\r\n account,\r\n longTokenId,\r\n contractSize,\r\n baseCost,\r\n feeCost,\r\n newPrice64x64\r\n );\r\n }\r\n\r\n /**\r\n * @notice reassign short position to new underwriter\r\n * @param l storage layout struct\r\n * @param account holder of positions to be reassigned\r\n * @param maturity timestamp of option maturity\r\n * @param strike64x64 64x64 fixed point representation of strike price\r\n * @param isCall true for call, false for put\r\n * @param contractSize quantity of option contract tokens to reassign\r\n * @param newPrice64x64 64x64 fixed point representation of current spot price\r\n * @return baseCost quantity of tokens required to reassign short position\r\n * @return feeCost quantity of tokens required to pay fees\r\n * @return amountOut quantity of liquidity freed\r\n */\r\n function _reassign(\r\n PoolStorage.Layout storage l,\r\n address account,\r\n uint64 maturity,\r\n int128 strike64x64,\r\n bool isCall,\r\n uint256 contractSize,\r\n int128 newPrice64x64\r\n )\r\n internal\r\n returns (\r\n uint256 baseCost,\r\n uint256 feeCost,\r\n uint256 amountOut\r\n )\r\n {\r\n (baseCost, feeCost) = _purchase(\r\n l,\r\n account,\r\n maturity,\r\n strike64x64,\r\n isCall,\r\n contractSize,\r\n newPrice64x64\r\n );\r\n\r\n _annihilate(account, maturity, strike64x64, isCall, contractSize);\r\n\r\n uint256 annihilateAmount = isCall\r\n ? contractSize\r\n : l.fromUnderlyingToBaseDecimals(strike64x64.mulu(contractSize));\r\n\r\n amountOut = annihilateAmount - baseCost - feeCost;\r\n }\r\n\r\n /**\r\n * @notice exercise option on behalf of holder\r\n * @dev used for processing of expired options if passed holder is zero address\r\n * @param holder owner of long option tokens to exercise\r\n * @param longTokenId long option token id\r\n * @param contractSize quantity of tokens to exercise\r\n */\r\n function _exercise(\r\n address holder,\r\n uint256 longTokenId,\r\n uint256 contractSize\r\n ) internal {\r\n uint64 maturity;\r\n int128 strike64x64;\r\n bool isCall;\r\n\r\n bool onlyExpired = holder == address(0);\r\n\r\n {\r\n PoolStorage.TokenType tokenType;\r\n (tokenType, maturity, strike64x64) = PoolStorage.parseTokenId(\r\n longTokenId\r\n );\r\n require(\r\n tokenType == PoolStorage.TokenType.LONG_CALL ||\r\n tokenType == PoolStorage.TokenType.LONG_PUT,\r\n \"invalid type\"\r\n );\r\n require(!onlyExpired || maturity < block.timestamp, \"not expired\");\r\n isCall = tokenType == PoolStorage.TokenType.LONG_CALL;\r\n }\r\n\r\n PoolStorage.Layout storage l = PoolStorage.layout();\r\n\r\n int128 spot64x64 = _update(l);\r\n\r\n if (maturity < block.timestamp) {\r\n spot64x64 = l.getPriceUpdateAfter(maturity);\r\n }\r\n\r\n require(\r\n onlyExpired ||\r\n (\r\n isCall\r\n ? (spot64x64 > strike64x64)\r\n : (spot64x64 < strike64x64)\r\n ),\r\n \"not ITM\"\r\n );\r\n\r\n uint256 exerciseValue;\r\n // option has a non-zero exercise value\r\n if (isCall) {\r\n if (spot64x64 > strike64x64) {\r\n exerciseValue = spot64x64.sub(strike64x64).div(spot64x64).mulu(\r\n contractSize\r\n );\r\n }\r\n } else {\r\n if (spot64x64 < strike64x64) {\r\n exerciseValue = l.fromUnderlyingToBaseDecimals(\r\n strike64x64.sub(spot64x64).mulu(contractSize)\r\n );\r\n }\r\n }\r\n\r\n uint256 totalFee;\r\n\r\n if (onlyExpired) {\r\n totalFee += _burnLongTokenLoop(\r\n contractSize,\r\n exerciseValue,\r\n longTokenId,\r\n isCall\r\n );\r\n } else {\r\n // burn long option tokens from sender\r\n _burn(holder, longTokenId, contractSize);\r\n\r\n uint256 fee;\r\n\r\n if (exerciseValue > 0) {\r\n fee = _getFeeWithDiscount(\r\n holder,\r\n FEE_64x64.mulu(exerciseValue)\r\n );\r\n totalFee += fee;\r\n\r\n _pushTo(holder, _getPoolToken(isCall), exerciseValue - fee);\r\n }\r\n\r\n emit Exercise(\r\n holder,\r\n longTokenId,\r\n contractSize,\r\n exerciseValue,\r\n fee\r\n );\r\n }\r\n\r\n totalFee += _burnShortTokenLoop(\r\n contractSize,\r\n exerciseValue,\r\n PoolStorage.formatTokenId(\r\n _getTokenType(isCall, false),\r\n maturity,\r\n strike64x64\r\n ),\r\n isCall\r\n );\r\n\r\n _mint(\r\n FEE_RECEIVER_ADDRESS,\r\n _getReservedLiquidityTokenId(isCall),\r\n totalFee\r\n );\r\n }\r\n\r\n function _mintShortTokenLoop(\r\n PoolStorage.Layout storage l,\r\n address buyer,\r\n uint256 contractSize,\r\n uint256 premium,\r\n uint256 shortTokenId,\r\n bool isCall\r\n ) internal {\r\n uint256 freeLiqTokenId = _getFreeLiquidityTokenId(isCall);\r\n (, , int128 strike64x64) = PoolStorage.parseTokenId(shortTokenId);\r\n\r\n uint256 toPay = isCall\r\n ? contractSize\r\n : l.fromUnderlyingToBaseDecimals(strike64x64.mulu(contractSize));\r\n\r\n while (toPay > 0) {\r\n address underwriter = l.liquidityQueueAscending[isCall][address(0)];\r\n uint256 balance = _balanceOf(underwriter, freeLiqTokenId);\r\n\r\n // If dust left, we remove underwriter and skip to next\r\n if (balance < _getMinimumAmount(l, isCall)) {\r\n l.removeUnderwriter(underwriter, isCall);\r\n continue;\r\n }\r\n\r\n if (!l.getReinvestmentStatus(underwriter, isCall)) {\r\n _burn(underwriter, freeLiqTokenId, balance);\r\n _mint(\r\n underwriter,\r\n _getReservedLiquidityTokenId(isCall),\r\n balance\r\n );\r\n _subUserTVL(l, underwriter, isCall, balance);\r\n continue;\r\n }\r\n\r\n // amount of liquidity provided by underwriter, accounting for reinvested premium\r\n uint256 intervalContractSize = ((balance -\r\n l.pendingDeposits[underwriter][l.nextDeposits[isCall].eta][\r\n isCall\r\n ]) * (toPay + premium)) / toPay;\r\n if (intervalContractSize == 0) continue;\r\n if (intervalContractSize > toPay) intervalContractSize = toPay;\r\n\r\n // amount of premium paid to underwriter\r\n uint256 intervalPremium = (premium * intervalContractSize) / toPay;\r\n premium -= intervalPremium;\r\n toPay -= intervalContractSize;\r\n _addUserTVL(l, underwriter, isCall, intervalPremium);\r\n\r\n // burn free liquidity tokens from underwriter\r\n _burn(\r\n underwriter,\r\n freeLiqTokenId,\r\n intervalContractSize - intervalPremium\r\n );\r\n\r\n if (isCall == false) {\r\n // For PUT, conversion to contract amount is done here (Prior to this line, it is token amount)\r\n intervalContractSize = l.fromBaseToUnderlyingDecimals(\r\n strike64x64.inv().mulu(intervalContractSize)\r\n );\r\n }\r\n\r\n // mint short option tokens for underwriter\r\n // toPay == 0 ? contractSize : intervalContractSize : To prevent minting less than amount,\r\n // because of rounding (Can happen for put, because of fixed point precision)\r\n _mint(\r\n underwriter,\r\n shortTokenId,\r\n toPay == 0 ? contractSize : intervalContractSize\r\n );\r\n\r\n emit Underwrite(\r\n underwriter,\r\n buyer,\r\n shortTokenId,\r\n toPay == 0 ? contractSize : intervalContractSize,\r\n intervalPremium,\r\n false\r\n );\r\n\r\n contractSize -= intervalContractSize;\r\n }\r\n }\r\n\r\n function _burnLongTokenLoop(\r\n uint256 contractSize,\r\n uint256 exerciseValue,\r\n uint256 longTokenId,\r\n bool isCall\r\n ) internal returns (uint256 totalFee) {\r\n EnumerableSet.AddressSet storage holders = ERC1155EnumerableStorage\r\n .layout()\r\n .accountsByToken[longTokenId];\r\n\r\n while (contractSize > 0) {\r\n address longTokenHolder = holders.at(holders.length() - 1);\r\n\r\n uint256 intervalContractSize = _balanceOf(\r\n longTokenHolder,\r\n longTokenId\r\n );\r\n if (intervalContractSize > contractSize)\r\n intervalContractSize = contractSize;\r\n\r\n uint256 intervalExerciseValue;\r\n\r\n uint256 fee;\r\n if (exerciseValue > 0) {\r\n intervalExerciseValue =\r\n (exerciseValue * intervalContractSize) /\r\n contractSize;\r\n\r\n fee = _getFeeWithDiscount(\r\n longTokenHolder,\r\n FEE_64x64.mulu(intervalExerciseValue)\r\n );\r\n totalFee += fee;\r\n\r\n exerciseValue -= intervalExerciseValue;\r\n _pushTo(\r\n longTokenHolder,\r\n _getPoolToken(isCall),\r\n intervalExerciseValue - fee\r\n );\r\n }\r\n\r\n contractSize -= intervalContractSize;\r\n\r\n emit Exercise(\r\n longTokenHolder,\r\n longTokenId,\r\n intervalContractSize,\r\n intervalExerciseValue - fee,\r\n fee\r\n );\r\n\r\n _burn(longTokenHolder, longTokenId, intervalContractSize);\r\n }\r\n }\r\n\r\n function _burnShortTokenLoop(\r\n uint256 contractSize,\r\n uint256 exerciseValue,\r\n uint256 shortTokenId,\r\n bool isCall\r\n ) internal returns (uint256 totalFee) {\r\n EnumerableSet.AddressSet storage underwriters = ERC1155EnumerableStorage\r\n .layout()\r\n .accountsByToken[shortTokenId];\r\n (, , int128 strike64x64) = PoolStorage.parseTokenId(shortTokenId);\r\n\r\n while (contractSize > 0) {\r\n address underwriter = underwriters.at(underwriters.length() - 1);\r\n\r\n // amount of liquidity provided by underwriter\r\n uint256 intervalContractSize = _balanceOf(\r\n underwriter,\r\n shortTokenId\r\n );\r\n if (intervalContractSize > contractSize)\r\n intervalContractSize = contractSize;\r\n\r\n // amount of value claimed by buyer\r\n uint256 intervalExerciseValue = (exerciseValue *\r\n intervalContractSize) / contractSize;\r\n exerciseValue -= intervalExerciseValue;\r\n contractSize -= intervalContractSize;\r\n\r\n uint256 freeLiq = isCall\r\n ? intervalContractSize - intervalExerciseValue\r\n : PoolStorage.layout().fromUnderlyingToBaseDecimals(\r\n strike64x64.mulu(intervalContractSize)\r\n ) - intervalExerciseValue;\r\n\r\n uint256 fee = _getFeeWithDiscount(\r\n underwriter,\r\n FEE_64x64.mulu(freeLiq)\r\n );\r\n totalFee += fee;\r\n\r\n uint256 tvlToSubtract = intervalExerciseValue;\r\n\r\n // mint free liquidity tokens for underwriter\r\n if (\r\n PoolStorage.layout().getReinvestmentStatus(underwriter, isCall)\r\n ) {\r\n _addToDepositQueue(underwriter, freeLiq - fee, isCall);\r\n tvlToSubtract += fee;\r\n } else {\r\n _mint(\r\n underwriter,\r\n _getReservedLiquidityTokenId(isCall),\r\n freeLiq - fee\r\n );\r\n tvlToSubtract += freeLiq;\r\n }\r\n\r\n _subUserTVL(\r\n PoolStorage.layout(),\r\n underwriter,\r\n isCall,\r\n tvlToSubtract\r\n );\r\n\r\n // burn short option tokens from underwriter\r\n _burn(underwriter, shortTokenId, intervalContractSize);\r\n\r\n emit AssignExercise(\r\n underwriter,\r\n shortTokenId,\r\n freeLiq - fee,\r\n intervalContractSize,\r\n fee\r\n );\r\n }\r\n }\r\n\r\n function _addToDepositQueue(\r\n address account,\r\n uint256 amount,\r\n bool isCallPool\r\n ) internal {\r\n PoolStorage.Layout storage l = PoolStorage.layout();\r\n\r\n _mint(account, _getFreeLiquidityTokenId(isCallPool), amount);\r\n\r\n uint256 nextBatch = (block.timestamp / BATCHING_PERIOD) *\r\n BATCHING_PERIOD +\r\n BATCHING_PERIOD;\r\n l.pendingDeposits[account][nextBatch][isCallPool] += amount;\r\n\r\n PoolStorage.BatchData storage batchData = l.nextDeposits[isCallPool];\r\n batchData.totalPendingDeposits += amount;\r\n batchData.eta = nextBatch;\r\n }\r\n\r\n function _processPendingDeposits(PoolStorage.Layout storage l, bool isCall)\r\n internal\r\n {\r\n PoolStorage.BatchData storage data = l.nextDeposits[isCall];\r\n\r\n if (data.eta == 0 || block.timestamp < data.eta) return;\r\n\r\n int128 oldLiquidity64x64 = l.totalFreeLiquiditySupply64x64(isCall);\r\n\r\n _setCLevel(\r\n l,\r\n oldLiquidity64x64,\r\n oldLiquidity64x64.add(\r\n ABDKMath64x64Token.fromDecimals(\r\n data.totalPendingDeposits,\r\n l.getTokenDecimals(isCall)\r\n )\r\n ),\r\n isCall\r\n );\r\n\r\n delete l.nextDeposits[isCall];\r\n }\r\n\r\n function _getFreeLiquidityTokenId(bool isCall)\r\n internal\r\n view\r\n returns (uint256 freeLiqTokenId)\r\n {\r\n freeLiqTokenId = isCall\r\n ? UNDERLYING_FREE_LIQ_TOKEN_ID\r\n : BASE_FREE_LIQ_TOKEN_ID;\r\n }\r\n\r\n function _getReservedLiquidityTokenId(bool isCall)\r\n internal\r\n view\r\n returns (uint256 reservedLiqTokenId)\r\n {\r\n reservedLiqTokenId = isCall\r\n ? UNDERLYING_RESERVED_LIQ_TOKEN_ID\r\n : BASE_RESERVED_LIQ_TOKEN_ID;\r\n }\r\n\r\n function _getPoolToken(bool isCall) internal view returns (address token) {\r\n token = isCall\r\n ? PoolStorage.layout().underlying\r\n : PoolStorage.layout().base;\r\n }\r\n\r\n function _getTokenType(bool isCall, bool isLong)\r\n internal\r\n pure\r\n returns (PoolStorage.TokenType tokenType)\r\n {\r\n if (isCall) {\r\n tokenType = isLong\r\n ? PoolStorage.TokenType.LONG_CALL\r\n : PoolStorage.TokenType.SHORT_CALL;\r\n } else {\r\n tokenType = isLong\r\n ? PoolStorage.TokenType.LONG_PUT\r\n : PoolStorage.TokenType.SHORT_PUT;\r\n }\r\n }\r\n\r\n function _getMinimumAmount(PoolStorage.Layout storage l, bool isCall)\r\n internal\r\n view\r\n returns (uint256 minimumAmount)\r\n {\r\n minimumAmount = isCall ? l.underlyingMinimum : l.baseMinimum;\r\n }\r\n\r\n function _getPoolCapAmount(PoolStorage.Layout storage l, bool isCall)\r\n internal\r\n view\r\n returns (uint256 poolCapAmount)\r\n {\r\n poolCapAmount = isCall ? l.underlyingPoolCap : l.basePoolCap;\r\n }\r\n\r\n function _setCLevel(\r\n PoolStorage.Layout storage l,\r\n int128 oldLiquidity64x64,\r\n int128 newLiquidity64x64,\r\n bool isCallPool\r\n ) internal {\r\n int128 oldCLevel64x64 = l.getDecayAdjustedCLevel64x64(isCallPool);\r\n\r\n int128 cLevel64x64 = l.applyCLevelLiquidityChangeAdjustment(\r\n oldCLevel64x64,\r\n oldLiquidity64x64,\r\n newLiquidity64x64,\r\n isCallPool\r\n );\r\n\r\n l.setCLevel(cLevel64x64, isCallPool);\r\n\r\n emit UpdateCLevel(\r\n isCallPool,\r\n cLevel64x64,\r\n oldLiquidity64x64,\r\n newLiquidity64x64\r\n );\r\n }\r\n\r\n /**\r\n * @notice calculate and store updated market state\r\n * @param l storage layout struct\r\n * @return newPrice64x64 64x64 fixed point representation of current spot price\r\n */\r\n function _update(PoolStorage.Layout storage l)\r\n internal\r\n returns (int128 newPrice64x64)\r\n {\r\n if (l.updatedAt == block.timestamp) {\r\n return (l.getPriceUpdate(block.timestamp));\r\n }\r\n\r\n newPrice64x64 = l.fetchPriceUpdate();\r\n\r\n if (l.getPriceUpdate(block.timestamp) == 0) {\r\n l.setPriceUpdate(block.timestamp, newPrice64x64);\r\n }\r\n\r\n l.updatedAt = block.timestamp;\r\n\r\n _processPendingDeposits(l, true);\r\n _processPendingDeposits(l, false);\r\n }\r\n\r\n /**\r\n * @notice transfer ERC20 tokens to message sender\r\n * @param token ERC20 token address\r\n * @param amount quantity of token to transfer\r\n */\r\n function _pushTo(\r\n address to,\r\n address token,\r\n uint256 amount\r\n ) internal {\r\n if (amount == 0) return;\r\n\r\n require(IERC20(token).transfer(to, amount), \"ERC20 transfer failed\");\r\n }\r\n\r\n /**\r\n * @notice transfer ERC20 tokens from message sender\r\n * @param from address from which tokens are pulled from\r\n * @param token ERC20 token address\r\n * @param amount quantity of token to transfer\r\n * @param skipWethDeposit if false, will not try to deposit weth from attach eth\r\n */\r\n function _pullFrom(\r\n address from,\r\n address token,\r\n uint256 amount,\r\n bool skipWethDeposit\r\n ) internal {\r\n if (!skipWethDeposit) {\r\n if (token == WETH_ADDRESS) {\r\n if (msg.value > 0) {\r\n if (msg.value > amount) {\r\n IWETH(WETH_ADDRESS).deposit{value: amount}();\r\n\r\n (bool success, ) = payable(msg.sender).call{\r\n value: msg.value - amount\r\n }(\"\");\r\n\r\n require(success, \"ETH refund failed\");\r\n\r\n amount = 0;\r\n } else {\r\n unchecked {\r\n amount -= msg.value;\r\n }\r\n\r\n IWETH(WETH_ADDRESS).deposit{value: msg.value}();\r\n }\r\n }\r\n } else {\r\n require(msg.value == 0, \"not WETH deposit\");\r\n }\r\n }\r\n\r\n if (amount > 0) {\r\n require(\r\n IERC20(token).transferFrom(from, address(this), amount),\r\n \"ERC20 transfer failed\"\r\n );\r\n }\r\n }\r\n\r\n function _mint(\r\n address account,\r\n uint256 tokenId,\r\n uint256 amount\r\n ) internal {\r\n _mint(account, tokenId, amount, \"\");\r\n }\r\n\r\n function _addUserTVL(\r\n PoolStorage.Layout storage l,\r\n address user,\r\n bool isCallPool,\r\n uint256 amount\r\n ) internal {\r\n uint256 userTVL = l.userTVL[user][isCallPool];\r\n uint256 totalTVL = l.totalTVL[isCallPool];\r\n\r\n IPremiaMining(PREMIA_MINING_ADDRESS).allocatePending(\r\n user,\r\n address(this),\r\n isCallPool,\r\n userTVL,\r\n userTVL + amount,\r\n totalTVL\r\n );\r\n\r\n l.userTVL[user][isCallPool] = userTVL + amount;\r\n l.totalTVL[isCallPool] = totalTVL + amount;\r\n }\r\n\r\n function _subUserTVL(\r\n PoolStorage.Layout storage l,\r\n address user,\r\n bool isCallPool,\r\n uint256 amount\r\n ) internal {\r\n uint256 userTVL = l.userTVL[user][isCallPool];\r\n uint256 totalTVL = l.totalTVL[isCallPool];\r\n\r\n IPremiaMining(PREMIA_MINING_ADDRESS).allocatePending(\r\n user,\r\n address(this),\r\n isCallPool,\r\n userTVL,\r\n userTVL - amount,\r\n totalTVL\r\n );\r\n l.userTVL[user][isCallPool] = userTVL - amount;\r\n l.totalTVL[isCallPool] = totalTVL - amount;\r\n }\r\n\r\n /**\r\n * @notice ERC1155 hook: track eligible underwriters\r\n * @param operator transaction sender\r\n * @param from token sender\r\n * @param to token receiver\r\n * @param ids token ids transferred\r\n * @param amounts token quantities transferred\r\n * @param data data payload\r\n */\r\n function _beforeTokenTransfer(\r\n address operator,\r\n address from,\r\n address to,\r\n uint256[] memory ids,\r\n uint256[] memory amounts,\r\n bytes memory data\r\n ) internal virtual override {\r\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\r\n\r\n PoolStorage.Layout storage l = PoolStorage.layout();\r\n\r\n for (uint256 i; i < ids.length; i++) {\r\n uint256 id = ids[i];\r\n uint256 amount = amounts[i];\r\n\r\n if (amount == 0) continue;\r\n\r\n if (from == address(0)) {\r\n l.tokenIds.add(id);\r\n }\r\n\r\n if (\r\n to == address(0) &&\r\n ERC1155EnumerableStorage.layout().totalSupply[id] == 0\r\n ) {\r\n l.tokenIds.remove(id);\r\n }\r\n\r\n // prevent transfer of free and reserved liquidity during waiting period\r\n\r\n if (\r\n id == UNDERLYING_FREE_LIQ_TOKEN_ID ||\r\n id == BASE_FREE_LIQ_TOKEN_ID ||\r\n id == UNDERLYING_RESERVED_LIQ_TOKEN_ID ||\r\n id == BASE_RESERVED_LIQ_TOKEN_ID\r\n ) {\r\n if (from != address(0) && to != address(0)) {\r\n bool isCallPool = id == UNDERLYING_FREE_LIQ_TOKEN_ID ||\r\n id == UNDERLYING_RESERVED_LIQ_TOKEN_ID;\r\n\r\n require(\r\n l.depositedAt[from][isCallPool] + (1 days) <\r\n block.timestamp,\r\n \"liq lock 1d\"\r\n );\r\n }\r\n }\r\n\r\n if (\r\n id == UNDERLYING_FREE_LIQ_TOKEN_ID ||\r\n id == BASE_FREE_LIQ_TOKEN_ID\r\n ) {\r\n bool isCallPool = id == UNDERLYING_FREE_LIQ_TOKEN_ID;\r\n uint256 minimum = _getMinimumAmount(l, isCallPool);\r\n\r\n if (from != address(0)) {\r\n uint256 balance = _balanceOf(from, id);\r\n\r\n if (balance > minimum && balance <= amount + minimum) {\r\n require(\r\n balance -\r\n l.pendingDeposits[from][\r\n l.nextDeposits[isCallPool].eta\r\n ][isCallPool] >=\r\n amount,\r\n \"Insuf balance\"\r\n );\r\n l.removeUnderwriter(from, isCallPool);\r\n }\r\n\r\n if (to != address(0)) {\r\n _subUserTVL(l, from, isCallPool, amounts[i]);\r\n _addUserTVL(l, to, isCallPool, amounts[i]);\r\n }\r\n }\r\n\r\n if (to != address(0)) {\r\n uint256 balance = _balanceOf(to, id);\r\n\r\n if (balance <= minimum && balance + amount > minimum) {\r\n l.addUnderwriter(to, isCallPool);\r\n }\r\n }\r\n }\r\n\r\n // Update userTVL on SHORT options transfers\r\n (\r\n PoolStorage.TokenType tokenType,\r\n ,\r\n int128 strike64x64\r\n ) = PoolStorage.parseTokenId(id);\r\n\r\n if (\r\n (from != address(0) && to != address(0)) &&\r\n (tokenType == PoolStorage.TokenType.SHORT_CALL ||\r\n tokenType == PoolStorage.TokenType.SHORT_PUT)\r\n ) {\r\n bool isCall = tokenType == PoolStorage.TokenType.SHORT_CALL;\r\n uint256 collateral = isCall\r\n ? amount\r\n : l.fromUnderlyingToBaseDecimals(strike64x64.mulu(amount));\r\n\r\n _subUserTVL(l, from, isCall, collateral);\r\n _addUserTVL(l, to, isCall, collateral);\r\n }\r\n }\r\n }\r\n}\r\n"},"@solidstate/contracts/token/ERC1155/base/ERC1155BaseStorage.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nlibrary ERC1155BaseStorage {\n struct Layout {\n mapping(uint256 => mapping(address => uint256)) balances;\n mapping(address => mapping(address => bool)) operatorApprovals;\n }\n\n bytes32 internal constant STORAGE_SLOT =\n keccak256('solidstate.contracts.storage.ERC1155Base');\n\n function layout() internal pure returns (Layout storage l) {\n bytes32 slot = STORAGE_SLOT;\n assembly {\n l.slot := slot\n }\n }\n}\n"},"@solidstate/contracts/utils/EnumerableSet.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title Set implementation with enumeration functions\n * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts (MIT license)\n */\nlibrary EnumerableSet {\n struct Set {\n bytes32[] _values;\n // 1-indexed to allow 0 to signify nonexistence\n mapping(bytes32 => uint256) _indexes;\n }\n\n struct Bytes32Set {\n Set _inner;\n }\n\n struct AddressSet {\n Set _inner;\n }\n\n struct UintSet {\n Set _inner;\n }\n\n function at(Bytes32Set storage set, uint256 index)\n internal\n view\n returns (bytes32)\n {\n return _at(set._inner, index);\n }\n\n function at(AddressSet storage set, uint256 index)\n internal\n view\n returns (address)\n {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n function at(UintSet storage set, uint256 index)\n internal\n view\n returns (uint256)\n {\n return uint256(_at(set._inner, index));\n }\n\n function contains(Bytes32Set storage set, bytes32 value)\n internal\n view\n returns (bool)\n {\n return _contains(set._inner, value);\n }\n\n function contains(AddressSet storage set, address value)\n internal\n view\n returns (bool)\n {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n function contains(UintSet storage set, uint256 value)\n internal\n view\n returns (bool)\n {\n return _contains(set._inner, bytes32(value));\n }\n\n function indexOf(Bytes32Set storage set, bytes32 value)\n internal\n view\n returns (uint256)\n {\n return _indexOf(set._inner, value);\n }\n\n function indexOf(AddressSet storage set, address value)\n internal\n view\n returns (uint256)\n {\n return _indexOf(set._inner, bytes32(uint256(uint160(value))));\n }\n\n function indexOf(UintSet storage set, uint256 value)\n internal\n view\n returns (uint256)\n {\n return _indexOf(set._inner, bytes32(value));\n }\n\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n function add(Bytes32Set storage set, bytes32 value)\n internal\n returns (bool)\n {\n return _add(set._inner, value);\n }\n\n function add(AddressSet storage set, address value)\n internal\n returns (bool)\n {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n function remove(Bytes32Set storage set, bytes32 value)\n internal\n returns (bool)\n {\n return _remove(set._inner, value);\n }\n\n function remove(AddressSet storage set, address value)\n internal\n returns (bool)\n {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n function remove(UintSet storage set, uint256 value)\n internal\n returns (bool)\n {\n return _remove(set._inner, bytes32(value));\n }\n\n function _at(Set storage set, uint256 index)\n private\n view\n returns (bytes32)\n {\n require(\n set._values.length > index,\n 'EnumerableSet: index out of bounds'\n );\n return set._values[index];\n }\n\n function _contains(Set storage set, bytes32 value)\n private\n view\n returns (bool)\n {\n return set._indexes[value] != 0;\n }\n\n function _indexOf(Set storage set, bytes32 value)\n private\n view\n returns (uint256)\n {\n unchecked {\n return set._indexes[value] - 1;\n }\n }\n\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n uint256 index = valueIndex - 1;\n bytes32 last = set._values[set._values.length - 1];\n\n // move last value to now-vacant index\n\n set._values[index] = last;\n set._indexes[last] = index + 1;\n\n // clear last index\n\n set._values.pop();\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n}\n"},"contracts/mining/PremiaMiningStorage.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\r\n// For further clarification please see https://license.premia.legal\r\n\r\npragma solidity ^0.8.0;\r\n\r\nlibrary PremiaMiningStorage {\r\n bytes32 internal constant STORAGE_SLOT =\r\n keccak256(\"premia.contracts.storage.PremiaMining\");\r\n\r\n // Info of each pool.\r\n struct PoolInfo {\r\n uint256 allocPoint; // How many allocation points assigned to this pool. PREMIA to distribute per block.\r\n uint256 lastRewardTimestamp; // Last timestamp that PREMIA distribution occurs\r\n uint256 accPremiaPerShare; // Accumulated PREMIA per share, times 1e12. See below.\r\n }\r\n\r\n // Info of each user.\r\n struct UserInfo {\r\n uint256 reward; // Total allocated unclaimed reward\r\n uint256 rewardDebt; // Reward debt. See explanation below.\r\n //\r\n // We do some fancy math here. Basically, any point in time, the amount of PREMIA\r\n // entitled to a user but is pending to be distributed is:\r\n //\r\n // pending reward = (user.amount * pool.accPremiaPerShare) - user.rewardDebt\r\n //\r\n // Whenever a user deposits or withdraws LP tokens to a pool. Here's what happens:\r\n // 1. The pool's `accPremiaPerShare` (and `lastRewardBlock`) gets updated.\r\n // 2. User receives the pending reward sent to his/her address.\r\n // 3. User's `amount` gets updated.\r\n // 4. User's `rewardDebt` gets updated.\r\n }\r\n\r\n struct Layout {\r\n // Total PREMIA left to distribute\r\n uint256 premiaAvailable;\r\n // Amount of premia distributed per year\r\n uint256 premiaPerYear;\r\n // pool -> isCallPool -> PoolInfo\r\n mapping(address => mapping(bool => PoolInfo)) poolInfo;\r\n // pool -> isCallPool -> user -> UserInfo\r\n mapping(address => mapping(bool => mapping(address => UserInfo))) userInfo;\r\n // Total allocation points. Must be the sum of all allocation points in all pools.\r\n uint256 totalAllocPoint;\r\n }\r\n\r\n function layout() internal pure returns (Layout storage l) {\r\n bytes32 slot = STORAGE_SLOT;\r\n assembly {\r\n l.slot := slot\r\n }\r\n }\r\n}\r\n"},"@solidstate/contracts/utils/IWETH.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IERC20 } from '../token/ERC20/IERC20.sol';\nimport { IERC20Metadata } from '../token/ERC20/metadata/IERC20Metadata.sol';\n\n/**\n * @title WETH (Wrapped ETH) interface\n */\ninterface IWETH is IERC20, IERC20Metadata {\n /**\n * @notice convert ETH to WETH\n */\n function deposit() external payable;\n\n /**\n * @notice convert WETH to ETH\n * @dev if caller is a contract, it should have a fallback or receive function\n * @param amount quantity of WETH to convert, denominated in wei\n */\n function withdraw(uint256 amount) external;\n}\n"},"@solidstate/contracts/token/ERC1155/IERC1155Internal.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IERC165 } from '../../introspection/IERC165.sol';\n\n/**\n * @notice Partial ERC1155 interface needed by internal functions\n */\ninterface IERC1155Internal {\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 value\n );\n\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n event ApprovalForAll(\n address indexed account,\n address indexed operator,\n bool approved\n );\n}\n"},"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorV3Interface {\n\n function decimals()\n external\n view\n returns (\n uint8\n );\n\n function description()\n external\n view\n returns (\n string memory\n );\n\n function version()\n external\n view\n returns (\n uint256\n );\n\n // getRoundData and latestRoundData should both raise \"No data present\"\n // if they do not have data to report, instead of returning unset values\n // which could be misinterpreted as actual reported values.\n function getRoundData(\n uint80 _roundId\n )\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n function latestRoundData()\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n}\n"},"@solidstate/contracts/access/OwnableStorage.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nlibrary OwnableStorage {\n struct Layout {\n address owner;\n }\n\n bytes32 internal constant STORAGE_SLOT =\n keccak256('solidstate.contracts.storage.Ownable');\n\n function layout() internal pure returns (Layout storage l) {\n bytes32 slot = STORAGE_SLOT;\n assembly {\n l.slot := slot\n }\n }\n\n function setOwner(Layout storage l, address owner) internal {\n l.owner = owner;\n }\n}\n"}},"settings":{"optimizer":{"enabled":true,"runs":200},"outputSelection":{"*":{"*":["evm.bytecode","evm.deployedBytecode","devdoc","userdoc","metadata","abi"]}},"libraries":{"contracts/libraries/OptionMath.sol":{"OptionMath":"0x0f6e8ef18fb5bb61d545fee60f779d8aed60408f"}}}},"ABI":"[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"ivolOracle\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"weth\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"premiaMining\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeReceiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeDiscountAddress\",\"type\":\"address\"},{\"internalType\":\"int128\",\"name\":\"fee64x64\",\"type\":\"int128\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"shortTokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Annihilate\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"underwriter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"shortTokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"freedAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"intervalContractSize\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"name\":\"AssignExercise\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isCallPool\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"longTokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"contractSize\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"exerciseValue\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"name\":\"Exercise\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"isCallPool\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeeWithdrawal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"longTokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"contractSize\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"baseCost\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeCost\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"int128\",\"name\":\"spot64x64\",\"type\":\"int128\"}],\"name\":\"Purchase\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"}],\"name\":\"TransferBatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"TransferSingle\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"underwriter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"longReceiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"shortTokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"intervalContractSize\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"intervalPremium\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isManualUnderwrite\",\"type\":\"bool\"}],\"name\":\"Underwrite\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"isCall\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"int128\",\"name\":\"cLevel64x64\",\"type\":\"int128\"},{\"indexed\":false,\"internalType\":\"int128\",\"name\":\"oldLiquidity64x64\",\"type\":\"int128\"},{\"indexed\":false,\"internalType\":\"int128\",\"name\":\"newLiquidity64x64\",\"type\":\"int128\"}],\"name\":\"UpdateCLevel\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"int128\",\"name\":\"steepness64x64\",\"type\":\"int128\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isCallPool\",\"type\":\"bool\"}],\"name\":\"UpdateSteepness\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isCallPool\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"depositedAt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"holder\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"longTokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"contractSize\",\"type\":\"uint256\"}],\"name\":\"exerciseFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"longTokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"contractSize\",\"type\":\"uint256\"}],\"name\":\"processExpired\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]","ContractName":"PoolExercise","CompilerVersion":"v0.8.9+commit.e5eed63a","OptimizationUsed":1,"Runs":200,"ConstructorArguments":"0x0000000000000000000000003a87bb29b984d672664aa1dd2d19d2e8b24f0f2a000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000009abb27581c2e46a114f8c367355851e0580e9703000000000000000000000000c4b2c51f969e0713e799de73b7f130fb7bb604cf000000000000000000000000f1bb87563a122211d40d393ebf1c633c330377f900000000000000000000000000000000000000000000000007ae147ae147ae14","EVMVersion":"Default","Library":"","LicenseType":"","Proxy":0,"SwarmSource":""}] \ No newline at end of file