From a79adeaa3c9c95bc3eef57f550d9d1ddd1f922a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20M=C3=B6ller?= Date: Wed, 30 Aug 2023 12:07:22 +0200 Subject: [PATCH 1/5] feat(dexs): add 1inch and pancakeswap whitelist for zkSync (#512) --- config/dexs.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/config/dexs.json b/config/dexs.json index 5b861095c..fc89e4afb 100644 --- a/config/dexs.json +++ b/config/dexs.json @@ -369,7 +369,9 @@ "0x0222D030e8DFAEDE2a4e7B5F181Ac1A4206A75f0", "0x9ca271A532392230EAe919Fb5460aEa9D9718424", "0xB49EaD76FE09967D7CA0dbCeF3C3A06eb3Aa0cB4", - "0x36a1acbbcafca2468b85011ddd16e7cb4d673230" + "0x36a1acbbcafca2468b85011ddd16e7cb4d673230", + "0x6e2b76966cbd9cf4cc2fa0d76d24d5241e0abc2f", + "0x5aEaF2883FBf30f3D62471154eDa3C0c1b05942d" ], "velas": [ "0xf068cc770f32042Ff4a8fD196045641234dFaa47", From 73610ce77e4f03640ac235f7182dc97a00e934cb Mon Sep 17 00:00:00 2001 From: Ed Zynda Date: Wed, 30 Aug 2023 14:40:53 +0300 Subject: [PATCH 2/5] deploy Across to zksync (#513) --- config/across.json | 4 + deploy/012_deploy_across_facet.ts | 35 + deployments/zksync.diamond.json | 6 +- deployments/zksync.json | 5 +- deployments/zksync/AcrossFacet.json | 697 ++++++++++++++++++ .../32cb99d43bfe55793e8aa30cc4ac2e58.json | 367 +++++++++ 6 files changed, 1111 insertions(+), 3 deletions(-) create mode 100644 deploy/012_deploy_across_facet.ts create mode 100644 deployments/zksync/AcrossFacet.json create mode 100644 deployments/zksync/solcInputs/32cb99d43bfe55793e8aa30cc4ac2e58.json diff --git a/config/across.json b/config/across.json index e46f998da..4418d1737 100644 --- a/config/across.json +++ b/config/across.json @@ -26,5 +26,9 @@ "mumbai": { "acrossSpokePool": "0x45fF03629D024b7763275e732a2d80202c18b31C", "weth": "0x9c3C9283D3e44854697Cd22D3Faa240Cfb032889" + }, + "zksync": { + "acrossSpokePool": "0xE0B015E54d54fc84a6cB9B666099c46adE9335FF", + "weth": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" } } diff --git a/deploy/012_deploy_across_facet.ts b/deploy/012_deploy_across_facet.ts new file mode 100644 index 000000000..f909ed8e2 --- /dev/null +++ b/deploy/012_deploy_across_facet.ts @@ -0,0 +1,35 @@ +import { HardhatRuntimeEnvironment } from 'hardhat/types' +import { DeployFunction } from 'hardhat-deploy/types' +import { network } from 'hardhat' +import { diamondContractName, deployFacet } from './9999_utils' +import config from '../config/across.json' + +interface AcrossConfig { + [network: string]: { + acrossSpokePool?: string + weth?: string + } +} + +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + if (!(config as AcrossConfig)[network.name]) { + console.log(`No Across config set for ${network.name}. Skipping...`) + return + } + + const SPOKE_POOL = (config as AcrossConfig)[network.name].acrossSpokePool + const WETH = (config as AcrossConfig)[network.name].weth + + await deployFacet(hre, 'AcrossFacet', { args: [SPOKE_POOL, WETH] }) +} + +export default func + +func.id = 'deploy_across_facet' +func.tags = ['DeployAcrossFacet'] +func.dependencies = [ + // 'InitialFacets', + // diamondContractName, + // 'InitFacets', + // 'DeployDexManagerFacet', +] diff --git a/deployments/zksync.diamond.json b/deployments/zksync.diamond.json index 2f5b0dc73..b1c1e8792 100644 --- a/deployments/zksync.diamond.json +++ b/deployments/zksync.diamond.json @@ -20,6 +20,10 @@ "0x862FB4813657A40D1828Cac1e28a600625D78fC0": { "Name": "PeripheryRegistryFacet", "Version": "1.0.0" + }, + "0x7dEfADC99d3E3f5f8d0C7dCFA7D2495B898ef5D8": { + "Name": "AcrossFacet", + "Version": "2.0.0" } }, "Periphery": { @@ -30,4 +34,4 @@ "ServiceFeeCollector": "0x682dBe3f437f040535e728454D7F7f19Ead738b3" } } -} \ No newline at end of file +} diff --git a/deployments/zksync.json b/deployments/zksync.json index 316d93430..1c60ca4cb 100644 --- a/deployments/zksync.json +++ b/deployments/zksync.json @@ -8,5 +8,6 @@ "Executor": "0xa9bfa49F26733271f4FD34A4b57bB7C563Ae056A", "Receiver": "0xdeDB2DAe4a9BC63910a722a3b7DC930C7E6f6421", "FeeCollector": "0x8dBf6f59187b2EB36B980F3D8F4cFC6DC4E4642e", - "ServiceFeeCollector": "0x682dBe3f437f040535e728454D7F7f19Ead738b3" -} \ No newline at end of file + "ServiceFeeCollector": "0x682dBe3f437f040535e728454D7F7f19Ead738b3", + "AcrossFacet": "0x7dEfADC99d3E3f5f8d0C7dCFA7D2495B898ef5D8" +} diff --git a/deployments/zksync/AcrossFacet.json b/deployments/zksync/AcrossFacet.json new file mode 100644 index 000000000..3e4e34cd1 --- /dev/null +++ b/deployments/zksync/AcrossFacet.json @@ -0,0 +1,697 @@ +{ + "address": "0x7dEfADC99d3E3f5f8d0C7dCFA7D2495B898ef5D8", + "abi": [ + { + "inputs": [ + { + "internalType": "contract IAcrossSpokePool", + "name": "_spokePool", + "type": "address" + }, + { + "internalType": "address", + "name": "_wrappedNative", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "CannotBridgeToSameNetwork", + "type": "error" + }, + { + "inputs": [], + "name": "ContractCallNotAllowed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "minAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receivedAmount", + "type": "uint256" + } + ], + "name": "CumulativeSlippageTooHigh", + "type": "error" + }, + { + "inputs": [], + "name": "InformationMismatch", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "required", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "name": "InsufficientBalance", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAmount", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidContract", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidReceiver", + "type": "error" + }, + { + "inputs": [], + "name": "NativeAssetTransferFailed", + "type": "error" + }, + { + "inputs": [], + "name": "NoSwapDataProvided", + "type": "error" + }, + { + "inputs": [], + "name": "NoSwapFromZeroBalance", + "type": "error" + }, + { + "inputs": [], + "name": "NoTransferToNullAddress", + "type": "error" + }, + { + "inputs": [], + "name": "NullAddrIsNotAValidSpender", + "type": "error" + }, + { + "inputs": [], + "name": "NullAddrIsNotAnERC20Token", + "type": "error" + }, + { + "inputs": [], + "name": "ReentrancyError", + "type": "error" + }, + { + "inputs": [], + "name": "SliceOutOfBounds", + "type": "error" + }, + { + "inputs": [], + "name": "SliceOverflow", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "transactionId", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "string", + "name": "integrator", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "referrer", + "type": "string" + }, + { + "indexed": false, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "fromAssetId", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "toAssetId", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fromAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "toAmount", + "type": "uint256" + } + ], + "name": "LiFiGenericSwapCompleted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "transactionId", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "string", + "name": "integrator", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "referrer", + "type": "string" + }, + { + "indexed": false, + "internalType": "address", + "name": "fromAssetId", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "toAssetId", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fromAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "toAmount", + "type": "uint256" + } + ], + "name": "LiFiSwappedGeneric", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "transactionId", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "receivingAssetId", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "LiFiTransferCompleted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "transactionId", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "receivingAssetId", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "LiFiTransferRecovered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "transactionId", + "type": "bytes32" + }, + { + "internalType": "string", + "name": "bridge", + "type": "string" + }, + { + "internalType": "string", + "name": "integrator", + "type": "string" + }, + { + "internalType": "address", + "name": "referrer", + "type": "address" + }, + { + "internalType": "address", + "name": "sendingAssetId", + "type": "address" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "minAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "destinationChainId", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "hasSourceSwaps", + "type": "bool" + }, + { + "internalType": "bool", + "name": "hasDestinationCall", + "type": "bool" + } + ], + "indexed": false, + "internalType": "struct ILiFi.BridgeData", + "name": "bridgeData", + "type": "tuple" + } + ], + "name": "LiFiTransferStarted", + "type": "event" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "transactionId", + "type": "bytes32" + }, + { + "internalType": "string", + "name": "bridge", + "type": "string" + }, + { + "internalType": "string", + "name": "integrator", + "type": "string" + }, + { + "internalType": "address", + "name": "referrer", + "type": "address" + }, + { + "internalType": "address", + "name": "sendingAssetId", + "type": "address" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "minAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "destinationChainId", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "hasSourceSwaps", + "type": "bool" + }, + { + "internalType": "bool", + "name": "hasDestinationCall", + "type": "bool" + } + ], + "internalType": "struct ILiFi.BridgeData", + "name": "_bridgeData", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "int64", + "name": "relayerFeePct", + "type": "int64" + }, + { + "internalType": "uint32", + "name": "quoteTimestamp", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "message", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "maxCount", + "type": "uint256" + } + ], + "internalType": "struct AcrossFacet.AcrossData", + "name": "_acrossData", + "type": "tuple" + } + ], + "name": "startBridgeTokensViaAcross", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "transactionId", + "type": "bytes32" + }, + { + "internalType": "string", + "name": "bridge", + "type": "string" + }, + { + "internalType": "string", + "name": "integrator", + "type": "string" + }, + { + "internalType": "address", + "name": "referrer", + "type": "address" + }, + { + "internalType": "address", + "name": "sendingAssetId", + "type": "address" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "minAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "destinationChainId", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "hasSourceSwaps", + "type": "bool" + }, + { + "internalType": "bool", + "name": "hasDestinationCall", + "type": "bool" + } + ], + "internalType": "struct ILiFi.BridgeData", + "name": "_bridgeData", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "callTo", + "type": "address" + }, + { + "internalType": "address", + "name": "approveTo", + "type": "address" + }, + { + "internalType": "address", + "name": "sendingAssetId", + "type": "address" + }, + { + "internalType": "address", + "name": "receivingAssetId", + "type": "address" + }, + { + "internalType": "uint256", + "name": "fromAmount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "bool", + "name": "requiresDeposit", + "type": "bool" + } + ], + "internalType": "struct LibSwap.SwapData[]", + "name": "_swapData", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "int64", + "name": "relayerFeePct", + "type": "int64" + }, + { + "internalType": "uint32", + "name": "quoteTimestamp", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "message", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "maxCount", + "type": "uint256" + } + ], + "internalType": "struct AcrossFacet.AcrossData", + "name": "_acrossData", + "type": "tuple" + } + ], + "name": "swapAndStartBridgeTokensViaAcross", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } + ], + "transactionHash": "0x78057c84ae2216fff32f3f58a673e0f84d783bd5d8033490cb4c0a4acd4aeb5d", + "receipt": { + "to": "0x0000000000000000000000000000000000008006", + "from": "0x11F11121DF7256C40339393b0FB045321022ce44", + "contractAddress": "0x7dEfADC99d3E3f5f8d0C7dCFA7D2495B898ef5D8", + "transactionIndex": 2, + "gasUsed": "22617301", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x09d9e97ff02056a6368be59c23889d61954901f5400d1b13e3542fc479ba1061", + "transactionHash": "0x78057c84ae2216fff32f3f58a673e0f84d783bd5d8033490cb4c0a4acd4aeb5d", + "logs": [ + { + "transactionIndex": 2, + "blockNumber": 12560360, + "transactionHash": "0x78057c84ae2216fff32f3f58a673e0f84d783bd5d8033490cb4c0a4acd4aeb5d", + "address": "0x000000000000000000000000000000000000800A", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x00000000000000000000000011f11121df7256c40339393b0fb045321022ce44", + "0x0000000000000000000000000000000000000000000000000000000000008001" + ], + "data": "0x000000000000000000000000000000000000000000000000001e8ebfdd0f8800", + "logIndex": 12, + "blockHash": "0x09d9e97ff02056a6368be59c23889d61954901f5400d1b13e3542fc479ba1061" + }, + { + "transactionIndex": 2, + "blockNumber": 12560360, + "transactionHash": "0x78057c84ae2216fff32f3f58a673e0f84d783bd5d8033490cb4c0a4acd4aeb5d", + "address": "0x0000000000000000000000000000000000008008", + "topics": [ + "0x3a36e47291f4201faf137fab081d92295bce2d53be2c6ca68ba82c7faa9ce241", + "0x000000000000000000000000000000000000000000000000000000000000800e", + "0xe225fa9141ce246af821803e9abd6cfdcd97d566bb8fda7af29b0836047dfeee" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000454a056e00000000000000000bf501c00000040f00000000010000190000002402000039000000400100043d000000000101043b0000000002000019000000000110004c0000000000210435000000000001042d000000000010043500000004020000390000000000120435000000040010043f0000030301000041000000000500001900000002011003670000000000320435000000000202043b0bf501a40000040f0000000001010433000000000013043500000000030000190000000000310435000000000023043500000000001004390000000001030019000000410100003900000000030100190000000001000414000000400300043d000000000220004c00000000020204330000000400100443000003010210009c000000400010043f00000b4f0000213d00000000040000190000000003030433000000030100002900000000060000190000002002000039000000400020043f000000000101041a000000cd0000213d00000004030000290bf5015e0000040f00000020060000390bf5075d0000040f0bf505be0000040f000000c00110021000000007010000290000800a01000039000003080100004100000000002404350000000105500039000000000330004c000000cd0000c13d0000000201000367ffffffffffffffff0000001f022000390000000002014019000000200210008c0000000101000031000000ff011001900bf501950000040f000000200010043f000000010200003100000000050300190000000901000029000001000330008900000003033002100000004402000039000000060100002900000000070000190000000001120019000000000606043b0bf50beb0000040f000000000221004b0000000402000029000300000001001d0000000001000410000000000252019f00000000050404330000000504400210000000000645004b00000005065002100000000005010019000000600330027000000009030000290000002401200039000000010300002900000024040000390000031e01000041000003010110009c000000000121034f00000000023201cf000000000232022f000000000535022f00000000053501cf0000000004410019000000000242034f000000000530004c0000000000670435000000000662034f000000000761001900000005044002720000001f0340018f000000010400003100000003020003670bf5014b0000040f0bf503dd0000040f00000040021000390000002002100039000003060420009c00000009020000290000006001100039000200000001001d000100000001001d000000010200c039000002820000213d000000200220003900000000010500190003000000010355000002ff0410009c0000000602000029000400000001001d000700000001001d0000001101000039000500000001001d0000000003050019000003000330009c00000300033001970000030004000041000009dc0000213d000000020300002900000044012000390000083c0000213d000000000103043300000000006104350bf5087d0000040f000000000442004b0000000002340019000000600420018f000100000003001d0000032301000041000006b60000213d0000000002050019000000040250008c00000006050000290000031c011001c7000002ff0340009c0000000c020000290000000a020000290000002001000039000000040420008c000000110300002900000004013000390000800201000039000400000002001d00000301022001970000030103300197000000200110003900000004021000390000000f01000029000000000112034f0000000c030000290000000b01000029000900000001001d00000008010000290000000f02000029000600000001001d000003a80000413d0000000002040019000000030300002900000001040000290000000000410435000000000112019f00000000020300190000000102200190000002ff010000410000000001020019000102ff0030019d00000040033002100000000002310049000000000201043300000001010000290000030c020000410000000502000029000000000303043b000000000707043b000000200300008a0000030701000041000003000110009c000000000410004c000003000110019700000004011000390000000003046019000000000400a019000000000504401953616665455243320200000000000000800000000000000000000008030000290000000702000029000009eb0000613d0000032b0200004100000024021000390bf508fe0000040f00000020012000390000000506000029000000040230003900000024023000390000001f0110008c000007580000613d000400000003001d00000004012000390000008001200039000003200120009c000000200110008c000000a002100039000006b90000613d000000000221034f000080090200003900000001030000390000000001028019000002ff02000041000000a00340003900000000020100190bf504480000040f000000400030043f00000004070000290000059b0000613d0000000400300443000a00000003001d000800000003001d0000001004000029000000000034043500000000004204350000003201000039000000050300002900000000030700190000000103300039000000000332034f0000000202000367000003a10000a13d000000000207001900000002022003670000000b02000029000000400200043d0000000e07000029000900000002001d0000000d01000029000c00000003001d00000301011001980000000802000029000000000210004c0000000204000029000003060410009c0000030006000041000000000505043b00000020033000390000000106004039000000400110021000000060022002100000000001044019000002ff0320009c00000000020004140000000505500210000000000756004b0000000106600039000000000078043500000005076002100bf50bf00000040f000000000113019f00000060044002100bf50a200000040f00000000030200190000000501000029000000000112004b0000800b0100003900000007040000290000000603000029000500000004001d000600000005001d0000000101000039000000040430003900000300050000410bf501b60000040f0000010002200089000000000525022f00000003022002100000000001000416000003060310009c000000000630004c0000000002000031000000010120019037311d699902d1ed0a0602439da45ea37a8ac5d3b7183f2200000000ffffffff000000010200003900000bdd0000213d00000bda0000213d000000200550003900000000024300190000032102000041000000010520018f000000010500003900000000013400190000001f011000390000000505000029000009e30000413d000009dc0000c13d000003060630009c000000600220018f000000050400002900000004050000290000000307000029000300000007001d00000000040200190000092f0000613d00000044021000390bf509370000040f000008c50000c13d000000000320004c000400000005001d00000000001404350000032b0100004100000064012000390000000304000029000000000064043500000328030000410000083c0000c13d0000084b0000613d00000044040000390000032701000041000500000002001d000007550000213d000300000002001d0000032101000041000003220100004100000326020000410000000002060019000000440100003900000020032000390000000104700190000006cc0000213d00000001070040390000000905000029000000000321004b000006b20000613d000000000113004b0bf50a6d0000040f00000325010000410000032401100197000006b60000413d000000040220008c000000ff02100195000000200220011a00000020022000c9000000000200041500000020011000c90000000001000415000003130320009c000300000004001d0000000502300210000000000223004b0000800d02000039000000c00220021000000000020340190000000003044019000000e00340003900000011040000290000004002300039000000200140003900000020013000390000059e0000613d00000000043100490bf5040a0000040f000000020900002900000003080000290000031b01000041001100000003001d000200000002001d0000000d0300002900000000003004390000031a030000410000059b0000213d000002ff0220009c0000059b0000c13d000500000003001d000600000003001d000b00000003001d000000000232019f000000000200601900000317020000410bf507b60000040f00000011010000290000030102100197000000000305043300008005010000390000031901000041000f00000002001d0000000000010435000000000131016f00000000060504330000000008720019000000000343019f0000002004100039000000000336013f000000000736004b000000000214034f000000000550004c0000000005070019000000000224034f00000002040003670000000d0200002900000002010000290000000f03000029000000000201043b0000000a0a0000290000039e0000213d0000000004030433000000000232034f000000000534004b00000000007204350000000102004039000b00000002001d000000000121016f000000200200008a000000010320008a000000000120004c0000000e02000029000000a001200039000000000143004b000800000001001d000d00000002001d000003000220009c00000300022001970000000002120049000002820000c13d000000c0024000390000008002400039000000600240003900000040024000390bf501c90000040f000100000002001d000200000003001d000300000005001d0003000000000002000000000002043500000000022501cf000000000565034f0000000506600210000000000720004c000000000867004b00000001077000390000000000890435000000000808043b000000000885034f0000000009830019000000050870021000000005064002720000001f0240018f000000000225004b0000000106600190000000000104601900000300062001970000001f0130003900000bf70001043000000bf60001042e0000000001310019000002ff0510009c000002ff0540009c0000000001024019000000000045043500000100044000890000000304400210000000000640004c00000005055002720000001f0450018f000200000006001d000000010120018f0000000001058019000000000334019f0000000004058019000002ff0640009c0000000003058019000002ff0630009c000002ff050000410000030a02000041000000000001041b00000000010004110bf5045b0000040f0bf5093e0000040f0000030101100197000000800130003900000002020000290000012001300039000001460000c13d00000100013000390000030b020000410000030901000041000000e001300039000200000004001d000100000005001d00000004010000290000030d020000410000000703000029000000000241004b0000000004000416000000000012041b0000030702000041000700000005001d000000240430003900000000040600190000000005008019000003010320009c000000000520004c00000000007604350000030e02000041000000010110008c0000000001026019000000000200a01900000000030240190000030002000041000003060210009c0bf5021a0000040f0000000401100370000000040320008a000000000301043b0004000000000002656e746c79000000727465642073696c696f6e20726576655472616e736163746eefed2000000000e46e079c0000000055cc4d5394440b384c5312701c8cba1176e53cb0607060f57bfdfdb5e3a37769000000e00000000008cc6b5d955391325d622183e25ac5afcd93958e4c903827796b89b91644bc985a04673700000000ffffffffffffff5f23b872dd000000007472616374000000206e6f6e2d636f6e2063616c6c20746f416464726573733a6f6e20646964206e206f706572617469303a20455243323065640000000000006f742073756363656c206661696c65646576656c2063616c303a206c6f772d6cffffffffffffffc063ba9bff0000000008c379a0000000006e6f6e2d7a65726f76652066726f6d20303a20617070726f6f77616e636500007a65726f20616c6c20746f206e6f6e2d095ea7b300000000dd62ed3e00000000945398040000000011a3725a714e7f1fffffffff0000000011a3725a714e7f1e21f7434500000000cf47918100000000ffffffffffffff7fa9059cbb0000000070a08231000000005c2e27ecbe1644f1af8e0b0b54b893089347222505213b55cba69f43792f9f391186ec3300000000023a8d90e8508b8302500962caba6a1568e884a7374b41e01806aa1896bbf265ab882de59d99a32eff553aecb10793d015d089f94afb7896310ab089e4439a4c7fffffffffffffff0503c3ed00000000275c273c000000000000000100000000fffffffffffffec000000000000000010200000200000000000000400000000029f745a7000000001e4ec46b000000002c5211c6000000004ac09ad30000000050dc905c000000000d0df415241f670b5976f597df104ee23bc6df8224c17b489a8a0592ac89c5ad125fc972a6507f396b1951864fbfc14e829bd487b90b72539cc7f708afc65944b77752890e8b697b97769bf42adb48cf858c00edc14abc52a65bb2f450488ab0000000001fd8010c000000003a3f73324e487b7100000000000000020000000000000bf50000043200000bf20000013d00000bf30021042300000bed0000013d00000bee0021042100000bce0000013d00000000070704330000000007250019000000000645001900000bd60000813d000000000635004b000000000445004b0000000005230019000000200250003900000bdd0000c13d000003060720009c000000000662004b0000000002160019000000000626016f0000003f0630003900000bda0000c13d0000000003066019000000000383013f0000000006008019000000000983004b00000300084001970000000007068019000000000743004b0000001f0350003900000000053500190000000004430019000003060650009c000000000503043300000bda0000613d000000000506c019000003000770009c000000000870004c000003000740019700000000060520190000001f0640008c00000b8c0000013d00000b930000813d000000000641004b000000040550003900000000041200190000000005140019000000000434019f00000020040060390000001f0320019000000be40000813d000000000332004b0000001f0300008a000000040220008a00000bd80000013d0000033a030000410000001d0200003900000bdd0000813d0000032d0210009c00000b7f0000813d000000440320008c000900000003001d0bf50b720000040f0000033802000041000003390200004100000b4f0000613d000003370400004100000336011001c700000000020180190000002002400039000000040400002900000000022400490000000002032019000000000234004b0000033501000041000000000103043b00000b660000613d0000000003028019000002ff0530009c000000000402801900000afe0000013d00000ae70000613d00000afe0000613d000000040260008c00000004060000290000000000260435000000000272019f000000000727022f00000000072701cf0000000007060433000000000663001900000ad90000613d00000ac20000413d00000aca0000613d0000000205500367000003010220009c000000020210036700000b5c0000413d000003010310009c00000aad0000613d000000000200c01900000b570000613d000800000002001d000000800230003900000b520000613d00000000002004390000031a0200004100000b4f0000813d000003130310009c000000020120036700090000000000020000033402000041000003220200004100000a680000613d00000a4b0000013d00000a450000613d000000000230004c00000a4b0000613d000000040240008c00000a560000413d000000000131004b00000a510000613d00000a090000613d000009f20000413d000009fa0000613d000009e60000413d000000000141004b000009db0000613d000000000252004b000000000242004900000a190000413d000000000342004b0000000002030433000000200220008c0000000104600190000000000441004b000000600410018f000000200120008c000009bc0000613d0000000306000029000003330120009c000000640100003900000000007104350000033203000041000003060620009c0000000002320019000009880000613d00000a140000613d000003010710019800000a0b0000413d0000000001070433000009e30000a13d00000000037200190000095d0000613d000000040270003900000301031001970000000000170435000000400700043d000009d80000613d0000030105100198000009e60000613d000000000240004c0005000000000002000000000353019f00000000034301cf000000000343022f000000000545022f00000000054501cf00000000050204330000000002520019000000000353034f000009180000413d000000000773034f000009200000613d00000001050000310000000303000367000009300000c13d0000000104400190000009300000213d000003060530009c0000000104004039000000000413004b0000000003310019000000000331016f0000003f01200039000009300000813d000003110120009c0000000102000032000000600100003900000064020000390000001d03000039000003310300004100000084020000390000002a0300003900000330030000410000032f0300004100000064021000390000000102000029000008ee0000c13d000008dd0000613d00000000020460190000000004052019000000000420004c0000000003054019000000200320008c000008c40000613d000008f00000613d0000031a01000041000008ae0000c13d000008cf0000c13d0000000103300190000300000003001d00000001030060390000000004020433000008980000613d000000040350008c000100000004001d0000032e030000410000004001400039000008c80000813d0000032d0140009c000000400400043d00000301051001970000008403000039000000200300003900000036030000390000032a030000410000032903000041000008690000613d000008520000413d0000085a0000613d0000032c01000041000000010300008a0000086b0000c13d000008430000413d000008170000613d000000000047043500000004073000390000083b0000813d000000000181004b000008430000a13d0000000104900190000000010900403900000000090000190000000208000029000200000008001d000007db0000613d000400000007001d000500000006001d000000040270008c000003010420019700000000020004100000000000620435000008460000613d00000301062001980000083b0000613d000003010750019800000000080300190006000000000002000007b40000613d0000079d0000413d000007a50000613d0000078b0000013d000007930000a13d0000078c0000c13d00000001045001900000078c0000213d0000000105004039000007960000613d0000000105000029000007710000613d0000000004000410000007840000613d00000301021001980001000000000002000007070000013d000007550000413d000800010000003d000000080220008a0000072f0000013d000000070110008a000700ff001001930000072a0000613d000007550000813d000007540000813d00000000040300190008000000000002000006ff0000613d000006e80000413d000006f00000613d00000044030000390000064e0000013d000006b20000013d0000000000630435000000440320003900000000004304350000031f04000041000006d80000413d000000000163004b000006cc0000c13d000006e10000613d00000002060000290000068a0000613d000006d30000613d000006af0000613d000000000150004c0000000006210049000006be0000413d0000000002230019000006c50000a13d000000000232004b000003010120009c000006b50000813d0bf507010000040f0000000a03000029000006be0000613d000000000130004c000005ea0000013d0000000c01000029000e00010000003d000a00000002001d0000000e0220008a000006110000013d000a00000001001d0000000d0110008a000d00ff001001930000060c0000613d000006b60000813d000c00000001001d000006b50000613d0000000101100190000006350000c13d000000010130008c000e000000000002000005dd0000613d000000000532004b000000df0330008a00000000031000790000000002120019000005d60000813d000005bc0000613d000005a50000413d000005ad0000613d000004c70000a13d000003060130009c0000058e0000013d00000000040500190000000003060019000000000223019f00000060033002100000004002200210000002ff0230009c0000058a0000613d000000000160004c0000000806000029000005910000613d0000000d0500002900000007060000290000000804000029000000000a02043b00000060022000390000002400100443001100000002001d000000000225034f000000000226004b000700000006001d00000318036001970000031602600198000000000602043b000000000215034f00000002050003670000000e010000290000031d04000041000002ff0430009c0000000003000414000000000131019f0000006001100210000000000141004900000140034000390000012002500039000001200340003900000100025000390000010003400039000000c003400039000000800340003900000060025000390000001005000029000000600440003900000040011000390000001001000029000000200310008a00000000014200490000016002300039000000000052043500000140050000390000000002040433000005940000813d000003110130009c0000001105000029000004c40000613d00000009060000290000000805000029000000000a01043b0000006001200039000900000005001d000000a0036000390000000e03000029000700000003001d000000e003600039000000100600002900000318035001970000031602500198000000000502043b0000051d0000613d000c00000005001d000000c00540003900000024000004430000000001000412001100000001001d0000000001020433000e00000002001d0000008002100039001000000001001d001100000000000200000000012300190000044c0000013d00000000006504350000000006060433000000000614001900000020044000390000000005240019000004540000813d00000000030104330000001f019000390000000000a10435000000e001100039000000000003043500000000039200190000000000350435000000000363019f00000000033401cf000000000434022f000000000404043b000000000636022f00000000063601cf0000000005520019000000000454034f0000043f0000613d000004280000413d000000000774034f000004300000613d0000000505900272000000020480036700000120021000390000001f0390018f000000000093043500000100031000390000008004100039000003180460019700000000030060190000031703000041000003160360019800000040051000390000000000570435000000600710003900000000007b0435000000a00b100039000002ff077001970000000000cb0435000001000c000039000000c00b100039000004070000c13d000000000400801900000300061001970000000005042019000000000531004b0000000003230049000004070000213d000004070000613d0000000005066019000003000550009c000000000558013f000000000600a019000000000958004b000003000820019700000300055001970000000007064019000000000752004b0000001f0540008a000000000413004900000000030000310000031402000041000000240310003900000315020000410000039b0000a13d000000000231004b000003d40000413d000000000142004b00000000022100490bf505e00000040f0000000b05000029000f00000004001d0000000004000411000003590000013d0000008001100039000003010430009c0000004003100039000003740000613d0000039e0000c13d000000000443004b000000010400c039000000000430004c000000c003100039000f00000003001d000003780000813d000000000173004b0000032b0000013d0000000001310049000000000454004b00000000040404330000000b04000029000000000431004b0000000003000416000000000353004b0000000b03000029000003550000c13d0000000002a2001900000005025002100000000f05000029000000000121004b000003010130009c000f00000005001d000003580000813d000000000175004b000a0000000a001d0000000001980049000000000141019f00000000011201cf000000000212022f0000010001100089000000000414022f00000000041401cf000000030110021000000000033a00190000000503300210000003270000613d000003100000413d00000001044000390000000000560435000000000552034f00000000065a00190000000505400210000003180000613d0000000503300272000000200a2000390000001f0130018f000003b40000c13d000003b40000213d0000003f013000390000000503700210000003b40000813d000003110170009c000000000212004b000002f50000c13d00000005090000290000000c080000290000039e0000813d000003130110009c000003cf0000613d000003ca0000613d000f00000001001d000000e001200039000003c50000613d000000c001200039000003c00000613d000003af0000c13d0000012001200039000003af0000613d0000010001200039000003bb0000613d000e00000003001d000400000004001d000f0000000000020000029a0000613d0000000002036019000000000300801900000000040320190000007f0420008c0000030003000041000000000104001900000120024000390000010002400039000000e002400039000000c001300039000000a002400039000000a001300039000000600130003900000040013000390000000001510019000000200150003900000002015003670000014001300039000002850000813d000003120130009c000002820000613d000000000406401900000000030620190000013f0310008c00000000015200490000000002140019000000000262019f000000000626022f00000000062601cf000000000603043300000000036300190000020c0000613d000001f50000413d000001fd0000613d00000020031000390000000205300367000002170000213d0000000005430019000000400050043f000002100000c13d000002100000213d000003060750009c000000000615004b0000000005510019000000000551016f000000200500008a0000003f01400039000002100000813d000003110140009c000000000401043b0000000201300367000002170000613d000000000161013f000000000761004b000000000521004b00000000010380190000000002038019000002ff0420009c000002ff03000041000000000121001900000000020480190000000001048019000002ff04000041000001b30000613d00000310011000410000000004000414000001a10000613d00008010020000390000030f011001c7000100000003001f000000000474019f00000000044601cf000000000646022f000000000747022f00000000074701cf00000000070504330000000005590019000000000651034f000001910000613d000000010220018f000001790000413d000000000771034f0000000008790019000001810000613d0000000005034019000000000453004b0000000205000029000002ff0330019700000001090000290002000000000002000001400000a13d00000000012100490000011c0000c13d000001090000c13d0000000002050433000000c0053000390bf5029d0000040f0bf5028c0000040f000400000009001d000001000000c13d0000030102200198000000a002300039000000e70000813d000600000006001d000000f10000a13d0000004401100370000000000323004b00000000034300190000000503500210000003060450009c000000000504043b000000000441034f000000000440004c0000000004056019000003000440009c000000000474013f000000000874004b000003000720019700000300044001970000000006058019000000000624004b0000002304300039000003060230009c000000000302043b00000024021003700000000009010019000000600530008c0000030203000041000000c0020000390000010001000039000001200010044300000002010000390000010000200443000001a0001004430000018000200443000000a00100043d00000160001004430000014000000443000000800100043d000000a00020043f000000800010043f000000e00200043d000000c00100043d000000400310008c00000000022301cf000000000323022f00000000052501cf000000c004400039000000000343034f000000740000613d0000005d0000413d000000c006600039000000000763034f000000650000613d000000050410027200000002030003670000001f0210018f000000570000213d000000bf0320008c000000000232016f000000df021000390000000001000031000000d00000c13d000000800310008c000000000160007900000004061000390000002401000039000000400530008c000003050330009c000000960000613d000003040430009c000000e003300270000000cd0000413d000000040120008c0000008001000039000000470000c13d000100000000001f000002ff0030019d00020000000103550003000000410355000002ff0430019700070000000000020214056d001c0058056c056b056a056905680128056705660023012705650564003a02130563056205610560003902120085055f000f00c70084012600c60083008200c500380039021100050125002c00c402100057055e00100005020f002c055d055c020e055b0016020d00c300c2020c00c1001a020b0007003900c0002b020a055a000402090008000b00010124000700390559055800bf055705560555000e000a001b000d000300020001002a0554055305520551000f0056055000be054f020800370055054e0207054d0054054c0123054b0053054a012200bd01210549054800520036020e05470016020d00c300c2020c00c1001a020b0007003905460022002c05450206002c05440543054205410540053f0029053e053d053c053b053a0539053805370120021200850536000f00c70084012600c60083008200c500380039021100050125002c00c402100535003a053405330532002c05310127011f05300028052f052e052d052c0205052b052a0204052905280039011e052705260525002c0203052405230522002c0521000501250520000200060001051f0202011d020102000035001900510081002100340003001301ff01fe051e000e000a0080000d00030002000101fd051d0020051c051b000401fc0008000b000100c4007f051a011c011b051901fb00bc011a01190518000200060016012005170516001f0515000400bb0008000b000101fa01f9005001f80014007e01f700190118000b0013004f01170514000401f60008000b000101fd01f50014000701f401f30014000701f4002701f20513007e00ba00b901f1001401f001ef0033007d01ee0035001901160021003400030013004f0115004e051200b801ed011400c001ec0002000600160120000401eb0008000b000101ea01e901e800b701e701e6011301e5007c01e400320112004d001c005800b6007b01e30009051101e201fa01ea01e901e800b701e701e6011301e5007c01e40032011201110510001c0058050f050e050d050c01e101e0050b00280110050a050900be010f010e010d0508050701df0506010c0505050401de050305020501004c01dd050004ff04fe01dc04fd007b00b5000900b4010b010a01db003204fc04fb011100b304fa00050009000200060001001c00b404f901da010900320108004b04f800b2011100b304f70005000900020006000104f601d904f5010701d8010a04f4010804f301d704f204f104f0007c04ef0107010800b101d6001c01d5008504ee000f00c701d400c304ed00c604ec00c1007a01d3000704eb04ea04e904e804e704e604e504e4000404e304e20028010604e104e001d204df04de00b0010504dd01d104dc01d004db04da01cf04d9004a01ce01cd01cc01cb01ca01c901c804d801c704d701c601c504d6012304d504d404d301040121012201c404d2001804d1007901c30009000e000a001b000d00030002000100020006000101c2005704d0010304cf001604ce00c300c2002504cd00c1001a01d3000704cc001e04cb04ca04c9002304c80005001504c7001000050102007804c601c101c001bf01be00af00ae01f20079000c04c500100005020f007801d800ad01be010100ae01bd000c04c4001000050022007801bc000c01f1001000050022007801bb000c04c3001000050022007804c2000c04c10010000501ba000c01f80010000504c0000c01f500100005010000060077004e01b904bf000c01f300100005010000060077004e01b904be000c04bd0009000200060001000e000a001b000d00030002000101b804bc04bb002504ba01b7020704b901b600ad04b8001f04b7000900020006000104b604b504b401b501b400c0002b020a04b3011d0201020000350019005100500021003400030013001c01ff01b300ac00ff04b20014000704b104b00014000704af01b2001400fe04ae011b00fd04ad00ab0014000704ac04ab001404aa01f700190118000b001300aa011704a901b101b004a800490014007600a90014007501af00fc0031007400100005007f04a704a60033003000a80033000704a504a404a30124007304a200ac007301b800fb00fa04a104a0049f049e01ae01ad00f9004b01ac004e000601ab0102049d00b3049c002300f801aa049b049a012700f704990498002504970496049501040494049301a9049200c20491049001a8048f048e01a7048d048c0012048b048a04890488001504870081000f04860485048400fc00f6008204830031007400100213048201a600a7001400aa048100f5001a00fd00300480047f01a5047e000c00a60038047d047c0026047b00f5047a047900ac04780477047600f50475000c01a5003700fa047400160473047200fc00f604710031047000f400f300bd046f0025046e046d046c0038046b046a00f300bd046901a6046800a501a4001a01ef01a300f200fa0467046601a201a100f1046504640463003300300073004e00ac0073046200af046104600049000800a9004f01ee003500190027002100340003001300f0045f045e00b800a4011400c001ec0009000200060001000e000a00ef000d000300020001000e000a0080000d000300020001000401eb0008000b0001000e000a001b000d000300020001000402090008000b0001000401fc0008000b0001000400bb0008000b0001000401f60008000b00010004045d0008000b00010004045c0018045b000800a300ee00480001045a0459045801a0019f001201030457004a0456045504540453045204510450019e044f019d044e004b019c00120072044d044c00a20085044b000f044a00840449019b0448019a0083008200c50038044700090002000600010446044504440443044204410440043f043e01dc00a1019900ed043d043c043b043a0198043900ed0438043700a0000804360435043404330432002801100197043100be010f010e010d04300126042f010c042e042d00470196042c042b042a004604290428042704260425042404230422042100bf0195004b0009042000110079002501a9041f041e041d041c041b041a04190418019401d500bf0195004b0009041701930416041504140413041201920019041100a80021041001910048001300ec040f0190018f018e00fe040e01b5040d018d01a000a4019c040c040b018c018b040a018a040904080189002600eb00a6002604070406002600a10188040500ea002600a10187040401d101860071019f0012009f018501840070006f01830182018100e900500180009e0003001300aa000700e8001e017f017e00150403010b019300100402009d00bc011a01190401040000e7017d017c017b009c01a1009b03ff017a00a403fe006e009c0007017903fd00ec03fc017f00e6009a0015017803fb000801770014017603fa03f903f800e500e4017503f703f603f503f4001403f300ed00e503f203f1002000a0017503f0001801b1002000a000e300180099002000a003ef0018009800200174001800f8002003ee001803ed0020001f0006007703ec001803eb0020001f0006007703ea001803e900e200970115017300b7007c00e103e803e703e603e50172017100b10096017000e003e4004d012800e80009004500eb03e303e200a403e103e003df018c018b03de018a017401890026018800e300ea002600a1018703dd03dc0186007103db0012009f018501840070006f01830182018100e900500180009e0003001301a3000700e800f903da017e000c001d00760192001900450021009a03d901910048001300aa03d800f703d7001c018e00c400bc03d6009503d500e7017d017c017b009c03d4009403d3017a03d203d103d000b403cf00e4017203ce0097001c017303cd03cc00af00970109003200b1009600df03cb03ca000f004d001c005800b6007b01e303c900ba00930044006e0007009c017903c800ec03c7000e000a001b000d000300020001000200060001006d0004006c006b006a03c6000f005600690068004c00670037005503c5006603c4005400650064004700530063006200120046006100600052003600430001016f03c3016e03c200f7001203c103c0008503bf000f00c7008401d4019b00c6019a0083008200c5003803be004b0009000e000a00ef000d00030002000100020006000103bd011c016d01ac00a803bc03bb011d01b4001603ba03b900a700ff003103b80070003a00de0012016c03b7001f03b600980079005f000500220092000a009100420041002b03b5004000dd016b03b4016a03b3003a03b2016903b1016803b003af0098005f000500220092000a009100420041002b009901670166004000dd03ae00dc006f01650164001000050163000a016200420041002b004000dd00450098016100e0000203ad00ea03ac03ab009901af00a700eb0031007400100005007f005e0092004500f803aa03a9002701f0007e004900a20081001600a9016003a800a7009900fd00310074001001a403a7009200330117015f00fb00b50030007d002000a603a603a5016e00f003a40020015e03a3015e015d015f03a203a103a0001e01fb0007039f005d00150051018f011e001d00360094039e005c01e2002f009300440090002e005b039d015d0007039c003f003e0029003d003c008f008e008d004a015c0072015b015a039b002a00db01640026039a005a039901590398039703960395002d00170158000c00da015b00d90023007a008c039400270157011400a600f203930009000200060001000401560008000b0001000e000a0080000d000300020001000e000a00ef000d000300020001000e000a001b000d00030002000101550015000b001a000100170154000c00d8008b039200b500b20001006d0004006c006b006a0391000f005600690068004c00670037005503900066038f005400650064004700530063006200120046006100600052003600430001038e038d01530076001601f901b3038c002700ad00d7003100ab0070003a00de0012016c038b001f038a007d0079005f000500220152000a009100420041002b0389004000d6016b0388016a0081003a038701690386016801510385007d005f000500220152000a009100420041002b00bc01670166004000d6004900dc006f01650384001000050163000a016200420041002b004000d600ba007d0161002d00f2010103830009000200060001000401560008000b0001038203810380001e005d0015009d037f00b0001d009b037e005c002f0090037d002e005b0007037c003f003e0029003d003c008f008e008d000f037b0072037a03790378002a00d50377008a037600350019005100210034000300130009000e000a001b000d000300020001000200060001006d0004006c006b006a0375000f005600690068004c0067003700550374006603730054006500640047005300630062001200460061006000520036004300010372037100570370036f001e036e036d0150001500d4001d036c036b036a00d3016d00ee0369011c036803670366014f002f00f6004403650090002e005b036400e700d200950007014e003f003e0029003d003c008f008e008d03630362007200890361014d002a00d50360008a035f035e00d1014c0017005a008b01580075000c0088019400da008900d90023007a008c004f00d200950150001e00150203001d014b035d014a035c009b035b014f002f004400d7002e002d00d200950007014e003f003e0029003d003c008f008e008d004a015c00720089015a014d002a00db035a008a0007035900d1014c0017008803580017005a008b01a2000c00da008900d90023007a008c0009000e000a001b000d00030002000100020006000103570015000b001a0001006d0004006c006b006a0356000f005600690068004c006700370055035500660354005400650064004700530063006200120046006100600052003600430001014903530017008803520017005a035100170148000c00d803500017034f00b500b200010214034e034d034c034b034a0023017703490017009a007503480147001d014603470016034603450159004f000f006e000700160344034300d000b900ae034203410145002d03400050033f001900e9009e000300130007033e002700b90145033d011f033c0016033b01b7033a0025033901b600b20338001f014400a20014010000060077004e0144000703370009000200060001000e000a001b000d000300020001001c01b0033600f9009f0148000c00d803350143002d00b8001a0001000403340333001101420332001100cf0331001100ce000800a300870011033000010178000100040142032f001100cf032e001100ce000800a300870011032d0001032c032b0141032a0329032800bf032700040326032500250324032303220321032000e600080071031f031e01e101e0031d002801100197031c00be010f010e010d031b01df0141010c031a031901de03180317031600bd01dd03150314031300110009000e000a001b000d0003000200010115002900080071001a00e500090312014003110310030f030e030d005d030c01ed030b030a001d01c000110094011b01460309005c002f009300f1019e013f002e013e013d013c000700cd003f003e0029003d003c013b0308016f000601ab013a008600b3013900e600d50307030601fe0305005103040303005d001500d3001d01aa0094013f0302005c002f009300440090002e013e005b013d013c000700cd003f003e0029003d003c013b030103000086002a00db0138008a007600d102ff0017014900b0008802fe005a0087001702fd000c02fc008601b20023007a008c004f0137005d001e0015011e001d02fb014b009b02fa005c002f004400d7002e002d0137000700cd004302f9009a01db013602f8013502f7002801060102008602f60139002302f5013802f400af02f302f202f102f002ef00bb0008000b0001012402ee02ed0009000e000a001b000d000300020001000200060001000400bb0008000b0001006d0004006c006b006a02ec000f005600690068004c00670037005502eb006602ea00540065006400470053006300620012004600610060005200360043000100d4000c01540015009d00b00048001a000101550015000b001a0001000e000a0080000d00030002000101c2015300fe007502e90035001900510076002100340003001300ae02e802e70134001d010102e602e502e402e300e201d900e10032009600df000f004d001c005800b6007b013302e200ad00160025000f006e005701c100d00027000702e10009000402e00008000b00010035001900ba00210034000300130132001e001800d3014a00ee00d4000c0048001a0001000402df0008000b000102de005002dd000502dc02db00fb02da02d90021009e00030013000702d8005902d7003a00de001202d6001f02d501760151005f0005007f005e00240033003000cc001f00ff02d401bf007e0045007400ab0010000500220024003000750033000702d300f4011600a5000502d200590024010501a800120206002400cb018d00a9002d0160004502d102d00012009f02cf002400dc006f001e0057014001d0001d02ce01cf02cd004a01ce01cd01cc01cb01ca01c901c802cc01c702cb01c601c502ca012302c902c802c701040121012201c402c602c5013101c3013402c402c302c200cc001f02c10157000f006e005702c000e201da02bf011302be02bd00b70198007c00e100320112009600df005b0204000f004d001c005800b6007b0133020200d000cc001f02bc004900100005002200730024003000f4005900f3007f02bb00a8005e0024011600a500050081005e0024004900a5000500ab005e00240004007e02ba00190118000b00130087011902b9000602b802b702b600e3001801bb00cb001101bc011a001101bd00f0001102b50059001101ba000c0027014700b4010b010a02b4009701090107017100b102b3017000e002b2004d012802b10009000200060001000402b00008000b0001000402af0008000b0001000400cf00110132000800a300cb00110048000102ae00ce001e02ad001800e4009d0143005900b8001a000100b902ac02ab000402aa02a90070002a02a8000802a7007102a602a502a402a302a202a1002502a0029f029e001e0135029d029c029b029a0196008b013000a202990018013601ae01ad002301a7011f02980028029702960295020502940293019d0292010502910290012f028f028e028d0103028c004a028b0084028a028902880287008300f10286003802850190013a012e0284028302820281002801060280012e01d2027f002a0017027e027d027c012f0199000f027b027a0279027802770208013002760131001600110009000200060001000e000a001b000d000300020001000e000a0080000d0003000200010275012d0009000602740273012d000900060272027101d701d60000000000000000000000000000012c00ca0000000000000000012c003b003b0270000000000000026f000000000000000000000000026e000000000000026d000000000000003b026c026b026a0269026802670266026502640263026202610260000000000000025f000000000000025e000000000000025d000000000000025c00000000000000c90000025b0000025a0000000000000000000002590000000000000000025800000257000000000256000000000000025500000000000000000000000000ca003b003b003b00ca00000000000002540253025202510250024f024e024d024c024b00000000000000c9000000000000024a02490248024702460000000000000245000000000000000000000000024402430000000000000242000000000000012b012a012902410240000000000000012b012a0129023f023e000000000000023d000000000000023c000000000000023b023a0239000000c802380237023602350000000000000234000000000000000000000000023300c8023202310230022f022e0000000000c8022d022c022b022a022902280227022600000000000000000000000002250224000000000000022302220221022000c90000021f0000021e021d021c021b021a0000000000000219000000000000021802170216021500000000000000000000000000000000000000000000", + "logIndex": 13, + "blockHash": "0x09d9e97ff02056a6368be59c23889d61954901f5400d1b13e3542fc479ba1061" + }, + { + "transactionIndex": 2, + "blockNumber": 12560360, + "transactionHash": "0x78057c84ae2216fff32f3f58a673e0f84d783bd5d8033490cb4c0a4acd4aeb5d", + "address": "0x0000000000000000000000000000000000008004", + "topics": [ + "0xc94722ff13eacf53547c4741dab5228353a05938ffcdd5d4a2d533ae0e618287", + "0x0100033bc2b36182964508d7f361fbdca6a82fa5b42bc7c7dd478a7a1c1d35f7", + "0x0000000000000000000000000000000000000000000000000000000000000000" + ], + "data": "0x", + "logIndex": 14, + "blockHash": "0x09d9e97ff02056a6368be59c23889d61954901f5400d1b13e3542fc479ba1061" + }, + { + "transactionIndex": 2, + "blockNumber": 12560360, + "transactionHash": "0x78057c84ae2216fff32f3f58a673e0f84d783bd5d8033490cb4c0a4acd4aeb5d", + "address": "0x0000000000000000000000000000000000008006", + "topics": [ + "0x290afdae231a3fc0bbae8b1af63698b0a1d79b21ad17df0342dfb952fe74f8e5", + "0x00000000000000000000000011f11121df7256c40339393b0fb045321022ce44", + "0x0100033bc2b36182964508d7f361fbdca6a82fa5b42bc7c7dd478a7a1c1d35f7", + "0x0000000000000000000000007defadc99d3e3f5f8d0c7dcfa7d2495b898ef5d8" + ], + "data": "0x", + "logIndex": 15, + "blockHash": "0x09d9e97ff02056a6368be59c23889d61954901f5400d1b13e3542fc479ba1061" + }, + { + "transactionIndex": 2, + "blockNumber": 12560360, + "transactionHash": "0x78057c84ae2216fff32f3f58a673e0f84d783bd5d8033490cb4c0a4acd4aeb5d", + "address": "0x000000000000000000000000000000000000800A", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x0000000000000000000000000000000000000000000000000000000000008001", + "0x00000000000000000000000011f11121df7256c40339393b0fb045321022ce44" + ], + "data": "0x000000000000000000000000000000000000000000000000000a782bad170380", + "logIndex": 16, + "blockHash": "0x09d9e97ff02056a6368be59c23889d61954901f5400d1b13e3542fc479ba1061" + } + ], + "blockNumber": 12560360, + "cumulativeGasUsed": "0", + "status": 1, + "byzantium": true + }, + "args": [ + "0xE0B015E54d54fc84a6cB9B666099c46adE9335FF", + "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" + ], + "numDeployments": 1, + "solcInputHash": "32cb99d43bfe55793e8aa30cc4ac2e58", + "bytecode": "0x0004000000000002000700000000000200000000030100190000006003300270000002ff0430019700030000004103550002000000010355000002ff0030019d000100000000001f0000000101200190000000470000c13d0000008001000039000000400010043f0000000002000031000000040120008c000000cd0000413d0000000201000367000000000301043b000000e003300270000003040430009c000000960000613d000003050330009c000000cd0000c13d000000040320008a0000030004000041000000400530008c000000000500001900000000050440190000030003300197000000000630004c000000000400a019000003000330009c00000000030500190000000003046019000000000330004c000000cd0000c13d0000000401100370000000000101043b000003060310009c000000cd0000213d00000004011000390bf5021a0000040f000000000501001900000024010000390000000201100367000000000101043b000003060210009c000000cd0000213d000000040610003900000000016000790000030002000041000000800310008c000000000300001900000000030240190000030001100197000000000410004c000000000200a019000003000110009c00000000010300190000000001026019000000000110004c000000cd0000c13d0000030701000041000000000101041a000000010110008c000000d00000c13d000000400100043d0000030e02000041000000000021043500000004020000390bf501c00000040f0000000001000416000000000110004c000000cd0000c13d0000000001000031000000df02100039000000200300008a000000000232016f000000bf0320008c000000570000213d000003030100004100000000001004350000004101000039000000040010043f000000240200003900000000010000190bf501c00000040f000000400020043f0000001f0210018f00000002030003670000000504100272000000650000613d00000000050000190000000506500210000000000763034f000000000707043b000000c00660003900000000007604350000000105500039000000000645004b0000005d0000413d000000000520004c000000740000613d0000000504400210000000000343034f0000000302200210000000c004400039000000000504043300000000052501cf000000000525022f000000000303043b0000010002200089000000000323022f00000000022301cf000000000252019f00000000002404350000030002000041000000400310008c000000000300001900000000030240190000030001100197000000000410004c000000000200a019000003000110009c00000000010300190000000001026019000000000110004c000000cd0000c13d000000c00100043d000003010210009c000000cd0000213d000000e00200043d000003010320009c000000cd0000213d000000800010043f000000a00020043f000000800100043d00000140000004430000016000100443000000a00100043d00000020020000390000018000200443000001a0001004430000010000200443000000020100003900000120001004430000010001000039000000c00200003900000302030000410bf501b60000040f000000040320008a0000030004000041000000600530008c000000000500001900000000050440190000030003300197000000000630004c000000000400a019000003000330009c00000000030500190000000003046019000000000330004c000000cd0000c13d0000000401100370000000000101043b000003060310009c000000cd0000213d00000004011000390bf5021a0000040f000000000901001900000002010003670000002402100370000000000302043b000003060230009c000000cd0000213d000000230430003900000000020000310000030005000041000000000624004b0000000006000019000000000605801900000300044001970000030007200197000000000874004b0000000005008019000000000474013f000003000440009c00000000040600190000000004056019000000000440004c000000cd0000c13d0000000404300039000000000441034f000000000504043b000003060450009c000000cd0000213d000000240430003900000005035002100000000003430019000000000323004b000000cd0000213d0000004401100370000000000101043b000003060310009c000000f10000a13d000000000100001900000000020000190bf501c00000040f000600000006001d000700000005001d00000001010000390000030702000041000000000012041b000003080100004100000000001004390000000001000410000500000001001d00000004001004430000800a0100003900000024020000390bf501a40000040f0000000004000416000000000241004b000000e70000813d000003030100004100000000001004350000001101000039000000040010043f000000240200003900000000010000190bf501c00000040f0000000703000029000000a00230003900000000020204330000030102200198000001000000c13d000000400100043d0000030d02000041000000000021043500000004020000390bf501c00000040f0000000401100039000700000001001d000400000009001d000600000005001d000500000004001d0bf5028c0000040f00000004010000290000000502000029000000060300002900000007040000290bf5029d0000040f0000000001000019000000000200001900000000030000190bf501b60000040f000000c0053000390000000002050433000000000220004c000001090000c13d000000400100043d0000030c02000041000000000021043500000004020000390bf501c00000040f000100000005001d000200000004001d000300000001001d000000e0013000390000000001010433000400000001001d000003090100004100000000001004390000800b0100003900000004020000390bf501a40000040f0000000402000029000000000112004b0000011c0000c13d000000400100043d0000030b02000041000000000021043500000004020000390bf501c00000040f000000070300002900000100013000390000000001010433000000000110004c000001460000c13d00000120013000390000000001010433000000000110004c000001460000c13d000000030100002900000002020000290000000001210049000400000001001d000000010100002900000000020104330000008001300039000000000101043300000301011001970bf5093e0000040f000000070100002900000006020000290bf5045b0000040f00000308010000410000000000100439000000050100002900000004001004430000800a0100003900000024020000390bf501a40000040f00000004020000290000000003020019000000000221004b000001400000a13d000000000231004900000000010004110bf50a200000040f0000030701000041000000000001041b0000000001000019000000000200001900000000030000190bf501b60000040f000000400100043d0000030a02000041000000000021043500000004020000390bf501c00000040f000002ff05000041000002ff0630009c00000000030580190000004003300210000002ff0640009c00000000040580190000006004400210000000000334019f000002ff0410009c0000000001058019000000c001100210000000000113019f0bf50beb0000040f00000000030100190000006003300270000102ff0030019d0003000000010355000000010120018f000000000001042d0002000000000002000200000006001d000100000005001d000002ff05000041000002ff0630009c00000000030580190000004003300210000002ff0640009c00000000040580190000006004400210000000000334019f000002ff0410009c0000000001058019000000c001100210000000000113019f0bf50bf00000040f000000010900002900000000030100190000006003300270000002ff033001970000000205000029000000000453004b00000000050340190000001f0450018f0000000505500272000001810000613d000000000600001900000005076002100000000008790019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000001790000413d000000010220018f000000000640004c000001910000613d0000000505500210000000000651034f00000000055900190000000304400210000000000705043300000000074701cf000000000747022f000000000606043b0000010004400089000000000646022f00000000044601cf000000000474019f0000000000450435000100000003001f00030000000103550000000001020019000000000001042d000002ff010000410000000002000414000002ff0320009c0000000001024019000000c0011002100000030f011001c700008010020000390bf50bf00000040f0000000102200190000001a10000613d000000000101043b000000000001042d000000000100001900000000020000190bf501c00000040f0000000003010019000002ff010000410000000004000414000002ff0540009c0000000001044019000000c00110021000000060022002100000000001120019000003100110004100000000020300190bf50bf00000040f0000000102200190000001b30000613d000000000101043b000000000001042d000000000100001900000000020000190bf501c00000040f000002ff04000041000002ff0510009c000000000104801900000040011002100000000001310019000002ff0320009c00000000020480190000006002200210000000000121001900000bf60001042e000002ff03000041000002ff0420009c0000000002038019000002ff0410009c000000000103801900000040011002100000006002200210000000000112019f00000bf70001043000000000030100190000001f013000390000030004000041000000000521004b0000000005000019000000000504401900000300062001970000030001100197000000000761004b000000000400a019000000000161013f000003000110009c00000000010500190000000001046019000000000110004c000002170000613d0000000201300367000000000401043b000003110140009c000002100000813d0000003f01400039000000200500008a000000000551016f000000400100043d0000000005510019000000000615004b00000000060000190000000106004039000003060750009c000002100000213d0000000106600190000002100000c13d000000400050043f000000000041043500000020033000390000000005430019000000000225004b000002170000213d0000001f0240018f000000020530036700000020031000390000000506400272000001fd0000613d000000000700001900000005087002100000000009830019000000000885034f000000000808043b00000000008904350000000107700039000000000867004b000001f50000413d000000000720004c0000020c0000613d0000000506600210000000000565034f00000000036300190000000302200210000000000603043300000000062601cf000000000626022f000000000505043b0000010002200089000000000525022f00000000022501cf000000000262019f0000000000230435000000000214001900000020022000390000000000020435000000000001042d000003030100004100000000001004350000004101000039000000040010043f000000240200003900000000010000190bf501c00000040f000000000100001900000000020000190bf501c00000040f00030000000000020000000005010019000000000152004900000300060000410000013f0310008c000000000300001900000000030620190000030001100197000000000410004c00000000040000190000000004064019000003000110009c00000000010300190000000001046019000000000110004c000002820000613d000000400300043d000003120130009c000002850000813d0000014001300039000000400010043f0000000201500367000000000101043b000000000013043500000020015000390000000201100367000000000101043b000003060410009c000002820000213d0000000001510019000300000005001d000200000003001d000100000002001d0bf501c90000040f0000000104000029000000030300002900000002020000290000002002200039000000000012043500000040013000390000000201100367000000000101043b000003060210009c000002820000213d000000000131001900000000020400190bf501c90000040f000000020400002900000003030000290000004002400039000000000012043500000060013000390000000201100367000000000101043b000003010210009c000002820000213d0000006002400039000000000012043500000080013000390000000201100367000000000101043b000003010210009c000002820000213d00000080024000390000000000120435000000a0013000390000000201100367000000000101043b000003010210009c000002820000213d000000a0024000390000000000120435000000c0013000390000000201100367000000000101043b000000c0024000390000000000120435000000e0013000390000000201100367000000000101043b000000e002400039000000000012043500000100013000390000000201100367000000000101043b000000000210004c0000000002000019000000010200c039000000000221004b000002820000c13d0000010002400039000000000012043500000120013000390000000201100367000000000101043b000000000210004c0000000002000019000000010200c039000000000221004b000002820000c13d000001200240003900000000001204350000000001040019000000000001042d000000000100001900000000020000190bf501c00000040f000003030100004100000000001004350000004101000039000000040010043f000000240200003900000000010000190bf501c00000040f000000000212004900000300030000410000007f0420008c000000000400001900000000040320190000030002200197000000000520004c0000000003008019000003000220009c00000000020400190000000002036019000000000220004c0000029a0000613d000000000001042d000000000100001900000000020000190bf501c00000040f000f000000000002000400000004001d000e00000003001d000d00000002001d000800000001001d0000030701000041000000000101041a000000010110008c000003bb0000613d00000001010000390000030702000041000000000012041b000003080100004100000000001004390000000001000410000300000001001d00000004001004430000800a0100003900000024020000390bf501a40000040f00000000030100190000000004000416000000000143004b000003a80000413d000000080200002900000100012000390000000001010433000000000110004c000003af0000613d00000120012000390000000001010433000000000110004c000003af0000c13d000000a00120003900000000010104330000030101100198000003c00000613d000500000004001d000c00000003001d000000c001200039000600000001001d0000000001010433000000000110004c000003c50000613d000000e0012000390000000001010433000f00000001001d000003090100004100000000001004390000800b0100003900000004020000390bf501a40000040f0000000f02000029000000000112004b000003ca0000613d0000000e02000029000000000120004c000003cf0000613d00000006010000290000000001010433000100000001001d00000008010000290000000001010433000200000001001d000000010320008a0000000d010000290bf505be0000040f00000060011000390000000201100367000000000101043b000700000001001d000003130110009c0000039e0000813d00000007010000290bf5075d0000040f000900000001001d0000000701000029000000000110004c0000000c080000290000000509000029000002f50000c13d00000000010004160000000902000029000000000212004b000003a80000413d00000009020000290000000002120049000900000002001d0000000e07000029000003110170009c000003b40000813d00000005037002100000003f01300039000000200200008a000000000121016f000000400200043d0000000001120019000b00000002001d000000000221004b00000000020000190000000102004039000003060410009c000003b40000213d0000000102200190000003b40000c13d000000400010043f0000000b0200002900000000007204350000001f0130018f000000200a200039000000000200003100000002022003670000000503300272000003180000613d0000000004000019000000050540021000000000065a0019000000000552034f000000000505043b00000000005604350000000104400039000000000534004b000003100000413d000000000410004c000003270000613d0000000503300210000000000232034f00000000033a00190000000301100210000000000403043300000000041401cf000000000414022f000000000202043b0000010001100089000000000212022f00000000011201cf000000000141019f00000000001304350000000001980049000500000001001d0000000005000019000a0000000a001d000000000175004b000003580000813d0000000d0100002900000000020700190000000003050019000f00000005001d0bf505be0000040f00000060011000390000000201100367000000000301043b000003010130009c0000039e0000213d0000000b0100002900000000010104330000000f02000029000000000121004b000003a10000a13d0000000001030019000c00000003001d0bf5075d0000040f0000000f0500002900000005025002100000000a0a0000290000000002a2001900000000001204350000000c03000029000000000330004c000003550000c13d0000000b030000290000000003030433000000000353004b000003a10000a13d0000000003000416000000000431004b000003a80000413d0000000b040000290000000004040433000000000454004b000003a10000a13d000000000131004900000000001204350000000a0a00002900000001055000390000000e070000290000032b0000013d0000000003000019000000000173004b000003780000813d0000000d010000290000000002070019000f00000003001d0bf505be0000040f000000c0031000390000000202000367000000000332034f000000000303043b000000000430004c0000000004000019000000010400c039000000000443004b0000039e0000c13d000000000330004c000003740000613d0000004003100039000000000332034f000000000303043b000003010430009c0000039e0000213d0000008001100039000000000112034f000000000201043b00000000010300190bf5093e0000040f0000000f0300002900000001033000390000000e07000029000003590000013d000000000400041100000002010000290000000d020000290000000003070019000f00000004001d0000000b050000290bf505e00000040f00000007010000290bf5075d0000040f0000000902000029000000000221004b000003a80000413d000000090200002900000000022100490000000104000029000000000142004b000003d40000413d00000006010000290000000000210435000000080100002900000004020000290bf5045b0000040f00000308010000410000000000100439000000030100002900000004001004430000800a0100003900000024020000390bf501a40000040f0000000503000029000000000231004b0000039b0000a13d00000000023100490000000f010000290bf50a200000040f0000030701000041000000000001041b000000000001042d000000000100001900000000020000190bf501c00000040f000003030100004100000000001004350000003201000039000000040010043f000000240200003900000000010000190bf501c00000040f000003030100004100000000001004350000001101000039000000040010043f000000240200003900000000010000190bf501c00000040f000000400100043d0000030a02000041000000000021043500000004020000390bf501c00000040f000003030100004100000000001004350000004101000039000000040010043f000000240200003900000000010000190bf501c00000040f000000400100043d0000030e02000041000000000021043500000004020000390bf501c00000040f000000400100043d0000030d02000041000000000021043500000004020000390bf501c00000040f000000400100043d0000030c02000041000000000021043500000004020000390bf501c00000040f000000400100043d0000030b02000041000000000021043500000004020000390bf501c00000040f000000400100043d0000031502000041000000000021043500000004020000390bf501c00000040f000000400100043d00000024031000390000000000230435000003140200004100000000002104350000000402100039000000000042043500000044020000390bf501c00000040f000000000300003100000000041300490000001f0540008a0000000204000367000000000224034f000000000202043b0000030006000041000000000752004b0000000007000019000000000706401900000300055001970000030008200197000000000958004b000000000600a019000000000558013f000003000550009c00000000050700190000000005066019000000000550004c000004070000613d0000000001120019000000000214034f000000000202043b000003060420009c000004070000213d000000000323004900000020011000390000030004000041000000000531004b0000000005000019000000000504201900000300033001970000030006100197000000000736004b0000000004008019000000000336013f000003000330009c00000000030500190000000003046019000000000330004c000004070000c13d000000000001042d000000000100001900000000020000190bf501c00000040f000000c00b100039000001000c0000390000000000cb0435000002ff07700197000000a00b10003900000000007b043500000060071000390000000000570435000000400510003900000000004504350000030103300197000000200410003900000000003404350000031603600198000003170300004100000000030060190000031804600197000000000343019f0000008004100039000000000034043500000100031000390000000000930435000003010220019700000000002104350000001f0390018f000001200210003900000002048003670000000505900272000004300000613d000000000600001900000005076002100000000008720019000000000774034f000000000707043b00000000007804350000000106600039000000000756004b000004280000413d000000000630004c0000043f0000613d0000000505500210000000000454034f00000000055200190000000303300210000000000605043300000000063601cf000000000636022f000000000404043b0000010003300089000000000434022f00000000033401cf000000000363019f000000000035043500000000039200190000000000030435000000e0011000390000000000a104350000001f01900039000000200300008a000000000131016f0000000001120019000000000001042d0000000003010433000000000032043500000020022000390000000004000019000000000534004b000004540000813d000000000524001900000020044000390000000006140019000000000606043300000000006504350000044c0000013d000000000123001900000000000104350000001f01300039000000200300008a000000000131016f0000000001120019000000000001042d0011000000000002000f00000002001d001000000001001d0000008002100039000e00000002001d0000000001020433001100000001001d000003190100004100000000001004390000000001000412000900000001001d00000004001004430000002400000443000080050100003900000044020000390bf501a40000040f0000001004000029000000c0054000390000000003050433000003010210019700000011010000290000030101100198000c00000005001d000d00000002001d0000051d0000613d0bf507b60000040f00000002040003670000000f01000029000000000214034f000000000502043b0000031602500198000003170200004100000000020060190000031803500197000000000232019f0000001006000029000000e003600039000b00000003001d0000000003030433000800000003001d0000000c030000290000000003030433000700000003001d0000000e0300002900000000030304330000030103300197000600000003001d000000a003600039000a00000003001d00000000030304330000030103300197000500000003001d000900000005001d000000000225004b0000059b0000c13d0000002002100039000000000224034f000000000202043b000400000002001d000002ff0220009c0000059b0000213d00000040021000390bf503dd0000040f0000031a0300004100000000003004390000000d030000290000000400300443000300000001001d000200000002001d000080020100003900000024020000390bf501a40000040f0000000f02000029000000000110004c0000059b0000613d000000400300043d001100000003001d0000031b01000041000000000013043500000060012000390000000002000414000f00000002001d0000000201100367000000000a01043b0000000401300039000000050200002900000006030000290000000704000029000000080500002900000009060000290000000407000029000000030800002900000002090000290bf5040a0000040f00000011030000290000000d02000029000000040420008c000004c40000613d00000000043100490000000f0100002900000011050000290bf5014b0000040f0000001103000029000000000110004c0000059e0000613d000003110130009c0000001004000029000005940000813d001100000003001d000000400030043f000000200100003900000000001304350000002001300039000000000204043300000000002104350000002001400039000000000101043300000040023000390000014005000039000000000052043500000160023000390bf504480000040f000000000201001900000011040000290000000001420049000000200310008a000000100100002900000040011000390000000001010433000000600440003900000000003404350bf504480000040f00000010050000290000006002500039000000000202043300000301022001970000001104000029000000800340003900000000002304350000000e0200002900000000020204330000030102200197000000a00340003900000000002304350000000a0200002900000000020204330000030102200197000000c00340003900000000002304350000000c020000290000000002020433000000e00340003900000000002304350000000b0200002900000000020204330000010003400039000000000023043500000100025000390000000002020433000000000220004c0000000002000019000000010200c0390000012003400039000000000023043500000120025000390000000002020433000000000220004c0000000002000019000000010200c039000001400340003900000000002304350000000001410049000002ff02000041000002ff0340009c000000000302001900000000030440190000004003300210000002ff0410009c00000000010280190000006001100210000000000131019f0000000003000414000002ff0430009c0000000002034019000000c002200210000000000112019f0000031c011001c70000800d0200003900000001030000390000031d040000410bf50beb0000040f00000001012001900000059b0000613d000000000001042d0000000901000029000800000003001d0000000e0100002900000002050003670000000f01000029000000000215034f000000000602043b0000031602600198000003170200004100000000020060190000031803600197000000000232019f000000e003400039000b00000003001d0000000003030433000600000003001d000000a003400039000a00000003001d00000000030304330000030103300197000500000003001d000700000006001d000000000226004b0000059b0000c13d0000002002100039000000000225034f000000000202043b000400000002001d000002ff0220009c0000059b0000213d00000040021000390bf503dd0000040f0000031a0300004100000000003004390000000d030000290000000400300443000300000001001d000200000002001d000080020100003900000024020000390bf501a40000040f0000000f03000029000000000110004c0000059b0000613d000000400200043d001100000002001d0000031b0100004100000000001204350000000001000414000100000001001d000003190100004100000000001004390000000901000029000000040010044300000020010000390000002400100443000080050100003900000044020000390bf501a40000040f0000000f0200002900000060022000390000000202200367000000000a02043b00000000030100190000001101000029000000040110003900000005020000290000000804000029000000060500002900000007060000290000000407000029000000030800002900000002090000290bf5040a0000040f00000011030000290000000d05000029000000040250008c000005910000613d00000000043100490000000806000029000000000160004c0000058a0000613d000002ff01000041000002ff0230009c000000000201001900000000020340190000004002200210000002ff0340009c000000000301001900000000030440190000006003300210000000000223019f0000000104000029000002ff0340009c0000000001044019000000c001100210000000000112019f0000031c011001c700008009020000390000000003060019000000000405001900000000050000190bf50beb0000040f00000000030100190000006003300270000102ff0030019d0003000000010355000000010120018f0000058e0000013d0000000101000029000000000205001900000000050300190bf5014b0000040f000000000110004c00000011030000290000059e0000613d000003060130009c0000001004000029000004c70000a13d000003030100004100000000001004350000004101000039000000040010043f000000240200003900000000010000190bf501c00000040f000000000100001900000000020000190bf501c00000040f0000000302000367000000400100043d00000001040000310000001f0340018f0000000504400272000005ad0000613d000000000500001900000005065002100000000007610019000000000662034f000000000606043b00000000006704350000000105500039000000000645004b000005a50000413d000000000530004c000005bc0000613d0000000504400210000000000242034f00000000044100190000000303300210000000000504043300000000053501cf000000000535022f000000000202043b0000010003300089000000000232022f00000000023201cf000000000252019f000000000024043500000001020000310bf501c00000040f000000000223004b000005d60000813d000000050230021000000000021200190000000202200367000000000202043b0000000003100079000000df0330008a0000030004000041000000000532004b0000000005000019000000000504401900000300033001970000030006200197000000000736004b000000000400a019000000000336013f000003000330009c00000000030500190000000003046019000000000330004c000005dd0000613d0000000001120019000000000001042d000003030100004100000000001004350000003201000039000000040010043f000000240200003900000000010000190bf501c00000040f000000000100001900000000020000190bf501c00000040f000e000000000002000600000005001d000300000004001d000b00000002001d000900000001001d000000010130008c000006350000c13d0000000101000039000800000001001d00000000030000190000000101100190000006b50000613d0000000b0100002900000008020000290bf505be0000040f000c00000001001d00000040021000390000000201000367000000000221034f000000000202043b000003130320009c000006b60000813d000000000220004c0000060c0000613d0000000c020000290000002002200039000000000121034f000000000101043b000003010210009c000006b60000213d00000000001004350000032301000041000000200010043f0bf501950000040f000000000101041a000d00ff00100193000000ff01100190000006b90000613d00000000010004150000000d0110008a00000020011000c9000a00000001001d0000000201000367000006110000013d00000000020004150000000e0220008a00000020022000c9000a00000002001d000e00010000003d0000000c02000029000000000121034f000000000101043b000003010210009c000006b60000213d00000000001004350000032301000041000000200010043f0bf501950000040f000000000101041a0000000a02000029000000200220011a000000ff02100195000000ff01100190000006b90000613d0000000c01000029000000a0021000390bf503dd0000040f000000040220008c000006b60000413d0000000201100367000000000101043b000003240110019700000000001004350000032501000041000000200010043f0bf501950000040f000000000101041a000000ff01100190000006b90000613d00000009010000290000000c020000290bf50a6d0000040f00000001030000390000000001000019000005ea0000013d000a00000003001d000000000130004c000006be0000613d0000000a02000029000000010320008a0000000b01000029000800000003001d0bf505be0000040f00000060011000390000000201100367000000000101043b000700000001001d000003010110009c000006b60000213d00000009010000290000000b020000290000000a030000290bf507010000040f00000003010000290000030101100197000400000001001d00000006010000290000002001100039000500000001001d00000000030000190000000801000029000000000113004b000006b50000813d0000000b010000290000000a02000029000c00000003001d0bf505be0000040f00000060011000390000000201100367000000000201043b000003010120009c000006b60000213d0000000701000029000000000112004b000006b20000613d000900000002001d00000000010200190bf5075d0000040f000000060200002900000000020204330000000c03000029000000000232004b000006c50000a13d0000000502300210000000050300002900000000022300190000000002020433000000000321004b000006be0000413d000000000321004b0000000905000029000006b20000613d0000000006210049000000000150004c000006af0000613d000000400300043d0000000401000029000000000110004c000006d30000613d0000031e01000041000000000013043500000000010004100000030102100197000000040430003900000000010004140000000000240435000000040250008c0000068a0000613d0000002404000039000200000006001d000000200600003900000000020500190000000005030019000100000003001d0bf5015e0000040f000000010300002900000002060000290000000905000029000000000110004c000006e10000613d0000000101000031000000200210008c000000200200003900000000020140190000001f02200039000000600420018f0000000002340019000000000442004b00000000070000190000000107004039000003060420009c000006cc0000213d0000000104700190000006cc0000c13d000000400020043f000000200110008c000006b60000413d0000000003030433000000000163004b0000002401200039000006d80000413d00000020032000390000031f040000410000000000430435000000440320003900000000006304350000000403000029000000000031043500000044010000390000000000120435000003200120009c000006cc0000213d0000008001200039000000400010043f00000000010500190bf5087d0000040f000006b20000013d000000030100002900000000020600190bf50a200000040f0000000c0300002900000001033000390000064e0000013d000000000001042d000000000100001900000000020000190bf501c00000040f000000400100043d0000032602000041000000000021043500000004020000390bf501c00000040f000003030100004100000000001004350000001101000039000000040010043f000000240200003900000000010000190bf501c00000040f000003030100004100000000001004350000003201000039000000040010043f000000240200003900000000010000190bf501c00000040f000003030100004100000000001004350000004101000039000000040010043f000000240200003900000000010000190bf501c00000040f00000322010000410000000000130435000000040200003900000000010300190bf501c00000040f000000000031043500000321010000410000000000120435000000040120003900000000006104350000004403000039000000000102001900000000020300190bf501c00000040f0000000302000367000000400100043d00000001040000310000001f0340018f0000000504400272000006f00000613d000000000500001900000005065002100000000007610019000000000662034f000000000606043b00000000006704350000000105500039000000000645004b000006e80000413d000000000530004c000006ff0000613d0000000504400210000000000242034f00000000044100190000000303300210000000000504043300000000053501cf000000000535022f000000000202043b0000010003300089000000000232022f00000000023201cf000000000252019f000000000024043500000001020000310bf501c00000040f00080000000000020000000004030019000300000002001d000100000001001d0000000003000019000200000004001d000000000143004b000007540000813d00000003010000290000000002040019000400000003001d0bf505be0000040f000600000001001d00000040021000390000000201000367000000000221034f000000000202043b000003130320009c000007550000813d000000000220004c0000072a0000613d00000006020000290000002002200039000000000121034f000000000101043b000003010210009c000007550000213d00000000001004350000032301000041000000200010043f0bf501950000040f000000000101041a000700ff00100193000000ff01100190000007580000613d0000000001000415000000070110008a00000020011000c9000500000001001d00000002010003670000072f0000013d0000000002000415000000080220008a00000020022000c9000500000002001d000800010000003d0000000602000029000000000121034f000000000101043b000003010210009c000007550000213d00000000001004350000032301000041000000200010043f0bf501950000040f000000000101041a0000000502000029000000200220011a000000ff02100195000000ff01100190000007580000613d0000000601000029000000a0021000390bf503dd0000040f000000040220008c000007550000413d0000000201100367000000000101043b000003240110019700000000001004350000032501000041000000200010043f0bf501950000040f000000000101041a000000ff01100190000007580000613d000000010100002900000006020000290bf50a6d0000040f000000040300002900000001033000390000000204000029000007070000013d000000000001042d000000000100001900000000020000190bf501c00000040f000000400100043d0000032602000041000000000021043500000004020000390bf501c00000040f00010000000000020000030102100198000007840000613d000000400300043d0000031e0100004100000000001304350000000401300039000000000400041000000000004104350000000001000414000000040420008c000007710000613d00000024040000390000002006000039000100000003001d00000001050000290bf5015e0000040f0000000103000029000000000110004c000007960000613d0000000101000031000000200210008c000000200200003900000000020140190000001f02200039000000600420018f0000000002340019000000000442004b00000000050000190000000105004039000003060420009c0000078c0000213d00000001045001900000078c0000c13d000000400020043f0000001f0110008c000007930000a13d00000000010304330000078b0000013d00000308010000410000000000100439000000000100041000000004001004430000800a0100003900000024020000390bf501a40000040f000000000001042d000003030100004100000000001004350000004101000039000000040010043f000000240200003900000000010000190bf501c00000040f000000000100001900000000020000190bf501c00000040f0000000302000367000000400100043d00000001040000310000001f0340018f0000000504400272000007a50000613d000000000500001900000005065002100000000007610019000000000662034f000000000606043b00000000006704350000000105500039000000000645004b0000079d0000413d000000000530004c000007b40000613d0000000504400210000000000242034f00000000044100190000000303300210000000000504043300000000053501cf000000000535022f000000000202043b0000010003300089000000000232022f00000000023201cf000000000252019f000000000024043500000001020000310bf501c00000040f00060000000000020000000008030019000000000501001900000301075001980000083b0000613d000000400300043d0000030106200198000008460000613d00000327010000410000000000130435000000240230003900000000010004140000000000620435000000000200041000000301042001970000000402300039000300000004001d0000000000420435000000040270008c000600000005001d000500000006001d000400000007001d000007db0000613d0000004404000039000000200600003900000000020700190000000005030019000200000008001d000100000003001d0bf5015e0000040f00000001030000290000000208000029000000040700002900000005060000290000000605000029000000000110004c0000084b0000613d0000000101000031000000200210008c000000200200003900000000020140190000001f02200039000000600420018f0000000002340019000000000442004b00000000090000190000000109004039000003060420009c0000083c0000213d00000001049001900000083c0000c13d000000400020043f0000001f0110008c000008430000a13d0000000001030433000000000181004b0000083b0000813d000000200120003900000328030000410000000000310435000000240120003900000000006104350000004401000039000200000001001d000000000012043500000044012000390000000000010435000003200120009c0000083c0000213d0000008001200039000000400010043f00000000010500190bf5087d0000040f0000000402000029000000050600002900000006050000290000032701000041000000400300043d0000000000130435000000240430003900000000010004140000000000640435000000040730003900000003040000290000000000470435000000040420008c000008170000613d000000440400003900000020060000390000000005030019000400000003001d0bf5015e0000040f000000040300002900000005060000290000000605000029000000000110004c0000084b0000613d0000000101000031000000200210008c000000200200003900000000020140190000001f02200039000000600420018f0000000002340019000000000442004b00000000070000190000000107004039000003060420009c0000083c0000213d00000001047001900000083c0000c13d000000400020043f000000200110008c000008430000413d0000000001030433000000000110004c0000086b0000c13d0000002001200039000003280300004100000000003104350000004401200039000000010300008a00000000003104350000002401200039000000000061043500000002010000290000000000120435000003200120009c0000083c0000213d0000008001200039000000400010043f00000000010500190bf5087d0000040f000000000001042d000003030100004100000000001004350000004101000039000000040010043f000000240200003900000000010000190bf501c00000040f000000000100001900000000020000190bf501c00000040f0000032c010000410000000000130435000000040200003900000000010300190bf501c00000040f0000000302000367000000400100043d00000001040000310000001f0340018f00000005044002720000085a0000613d000000000500001900000005065002100000000007610019000000000662034f000000000606043b00000000006704350000000105500039000000000645004b000008520000413d000000000530004c000008690000613d0000000504400210000000000242034f00000000044100190000000303300210000000000504043300000000053501cf000000000535022f000000000202043b0000010003300089000000000232022f00000000023201cf000000000252019f000000000024043500000001020000310bf501c00000040f00000064012000390000032903000041000000000031043500000044012000390000032a0300004100000000003104350000002401200039000000360300003900000000003104350000032b0100004100000000001204350000000401200039000000200300003900000000003104350000008403000039000000000102001900000000020300190bf501c00000040f00040000000000020000030105100197000000400400043d0000032d0140009c000008c80000813d0000004001400039000000400010043f00000020014000390000032e0300004100000000003104350000002001000039000200000001001d000100000004001d00000000001404350000000001000414000400000005001d000000040350008c0000000003000019000008980000613d00000000040204330000002003200039000000040200002900000000050000190bf5014b0000040f000000000110004c00000000030000190000000103006039000300000003001d0bf508fe0000040f000000000201043300000003030000290000000103300190000008cf0000c13d000000000320004c0000000403000029000008ae0000c13d000300000001001d0000031a0100004100000000001004390000000400300443000080020100003900000024020000390bf501a40000040f000000000110004c000008f00000613d00000003010000290000000002010433000000000320004c000008c40000613d0000030005000041000000200320008c000000000300001900000000030540190000030002200197000000000420004c00000000040000190000000004052019000003000220009c00000000020300190000000002046019000000000220004c000008c50000c13d00000020011000390000000001010433000000000210004c0000000002000019000000010200c039000000000221004b000008c50000c13d000000000110004c000008dd0000613d000000000001042d000000000100001900000000020000190bf501c00000040f000003030100004100000000001004350000004101000039000000040010043f000000240200003900000000010000190bf501c00000040f0000000003010019000000000120004c000008ee0000c13d000000400200043d000400000002001d0000032b010000410000000000120435000000040120003900000001020000290bf509370000040f0000000403000029000000000231004900000000010300190bf501c00000040f000000400100043d00000064021000390000032f03000041000000000032043500000044021000390000033003000041000000000032043500000024021000390000002a0300003900000000003204350000032b02000041000000000021043500000004021000390000000203000029000000000032043500000084020000390bf501c00000040f00000020013000390bf501c00000040f000000400100043d00000044021000390000033103000041000000000032043500000024021000390000001d0300003900000000003204350000032b02000041000000000021043500000004021000390000000203000029000000000032043500000064020000390bf501c00000040f000000600100003900000001020000320000092f0000613d000003110120009c000009300000813d0000003f01200039000000200300008a000000000331016f000000400100043d0000000003310019000000000413004b00000000040000190000000104004039000003060530009c000009300000213d0000000104400190000009300000c13d000000400030043f00000000002104350000002002100039000000030300036700000001050000310000001f0450018f0000000505500272000009200000613d000000000600001900000005076002100000000008720019000000000773034f000000000707043b00000000007804350000000106600039000000000756004b000009180000413d000000000640004c0000092f0000613d0000000505500210000000000353034f00000000025200190000000304400210000000000502043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f0000000000320435000000000001042d000003030100004100000000001004350000004101000039000000040010043f000000240200003900000000010000190bf501c00000040f000000000302001900000020020000390000000000210435000000200210003900000000010300190bf504480000040f000000000001042d00050000000000020000000004020019000000000240004c000009e60000613d0000030105100198000009d80000613d000000400700043d0000031e0100004100000000001704350000000001000411000003010310019700000004027000390000000001000414000200000003001d0000000000320435000000040250008c000500000004001d000400000005001d0000095d0000613d00000024040000390000002006000039000000000205001900000000030700190000000005070019000300000007001d0bf5015e0000040f000000030700002900000004050000290000000504000029000000000110004c000009eb0000613d0000000101000031000000200210008c000000200200003900000000020140190000001f02200039000000600220018f0000000003720019000000000223004b00000000020000190000000102004039000003060630009c000009dc0000213d0000000102200190000009dc0000c13d000000400030043f0000001f0110008c000009e30000a13d0000000001070433000000000241004b00000a0b0000413d0000000001000410000003010710019800000a140000613d0000031e010000410000000000130435000000040230003900000000010004140000000000720435000000040250008c000300000007001d000009880000613d0000002404000039000000200600003900000000020500190000000005030019000100000003001d0bf5015e0000040f0000000307000029000000010300002900000004050000290000000504000029000000000110004c000009eb0000613d0000000101000031000000200210008c000000200200003900000000020140190000001f02200039000000600220018f0000000002320019000003060620009c000009dc0000213d000000400020043f000000200110008c000009e30000413d0000000001030433000100000001001d000000200120003900000332030000410000000000310435000000640120003900000000004104350000004401200039000000000071043500000024012000390000000203000029000000000031043500000064010000390000000000120435000003330120009c000009dc0000213d000000a001200039000000400010043f00000000010500190bf5087d0000040f000000040200002900000005050000290000031e01000041000000400300043d00000000001304350000000404300039000000000100041400000003060000290000000000640435000000040420008c000009bc0000613d000000240400003900000020060000390000000005030019000400000003001d0bf5015e0000040f00000004030000290000000505000029000000000110004c000009eb0000613d0000000102000031000000200120008c000000200100003900000000010240190000001f01100039000000600410018f0000000001340019000000000441004b00000000060000190000000106004039000003060410009c000009dc0000213d0000000104600190000009dc0000c13d000000400010043f000000200220008c000009e30000413d00000000020304330000000104000029000000000342004b00000a190000413d0000000002420049000000000252004b000009db0000613d0000030c02000041000000000021043500000004020000390bf501c00000040f0000000001000416000000000141004b000009e60000413d000000000001042d000003030100004100000000001004350000004101000039000000040010043f000000240200003900000000010000190bf501c00000040f000000000100001900000000020000190bf501c00000040f000000400100043d0000030c02000041000000000021043500000004020000390bf501c00000040f0000000302000367000000400100043d00000001040000310000001f0340018f0000000504400272000009fa0000613d000000000500001900000005065002100000000007610019000000000662034f000000000606043b00000000006704350000000105500039000000000645004b000009f20000413d000000000530004c00000a090000613d0000000504400210000000000242034f00000000044100190000000303300210000000000504043300000000053501cf000000000535022f000000000202043b0000010003300089000000000232022f00000000023201cf000000000252019f000000000024043500000001020000310bf501c00000040f000000240230003900000000001204350000032101000041000000000013043500000004013000390000000000410435000000440200003900000000010300190bf501c00000040f00000322010000410000000000130435000000040200003900000000010300190bf501c00000040f000003030100004100000000001004350000001101000039000000040010043f000000240200003900000000010000190bf501c00000040f0003000000000002000300000002001d0000030101100198000200000001001d00000a510000613d000003080100004100000000001004390000000001000410000100000001001d00000004001004430000800a0100003900000024020000390bf501a40000040f0000000303000029000000000131004b00000a560000413d000000010500003900000000010004140000000204000029000000040240008c00000a4b0000613d000000000230004c00000a450000613d000002ff02000041000002ff0510009c0000000001028019000000c0011002100000031c011001c7000080090200003900000000050000190bf50beb0000040f00000000030100190000006003300270000102ff0030019d0003000000010355000000010520018f00000a4b0000013d00000000020400190000000003000019000000000400001900000000050000190bf5014b0000040f0000000005010019000300000005001d0bf508fe0000040f0000000301000029000000000110004c00000a680000613d000000000001042d000000400100043d0000032202000041000000000021043500000004020000390bf501c00000040f00000308010000410000000000100439000000010100002900000004001004430000800a0100003900000024020000390bf501a40000040f0000032102000041000000400300043d000000000023043500000004023000390000000304000029000000000042043500000024023000390000000000120435000000440200003900000000010300190bf501c00000040f000000400100043d0000033402000041000000000021043500000004020000390bf501c00000040f0009000000000002000300000001001d0000000201200367000000000101043b000003130310009c00000b4f0000813d000900000002001d0000031a0200004100000000002004390000000400100443000080020100003900000024020000390bf501a40000040f000000000110004c00000b520000613d000000090300002900000080023000390000000201000367000000000221034f000000000202043b000800000002001d000000000220004c00000b570000613d0000004002300039000500000002001d000000000121034f000000000101043b000700000001001d000003010110009c00000b4f0000213d00000007010000290bf5075d0000040f0000000702000029000000000220004c0000000802000029000000000200c019000100000002001d000400000001001d00000009010000290000006001100039000600000001001d0000000201100367000000000101043b000003010210009c00000b4f0000213d0bf5075d0000040f000200000001001d0000000701000029000000000110004c00000aad0000613d00000002020003670000000501000029000000000112034f000000000101043b000003010310009c000000090300002900000b4f0000213d0000002003300039000000000232034f000000000202043b000003010320009c00000b4f0000213d00000008030000290bf507b60000040f00000008010000290000000403000029000000000113004b000000090100002900000b5c0000413d0000000202100367000000000202043b000400000002001d000003010220009c00000b4f0000213d000000a0021000390bf503dd0000040f000000400300043d000000000501001900000000040200190000001f0240018f00000000010004140000000205500367000000050640027200000aca0000613d000000000700001900000005087002100000000009830019000000000885034f000000000808043b00000000008904350000000107700039000000000867004b00000ac20000413d000000000720004c00000ad90000613d0000000506600210000000000565034f00000000066300190000000302200210000000000706043300000000072701cf000000000727022f000000000505043b0000010002200089000000000525022f00000000022501cf000000000272019f00000000002604350000000002430019000000000002043500000001050000390000000406000029000000040260008c00000afe0000613d0000000702000029000000000220004c00000ae70000613d000000000206001900000000050000190bf5014b0000040f000000000501001900000afe0000013d000002ff02000041000002ff0540009c00000000040280190000006004400210000002ff0530009c00000000030280190000004003300210000000000343019f000002ff0410009c0000000001028019000000c001100210000000000113019f0000031c011001c700008009020000390000000103000029000000000406001900000000050000190bf50beb0000040f00000000030100190000006003300270000102ff0030019d0003000000010355000000010520018f000700000005001d0bf508fe0000040f0000000702000029000000000220004c00000b660000613d00000006010000290000000201100367000000000101043b000003010210009c000000090200002900000b4f0000213d0bf5075d0000040f00000002020003670000000903000029000000000332034f000700000001001d000000000103043b000900000001001d000003010110009c00000b4f0000213d0000000501000029000000000112034f000000000101043b000500000001001d000003010110009c00000b4f0000213d0000000601000029000000000112034f000000000101043b000600000001001d000003010110009c00000b4f0000213d000000400100043d000400000001001d000003350100004100000000001004390000800b0100003900000004020000390bf501a40000040f00000002030000290000000704000029000000000234004b0000000002000019000000000203201900000000022400490000000404000029000000a0034000390000000000230435000000800240003900000008030000290000000000320435000000600240003900000006030000290000000000320435000000400240003900000005030000290000000000320435000000200240003900000009030000290000000000320435000000c002400039000000000012043500000003010000290000000000140435000002ff010000410000000002000414000002ff0320009c0000000002018019000002ff0340009c00000000010440190000004001100210000000c002200210000000000112019f00000336011001c70000800d02000039000000010300003900000337040000410bf50beb0000040f000000010120019000000b4f0000613d000000000001042d000000000100001900000000020000190bf501c00000040f000000400100043d0000033902000041000000000021043500000004020000390bf501c00000040f000000400100043d0000033802000041000000000021043500000004020000390bf501c00000040f000000400100043d000000240210003900000000003204350000032102000041000000000021043500000004021000390000000803000029000000000032043500000044020000390bf501c00000040f0bf50b720000040f0000032b02000041000000400300043d000900000003001d0000000000230435000000000201001900000004013000390bf509370000040f0000000903000029000000000231004900000000010300190bf501c00000040f0000000002010433000000440320008c00000b7f0000813d000000400100043d0000032d0210009c00000bdd0000813d0000004002100039000000400020043f0000001d0200003900000000002104350000033a03000041000000200210003900000bd80000013d000000040220008a0000001f0300008a000000000332004b00000be40000813d0000001f0320019000000000040000190000002004006039000000000434019f0000000005140019000000400300043d000000000134001900000000041200190000000405500039000000000641004b00000b930000813d000000000605043300000000006104350000002005500039000000200110003900000b8c0000013d00000000002304350000001f01100039000000200200008a000000000121016f000000400010043f000000000403043300000300050000410000001f0640008c000000000600001900000000060520190000030007400197000000000870004c0000000005008019000003000770009c000000000506c019000000000550004c00000bda0000613d00000020033000390000000005030433000003060650009c00000bda0000213d000000000443001900000000053500190000001f035000390000030006000041000000000743004b0000000007000019000000000706801900000300033001970000030008400197000000000983004b0000000006008019000000000383013f000003000330009c00000000030700190000000003066019000000000330004c00000bda0000c13d0000000003050433000003060630009c00000bdd0000213d0000003f06300039000000000626016f0000000002160019000000000662004b00000000060000190000000106004039000003060720009c00000bdd0000213d000000010660019000000bdd0000c13d000000400020043f000000000031043500000020025000390000000005230019000000000445004b00000bda0000213d00000020041000390000000005000019000000000635004b00000bd60000813d0000000006450019000000000725001900000000070704330000000000760435000000200550003900000bce0000013d000000000243001900000000030000190000000000320435000000000001042d000000000100001900000000020000190bf501c00000040f000003030100004100000000001004350000004101000039000000040010043f000000240200003900000000010000190bf501c00000040f000003030100004100000000001004350000001101000039000000040010043f000000240200003900000000010000190bf501c00000040f00000bee002104210000000102000039000000000001042d000000000200001900000bed0000013d00000bf3002104230000000102000039000000000001042d000000000200001900000bf20000013d00000bf50000043200000bf60001042e00000bf700010430000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffff8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffff00000002000000000000000000000000000000000000000000000000000000004e487b7100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a3f7332000000000000000000000000000000000000000000000000000000001fd8010c000000000000000000000000000000000000000000000000ffffffffffffffffa65bb2f450488ab0858c00edc14abc5297769bf42adb48cfb77752890e8b697b9cc7f708afc65944829bd487b90b72536b1951864fbfc14e125fc972a6507f399a8a0592ac89c5ad3bc6df8224c17b485976f597df104ee20d0df415241f670b50dc905c000000000000000000000000000000000000000000000000000000004ac09ad3000000000000000000000000000000000000000000000000000000002c5211c6000000000000000000000000000000000000000000000000000000001e4ec46b0000000000000000000000000000000000000000000000000000000029f745a700000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000004000000000000000000000000002000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000fffffffffffffec00000000000000000000000010000000000000000000000000000000000000000275c273c000000000000000000000000000000000000000000000000000000000503c3ed000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000ffffffffffffffffffffffffffffffffffffffffffffffff80000000000000000000000000000000000000000000000000000000000000007fffffffffffffff310ab089e4439a4c15d089f94afb7896ff553aecb10793d0ab882de59d99a32e1806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b831186ec33000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000cba69f43792f9f399347222505213b55af8e0b0b54b893085c2e27ecbe1644f170a0823100000000000000000000000000000000000000000000000000000000a9059cbb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff7fcf4791810000000000000000000000000000000000000000000000000000000021f74345000000000000000000000000000000000000000000000000000000007a8ac5d3b7183f220a0602439da45ea337311d699902d1ed11a3725a714e7f1effffffff000000000000000000000000000000000000000000000000000000007a8ac5d3b7183f220a0602439da45ea337311d699902d1ed11a3725a714e7f1f9453980400000000000000000000000000000000000000000000000000000000dd62ed3e00000000000000000000000000000000000000000000000000000000095ea7b30000000000000000000000000000000000000000000000000000000020746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000005361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f08c379a00000000000000000000000000000000000000000000000000000000063ba9bff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffc05361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65646f742073756363656564000000000000000000000000000000000000000000005361666545524332303a204552433230206f7065726174696f6e20646964206e416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000023b872dd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff5f5a04673700000000000000000000000000000000000000000000000000000000796b89b91644bc98cd93958e4c9038275d622183e25ac5af08cc6b5d9553913202000000000000000000000000000000000000e00000000000000000000000007bfdfdb5e3a3776976e53cb0607060f54c5312701c8cba1155cc4d5394440b38e46e079c000000000000000000000000000000000000000000000000000000006eefed20000000000000000000000000000000000000000000000000000000005472616e73616374696f6e2072657665727465642073696c656e746c79000000", + "deployedBytecode": "0x0004000000000002000700000000000200000000030100190000006003300270000002ff0430019700030000004103550002000000010355000002ff0030019d000100000000001f0000000101200190000000470000c13d0000008001000039000000400010043f0000000002000031000000040120008c000000cd0000413d0000000201000367000000000301043b000000e003300270000003040430009c000000960000613d000003050330009c000000cd0000c13d000000040320008a0000030004000041000000400530008c000000000500001900000000050440190000030003300197000000000630004c000000000400a019000003000330009c00000000030500190000000003046019000000000330004c000000cd0000c13d0000000401100370000000000101043b000003060310009c000000cd0000213d00000004011000390bf5021a0000040f000000000501001900000024010000390000000201100367000000000101043b000003060210009c000000cd0000213d000000040610003900000000016000790000030002000041000000800310008c000000000300001900000000030240190000030001100197000000000410004c000000000200a019000003000110009c00000000010300190000000001026019000000000110004c000000cd0000c13d0000030701000041000000000101041a000000010110008c000000d00000c13d000000400100043d0000030e02000041000000000021043500000004020000390bf501c00000040f0000000001000416000000000110004c000000cd0000c13d0000000001000031000000df02100039000000200300008a000000000232016f000000bf0320008c000000570000213d000003030100004100000000001004350000004101000039000000040010043f000000240200003900000000010000190bf501c00000040f000000400020043f0000001f0210018f00000002030003670000000504100272000000650000613d00000000050000190000000506500210000000000763034f000000000707043b000000c00660003900000000007604350000000105500039000000000645004b0000005d0000413d000000000520004c000000740000613d0000000504400210000000000343034f0000000302200210000000c004400039000000000504043300000000052501cf000000000525022f000000000303043b0000010002200089000000000323022f00000000022301cf000000000252019f00000000002404350000030002000041000000400310008c000000000300001900000000030240190000030001100197000000000410004c000000000200a019000003000110009c00000000010300190000000001026019000000000110004c000000cd0000c13d000000c00100043d000003010210009c000000cd0000213d000000e00200043d000003010320009c000000cd0000213d000000800010043f000000a00020043f000000800100043d00000140000004430000016000100443000000a00100043d00000020020000390000018000200443000001a0001004430000010000200443000000020100003900000120001004430000010001000039000000c00200003900000302030000410bf501b60000040f000000040320008a0000030004000041000000600530008c000000000500001900000000050440190000030003300197000000000630004c000000000400a019000003000330009c00000000030500190000000003046019000000000330004c000000cd0000c13d0000000401100370000000000101043b000003060310009c000000cd0000213d00000004011000390bf5021a0000040f000000000901001900000002010003670000002402100370000000000302043b000003060230009c000000cd0000213d000000230430003900000000020000310000030005000041000000000624004b0000000006000019000000000605801900000300044001970000030007200197000000000874004b0000000005008019000000000474013f000003000440009c00000000040600190000000004056019000000000440004c000000cd0000c13d0000000404300039000000000441034f000000000504043b000003060450009c000000cd0000213d000000240430003900000005035002100000000003430019000000000323004b000000cd0000213d0000004401100370000000000101043b000003060310009c000000f10000a13d000000000100001900000000020000190bf501c00000040f000600000006001d000700000005001d00000001010000390000030702000041000000000012041b000003080100004100000000001004390000000001000410000500000001001d00000004001004430000800a0100003900000024020000390bf501a40000040f0000000004000416000000000241004b000000e70000813d000003030100004100000000001004350000001101000039000000040010043f000000240200003900000000010000190bf501c00000040f0000000703000029000000a00230003900000000020204330000030102200198000001000000c13d000000400100043d0000030d02000041000000000021043500000004020000390bf501c00000040f0000000401100039000700000001001d000400000009001d000600000005001d000500000004001d0bf5028c0000040f00000004010000290000000502000029000000060300002900000007040000290bf5029d0000040f0000000001000019000000000200001900000000030000190bf501b60000040f000000c0053000390000000002050433000000000220004c000001090000c13d000000400100043d0000030c02000041000000000021043500000004020000390bf501c00000040f000100000005001d000200000004001d000300000001001d000000e0013000390000000001010433000400000001001d000003090100004100000000001004390000800b0100003900000004020000390bf501a40000040f0000000402000029000000000112004b0000011c0000c13d000000400100043d0000030b02000041000000000021043500000004020000390bf501c00000040f000000070300002900000100013000390000000001010433000000000110004c000001460000c13d00000120013000390000000001010433000000000110004c000001460000c13d000000030100002900000002020000290000000001210049000400000001001d000000010100002900000000020104330000008001300039000000000101043300000301011001970bf5093e0000040f000000070100002900000006020000290bf5045b0000040f00000308010000410000000000100439000000050100002900000004001004430000800a0100003900000024020000390bf501a40000040f00000004020000290000000003020019000000000221004b000001400000a13d000000000231004900000000010004110bf50a200000040f0000030701000041000000000001041b0000000001000019000000000200001900000000030000190bf501b60000040f000000400100043d0000030a02000041000000000021043500000004020000390bf501c00000040f000002ff05000041000002ff0630009c00000000030580190000004003300210000002ff0640009c00000000040580190000006004400210000000000334019f000002ff0410009c0000000001058019000000c001100210000000000113019f0bf50beb0000040f00000000030100190000006003300270000102ff0030019d0003000000010355000000010120018f000000000001042d0002000000000002000200000006001d000100000005001d000002ff05000041000002ff0630009c00000000030580190000004003300210000002ff0640009c00000000040580190000006004400210000000000334019f000002ff0410009c0000000001058019000000c001100210000000000113019f0bf50bf00000040f000000010900002900000000030100190000006003300270000002ff033001970000000205000029000000000453004b00000000050340190000001f0450018f0000000505500272000001810000613d000000000600001900000005076002100000000008790019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000001790000413d000000010220018f000000000640004c000001910000613d0000000505500210000000000651034f00000000055900190000000304400210000000000705043300000000074701cf000000000747022f000000000606043b0000010004400089000000000646022f00000000044601cf000000000474019f0000000000450435000100000003001f00030000000103550000000001020019000000000001042d000002ff010000410000000002000414000002ff0320009c0000000001024019000000c0011002100000030f011001c700008010020000390bf50bf00000040f0000000102200190000001a10000613d000000000101043b000000000001042d000000000100001900000000020000190bf501c00000040f0000000003010019000002ff010000410000000004000414000002ff0540009c0000000001044019000000c00110021000000060022002100000000001120019000003100110004100000000020300190bf50bf00000040f0000000102200190000001b30000613d000000000101043b000000000001042d000000000100001900000000020000190bf501c00000040f000002ff04000041000002ff0510009c000000000104801900000040011002100000000001310019000002ff0320009c00000000020480190000006002200210000000000121001900000bf60001042e000002ff03000041000002ff0420009c0000000002038019000002ff0410009c000000000103801900000040011002100000006002200210000000000112019f00000bf70001043000000000030100190000001f013000390000030004000041000000000521004b0000000005000019000000000504401900000300062001970000030001100197000000000761004b000000000400a019000000000161013f000003000110009c00000000010500190000000001046019000000000110004c000002170000613d0000000201300367000000000401043b000003110140009c000002100000813d0000003f01400039000000200500008a000000000551016f000000400100043d0000000005510019000000000615004b00000000060000190000000106004039000003060750009c000002100000213d0000000106600190000002100000c13d000000400050043f000000000041043500000020033000390000000005430019000000000225004b000002170000213d0000001f0240018f000000020530036700000020031000390000000506400272000001fd0000613d000000000700001900000005087002100000000009830019000000000885034f000000000808043b00000000008904350000000107700039000000000867004b000001f50000413d000000000720004c0000020c0000613d0000000506600210000000000565034f00000000036300190000000302200210000000000603043300000000062601cf000000000626022f000000000505043b0000010002200089000000000525022f00000000022501cf000000000262019f0000000000230435000000000214001900000020022000390000000000020435000000000001042d000003030100004100000000001004350000004101000039000000040010043f000000240200003900000000010000190bf501c00000040f000000000100001900000000020000190bf501c00000040f00030000000000020000000005010019000000000152004900000300060000410000013f0310008c000000000300001900000000030620190000030001100197000000000410004c00000000040000190000000004064019000003000110009c00000000010300190000000001046019000000000110004c000002820000613d000000400300043d000003120130009c000002850000813d0000014001300039000000400010043f0000000201500367000000000101043b000000000013043500000020015000390000000201100367000000000101043b000003060410009c000002820000213d0000000001510019000300000005001d000200000003001d000100000002001d0bf501c90000040f0000000104000029000000030300002900000002020000290000002002200039000000000012043500000040013000390000000201100367000000000101043b000003060210009c000002820000213d000000000131001900000000020400190bf501c90000040f000000020400002900000003030000290000004002400039000000000012043500000060013000390000000201100367000000000101043b000003010210009c000002820000213d0000006002400039000000000012043500000080013000390000000201100367000000000101043b000003010210009c000002820000213d00000080024000390000000000120435000000a0013000390000000201100367000000000101043b000003010210009c000002820000213d000000a0024000390000000000120435000000c0013000390000000201100367000000000101043b000000c0024000390000000000120435000000e0013000390000000201100367000000000101043b000000e002400039000000000012043500000100013000390000000201100367000000000101043b000000000210004c0000000002000019000000010200c039000000000221004b000002820000c13d0000010002400039000000000012043500000120013000390000000201100367000000000101043b000000000210004c0000000002000019000000010200c039000000000221004b000002820000c13d000001200240003900000000001204350000000001040019000000000001042d000000000100001900000000020000190bf501c00000040f000003030100004100000000001004350000004101000039000000040010043f000000240200003900000000010000190bf501c00000040f000000000212004900000300030000410000007f0420008c000000000400001900000000040320190000030002200197000000000520004c0000000003008019000003000220009c00000000020400190000000002036019000000000220004c0000029a0000613d000000000001042d000000000100001900000000020000190bf501c00000040f000f000000000002000400000004001d000e00000003001d000d00000002001d000800000001001d0000030701000041000000000101041a000000010110008c000003bb0000613d00000001010000390000030702000041000000000012041b000003080100004100000000001004390000000001000410000300000001001d00000004001004430000800a0100003900000024020000390bf501a40000040f00000000030100190000000004000416000000000143004b000003a80000413d000000080200002900000100012000390000000001010433000000000110004c000003af0000613d00000120012000390000000001010433000000000110004c000003af0000c13d000000a00120003900000000010104330000030101100198000003c00000613d000500000004001d000c00000003001d000000c001200039000600000001001d0000000001010433000000000110004c000003c50000613d000000e0012000390000000001010433000f00000001001d000003090100004100000000001004390000800b0100003900000004020000390bf501a40000040f0000000f02000029000000000112004b000003ca0000613d0000000e02000029000000000120004c000003cf0000613d00000006010000290000000001010433000100000001001d00000008010000290000000001010433000200000001001d000000010320008a0000000d010000290bf505be0000040f00000060011000390000000201100367000000000101043b000700000001001d000003130110009c0000039e0000813d00000007010000290bf5075d0000040f000900000001001d0000000701000029000000000110004c0000000c080000290000000509000029000002f50000c13d00000000010004160000000902000029000000000212004b000003a80000413d00000009020000290000000002120049000900000002001d0000000e07000029000003110170009c000003b40000813d00000005037002100000003f01300039000000200200008a000000000121016f000000400200043d0000000001120019000b00000002001d000000000221004b00000000020000190000000102004039000003060410009c000003b40000213d0000000102200190000003b40000c13d000000400010043f0000000b0200002900000000007204350000001f0130018f000000200a200039000000000200003100000002022003670000000503300272000003180000613d0000000004000019000000050540021000000000065a0019000000000552034f000000000505043b00000000005604350000000104400039000000000534004b000003100000413d000000000410004c000003270000613d0000000503300210000000000232034f00000000033a00190000000301100210000000000403043300000000041401cf000000000414022f000000000202043b0000010001100089000000000212022f00000000011201cf000000000141019f00000000001304350000000001980049000500000001001d0000000005000019000a0000000a001d000000000175004b000003580000813d0000000d0100002900000000020700190000000003050019000f00000005001d0bf505be0000040f00000060011000390000000201100367000000000301043b000003010130009c0000039e0000213d0000000b0100002900000000010104330000000f02000029000000000121004b000003a10000a13d0000000001030019000c00000003001d0bf5075d0000040f0000000f0500002900000005025002100000000a0a0000290000000002a2001900000000001204350000000c03000029000000000330004c000003550000c13d0000000b030000290000000003030433000000000353004b000003a10000a13d0000000003000416000000000431004b000003a80000413d0000000b040000290000000004040433000000000454004b000003a10000a13d000000000131004900000000001204350000000a0a00002900000001055000390000000e070000290000032b0000013d0000000003000019000000000173004b000003780000813d0000000d010000290000000002070019000f00000003001d0bf505be0000040f000000c0031000390000000202000367000000000332034f000000000303043b000000000430004c0000000004000019000000010400c039000000000443004b0000039e0000c13d000000000330004c000003740000613d0000004003100039000000000332034f000000000303043b000003010430009c0000039e0000213d0000008001100039000000000112034f000000000201043b00000000010300190bf5093e0000040f0000000f0300002900000001033000390000000e07000029000003590000013d000000000400041100000002010000290000000d020000290000000003070019000f00000004001d0000000b050000290bf505e00000040f00000007010000290bf5075d0000040f0000000902000029000000000221004b000003a80000413d000000090200002900000000022100490000000104000029000000000142004b000003d40000413d00000006010000290000000000210435000000080100002900000004020000290bf5045b0000040f00000308010000410000000000100439000000030100002900000004001004430000800a0100003900000024020000390bf501a40000040f0000000503000029000000000231004b0000039b0000a13d00000000023100490000000f010000290bf50a200000040f0000030701000041000000000001041b000000000001042d000000000100001900000000020000190bf501c00000040f000003030100004100000000001004350000003201000039000000040010043f000000240200003900000000010000190bf501c00000040f000003030100004100000000001004350000001101000039000000040010043f000000240200003900000000010000190bf501c00000040f000000400100043d0000030a02000041000000000021043500000004020000390bf501c00000040f000003030100004100000000001004350000004101000039000000040010043f000000240200003900000000010000190bf501c00000040f000000400100043d0000030e02000041000000000021043500000004020000390bf501c00000040f000000400100043d0000030d02000041000000000021043500000004020000390bf501c00000040f000000400100043d0000030c02000041000000000021043500000004020000390bf501c00000040f000000400100043d0000030b02000041000000000021043500000004020000390bf501c00000040f000000400100043d0000031502000041000000000021043500000004020000390bf501c00000040f000000400100043d00000024031000390000000000230435000003140200004100000000002104350000000402100039000000000042043500000044020000390bf501c00000040f000000000300003100000000041300490000001f0540008a0000000204000367000000000224034f000000000202043b0000030006000041000000000752004b0000000007000019000000000706401900000300055001970000030008200197000000000958004b000000000600a019000000000558013f000003000550009c00000000050700190000000005066019000000000550004c000004070000613d0000000001120019000000000214034f000000000202043b000003060420009c000004070000213d000000000323004900000020011000390000030004000041000000000531004b0000000005000019000000000504201900000300033001970000030006100197000000000736004b0000000004008019000000000336013f000003000330009c00000000030500190000000003046019000000000330004c000004070000c13d000000000001042d000000000100001900000000020000190bf501c00000040f000000c00b100039000001000c0000390000000000cb0435000002ff07700197000000a00b10003900000000007b043500000060071000390000000000570435000000400510003900000000004504350000030103300197000000200410003900000000003404350000031603600198000003170300004100000000030060190000031804600197000000000343019f0000008004100039000000000034043500000100031000390000000000930435000003010220019700000000002104350000001f0390018f000001200210003900000002048003670000000505900272000004300000613d000000000600001900000005076002100000000008720019000000000774034f000000000707043b00000000007804350000000106600039000000000756004b000004280000413d000000000630004c0000043f0000613d0000000505500210000000000454034f00000000055200190000000303300210000000000605043300000000063601cf000000000636022f000000000404043b0000010003300089000000000434022f00000000033401cf000000000363019f000000000035043500000000039200190000000000030435000000e0011000390000000000a104350000001f01900039000000200300008a000000000131016f0000000001120019000000000001042d0000000003010433000000000032043500000020022000390000000004000019000000000534004b000004540000813d000000000524001900000020044000390000000006140019000000000606043300000000006504350000044c0000013d000000000123001900000000000104350000001f01300039000000200300008a000000000131016f0000000001120019000000000001042d0011000000000002000f00000002001d001000000001001d0000008002100039000e00000002001d0000000001020433001100000001001d000003190100004100000000001004390000000001000412000900000001001d00000004001004430000002400000443000080050100003900000044020000390bf501a40000040f0000001004000029000000c0054000390000000003050433000003010210019700000011010000290000030101100198000c00000005001d000d00000002001d0000051d0000613d0bf507b60000040f00000002040003670000000f01000029000000000214034f000000000502043b0000031602500198000003170200004100000000020060190000031803500197000000000232019f0000001006000029000000e003600039000b00000003001d0000000003030433000800000003001d0000000c030000290000000003030433000700000003001d0000000e0300002900000000030304330000030103300197000600000003001d000000a003600039000a00000003001d00000000030304330000030103300197000500000003001d000900000005001d000000000225004b0000059b0000c13d0000002002100039000000000224034f000000000202043b000400000002001d000002ff0220009c0000059b0000213d00000040021000390bf503dd0000040f0000031a0300004100000000003004390000000d030000290000000400300443000300000001001d000200000002001d000080020100003900000024020000390bf501a40000040f0000000f02000029000000000110004c0000059b0000613d000000400300043d001100000003001d0000031b01000041000000000013043500000060012000390000000002000414000f00000002001d0000000201100367000000000a01043b0000000401300039000000050200002900000006030000290000000704000029000000080500002900000009060000290000000407000029000000030800002900000002090000290bf5040a0000040f00000011030000290000000d02000029000000040420008c000004c40000613d00000000043100490000000f0100002900000011050000290bf5014b0000040f0000001103000029000000000110004c0000059e0000613d000003110130009c0000001004000029000005940000813d001100000003001d000000400030043f000000200100003900000000001304350000002001300039000000000204043300000000002104350000002001400039000000000101043300000040023000390000014005000039000000000052043500000160023000390bf504480000040f000000000201001900000011040000290000000001420049000000200310008a000000100100002900000040011000390000000001010433000000600440003900000000003404350bf504480000040f00000010050000290000006002500039000000000202043300000301022001970000001104000029000000800340003900000000002304350000000e0200002900000000020204330000030102200197000000a00340003900000000002304350000000a0200002900000000020204330000030102200197000000c00340003900000000002304350000000c020000290000000002020433000000e00340003900000000002304350000000b0200002900000000020204330000010003400039000000000023043500000100025000390000000002020433000000000220004c0000000002000019000000010200c0390000012003400039000000000023043500000120025000390000000002020433000000000220004c0000000002000019000000010200c039000001400340003900000000002304350000000001410049000002ff02000041000002ff0340009c000000000302001900000000030440190000004003300210000002ff0410009c00000000010280190000006001100210000000000131019f0000000003000414000002ff0430009c0000000002034019000000c002200210000000000112019f0000031c011001c70000800d0200003900000001030000390000031d040000410bf50beb0000040f00000001012001900000059b0000613d000000000001042d0000000901000029000800000003001d0000000e0100002900000002050003670000000f01000029000000000215034f000000000602043b0000031602600198000003170200004100000000020060190000031803600197000000000232019f000000e003400039000b00000003001d0000000003030433000600000003001d000000a003400039000a00000003001d00000000030304330000030103300197000500000003001d000700000006001d000000000226004b0000059b0000c13d0000002002100039000000000225034f000000000202043b000400000002001d000002ff0220009c0000059b0000213d00000040021000390bf503dd0000040f0000031a0300004100000000003004390000000d030000290000000400300443000300000001001d000200000002001d000080020100003900000024020000390bf501a40000040f0000000f03000029000000000110004c0000059b0000613d000000400200043d001100000002001d0000031b0100004100000000001204350000000001000414000100000001001d000003190100004100000000001004390000000901000029000000040010044300000020010000390000002400100443000080050100003900000044020000390bf501a40000040f0000000f0200002900000060022000390000000202200367000000000a02043b00000000030100190000001101000029000000040110003900000005020000290000000804000029000000060500002900000007060000290000000407000029000000030800002900000002090000290bf5040a0000040f00000011030000290000000d05000029000000040250008c000005910000613d00000000043100490000000806000029000000000160004c0000058a0000613d000002ff01000041000002ff0230009c000000000201001900000000020340190000004002200210000002ff0340009c000000000301001900000000030440190000006003300210000000000223019f0000000104000029000002ff0340009c0000000001044019000000c001100210000000000112019f0000031c011001c700008009020000390000000003060019000000000405001900000000050000190bf50beb0000040f00000000030100190000006003300270000102ff0030019d0003000000010355000000010120018f0000058e0000013d0000000101000029000000000205001900000000050300190bf5014b0000040f000000000110004c00000011030000290000059e0000613d000003060130009c0000001004000029000004c70000a13d000003030100004100000000001004350000004101000039000000040010043f000000240200003900000000010000190bf501c00000040f000000000100001900000000020000190bf501c00000040f0000000302000367000000400100043d00000001040000310000001f0340018f0000000504400272000005ad0000613d000000000500001900000005065002100000000007610019000000000662034f000000000606043b00000000006704350000000105500039000000000645004b000005a50000413d000000000530004c000005bc0000613d0000000504400210000000000242034f00000000044100190000000303300210000000000504043300000000053501cf000000000535022f000000000202043b0000010003300089000000000232022f00000000023201cf000000000252019f000000000024043500000001020000310bf501c00000040f000000000223004b000005d60000813d000000050230021000000000021200190000000202200367000000000202043b0000000003100079000000df0330008a0000030004000041000000000532004b0000000005000019000000000504401900000300033001970000030006200197000000000736004b000000000400a019000000000336013f000003000330009c00000000030500190000000003046019000000000330004c000005dd0000613d0000000001120019000000000001042d000003030100004100000000001004350000003201000039000000040010043f000000240200003900000000010000190bf501c00000040f000000000100001900000000020000190bf501c00000040f000e000000000002000600000005001d000300000004001d000b00000002001d000900000001001d000000010130008c000006350000c13d0000000101000039000800000001001d00000000030000190000000101100190000006b50000613d0000000b0100002900000008020000290bf505be0000040f000c00000001001d00000040021000390000000201000367000000000221034f000000000202043b000003130320009c000006b60000813d000000000220004c0000060c0000613d0000000c020000290000002002200039000000000121034f000000000101043b000003010210009c000006b60000213d00000000001004350000032301000041000000200010043f0bf501950000040f000000000101041a000d00ff00100193000000ff01100190000006b90000613d00000000010004150000000d0110008a00000020011000c9000a00000001001d0000000201000367000006110000013d00000000020004150000000e0220008a00000020022000c9000a00000002001d000e00010000003d0000000c02000029000000000121034f000000000101043b000003010210009c000006b60000213d00000000001004350000032301000041000000200010043f0bf501950000040f000000000101041a0000000a02000029000000200220011a000000ff02100195000000ff01100190000006b90000613d0000000c01000029000000a0021000390bf503dd0000040f000000040220008c000006b60000413d0000000201100367000000000101043b000003240110019700000000001004350000032501000041000000200010043f0bf501950000040f000000000101041a000000ff01100190000006b90000613d00000009010000290000000c020000290bf50a6d0000040f00000001030000390000000001000019000005ea0000013d000a00000003001d000000000130004c000006be0000613d0000000a02000029000000010320008a0000000b01000029000800000003001d0bf505be0000040f00000060011000390000000201100367000000000101043b000700000001001d000003010110009c000006b60000213d00000009010000290000000b020000290000000a030000290bf507010000040f00000003010000290000030101100197000400000001001d00000006010000290000002001100039000500000001001d00000000030000190000000801000029000000000113004b000006b50000813d0000000b010000290000000a02000029000c00000003001d0bf505be0000040f00000060011000390000000201100367000000000201043b000003010120009c000006b60000213d0000000701000029000000000112004b000006b20000613d000900000002001d00000000010200190bf5075d0000040f000000060200002900000000020204330000000c03000029000000000232004b000006c50000a13d0000000502300210000000050300002900000000022300190000000002020433000000000321004b000006be0000413d000000000321004b0000000905000029000006b20000613d0000000006210049000000000150004c000006af0000613d000000400300043d0000000401000029000000000110004c000006d30000613d0000031e01000041000000000013043500000000010004100000030102100197000000040430003900000000010004140000000000240435000000040250008c0000068a0000613d0000002404000039000200000006001d000000200600003900000000020500190000000005030019000100000003001d0bf5015e0000040f000000010300002900000002060000290000000905000029000000000110004c000006e10000613d0000000101000031000000200210008c000000200200003900000000020140190000001f02200039000000600420018f0000000002340019000000000442004b00000000070000190000000107004039000003060420009c000006cc0000213d0000000104700190000006cc0000c13d000000400020043f000000200110008c000006b60000413d0000000003030433000000000163004b0000002401200039000006d80000413d00000020032000390000031f040000410000000000430435000000440320003900000000006304350000000403000029000000000031043500000044010000390000000000120435000003200120009c000006cc0000213d0000008001200039000000400010043f00000000010500190bf5087d0000040f000006b20000013d000000030100002900000000020600190bf50a200000040f0000000c0300002900000001033000390000064e0000013d000000000001042d000000000100001900000000020000190bf501c00000040f000000400100043d0000032602000041000000000021043500000004020000390bf501c00000040f000003030100004100000000001004350000001101000039000000040010043f000000240200003900000000010000190bf501c00000040f000003030100004100000000001004350000003201000039000000040010043f000000240200003900000000010000190bf501c00000040f000003030100004100000000001004350000004101000039000000040010043f000000240200003900000000010000190bf501c00000040f00000322010000410000000000130435000000040200003900000000010300190bf501c00000040f000000000031043500000321010000410000000000120435000000040120003900000000006104350000004403000039000000000102001900000000020300190bf501c00000040f0000000302000367000000400100043d00000001040000310000001f0340018f0000000504400272000006f00000613d000000000500001900000005065002100000000007610019000000000662034f000000000606043b00000000006704350000000105500039000000000645004b000006e80000413d000000000530004c000006ff0000613d0000000504400210000000000242034f00000000044100190000000303300210000000000504043300000000053501cf000000000535022f000000000202043b0000010003300089000000000232022f00000000023201cf000000000252019f000000000024043500000001020000310bf501c00000040f00080000000000020000000004030019000300000002001d000100000001001d0000000003000019000200000004001d000000000143004b000007540000813d00000003010000290000000002040019000400000003001d0bf505be0000040f000600000001001d00000040021000390000000201000367000000000221034f000000000202043b000003130320009c000007550000813d000000000220004c0000072a0000613d00000006020000290000002002200039000000000121034f000000000101043b000003010210009c000007550000213d00000000001004350000032301000041000000200010043f0bf501950000040f000000000101041a000700ff00100193000000ff01100190000007580000613d0000000001000415000000070110008a00000020011000c9000500000001001d00000002010003670000072f0000013d0000000002000415000000080220008a00000020022000c9000500000002001d000800010000003d0000000602000029000000000121034f000000000101043b000003010210009c000007550000213d00000000001004350000032301000041000000200010043f0bf501950000040f000000000101041a0000000502000029000000200220011a000000ff02100195000000ff01100190000007580000613d0000000601000029000000a0021000390bf503dd0000040f000000040220008c000007550000413d0000000201100367000000000101043b000003240110019700000000001004350000032501000041000000200010043f0bf501950000040f000000000101041a000000ff01100190000007580000613d000000010100002900000006020000290bf50a6d0000040f000000040300002900000001033000390000000204000029000007070000013d000000000001042d000000000100001900000000020000190bf501c00000040f000000400100043d0000032602000041000000000021043500000004020000390bf501c00000040f00010000000000020000030102100198000007840000613d000000400300043d0000031e0100004100000000001304350000000401300039000000000400041000000000004104350000000001000414000000040420008c000007710000613d00000024040000390000002006000039000100000003001d00000001050000290bf5015e0000040f0000000103000029000000000110004c000007960000613d0000000101000031000000200210008c000000200200003900000000020140190000001f02200039000000600420018f0000000002340019000000000442004b00000000050000190000000105004039000003060420009c0000078c0000213d00000001045001900000078c0000c13d000000400020043f0000001f0110008c000007930000a13d00000000010304330000078b0000013d00000308010000410000000000100439000000000100041000000004001004430000800a0100003900000024020000390bf501a40000040f000000000001042d000003030100004100000000001004350000004101000039000000040010043f000000240200003900000000010000190bf501c00000040f000000000100001900000000020000190bf501c00000040f0000000302000367000000400100043d00000001040000310000001f0340018f0000000504400272000007a50000613d000000000500001900000005065002100000000007610019000000000662034f000000000606043b00000000006704350000000105500039000000000645004b0000079d0000413d000000000530004c000007b40000613d0000000504400210000000000242034f00000000044100190000000303300210000000000504043300000000053501cf000000000535022f000000000202043b0000010003300089000000000232022f00000000023201cf000000000252019f000000000024043500000001020000310bf501c00000040f00060000000000020000000008030019000000000501001900000301075001980000083b0000613d000000400300043d0000030106200198000008460000613d00000327010000410000000000130435000000240230003900000000010004140000000000620435000000000200041000000301042001970000000402300039000300000004001d0000000000420435000000040270008c000600000005001d000500000006001d000400000007001d000007db0000613d0000004404000039000000200600003900000000020700190000000005030019000200000008001d000100000003001d0bf5015e0000040f00000001030000290000000208000029000000040700002900000005060000290000000605000029000000000110004c0000084b0000613d0000000101000031000000200210008c000000200200003900000000020140190000001f02200039000000600420018f0000000002340019000000000442004b00000000090000190000000109004039000003060420009c0000083c0000213d00000001049001900000083c0000c13d000000400020043f0000001f0110008c000008430000a13d0000000001030433000000000181004b0000083b0000813d000000200120003900000328030000410000000000310435000000240120003900000000006104350000004401000039000200000001001d000000000012043500000044012000390000000000010435000003200120009c0000083c0000213d0000008001200039000000400010043f00000000010500190bf5087d0000040f0000000402000029000000050600002900000006050000290000032701000041000000400300043d0000000000130435000000240430003900000000010004140000000000640435000000040730003900000003040000290000000000470435000000040420008c000008170000613d000000440400003900000020060000390000000005030019000400000003001d0bf5015e0000040f000000040300002900000005060000290000000605000029000000000110004c0000084b0000613d0000000101000031000000200210008c000000200200003900000000020140190000001f02200039000000600420018f0000000002340019000000000442004b00000000070000190000000107004039000003060420009c0000083c0000213d00000001047001900000083c0000c13d000000400020043f000000200110008c000008430000413d0000000001030433000000000110004c0000086b0000c13d0000002001200039000003280300004100000000003104350000004401200039000000010300008a00000000003104350000002401200039000000000061043500000002010000290000000000120435000003200120009c0000083c0000213d0000008001200039000000400010043f00000000010500190bf5087d0000040f000000000001042d000003030100004100000000001004350000004101000039000000040010043f000000240200003900000000010000190bf501c00000040f000000000100001900000000020000190bf501c00000040f0000032c010000410000000000130435000000040200003900000000010300190bf501c00000040f0000000302000367000000400100043d00000001040000310000001f0340018f00000005044002720000085a0000613d000000000500001900000005065002100000000007610019000000000662034f000000000606043b00000000006704350000000105500039000000000645004b000008520000413d000000000530004c000008690000613d0000000504400210000000000242034f00000000044100190000000303300210000000000504043300000000053501cf000000000535022f000000000202043b0000010003300089000000000232022f00000000023201cf000000000252019f000000000024043500000001020000310bf501c00000040f00000064012000390000032903000041000000000031043500000044012000390000032a0300004100000000003104350000002401200039000000360300003900000000003104350000032b0100004100000000001204350000000401200039000000200300003900000000003104350000008403000039000000000102001900000000020300190bf501c00000040f00040000000000020000030105100197000000400400043d0000032d0140009c000008c80000813d0000004001400039000000400010043f00000020014000390000032e0300004100000000003104350000002001000039000200000001001d000100000004001d00000000001404350000000001000414000400000005001d000000040350008c0000000003000019000008980000613d00000000040204330000002003200039000000040200002900000000050000190bf5014b0000040f000000000110004c00000000030000190000000103006039000300000003001d0bf508fe0000040f000000000201043300000003030000290000000103300190000008cf0000c13d000000000320004c0000000403000029000008ae0000c13d000300000001001d0000031a0100004100000000001004390000000400300443000080020100003900000024020000390bf501a40000040f000000000110004c000008f00000613d00000003010000290000000002010433000000000320004c000008c40000613d0000030005000041000000200320008c000000000300001900000000030540190000030002200197000000000420004c00000000040000190000000004052019000003000220009c00000000020300190000000002046019000000000220004c000008c50000c13d00000020011000390000000001010433000000000210004c0000000002000019000000010200c039000000000221004b000008c50000c13d000000000110004c000008dd0000613d000000000001042d000000000100001900000000020000190bf501c00000040f000003030100004100000000001004350000004101000039000000040010043f000000240200003900000000010000190bf501c00000040f0000000003010019000000000120004c000008ee0000c13d000000400200043d000400000002001d0000032b010000410000000000120435000000040120003900000001020000290bf509370000040f0000000403000029000000000231004900000000010300190bf501c00000040f000000400100043d00000064021000390000032f03000041000000000032043500000044021000390000033003000041000000000032043500000024021000390000002a0300003900000000003204350000032b02000041000000000021043500000004021000390000000203000029000000000032043500000084020000390bf501c00000040f00000020013000390bf501c00000040f000000400100043d00000044021000390000033103000041000000000032043500000024021000390000001d0300003900000000003204350000032b02000041000000000021043500000004021000390000000203000029000000000032043500000064020000390bf501c00000040f000000600100003900000001020000320000092f0000613d000003110120009c000009300000813d0000003f01200039000000200300008a000000000331016f000000400100043d0000000003310019000000000413004b00000000040000190000000104004039000003060530009c000009300000213d0000000104400190000009300000c13d000000400030043f00000000002104350000002002100039000000030300036700000001050000310000001f0450018f0000000505500272000009200000613d000000000600001900000005076002100000000008720019000000000773034f000000000707043b00000000007804350000000106600039000000000756004b000009180000413d000000000640004c0000092f0000613d0000000505500210000000000353034f00000000025200190000000304400210000000000502043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f0000000000320435000000000001042d000003030100004100000000001004350000004101000039000000040010043f000000240200003900000000010000190bf501c00000040f000000000302001900000020020000390000000000210435000000200210003900000000010300190bf504480000040f000000000001042d00050000000000020000000004020019000000000240004c000009e60000613d0000030105100198000009d80000613d000000400700043d0000031e0100004100000000001704350000000001000411000003010310019700000004027000390000000001000414000200000003001d0000000000320435000000040250008c000500000004001d000400000005001d0000095d0000613d00000024040000390000002006000039000000000205001900000000030700190000000005070019000300000007001d0bf5015e0000040f000000030700002900000004050000290000000504000029000000000110004c000009eb0000613d0000000101000031000000200210008c000000200200003900000000020140190000001f02200039000000600220018f0000000003720019000000000223004b00000000020000190000000102004039000003060630009c000009dc0000213d0000000102200190000009dc0000c13d000000400030043f0000001f0110008c000009e30000a13d0000000001070433000000000241004b00000a0b0000413d0000000001000410000003010710019800000a140000613d0000031e010000410000000000130435000000040230003900000000010004140000000000720435000000040250008c000300000007001d000009880000613d0000002404000039000000200600003900000000020500190000000005030019000100000003001d0bf5015e0000040f0000000307000029000000010300002900000004050000290000000504000029000000000110004c000009eb0000613d0000000101000031000000200210008c000000200200003900000000020140190000001f02200039000000600220018f0000000002320019000003060620009c000009dc0000213d000000400020043f000000200110008c000009e30000413d0000000001030433000100000001001d000000200120003900000332030000410000000000310435000000640120003900000000004104350000004401200039000000000071043500000024012000390000000203000029000000000031043500000064010000390000000000120435000003330120009c000009dc0000213d000000a001200039000000400010043f00000000010500190bf5087d0000040f000000040200002900000005050000290000031e01000041000000400300043d00000000001304350000000404300039000000000100041400000003060000290000000000640435000000040420008c000009bc0000613d000000240400003900000020060000390000000005030019000400000003001d0bf5015e0000040f00000004030000290000000505000029000000000110004c000009eb0000613d0000000102000031000000200120008c000000200100003900000000010240190000001f01100039000000600410018f0000000001340019000000000441004b00000000060000190000000106004039000003060410009c000009dc0000213d0000000104600190000009dc0000c13d000000400010043f000000200220008c000009e30000413d00000000020304330000000104000029000000000342004b00000a190000413d0000000002420049000000000252004b000009db0000613d0000030c02000041000000000021043500000004020000390bf501c00000040f0000000001000416000000000141004b000009e60000413d000000000001042d000003030100004100000000001004350000004101000039000000040010043f000000240200003900000000010000190bf501c00000040f000000000100001900000000020000190bf501c00000040f000000400100043d0000030c02000041000000000021043500000004020000390bf501c00000040f0000000302000367000000400100043d00000001040000310000001f0340018f0000000504400272000009fa0000613d000000000500001900000005065002100000000007610019000000000662034f000000000606043b00000000006704350000000105500039000000000645004b000009f20000413d000000000530004c00000a090000613d0000000504400210000000000242034f00000000044100190000000303300210000000000504043300000000053501cf000000000535022f000000000202043b0000010003300089000000000232022f00000000023201cf000000000252019f000000000024043500000001020000310bf501c00000040f000000240230003900000000001204350000032101000041000000000013043500000004013000390000000000410435000000440200003900000000010300190bf501c00000040f00000322010000410000000000130435000000040200003900000000010300190bf501c00000040f000003030100004100000000001004350000001101000039000000040010043f000000240200003900000000010000190bf501c00000040f0003000000000002000300000002001d0000030101100198000200000001001d00000a510000613d000003080100004100000000001004390000000001000410000100000001001d00000004001004430000800a0100003900000024020000390bf501a40000040f0000000303000029000000000131004b00000a560000413d000000010500003900000000010004140000000204000029000000040240008c00000a4b0000613d000000000230004c00000a450000613d000002ff02000041000002ff0510009c0000000001028019000000c0011002100000031c011001c7000080090200003900000000050000190bf50beb0000040f00000000030100190000006003300270000102ff0030019d0003000000010355000000010520018f00000a4b0000013d00000000020400190000000003000019000000000400001900000000050000190bf5014b0000040f0000000005010019000300000005001d0bf508fe0000040f0000000301000029000000000110004c00000a680000613d000000000001042d000000400100043d0000032202000041000000000021043500000004020000390bf501c00000040f00000308010000410000000000100439000000010100002900000004001004430000800a0100003900000024020000390bf501a40000040f0000032102000041000000400300043d000000000023043500000004023000390000000304000029000000000042043500000024023000390000000000120435000000440200003900000000010300190bf501c00000040f000000400100043d0000033402000041000000000021043500000004020000390bf501c00000040f0009000000000002000300000001001d0000000201200367000000000101043b000003130310009c00000b4f0000813d000900000002001d0000031a0200004100000000002004390000000400100443000080020100003900000024020000390bf501a40000040f000000000110004c00000b520000613d000000090300002900000080023000390000000201000367000000000221034f000000000202043b000800000002001d000000000220004c00000b570000613d0000004002300039000500000002001d000000000121034f000000000101043b000700000001001d000003010110009c00000b4f0000213d00000007010000290bf5075d0000040f0000000702000029000000000220004c0000000802000029000000000200c019000100000002001d000400000001001d00000009010000290000006001100039000600000001001d0000000201100367000000000101043b000003010210009c00000b4f0000213d0bf5075d0000040f000200000001001d0000000701000029000000000110004c00000aad0000613d00000002020003670000000501000029000000000112034f000000000101043b000003010310009c000000090300002900000b4f0000213d0000002003300039000000000232034f000000000202043b000003010320009c00000b4f0000213d00000008030000290bf507b60000040f00000008010000290000000403000029000000000113004b000000090100002900000b5c0000413d0000000202100367000000000202043b000400000002001d000003010220009c00000b4f0000213d000000a0021000390bf503dd0000040f000000400300043d000000000501001900000000040200190000001f0240018f00000000010004140000000205500367000000050640027200000aca0000613d000000000700001900000005087002100000000009830019000000000885034f000000000808043b00000000008904350000000107700039000000000867004b00000ac20000413d000000000720004c00000ad90000613d0000000506600210000000000565034f00000000066300190000000302200210000000000706043300000000072701cf000000000727022f000000000505043b0000010002200089000000000525022f00000000022501cf000000000272019f00000000002604350000000002430019000000000002043500000001050000390000000406000029000000040260008c00000afe0000613d0000000702000029000000000220004c00000ae70000613d000000000206001900000000050000190bf5014b0000040f000000000501001900000afe0000013d000002ff02000041000002ff0540009c00000000040280190000006004400210000002ff0530009c00000000030280190000004003300210000000000343019f000002ff0410009c0000000001028019000000c001100210000000000113019f0000031c011001c700008009020000390000000103000029000000000406001900000000050000190bf50beb0000040f00000000030100190000006003300270000102ff0030019d0003000000010355000000010520018f000700000005001d0bf508fe0000040f0000000702000029000000000220004c00000b660000613d00000006010000290000000201100367000000000101043b000003010210009c000000090200002900000b4f0000213d0bf5075d0000040f00000002020003670000000903000029000000000332034f000700000001001d000000000103043b000900000001001d000003010110009c00000b4f0000213d0000000501000029000000000112034f000000000101043b000500000001001d000003010110009c00000b4f0000213d0000000601000029000000000112034f000000000101043b000600000001001d000003010110009c00000b4f0000213d000000400100043d000400000001001d000003350100004100000000001004390000800b0100003900000004020000390bf501a40000040f00000002030000290000000704000029000000000234004b0000000002000019000000000203201900000000022400490000000404000029000000a0034000390000000000230435000000800240003900000008030000290000000000320435000000600240003900000006030000290000000000320435000000400240003900000005030000290000000000320435000000200240003900000009030000290000000000320435000000c002400039000000000012043500000003010000290000000000140435000002ff010000410000000002000414000002ff0320009c0000000002018019000002ff0340009c00000000010440190000004001100210000000c002200210000000000112019f00000336011001c70000800d02000039000000010300003900000337040000410bf50beb0000040f000000010120019000000b4f0000613d000000000001042d000000000100001900000000020000190bf501c00000040f000000400100043d0000033902000041000000000021043500000004020000390bf501c00000040f000000400100043d0000033802000041000000000021043500000004020000390bf501c00000040f000000400100043d000000240210003900000000003204350000032102000041000000000021043500000004021000390000000803000029000000000032043500000044020000390bf501c00000040f0bf50b720000040f0000032b02000041000000400300043d000900000003001d0000000000230435000000000201001900000004013000390bf509370000040f0000000903000029000000000231004900000000010300190bf501c00000040f0000000002010433000000440320008c00000b7f0000813d000000400100043d0000032d0210009c00000bdd0000813d0000004002100039000000400020043f0000001d0200003900000000002104350000033a03000041000000200210003900000bd80000013d000000040220008a0000001f0300008a000000000332004b00000be40000813d0000001f0320019000000000040000190000002004006039000000000434019f0000000005140019000000400300043d000000000134001900000000041200190000000405500039000000000641004b00000b930000813d000000000605043300000000006104350000002005500039000000200110003900000b8c0000013d00000000002304350000001f01100039000000200200008a000000000121016f000000400010043f000000000403043300000300050000410000001f0640008c000000000600001900000000060520190000030007400197000000000870004c0000000005008019000003000770009c000000000506c019000000000550004c00000bda0000613d00000020033000390000000005030433000003060650009c00000bda0000213d000000000443001900000000053500190000001f035000390000030006000041000000000743004b0000000007000019000000000706801900000300033001970000030008400197000000000983004b0000000006008019000000000383013f000003000330009c00000000030700190000000003066019000000000330004c00000bda0000c13d0000000003050433000003060630009c00000bdd0000213d0000003f06300039000000000626016f0000000002160019000000000662004b00000000060000190000000106004039000003060720009c00000bdd0000213d000000010660019000000bdd0000c13d000000400020043f000000000031043500000020025000390000000005230019000000000445004b00000bda0000213d00000020041000390000000005000019000000000635004b00000bd60000813d0000000006450019000000000725001900000000070704330000000000760435000000200550003900000bce0000013d000000000243001900000000030000190000000000320435000000000001042d000000000100001900000000020000190bf501c00000040f000003030100004100000000001004350000004101000039000000040010043f000000240200003900000000010000190bf501c00000040f000003030100004100000000001004350000001101000039000000040010043f000000240200003900000000010000190bf501c00000040f00000bee002104210000000102000039000000000001042d000000000200001900000bed0000013d00000bf3002104230000000102000039000000000001042d000000000200001900000bf20000013d00000bf50000043200000bf60001042e00000bf700010430000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffff8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffff00000002000000000000000000000000000000000000000000000000000000004e487b7100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a3f7332000000000000000000000000000000000000000000000000000000001fd8010c000000000000000000000000000000000000000000000000ffffffffffffffffa65bb2f450488ab0858c00edc14abc5297769bf42adb48cfb77752890e8b697b9cc7f708afc65944829bd487b90b72536b1951864fbfc14e125fc972a6507f399a8a0592ac89c5ad3bc6df8224c17b485976f597df104ee20d0df415241f670b50dc905c000000000000000000000000000000000000000000000000000000004ac09ad3000000000000000000000000000000000000000000000000000000002c5211c6000000000000000000000000000000000000000000000000000000001e4ec46b0000000000000000000000000000000000000000000000000000000029f745a700000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000004000000000000000000000000002000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000fffffffffffffec00000000000000000000000010000000000000000000000000000000000000000275c273c000000000000000000000000000000000000000000000000000000000503c3ed000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000ffffffffffffffffffffffffffffffffffffffffffffffff80000000000000000000000000000000000000000000000000000000000000007fffffffffffffff310ab089e4439a4c15d089f94afb7896ff553aecb10793d0ab882de59d99a32e1806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b831186ec33000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000cba69f43792f9f399347222505213b55af8e0b0b54b893085c2e27ecbe1644f170a0823100000000000000000000000000000000000000000000000000000000a9059cbb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff7fcf4791810000000000000000000000000000000000000000000000000000000021f74345000000000000000000000000000000000000000000000000000000007a8ac5d3b7183f220a0602439da45ea337311d699902d1ed11a3725a714e7f1effffffff000000000000000000000000000000000000000000000000000000007a8ac5d3b7183f220a0602439da45ea337311d699902d1ed11a3725a714e7f1f9453980400000000000000000000000000000000000000000000000000000000dd62ed3e00000000000000000000000000000000000000000000000000000000095ea7b30000000000000000000000000000000000000000000000000000000020746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000005361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f08c379a00000000000000000000000000000000000000000000000000000000063ba9bff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffc05361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65646f742073756363656564000000000000000000000000000000000000000000005361666545524332303a204552433230206f7065726174696f6e20646964206e416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000023b872dd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff5f5a04673700000000000000000000000000000000000000000000000000000000796b89b91644bc98cd93958e4c9038275d622183e25ac5af08cc6b5d9553913202000000000000000000000000000000000000e00000000000000000000000007bfdfdb5e3a3776976e53cb0607060f54c5312701c8cba1155cc4d5394440b38e46e079c000000000000000000000000000000000000000000000000000000006eefed20000000000000000000000000000000000000000000000000000000005472616e73616374696f6e2072657665727465642073696c656e746c79000000", + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/zksync/solcInputs/32cb99d43bfe55793e8aa30cc4ac2e58.json b/deployments/zksync/solcInputs/32cb99d43bfe55793e8aa30cc4ac2e58.json new file mode 100644 index 000000000..798d74952 --- /dev/null +++ b/deployments/zksync/solcInputs/32cb99d43bfe55793e8aa30cc4ac2e58.json @@ -0,0 +1,367 @@ +{ + "language": "Solidity", + "sources": { + "lib/openzeppelin-contracts/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev 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. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling 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" + }, + "lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\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 * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\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" + }, + "lib/openzeppelin-contracts/contracts/token/ERC1155/utils/ERC1155Holder.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/utils/ERC1155Holder.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ERC1155Receiver.sol\";\n\n/**\n * Simple implementation of `ERC1155Receiver` that will allow a contract to hold ERC1155 tokens.\n *\n * IMPORTANT: When inheriting this contract, you must include a way to use the received tokens, otherwise they will be\n * stuck.\n *\n * @dev _Available since v3.1._\n */\ncontract ERC1155Holder is ERC1155Receiver {\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC1155Received.selector;\n }\n\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] memory,\n uint256[] memory,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC1155BatchReceived.selector;\n }\n}\n" + }, + "lib/openzeppelin-contracts/contracts/token/ERC1155/utils/ERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155Receiver.sol\";\nimport \"../../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);\n }\n}\n" + }, + "lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/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" + }, + "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/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 /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) 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(IERC20 token, address spender, uint256 value) 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 /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to\n * 0 before setting it to a non-zero value.\n */\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\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 require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation 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 * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\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 cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n }\n}\n" + }, + "lib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "lib/openzeppelin-contracts/contracts/token/ERC721/utils/ERC721Holder.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/utils/ERC721Holder.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Receiver.sol\";\n\n/**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers.\n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract ERC721Holder is IERC721Receiver {\n /**\n * @dev See {IERC721Receiver-onERC721Received}.\n *\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n}\n" + }, + "lib/openzeppelin-contracts/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.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 * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\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://consensys.net/diligence/blog/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.8.0/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(address target, bytes memory data, uint256 value) 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" + }, + "lib/openzeppelin-contracts/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" + }, + "lib/openzeppelin-contracts/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" + }, + "lib/openzeppelin-contracts/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" + }, + "lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "lib/sgn-v2-contracts/contracts/interfaces/IBridge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity >=0.8.0;\n\ninterface IBridge {\n function send(\n address _receiver,\n address _token,\n uint256 _amount,\n uint64 _dstChainId,\n uint64 _nonce,\n uint32 _maxSlippage\n ) external;\n\n function sendNative(\n address _receiver,\n uint256 _amount,\n uint64 _dstChainId,\n uint64 _nonce,\n uint32 _maxSlippage\n ) external payable;\n\n function relay(\n bytes calldata _relayRequest,\n bytes[] calldata _sigs,\n address[] calldata _signers,\n uint256[] calldata _powers\n ) external;\n\n function transfers(bytes32 transferId) external view returns (bool);\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 /**\n * @notice Verifies that a message is signed by a quorum among the signers.\n * @param _msg signed message\n * @param _sigs list of signatures sorted by signer addresses in ascending order\n * @param _signers sorted list of current signers\n * @param _powers powers of current signers\n */\n function verifySigs(\n bytes memory _msg,\n bytes[] calldata _sigs,\n address[] calldata _signers,\n uint256[] calldata _powers\n ) external view;\n}\n" + }, + "lib/sgn-v2-contracts/contracts/interfaces/IOriginalTokenVault.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity >=0.8.0;\n\ninterface IOriginalTokenVault {\n /**\n * @notice Lock original tokens to trigger mint at a remote chain's PeggedTokenBridge\n * @param _token local token address\n * @param _amount locked token amount\n * @param _mintChainId destination chainId to mint tokens\n * @param _mintAccount destination account to receive minted tokens\n * @param _nonce user input to guarantee unique depositId\n */\n function deposit(\n address _token,\n uint256 _amount,\n uint64 _mintChainId,\n address _mintAccount,\n uint64 _nonce\n ) external;\n\n /**\n * @notice Lock native token as original token to trigger mint at a remote chain's PeggedTokenBridge\n * @param _amount locked token amount\n * @param _mintChainId destination chainId to mint tokens\n * @param _mintAccount destination account to receive minted tokens\n * @param _nonce user input to guarantee unique depositId\n */\n function depositNative(\n uint256 _amount,\n uint64 _mintChainId,\n address _mintAccount,\n uint64 _nonce\n ) external payable;\n\n /**\n * @notice Withdraw locked original tokens triggered by a burn at a remote chain's PeggedTokenBridge.\n * @param _request The serialized Withdraw protobuf.\n * @param _sigs The list of signatures sorted by signing addresses in ascending order. A relay must be signed-off by\n * +2/3 of the bridge's current signing power to be delivered.\n * @param _signers The sorted list of signers.\n * @param _powers The signing powers of the signers.\n */\n function withdraw(\n bytes calldata _request,\n bytes[] calldata _sigs,\n address[] calldata _signers,\n uint256[] calldata _powers\n ) external;\n\n function records(bytes32 recordId) external view returns (bool);\n}\n" + }, + "lib/sgn-v2-contracts/contracts/interfaces/IOriginalTokenVaultV2.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity >=0.8.0;\n\ninterface IOriginalTokenVaultV2 {\n /**\n * @notice Lock original tokens to trigger mint at a remote chain's PeggedTokenBridge\n * @param _token local token address\n * @param _amount locked token amount\n * @param _mintChainId destination chainId to mint tokens\n * @param _mintAccount destination account to receive minted tokens\n * @param _nonce user input to guarantee unique depositId\n */\n function deposit(\n address _token,\n uint256 _amount,\n uint64 _mintChainId,\n address _mintAccount,\n uint64 _nonce\n ) external returns (bytes32);\n\n /**\n * @notice Lock native token as original token to trigger mint at a remote chain's PeggedTokenBridge\n * @param _amount locked token amount\n * @param _mintChainId destination chainId to mint tokens\n * @param _mintAccount destination account to receive minted tokens\n * @param _nonce user input to guarantee unique depositId\n */\n function depositNative(\n uint256 _amount,\n uint64 _mintChainId,\n address _mintAccount,\n uint64 _nonce\n ) external payable returns (bytes32);\n\n /**\n * @notice Withdraw locked original tokens triggered by a burn at a remote chain's PeggedTokenBridge.\n * @param _request The serialized Withdraw protobuf.\n * @param _sigs The list of signatures sorted by signing addresses in ascending order. A relay must be signed-off by\n * +2/3 of the bridge's current signing power to be delivered.\n * @param _signers The sorted list of signers.\n * @param _powers The signing powers of the signers.\n */\n function withdraw(\n bytes calldata _request,\n bytes[] calldata _sigs,\n address[] calldata _signers,\n uint256[] calldata _powers\n ) external returns (bytes32);\n\n function records(bytes32 recordId) external view returns (bool);\n}\n" + }, + "lib/sgn-v2-contracts/contracts/interfaces/IPeggedTokenBridge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity >=0.8.0;\n\ninterface IPeggedTokenBridge {\n /**\n * @notice Burn tokens to trigger withdrawal at a remote chain's OriginalTokenVault\n * @param _token local token address\n * @param _amount locked token amount\n * @param _withdrawAccount account who withdraw original tokens on the remote chain\n * @param _nonce user input to guarantee unique depositId\n */\n function burn(\n address _token,\n uint256 _amount,\n address _withdrawAccount,\n uint64 _nonce\n ) external;\n\n /**\n * @notice Mint tokens triggered by deposit at a remote chain's OriginalTokenVault.\n * @param _request The serialized Mint protobuf.\n * @param _sigs The list of signatures sorted by signing addresses in ascending order. A relay must be signed-off by\n * +2/3 of the sigsVerifier's current signing power to be delivered.\n * @param _signers The sorted list of signers.\n * @param _powers The signing powers of the signers.\n */\n function mint(\n bytes calldata _request,\n bytes[] calldata _sigs,\n address[] calldata _signers,\n uint256[] calldata _powers\n ) external;\n\n function records(bytes32 recordId) external view returns (bool);\n}\n" + }, + "lib/sgn-v2-contracts/contracts/interfaces/IPeggedTokenBridgeV2.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity >=0.8.0;\n\ninterface IPeggedTokenBridgeV2 {\n /**\n * @notice Burn pegged tokens to trigger a cross-chain withdrawal of the original tokens at a remote chain's\n * OriginalTokenVault, or mint at another remote chain\n * @param _token The pegged token address.\n * @param _amount The amount to burn.\n * @param _toChainId If zero, withdraw from original vault; otherwise, the remote chain to mint tokens.\n * @param _toAccount The account to receive tokens on the remote chain\n * @param _nonce A number to guarantee unique depositId. Can be timestamp in practice.\n */\n function burn(\n address _token,\n uint256 _amount,\n uint64 _toChainId,\n address _toAccount,\n uint64 _nonce\n ) external returns (bytes32);\n\n // same with `burn` above, use openzeppelin ERC20Burnable interface\n function burnFrom(\n address _token,\n uint256 _amount,\n uint64 _toChainId,\n address _toAccount,\n uint64 _nonce\n ) external returns (bytes32);\n\n /**\n * @notice Mint tokens triggered by deposit at a remote chain's OriginalTokenVault.\n * @param _request The serialized Mint protobuf.\n * @param _sigs The list of signatures sorted by signing addresses in ascending order. A relay must be signed-off by\n * +2/3 of the sigsVerifier's current signing power to be delivered.\n * @param _signers The sorted list of signers.\n * @param _powers The signing powers of the signers.\n */\n function mint(\n bytes calldata _request,\n bytes[] calldata _sigs,\n address[] calldata _signers,\n uint256[] calldata _powers\n ) external returns (bytes32);\n\n function records(bytes32 recordId) external view returns (bool);\n}\n" + }, + "lib/sgn-v2-contracts/contracts/message/interfaces/IMessageBus.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity >=0.8.0;\n\nimport \"../libraries/MsgDataTypes.sol\";\n\ninterface IMessageBus {\n /**\n * @notice Send a message to a contract on another chain.\n * Sender needs to make sure the uniqueness of the message Id, which is computed as\n * hash(type.MessageOnly, sender, receiver, srcChainId, srcTxHash, dstChainId, message).\n * If messages with the same Id are sent, only one of them will succeed at dst chain..\n * A fee is charged in the native gas token.\n * @param _receiver The address of the destination app contract.\n * @param _dstChainId The destination chain ID.\n * @param _message Arbitrary message bytes to be decoded by the destination app contract.\n */\n function sendMessage(\n address _receiver,\n uint256 _dstChainId,\n bytes calldata _message\n ) external payable;\n\n // same as above, except that receiver is an non-evm chain address,\n function sendMessage(\n bytes calldata _receiver,\n uint256 _dstChainId,\n bytes calldata _message\n ) external payable;\n\n /**\n * @notice Send a message associated with a token transfer to a contract on another chain.\n * If messages with the same srcTransferId are sent, only one of them will succeed at dst chain..\n * A fee is charged in the native token.\n * @param _receiver The address of the destination app contract.\n * @param _dstChainId The destination chain ID.\n * @param _srcBridge The bridge contract to send the transfer with.\n * @param _srcTransferId The transfer ID.\n * @param _dstChainId The destination chain ID.\n * @param _message Arbitrary message bytes to be decoded by the destination app contract.\n */\n function sendMessageWithTransfer(\n address _receiver,\n uint256 _dstChainId,\n address _srcBridge,\n bytes32 _srcTransferId,\n bytes calldata _message\n ) external payable;\n\n /**\n * @notice Execute a message not associated with a transfer.\n * @param _message Arbitrary message bytes originated from and encoded by the source app contract\n * @param _sigs The list of signatures sorted by signing addresses in ascending order. A relay must be signed-off by\n * +2/3 of the sigsVerifier's current signing power to be delivered.\n * @param _signers The sorted list of signers.\n * @param _powers The signing powers of the signers.\n */\n function executeMessage(\n bytes calldata _message,\n MsgDataTypes.RouteInfo calldata _route,\n bytes[] calldata _sigs,\n address[] calldata _signers,\n uint256[] calldata _powers\n ) external payable;\n\n /**\n * @notice Execute a message with a successful transfer.\n * @param _message Arbitrary message bytes originated from and encoded by the source app contract\n * @param _transfer The transfer info.\n * @param _sigs The list of signatures sorted by signing addresses in ascending order. A relay must be signed-off by\n * +2/3 of the sigsVerifier's current signing power to be delivered.\n * @param _signers The sorted list of signers.\n * @param _powers The signing powers of the signers.\n */\n function executeMessageWithTransfer(\n bytes calldata _message,\n MsgDataTypes.TransferInfo calldata _transfer,\n bytes[] calldata _sigs,\n address[] calldata _signers,\n uint256[] calldata _powers\n ) external payable;\n\n /**\n * @notice Execute a message with a refunded transfer.\n * @param _message Arbitrary message bytes originated from and encoded by the source app contract\n * @param _transfer The transfer info.\n * @param _sigs The list of signatures sorted by signing addresses in ascending order. A relay must be signed-off by\n * +2/3 of the sigsVerifier's current signing power to be delivered.\n * @param _signers The sorted list of signers.\n * @param _powers The signing powers of the signers.\n */\n function executeMessageWithTransferRefund(\n bytes calldata _message, // the same message associated with the original transfer\n MsgDataTypes.TransferInfo calldata _transfer,\n bytes[] calldata _sigs,\n address[] calldata _signers,\n uint256[] calldata _powers\n ) external payable;\n\n /**\n * @notice Withdraws message fee in the form of native gas token.\n * @param _account The address receiving the fee.\n * @param _cumulativeFee The cumulative fee credited to the account. Tracked by SGN.\n * @param _sigs The list of signatures sorted by signing addresses in ascending order. A withdrawal must be\n * signed-off by +2/3 of the sigsVerifier's current signing power to be delivered.\n * @param _signers The sorted list of signers.\n * @param _powers The signing powers of the signers.\n */\n function withdrawFee(\n address _account,\n uint256 _cumulativeFee,\n bytes[] calldata _sigs,\n address[] calldata _signers,\n uint256[] calldata _powers\n ) external;\n\n /**\n * @notice Calculates the required fee for the message.\n * @param _message Arbitrary message bytes to be decoded by the destination app contract.\n @ @return The required fee.\n */\n function calcFee(bytes calldata _message) external view returns (uint256);\n\n function liquidityBridge() external view returns (address);\n\n function pegBridge() external view returns (address);\n\n function pegBridgeV2() external view returns (address);\n\n function pegVault() external view returns (address);\n\n function pegVaultV2() external view returns (address);\n}\n" + }, + "lib/sgn-v2-contracts/contracts/message/interfaces/IMessageReceiverApp.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity >=0.8.0;\n\ninterface IMessageReceiverApp {\n enum ExecutionStatus {\n Fail, // execution failed, finalized\n Success, // execution succeeded, finalized\n Retry // execution rejected, can retry later\n }\n\n /**\n * @notice Called by MessageBus to execute a message\n * @param _sender The address of the source app contract\n * @param _srcChainId The source chain ID where the transfer is originated from\n * @param _message Arbitrary message bytes originated from and encoded by the source app contract\n * @param _executor Address who called the MessageBus execution function\n */\n function executeMessage(\n address _sender,\n uint64 _srcChainId,\n bytes calldata _message,\n address _executor\n ) external payable returns (ExecutionStatus);\n\n // same as above, except that sender is an non-evm chain address,\n // otherwise same as above.\n function executeMessage(\n bytes calldata _sender,\n uint64 _srcChainId,\n bytes calldata _message,\n address _executor\n ) external payable returns (ExecutionStatus);\n\n /**\n * @notice Called by MessageBus to execute a message with an associated token transfer.\n * The contract is guaranteed to have received the right amount of tokens before this function is called.\n * @param _sender The address of the source app contract\n * @param _token The address of the token that comes out of the bridge\n * @param _amount The amount of tokens received at this contract through the cross-chain bridge.\n * @param _srcChainId The source chain ID where the transfer is originated from\n * @param _message Arbitrary message bytes originated from and encoded by the source app contract\n * @param _executor Address who called the MessageBus execution function\n */\n function executeMessageWithTransfer(\n address _sender,\n address _token,\n uint256 _amount,\n uint64 _srcChainId,\n bytes calldata _message,\n address _executor\n ) external payable returns (ExecutionStatus);\n\n /**\n * @notice Only called by MessageBus if\n * 1. executeMessageWithTransfer reverts, or\n * 2. executeMessageWithTransfer returns ExecutionStatus.Fail\n * The contract is guaranteed to have received the right amount of tokens before this function is called.\n * @param _sender The address of the source app contract\n * @param _token The address of the token that comes out of the bridge\n * @param _amount The amount of tokens received at this contract through the cross-chain bridge.\n * @param _srcChainId The source chain ID where the transfer is originated from\n * @param _message Arbitrary message bytes originated from and encoded by the source app contract\n * @param _executor Address who called the MessageBus execution function\n */\n function executeMessageWithTransferFallback(\n address _sender,\n address _token,\n uint256 _amount,\n uint64 _srcChainId,\n bytes calldata _message,\n address _executor\n ) external payable returns (ExecutionStatus);\n\n /**\n * @notice Called by MessageBus to process refund of the original transfer from this contract.\n * The contract is guaranteed to have received the refund before this function is called.\n * @param _token The token address of the original transfer\n * @param _amount The amount of the original transfer\n * @param _message The same message associated with the original transfer\n * @param _executor Address who called the MessageBus execution function\n */\n function executeMessageWithTransferRefund(\n address _token,\n uint256 _amount,\n bytes calldata _message,\n address _executor\n ) external payable returns (ExecutionStatus);\n}\n" + }, + "lib/sgn-v2-contracts/contracts/message/libraries/MessageSenderLib.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity >=0.8.0;\n\nimport \"../../../../../lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\";\nimport \"../../../../../lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"../../interfaces/IBridge.sol\";\nimport \"../../interfaces/IOriginalTokenVault.sol\";\nimport \"../../interfaces/IOriginalTokenVaultV2.sol\";\nimport \"../../interfaces/IPeggedTokenBridge.sol\";\nimport \"../../interfaces/IPeggedTokenBridgeV2.sol\";\nimport \"../interfaces/IMessageBus.sol\";\nimport \"./MsgDataTypes.sol\";\n\nlibrary MessageSenderLib {\n using SafeERC20 for IERC20;\n\n // ============== Internal library functions called by apps ==============\n\n /**\n * @notice Sends a message to an app on another chain via MessageBus without an associated transfer.\n * @param _receiver The address of the destination app contract.\n * @param _dstChainId The destination chain ID.\n * @param _message Arbitrary message bytes to be decoded by the destination app contract.\n * @param _messageBus The address of the MessageBus on this chain.\n * @param _fee The fee amount to pay to MessageBus.\n */\n function sendMessage(\n address _receiver,\n uint64 _dstChainId,\n bytes memory _message,\n address _messageBus,\n uint256 _fee\n ) internal {\n IMessageBus(_messageBus).sendMessage{value: _fee}(_receiver, _dstChainId, _message);\n }\n\n // Send message to non-evm chain with bytes for receiver address,\n // otherwise same as above.\n function sendMessage(\n bytes calldata _receiver,\n uint64 _dstChainId,\n bytes memory _message,\n address _messageBus,\n uint256 _fee\n ) internal {\n IMessageBus(_messageBus).sendMessage{value: _fee}(_receiver, _dstChainId, _message);\n }\n\n /**\n * @notice Sends a message to an app on another chain via MessageBus with an associated transfer.\n * @param _receiver The address of the destination app contract.\n * @param _token The address of the token to be sent.\n * @param _amount The amount of tokens to be sent.\n * @param _dstChainId The destination chain ID.\n * @param _nonce A number input to guarantee uniqueness of transferId. Can be timestamp in practice.\n * @param _maxSlippage The max slippage accepted, given as percentage in point (pip). Eg. 5000 means 0.5%.\n * Must be greater than minimalMaxSlippage. Receiver is guaranteed to receive at least (100% - max slippage percentage) * amount or the\n * transfer can be refunded. Only applicable to the {MsgDataTypes.BridgeSendType.Liquidity}.\n * @param _message Arbitrary message bytes to be decoded by the destination app contract.\n * @param _bridgeSendType One of the {MsgDataTypes.BridgeSendType} enum.\n * @param _messageBus The address of the MessageBus on this chain.\n * @param _fee The fee amount to pay to MessageBus.\n * @return The transfer ID.\n */\n function sendMessageWithTransfer(\n address _receiver,\n address _token,\n uint256 _amount,\n uint64 _dstChainId,\n uint64 _nonce,\n uint32 _maxSlippage,\n bytes memory _message,\n MsgDataTypes.BridgeSendType _bridgeSendType,\n address _messageBus,\n uint256 _fee\n ) internal returns (bytes32) {\n (bytes32 transferId, address bridge) = sendTokenTransfer(\n _receiver,\n _token,\n _amount,\n _dstChainId,\n _nonce,\n _maxSlippage,\n _bridgeSendType,\n _messageBus\n );\n if (_message.length > 0) {\n IMessageBus(_messageBus).sendMessageWithTransfer{value: _fee}(\n _receiver,\n _dstChainId,\n bridge,\n transferId,\n _message\n );\n }\n return transferId;\n }\n\n /**\n * @notice Sends a token transfer via a bridge.\n * @param _receiver The address of the destination app contract.\n * @param _token The address of the token to be sent.\n * @param _amount The amount of tokens to be sent.\n * @param _dstChainId The destination chain ID.\n * @param _nonce A number input to guarantee uniqueness of transferId. Can be timestamp in practice.\n * @param _maxSlippage The max slippage accepted, given as percentage in point (pip). Eg. 5000 means 0.5%.\n * Must be greater than minimalMaxSlippage. Receiver is guaranteed to receive at least (100% - max slippage percentage) * amount or the\n * transfer can be refunded.\n * @param _bridgeSendType One of the {MsgDataTypes.BridgeSendType} enum.\n */\n function sendTokenTransfer(\n address _receiver,\n address _token,\n uint256 _amount,\n uint64 _dstChainId,\n uint64 _nonce,\n uint32 _maxSlippage,\n MsgDataTypes.BridgeSendType _bridgeSendType,\n address _messageBus\n ) internal returns (bytes32 transferId, address bridge) {\n if (_bridgeSendType == MsgDataTypes.BridgeSendType.Liquidity) {\n bridge = IMessageBus(_messageBus).liquidityBridge();\n IERC20(_token).safeIncreaseAllowance(bridge, _amount);\n IBridge(bridge).send(_receiver, _token, _amount, _dstChainId, _nonce, _maxSlippage);\n transferId = computeLiqBridgeTransferId(_receiver, _token, _amount, _dstChainId, _nonce);\n } else if (_bridgeSendType == MsgDataTypes.BridgeSendType.PegDeposit) {\n bridge = IMessageBus(_messageBus).pegVault();\n IERC20(_token).safeIncreaseAllowance(bridge, _amount);\n IOriginalTokenVault(bridge).deposit(_token, _amount, _dstChainId, _receiver, _nonce);\n transferId = computePegV1DepositId(_receiver, _token, _amount, _dstChainId, _nonce);\n } else if (_bridgeSendType == MsgDataTypes.BridgeSendType.PegBurn) {\n bridge = IMessageBus(_messageBus).pegBridge();\n IERC20(_token).safeIncreaseAllowance(bridge, _amount);\n IPeggedTokenBridge(bridge).burn(_token, _amount, _receiver, _nonce);\n // handle cases where certain tokens do not spend allowance for role-based burn\n IERC20(_token).safeApprove(bridge, 0);\n transferId = computePegV1BurnId(_receiver, _token, _amount, _nonce);\n } else if (_bridgeSendType == MsgDataTypes.BridgeSendType.PegV2Deposit) {\n bridge = IMessageBus(_messageBus).pegVaultV2();\n IERC20(_token).safeIncreaseAllowance(bridge, _amount);\n transferId = IOriginalTokenVaultV2(bridge).deposit(_token, _amount, _dstChainId, _receiver, _nonce);\n } else if (_bridgeSendType == MsgDataTypes.BridgeSendType.PegV2Burn) {\n bridge = IMessageBus(_messageBus).pegBridgeV2();\n IERC20(_token).safeIncreaseAllowance(bridge, _amount);\n transferId = IPeggedTokenBridgeV2(bridge).burn(_token, _amount, _dstChainId, _receiver, _nonce);\n // handle cases where certain tokens do not spend allowance for role-based burn\n IERC20(_token).safeApprove(bridge, 0);\n } else if (_bridgeSendType == MsgDataTypes.BridgeSendType.PegV2BurnFrom) {\n bridge = IMessageBus(_messageBus).pegBridgeV2();\n IERC20(_token).safeIncreaseAllowance(bridge, _amount);\n transferId = IPeggedTokenBridgeV2(bridge).burnFrom(_token, _amount, _dstChainId, _receiver, _nonce);\n // handle cases where certain tokens do not spend allowance for role-based burn\n IERC20(_token).safeApprove(bridge, 0);\n } else {\n revert(\"bridge type not supported\");\n }\n }\n\n function computeLiqBridgeTransferId(\n address _receiver,\n address _token,\n uint256 _amount,\n uint64 _dstChainId,\n uint64 _nonce\n ) internal view returns (bytes32) {\n return\n keccak256(\n abi.encodePacked(address(this), _receiver, _token, _amount, _dstChainId, _nonce, uint64(block.chainid))\n );\n }\n\n function computePegV1DepositId(\n address _receiver,\n address _token,\n uint256 _amount,\n uint64 _dstChainId,\n uint64 _nonce\n ) internal view returns (bytes32) {\n return\n keccak256(\n abi.encodePacked(address(this), _token, _amount, _dstChainId, _receiver, _nonce, uint64(block.chainid))\n );\n }\n\n function computePegV1BurnId(\n address _receiver,\n address _token,\n uint256 _amount,\n uint64 _nonce\n ) internal view returns (bytes32) {\n return keccak256(abi.encodePacked(address(this), _token, _amount, _receiver, _nonce, uint64(block.chainid)));\n }\n}\n" + }, + "lib/sgn-v2-contracts/contracts/message/libraries/MsgDataTypes.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity >=0.8.0;\n\nlibrary MsgDataTypes {\n string constant ABORT_PREFIX = \"MSG::ABORT:\";\n\n // bridge operation type at the sender side (src chain)\n enum BridgeSendType {\n Null,\n Liquidity,\n PegDeposit,\n PegBurn,\n PegV2Deposit,\n PegV2Burn,\n PegV2BurnFrom\n }\n\n // bridge operation type at the receiver side (dst chain)\n enum TransferType {\n Null,\n LqRelay, // relay through liquidity bridge\n LqWithdraw, // withdraw from liquidity bridge\n PegMint, // mint through pegged token bridge\n PegWithdraw, // withdraw from original token vault\n PegV2Mint, // mint through pegged token bridge v2\n PegV2Withdraw // withdraw from original token vault v2\n }\n\n enum MsgType {\n MessageWithTransfer,\n MessageOnly\n }\n\n enum TxStatus {\n Null,\n Success,\n Fail,\n Fallback,\n Pending // transient state within a transaction\n }\n\n struct TransferInfo {\n TransferType t;\n address sender;\n address receiver;\n address token;\n uint256 amount;\n uint64 wdseq; // only needed for LqWithdraw (refund)\n uint64 srcChainId;\n bytes32 refId;\n bytes32 srcTxHash; // src chain msg tx hash\n }\n\n struct RouteInfo {\n address sender;\n address receiver;\n uint64 srcChainId;\n bytes32 srcTxHash; // src chain msg tx hash\n }\n\n // used for msg from non-evm chains with longer-bytes address\n struct RouteInfo2 {\n bytes sender;\n address receiver;\n uint64 srcChainId;\n bytes32 srcTxHash;\n }\n\n // combination of RouteInfo and RouteInfo2 for easier processing\n struct Route {\n address sender; // from RouteInfo\n bytes senderBytes; // from RouteInfo2\n address receiver;\n uint64 srcChainId;\n bytes32 srcTxHash;\n }\n\n struct MsgWithTransferExecutionParams {\n bytes message;\n TransferInfo transfer;\n bytes[] sigs;\n address[] signers;\n uint256[] powers;\n }\n\n struct BridgeTransferParams {\n bytes request;\n bytes[] sigs;\n address[] signers;\n uint256[] powers;\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" + }, + "lib/solmate/src/tokens/WETH.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\nimport {ERC20} from \"./ERC20.sol\";\n\nimport {SafeTransferLib} from \"../utils/SafeTransferLib.sol\";\n\n/// @notice Minimalist and modern Wrapped Ether implementation.\n/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/WETH.sol)\n/// @author Inspired by WETH9 (https://github.com/dapphub/ds-weth/blob/master/src/weth9.sol)\ncontract WETH is ERC20(\"Wrapped Ether\", \"WETH\", 18) {\n using SafeTransferLib for address;\n\n event Deposit(address indexed from, uint256 amount);\n\n event Withdrawal(address indexed to, uint256 amount);\n\n function deposit() public payable virtual {\n _mint(msg.sender, msg.value);\n\n emit Deposit(msg.sender, msg.value);\n }\n\n function withdraw(uint256 amount) public virtual {\n _burn(msg.sender, amount);\n\n emit Withdrawal(msg.sender, amount);\n\n msg.sender.safeTransferETH(amount);\n }\n\n receive() external payable virtual {\n deposit();\n }\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/Errors/GenericErrors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nerror AlreadyInitialized();\nerror CannotAuthoriseSelf();\nerror CannotBridgeToSameNetwork();\nerror ContractCallNotAllowed();\nerror CumulativeSlippageTooHigh(uint256 minAmount, uint256 receivedAmount);\nerror ExternalCallFailed();\nerror InformationMismatch();\nerror InsufficientBalance(uint256 required, uint256 balance);\nerror InvalidAmount();\nerror InvalidCallData();\nerror InvalidConfig();\nerror InvalidContract();\nerror InvalidDestinationChain();\nerror InvalidFallbackAddress();\nerror InvalidReceiver();\nerror InvalidSendingToken();\nerror NativeAssetNotSupported();\nerror NativeAssetTransferFailed();\nerror NoSwapDataProvided();\nerror NoSwapFromZeroBalance();\nerror NotAContract();\nerror NotInitialized();\nerror NoTransferToNullAddress();\nerror NullAddrIsNotAnERC20Token();\nerror NullAddrIsNotAValidSpender();\nerror OnlyContractOwner();\nerror RecoveryAddressCannotBeZero();\nerror ReentrancyError();\nerror TokenNotSupported();\nerror UnAuthorized();\nerror UnsupportedChainId(uint256 chainId);\nerror WithdrawFailed();\nerror ZeroAmount();\n" + }, + "src/Facets/AccessManagerFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { LibDiamond } from \"../Libraries/LibDiamond.sol\";\nimport { LibAccess } from \"../Libraries/LibAccess.sol\";\nimport { CannotAuthoriseSelf } from \"../Errors/GenericErrors.sol\";\n\n/// @title Access Manager Facet\n/// @author LI.FI (https://li.fi)\n/// @notice Provides functionality for managing method level access control\n/// @custom:version 1.0.0\ncontract AccessManagerFacet {\n /// Events ///\n\n event ExecutionAllowed(address indexed account, bytes4 indexed method);\n event ExecutionDenied(address indexed account, bytes4 indexed method);\n\n /// External Methods ///\n\n /// @notice Sets whether a specific address can call a method\n /// @param _selector The method selector to set access for\n /// @param _executor The address to set method access for\n /// @param _canExecute Whether or not the address can execute the specified method\n function setCanExecute(\n bytes4 _selector,\n address _executor,\n bool _canExecute\n ) external {\n if (_executor == address(this)) {\n revert CannotAuthoriseSelf();\n }\n LibDiamond.enforceIsContractOwner();\n _canExecute\n ? LibAccess.addAccess(_selector, _executor)\n : LibAccess.removeAccess(_selector, _executor);\n if (_canExecute) {\n emit ExecutionAllowed(_executor, _selector);\n } else {\n emit ExecutionDenied(_executor, _selector);\n }\n }\n\n /// @notice Check if a method can be executed by a specific address\n /// @param _selector The method selector to check\n /// @param _executor The address to check\n function addressCanExecuteMethod(\n bytes4 _selector,\n address _executor\n ) external view returns (bool) {\n return LibAccess.accessStorage().execAccess[_selector][_executor];\n }\n}\n" + }, + "src/Facets/AcrossFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport \"../../lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\";\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { IAcrossSpokePool } from \"../Interfaces/IAcrossSpokePool.sol\";\nimport { LibAsset } from \"../Libraries/LibAsset.sol\";\nimport { LibSwap } from \"../Libraries/LibSwap.sol\";\nimport { ReentrancyGuard } from \"../Helpers/ReentrancyGuard.sol\";\nimport { SwapperV2 } from \"../Helpers/SwapperV2.sol\";\nimport { Validatable } from \"../Helpers/Validatable.sol\";\n\n/// @title Across Facet\n/// @author LI.FI (https://li.fi)\n/// @notice Provides functionality for bridging through Across Protocol\n/// @custom:version 2.0.0\ncontract AcrossFacet is ILiFi, ReentrancyGuard, SwapperV2, Validatable {\n /// Storage ///\n\n /// @notice The contract address of the spoke pool on the source chain.\n IAcrossSpokePool private immutable spokePool;\n\n /// @notice The WETH address on the current chain.\n address private immutable wrappedNative;\n\n /// Types ///\n\n /// @param relayerFeePct The relayer fee in token percentage with 18 decimals.\n /// @param quoteTimestamp The timestamp associated with the suggested fee.\n /// @param message Arbitrary data that can be used to pass additional information to the recipient along with the tokens.\n /// @param maxCount Used to protect the depositor from frontrunning to guarantee their quote remains valid.\n struct AcrossData {\n int64 relayerFeePct;\n uint32 quoteTimestamp;\n bytes message;\n uint256 maxCount;\n }\n\n /// Constructor ///\n\n /// @notice Initialize the contract.\n /// @param _spokePool The contract address of the spoke pool on the source chain.\n /// @param _wrappedNative The address of the wrapped native token on the source chain.\n constructor(IAcrossSpokePool _spokePool, address _wrappedNative) {\n spokePool = _spokePool;\n wrappedNative = _wrappedNative;\n }\n\n /// External Methods ///\n\n /// @notice Bridges tokens via Across\n /// @param _bridgeData the core information needed for bridging\n /// @param _acrossData data specific to Across\n function startBridgeTokensViaAcross(\n ILiFi.BridgeData memory _bridgeData,\n AcrossData calldata _acrossData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n validateBridgeData(_bridgeData)\n doesNotContainSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n {\n LibAsset.depositAsset(\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount\n );\n _startBridge(_bridgeData, _acrossData);\n }\n\n /// @notice Performs a swap before bridging via Across\n /// @param _bridgeData the core information needed for bridging\n /// @param _swapData an array of swap related data for performing swaps before bridging\n /// @param _acrossData data specific to Across\n function swapAndStartBridgeTokensViaAcross(\n ILiFi.BridgeData memory _bridgeData,\n LibSwap.SwapData[] calldata _swapData,\n AcrossData calldata _acrossData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n containsSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n _bridgeData.minAmount = _depositAndSwap(\n _bridgeData.transactionId,\n _bridgeData.minAmount,\n _swapData,\n payable(msg.sender)\n );\n _startBridge(_bridgeData, _acrossData);\n }\n\n /// Internal Methods ///\n\n /// @dev Contains the business logic for the bridge via Across\n /// @param _bridgeData the core information needed for bridging\n /// @param _acrossData data specific to Across\n function _startBridge(\n ILiFi.BridgeData memory _bridgeData,\n AcrossData calldata _acrossData\n ) internal {\n if (LibAsset.isNativeAsset(_bridgeData.sendingAssetId)) {\n spokePool.deposit{ value: _bridgeData.minAmount }(\n _bridgeData.receiver,\n wrappedNative,\n _bridgeData.minAmount,\n _bridgeData.destinationChainId,\n _acrossData.relayerFeePct,\n _acrossData.quoteTimestamp,\n _acrossData.message,\n _acrossData.maxCount\n );\n } else {\n LibAsset.maxApproveERC20(\n IERC20(_bridgeData.sendingAssetId),\n address(spokePool),\n _bridgeData.minAmount\n );\n spokePool.deposit(\n _bridgeData.receiver,\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount,\n _bridgeData.destinationChainId,\n _acrossData.relayerFeePct,\n _acrossData.quoteTimestamp,\n _acrossData.message,\n _acrossData.maxCount\n );\n }\n\n emit LiFiTransferStarted(_bridgeData);\n }\n}\n" + }, + "src/Facets/AllBridgeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { IAllBridge } from \"../Interfaces/IAllBridge.sol\";\nimport { LibAsset, IERC20 } from \"../Libraries/LibAsset.sol\";\nimport { SwapperV2 } from \"../Helpers/SwapperV2.sol\";\nimport { ReentrancyGuard } from \"../Helpers/ReentrancyGuard.sol\";\nimport { Validatable } from \"../Helpers/Validatable.sol\";\nimport { LibSwap } from \"../Libraries/LibSwap.sol\";\n\n/// @title Allbridge Facet\n/// @author Li.Finance (https://li.finance)\n/// @notice Provides functionality for bridging through AllBridge\n/// @custom:version 2.0.0\ncontract AllBridgeFacet is ILiFi, ReentrancyGuard, SwapperV2, Validatable {\n /// @notice The contract address of the AllBridge router on the source chain.\n IAllBridge private immutable allBridge;\n\n /// @notice The struct for the AllBridge data.\n /// @param fees The amount of token to pay the messenger and the bridge\n /// @param recipient The address of the token receiver after bridging.\n /// @param destinationChainId The destination chain id.\n /// @param receiveToken The token to receive on the destination chain.\n /// @param nonce A random nonce to associate with the tx.\n /// @param messenger The messenger protocol enum\n /// @param payFeeWithSendingAsset Whether to pay the relayer fee with the sending asset or not\n struct AllBridgeData {\n uint256 fees;\n bytes32 recipient;\n uint256 destinationChainId;\n bytes32 receiveToken;\n uint256 nonce;\n IAllBridge.MessengerProtocol messenger;\n bool payFeeWithSendingAsset;\n }\n\n /// @notice Initializes the AllBridge contract\n /// @param _allBridge The address of the AllBridge contract\n constructor(IAllBridge _allBridge) {\n allBridge = _allBridge;\n }\n\n /// @notice Bridge tokens to another chain via AllBridge\n /// @param _bridgeData The bridge data struct\n function startBridgeTokensViaAllBridge(\n ILiFi.BridgeData memory _bridgeData,\n AllBridgeData calldata _allBridgeData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n validateBridgeData(_bridgeData)\n doesNotContainSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n {\n LibAsset.depositAsset(\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount\n );\n _startBridge(_bridgeData, _allBridgeData);\n }\n\n /// @notice Bridge tokens to another chain via AllBridge\n /// @param _bridgeData The bridge data struct\n /// @param _swapData The swap data struct\n /// @param _allBridgeData The AllBridge data struct\n function swapAndStartBridgeTokensViaAllBridge(\n ILiFi.BridgeData memory _bridgeData,\n LibSwap.SwapData[] calldata _swapData,\n AllBridgeData calldata _allBridgeData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n containsSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n _bridgeData.minAmount = _depositAndSwap(\n _bridgeData.transactionId,\n _bridgeData.minAmount,\n _swapData,\n payable(msg.sender)\n );\n _startBridge(_bridgeData, _allBridgeData);\n }\n\n /// @notice Bridge tokens to another chain via AllBridge\n /// @param _bridgeData The bridge data struct\n /// @param _allBridgeData The allBridge data struct for AllBridge specicific data\n function _startBridge(\n ILiFi.BridgeData memory _bridgeData,\n AllBridgeData calldata _allBridgeData\n ) internal {\n LibAsset.maxApproveERC20(\n IERC20(_bridgeData.sendingAssetId),\n address(allBridge),\n _bridgeData.minAmount\n );\n\n if (_allBridgeData.payFeeWithSendingAsset) {\n allBridge.swapAndBridge(\n bytes32(uint256(uint160(_bridgeData.sendingAssetId))),\n _bridgeData.minAmount,\n _allBridgeData.recipient,\n _allBridgeData.destinationChainId,\n _allBridgeData.receiveToken,\n _allBridgeData.nonce,\n _allBridgeData.messenger,\n _allBridgeData.fees\n );\n } else {\n allBridge.swapAndBridge{ value: _allBridgeData.fees }(\n bytes32(uint256(uint160(_bridgeData.sendingAssetId))),\n _bridgeData.minAmount,\n _allBridgeData.recipient,\n _allBridgeData.destinationChainId,\n _allBridgeData.receiveToken,\n _allBridgeData.nonce,\n _allBridgeData.messenger,\n 0\n );\n }\n\n emit LiFiTransferStarted(_bridgeData);\n }\n}\n" + }, + "src/Facets/AmarokFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { IConnextHandler } from \"../Interfaces/IConnextHandler.sol\";\nimport { LibAsset, IERC20 } from \"../Libraries/LibAsset.sol\";\nimport { ReentrancyGuard } from \"../Helpers/ReentrancyGuard.sol\";\nimport { InformationMismatch } from \"../Errors/GenericErrors.sol\";\nimport { SwapperV2, LibSwap } from \"../Helpers/SwapperV2.sol\";\nimport { Validatable } from \"../Helpers/Validatable.sol\";\n\n/// @title Amarok Facet\n/// @author LI.FI (https://li.fi)\n/// @notice Provides functionality for bridging through Connext Amarok\n/// @custom:version 2.0.0\ncontract AmarokFacet is ILiFi, ReentrancyGuard, SwapperV2, Validatable {\n /// Storage ///\n\n /// @notice The contract address of the connext handler on the source chain.\n IConnextHandler private immutable connextHandler;\n\n /// @param callData The data to execute on the receiving chain. If no crosschain call is needed, then leave empty.\n /// @param callTo The address of the contract on dest chain that will receive bridged funds and execute data\n /// @param relayerFee The amount of relayer fee the tx called xcall with\n /// @param slippageTol Max bps of original due to slippage (i.e. would be 9995 to tolerate .05% slippage)\n /// @param delegate Destination delegate address\n /// @param destChainDomainId The Amarok-specific domainId of the destination chain\n /// @param payFeeWithSendingAsset Whether to pay the relayer fee with the sending asset or not\n struct AmarokData {\n bytes callData;\n address callTo;\n uint256 relayerFee;\n uint256 slippageTol;\n address delegate;\n uint32 destChainDomainId;\n bool payFeeWithSendingAsset;\n }\n\n /// Constructor ///\n\n /// @notice Initialize the contract.\n /// @param _connextHandler The contract address of the connext handler on the source chain.\n constructor(IConnextHandler _connextHandler) {\n connextHandler = _connextHandler;\n }\n\n /// External Methods ///\n\n /// @notice Bridges tokens via Amarok\n /// @param _bridgeData Data containing core information for bridging\n /// @param _amarokData Data specific to bridge\n function startBridgeTokensViaAmarok(\n BridgeData calldata _bridgeData,\n AmarokData calldata _amarokData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n doesNotContainSourceSwaps(_bridgeData)\n validateBridgeData(_bridgeData)\n noNativeAsset(_bridgeData)\n {\n validateDestinationCallFlag(_bridgeData, _amarokData);\n\n LibAsset.depositAsset(\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount\n );\n\n _startBridge(_bridgeData, _amarokData);\n }\n\n /// @notice Performs a swap before bridging via Amarok\n /// @param _bridgeData The core information needed for bridging\n /// @param _swapData An array of swap related data for performing swaps before bridging\n /// @param _amarokData Data specific to Amarok\n function swapAndStartBridgeTokensViaAmarok(\n BridgeData memory _bridgeData,\n LibSwap.SwapData[] calldata _swapData,\n AmarokData calldata _amarokData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n containsSourceSwaps(_bridgeData)\n validateBridgeData(_bridgeData)\n noNativeAsset(_bridgeData)\n {\n validateDestinationCallFlag(_bridgeData, _amarokData);\n\n _bridgeData.minAmount = _depositAndSwap(\n _bridgeData.transactionId,\n _bridgeData.minAmount,\n _swapData,\n payable(msg.sender),\n _amarokData.relayerFee\n );\n\n _startBridge(_bridgeData, _amarokData);\n }\n\n /// Private Methods ///\n\n /// @dev Contains the business logic for the bridge via Amarok\n /// @param _bridgeData The core information needed for bridging\n /// @param _amarokData Data specific to Amarok\n function _startBridge(\n BridgeData memory _bridgeData,\n AmarokData calldata _amarokData\n ) private {\n // give max approval for token to Amarok bridge, if not already\n LibAsset.maxApproveERC20(\n IERC20(_bridgeData.sendingAssetId),\n address(connextHandler),\n _bridgeData.minAmount\n );\n\n // initiate bridge transaction\n if (_amarokData.payFeeWithSendingAsset) {\n connextHandler.xcall(\n _amarokData.destChainDomainId,\n _amarokData.callTo,\n _bridgeData.sendingAssetId,\n _amarokData.delegate,\n _bridgeData.minAmount - _amarokData.relayerFee,\n _amarokData.slippageTol,\n _amarokData.callData,\n _amarokData.relayerFee\n );\n } else {\n connextHandler.xcall{ value: _amarokData.relayerFee }(\n _amarokData.destChainDomainId,\n _amarokData.callTo,\n _bridgeData.sendingAssetId,\n _amarokData.delegate,\n _bridgeData.minAmount,\n _amarokData.slippageTol,\n _amarokData.callData\n );\n }\n\n emit LiFiTransferStarted(_bridgeData);\n }\n\n function validateDestinationCallFlag(\n ILiFi.BridgeData memory _bridgeData,\n AmarokData calldata _amarokData\n ) private pure {\n if (\n (_amarokData.callData.length > 0) != _bridgeData.hasDestinationCall\n ) {\n revert InformationMismatch();\n }\n }\n}\n" + }, + "src/Facets/ArbitrumBridgeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { IGatewayRouter } from \"../Interfaces/IGatewayRouter.sol\";\nimport { LibAsset, IERC20 } from \"../Libraries/LibAsset.sol\";\nimport { ReentrancyGuard } from \"../Helpers/ReentrancyGuard.sol\";\nimport { InvalidAmount } from \"../Errors/GenericErrors.sol\";\nimport { SwapperV2, LibSwap } from \"../Helpers/SwapperV2.sol\";\nimport { Validatable } from \"../Helpers/Validatable.sol\";\n\n/// @title Arbitrum Bridge Facet\n/// @author Li.Finance (https://li.finance)\n/// @notice Provides functionality for bridging through Arbitrum Bridge\n/// @custom:version 1.0.0\ncontract ArbitrumBridgeFacet is\n ILiFi,\n ReentrancyGuard,\n SwapperV2,\n Validatable\n{\n /// Storage ///\n\n /// @notice The contract address of the gateway router on the source chain.\n IGatewayRouter private immutable gatewayRouter;\n\n /// @notice The contract address of the inbox on the source chain.\n IGatewayRouter private immutable inbox;\n\n /// Types ///\n\n /// @param maxSubmissionCost Max gas deducted from user's L2 balance to cover base submission fee.\n /// @param maxGas Max gas deducted from user's L2 balance to cover L2 execution.\n /// @param maxGasPrice price bid for L2 execution.\n struct ArbitrumData {\n uint256 maxSubmissionCost;\n uint256 maxGas;\n uint256 maxGasPrice;\n }\n\n /// Constructor ///\n\n /// @notice Initialize the contract.\n /// @param _gatewayRouter The contract address of the gateway router on the source chain.\n /// @param _inbox The contract address of the inbox on the source chain.\n constructor(IGatewayRouter _gatewayRouter, IGatewayRouter _inbox) {\n gatewayRouter = _gatewayRouter;\n inbox = _inbox;\n }\n\n /// External Methods ///\n\n /// @notice Bridges tokens via Arbitrum Bridge\n /// @param _bridgeData Data containing core information for bridging\n /// @param _arbitrumData Data for gateway router address, asset id and amount\n function startBridgeTokensViaArbitrumBridge(\n ILiFi.BridgeData memory _bridgeData,\n ArbitrumData calldata _arbitrumData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n doesNotContainSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n uint256 cost = _arbitrumData.maxSubmissionCost +\n _arbitrumData.maxGas *\n _arbitrumData.maxGasPrice;\n\n LibAsset.depositAsset(\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount\n );\n\n _startBridge(_bridgeData, _arbitrumData, cost);\n }\n\n /// @notice Performs a swap before bridging via Arbitrum Bridge\n /// @param _bridgeData Data containing core information for bridging\n /// @param _swapData An array of swap related data for performing swaps before bridging\n /// @param _arbitrumData Data for gateway router address, asset id and amount\n function swapAndStartBridgeTokensViaArbitrumBridge(\n ILiFi.BridgeData memory _bridgeData,\n LibSwap.SwapData[] calldata _swapData,\n ArbitrumData calldata _arbitrumData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n containsSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n uint256 cost = _arbitrumData.maxSubmissionCost +\n _arbitrumData.maxGas *\n _arbitrumData.maxGasPrice;\n\n _bridgeData.minAmount = _depositAndSwap(\n _bridgeData.transactionId,\n _bridgeData.minAmount,\n _swapData,\n payable(msg.sender),\n cost\n );\n\n _startBridge(_bridgeData, _arbitrumData, cost);\n }\n\n /// Private Methods ///\n\n /// @dev Contains the business logic for the bridge via Arbitrum Bridge\n /// @param _bridgeData Data containing core information for bridging\n /// @param _arbitrumData Data for gateway router address, asset id and amount\n /// @param _cost Additional amount of native asset for the fee\n function _startBridge(\n ILiFi.BridgeData memory _bridgeData,\n ArbitrumData calldata _arbitrumData,\n uint256 _cost\n ) private {\n if (LibAsset.isNativeAsset(_bridgeData.sendingAssetId)) {\n inbox.unsafeCreateRetryableTicket{\n value: _bridgeData.minAmount + _cost\n }(\n _bridgeData.receiver,\n _bridgeData.minAmount, // l2CallValue\n _arbitrumData.maxSubmissionCost,\n _bridgeData.receiver, // excessFeeRefundAddress\n _bridgeData.receiver, // callValueRefundAddress\n _arbitrumData.maxGas,\n _arbitrumData.maxGasPrice,\n \"\"\n );\n } else {\n LibAsset.maxApproveERC20(\n IERC20(_bridgeData.sendingAssetId),\n gatewayRouter.getGateway(_bridgeData.sendingAssetId),\n _bridgeData.minAmount\n );\n gatewayRouter.outboundTransfer{ value: _cost }(\n _bridgeData.sendingAssetId,\n _bridgeData.receiver,\n _bridgeData.minAmount,\n _arbitrumData.maxGas,\n _arbitrumData.maxGasPrice,\n abi.encode(_arbitrumData.maxSubmissionCost, \"\")\n );\n }\n\n emit LiFiTransferStarted(_bridgeData);\n }\n}\n" + }, + "src/Facets/CalldataVerificationFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { LibSwap } from \"../Libraries/LibSwap.sol\";\nimport { AmarokFacet } from \"./AmarokFacet.sol\";\nimport { StargateFacet } from \"./StargateFacet.sol\";\nimport { CelerIMFacetBase, CelerIM } from \"../../src/Helpers/CelerIMFacetBase.sol\";\nimport { StandardizedCallFacet } from \"../../src/Facets/StandardizedCallFacet.sol\";\nimport { LibBytes } from \"../Libraries/LibBytes.sol\";\n\n/// @title Calldata Verification Facet\n/// @author LI.FI (https://li.fi)\n/// @notice Provides functionality for verifying calldata\n/// @custom:version 1.1.0\ncontract CalldataVerificationFacet {\n using LibBytes for bytes;\n\n /// @notice Extracts the bridge data from the calldata\n /// @param data The calldata to extract the bridge data from\n /// @return bridgeData The bridge data extracted from the calldata\n function extractBridgeData(\n bytes calldata data\n ) external pure returns (ILiFi.BridgeData memory bridgeData) {\n bridgeData = _extractBridgeData(data);\n }\n\n /// @notice Extracts the swap data from the calldata\n /// @param data The calldata to extract the swap data from\n /// @return swapData The swap data extracted from the calldata\n function extractSwapData(\n bytes calldata data\n ) external pure returns (LibSwap.SwapData[] memory swapData) {\n swapData = _extractSwapData(data);\n }\n\n /// @notice Extracts the bridge data and swap data from the calldata\n /// @param data The calldata to extract the bridge data and swap data from\n /// @return bridgeData The bridge data extracted from the calldata\n /// @return swapData The swap data extracted from the calldata\n function extractData(\n bytes calldata data\n )\n external\n pure\n returns (\n ILiFi.BridgeData memory bridgeData,\n LibSwap.SwapData[] memory swapData\n )\n {\n bridgeData = _extractBridgeData(data);\n if (bridgeData.hasSourceSwaps) {\n swapData = _extractSwapData(data);\n }\n }\n\n /// @notice Extracts the main parameters from the calldata\n /// @param data The calldata to extract the main parameters from\n /// @return bridge The bridge extracted from the calldata\n /// @return sendingAssetId The sending asset id extracted from the calldata\n /// @return receiver The receiver extracted from the calldata\n /// @return amount The min amountfrom the calldata\n /// @return destinationChainId The destination chain id extracted from the calldata\n /// @return hasSourceSwaps Whether the calldata has source swaps\n /// @return hasDestinationCall Whether the calldata has a destination call\n function extractMainParameters(\n bytes calldata data\n )\n public\n pure\n returns (\n string memory bridge,\n address sendingAssetId,\n address receiver,\n uint256 amount,\n uint256 destinationChainId,\n bool hasSourceSwaps,\n bool hasDestinationCall\n )\n {\n ILiFi.BridgeData memory bridgeData = _extractBridgeData(data);\n\n if (bridgeData.hasSourceSwaps) {\n LibSwap.SwapData[] memory swapData = _extractSwapData(data);\n sendingAssetId = swapData[0].sendingAssetId;\n amount = swapData[0].fromAmount;\n } else {\n sendingAssetId = bridgeData.sendingAssetId;\n amount = bridgeData.minAmount;\n }\n\n return (\n bridgeData.bridge,\n sendingAssetId,\n bridgeData.receiver,\n amount,\n bridgeData.destinationChainId,\n bridgeData.hasSourceSwaps,\n bridgeData.hasDestinationCall\n );\n }\n\n /// @notice Extracts the generic swap parameters from the calldata\n /// @param data The calldata to extract the generic swap parameters from\n /// @return sendingAssetId The sending asset id extracted from the calldata\n /// @return amount The amount extracted from the calldata\n /// @return receiver The receiver extracted from the calldata\n /// @return receivingAssetId The receiving asset id extracted from the calldata\n /// @return receivingAmount The receiving amount extracted from the calldata\n function extractGenericSwapParameters(\n bytes calldata data\n )\n public\n pure\n returns (\n address sendingAssetId,\n uint256 amount,\n address receiver,\n address receivingAssetId,\n uint256 receivingAmount\n )\n {\n LibSwap.SwapData[] memory swapData;\n bytes memory callData = data;\n\n if (\n abi.decode(data, (bytes4)) ==\n StandardizedCallFacet.standardizedCall.selector\n ) {\n // standardizedCall\n callData = abi.decode(data[4:], (bytes));\n }\n (, , , receiver, receivingAmount, swapData) = abi.decode(\n callData.slice(4, callData.length - 4),\n (bytes32, string, string, address, uint256, LibSwap.SwapData[])\n );\n\n sendingAssetId = swapData[0].sendingAssetId;\n amount = swapData[0].fromAmount;\n receivingAssetId = swapData[swapData.length - 1].receivingAssetId;\n return (\n sendingAssetId,\n amount,\n receiver,\n receivingAssetId,\n receivingAmount\n );\n }\n\n /// @notice Validates the calldata\n /// @param data The calldata to validate\n /// @param bridge The bridge to validate or empty string to ignore\n /// @param sendingAssetId The sending asset id to validate\n /// or 0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF to ignore\n /// @param receiver The receiver to validate\n /// or 0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF to ignore\n /// @param amount The amount to validate or type(uint256).max to ignore\n /// @param destinationChainId The destination chain id to validate\n /// or type(uint256).max to ignore\n /// @param hasSourceSwaps Whether the calldata has source swaps\n /// @param hasDestinationCall Whether the calldata has a destination call\n /// @return isValid Whether the calldata is validate\n function validateCalldata(\n bytes calldata data,\n string calldata bridge,\n address sendingAssetId,\n address receiver,\n uint256 amount,\n uint256 destinationChainId,\n bool hasSourceSwaps,\n bool hasDestinationCall\n ) external pure returns (bool isValid) {\n ILiFi.BridgeData memory bridgeData;\n (\n bridgeData.bridge,\n bridgeData.sendingAssetId,\n bridgeData.receiver,\n bridgeData.minAmount,\n bridgeData.destinationChainId,\n bridgeData.hasSourceSwaps,\n bridgeData.hasDestinationCall\n ) = extractMainParameters(data);\n return\n // Check bridge\n (keccak256(abi.encodePacked(bridge)) ==\n keccak256(abi.encodePacked(\"\")) ||\n keccak256(abi.encodePacked(bridgeData.bridge)) ==\n keccak256(abi.encodePacked(bridge))) &&\n // Check sendingAssetId\n (sendingAssetId == 0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF ||\n bridgeData.sendingAssetId == sendingAssetId) &&\n // Check receiver\n (receiver == 0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF ||\n bridgeData.receiver == receiver) &&\n // Check amount\n (amount == type(uint256).max || bridgeData.minAmount == amount) &&\n // Check destinationChainId\n (destinationChainId == type(uint256).max ||\n bridgeData.destinationChainId == destinationChainId) &&\n // Check hasSourceSwaps\n bridgeData.hasSourceSwaps == hasSourceSwaps &&\n // Check hasDestinationCall\n bridgeData.hasDestinationCall == hasDestinationCall;\n }\n\n /// @notice Validates the destination calldata\n /// @param data The calldata to validate\n /// @param callTo The call to address to validate\n /// @param dstCalldata The destination calldata to validate\n /// @return isValid Whether the destination calldata is validate\n function validateDestinationCalldata(\n bytes calldata data,\n bytes calldata callTo,\n bytes calldata dstCalldata\n ) external pure returns (bool isValid) {\n bytes memory callData = data;\n\n // Handle standardizedCall\n if (\n abi.decode(data, (bytes4)) ==\n StandardizedCallFacet.standardizedCall.selector\n ) {\n callData = abi.decode(data[4:], (bytes));\n }\n\n bytes4 selector = abi.decode(callData, (bytes4));\n\n // Case: Amarok\n if (selector == AmarokFacet.startBridgeTokensViaAmarok.selector) {\n (, AmarokFacet.AmarokData memory amarokData) = abi.decode(\n callData.slice(4, callData.length - 4),\n (ILiFi.BridgeData, AmarokFacet.AmarokData)\n );\n\n return\n keccak256(dstCalldata) == keccak256(amarokData.callData) &&\n abi.decode(callTo, (address)) == amarokData.callTo;\n }\n if (\n selector == AmarokFacet.swapAndStartBridgeTokensViaAmarok.selector\n ) {\n (, , AmarokFacet.AmarokData memory amarokData) = abi.decode(\n callData.slice(4, callData.length - 4),\n (ILiFi.BridgeData, LibSwap.SwapData[], AmarokFacet.AmarokData)\n );\n return\n keccak256(dstCalldata) == keccak256(amarokData.callData) &&\n abi.decode(callTo, (address)) == amarokData.callTo;\n }\n\n // Case: Stargate\n if (selector == StargateFacet.startBridgeTokensViaStargate.selector) {\n (, StargateFacet.StargateData memory stargateData) = abi.decode(\n callData.slice(4, callData.length - 4),\n (ILiFi.BridgeData, StargateFacet.StargateData)\n );\n return\n keccak256(dstCalldata) == keccak256(stargateData.callData) &&\n keccak256(callTo) == keccak256(stargateData.callTo);\n }\n if (\n selector ==\n StargateFacet.swapAndStartBridgeTokensViaStargate.selector\n ) {\n (, , StargateFacet.StargateData memory stargateData) = abi.decode(\n callData.slice(4, callData.length - 4),\n (\n ILiFi.BridgeData,\n LibSwap.SwapData[],\n StargateFacet.StargateData\n )\n );\n return\n keccak256(dstCalldata) == keccak256(stargateData.callData) &&\n keccak256(callTo) == keccak256(stargateData.callTo);\n }\n // Case: Celer\n if (\n selector == CelerIMFacetBase.startBridgeTokensViaCelerIM.selector\n ) {\n (, CelerIM.CelerIMData memory celerIMData) = abi.decode(\n callData.slice(4, callData.length - 4),\n (ILiFi.BridgeData, CelerIM.CelerIMData)\n );\n return\n keccak256(dstCalldata) == keccak256(celerIMData.callData) &&\n keccak256(callTo) == keccak256(celerIMData.callTo);\n }\n if (\n selector ==\n CelerIMFacetBase.swapAndStartBridgeTokensViaCelerIM.selector\n ) {\n (, , CelerIM.CelerIMData memory celerIMData) = abi.decode(\n callData.slice(4, callData.length - 4),\n (ILiFi.BridgeData, LibSwap.SwapData[], CelerIM.CelerIMData)\n );\n return\n keccak256(dstCalldata) == keccak256(celerIMData.callData) &&\n keccak256(callTo) == keccak256(celerIMData.callTo);\n }\n\n // All other cases\n return false;\n }\n\n /// Internal Methods ///\n\n /// @notice Extracts the bridge data from the calldata\n /// @param data The calldata to extract the bridge data from\n /// @return bridgeData The bridge data extracted from the calldata\n function _extractBridgeData(\n bytes calldata data\n ) internal pure returns (ILiFi.BridgeData memory bridgeData) {\n if (\n abi.decode(data, (bytes4)) ==\n StandardizedCallFacet.standardizedCall.selector\n ) {\n // StandardizedCall\n bytes memory unwrappedData = abi.decode(data[4:], (bytes));\n bridgeData = abi.decode(\n unwrappedData.slice(4, unwrappedData.length - 4),\n (ILiFi.BridgeData)\n );\n return bridgeData;\n }\n // normal call\n bridgeData = abi.decode(data[4:], (ILiFi.BridgeData));\n }\n\n /// @notice Extracts the swap data from the calldata\n /// @param data The calldata to extract the swap data from\n /// @return swapData The swap data extracted from the calldata\n function _extractSwapData(\n bytes calldata data\n ) internal pure returns (LibSwap.SwapData[] memory swapData) {\n if (\n abi.decode(data, (bytes4)) ==\n StandardizedCallFacet.standardizedCall.selector\n ) {\n // standardizedCall\n bytes memory unwrappedData = abi.decode(data[4:], (bytes));\n (, swapData) = abi.decode(\n unwrappedData.slice(4, unwrappedData.length - 4),\n (ILiFi.BridgeData, LibSwap.SwapData[])\n );\n return swapData;\n }\n // normal call\n (, swapData) = abi.decode(\n data[4:],\n (ILiFi.BridgeData, LibSwap.SwapData[])\n );\n }\n}\n" + }, + "src/Facets/CBridgeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { LibDiamond } from \"../Libraries/LibDiamond.sol\";\nimport { LibUtil } from \"../Libraries/LibUtil.sol\";\nimport { LibAsset, IERC20 } from \"../Libraries/LibAsset.sol\";\nimport { LibAccess } from \"../Libraries/LibAccess.sol\";\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { ICBridge } from \"../Interfaces/ICBridge.sol\";\nimport { ReentrancyGuard } from \"../Helpers/ReentrancyGuard.sol\";\nimport { CannotBridgeToSameNetwork } from \"../Errors/GenericErrors.sol\";\nimport { SwapperV2, LibSwap } from \"../Helpers/SwapperV2.sol\";\nimport { Validatable } from \"../Helpers/Validatable.sol\";\nimport { ContractCallNotAllowed, ExternalCallFailed } from \"../Errors/GenericErrors.sol\";\n\n/// @title CBridge Facet\n/// @author LI.FI (https://li.fi)\n/// @notice Provides functionality for bridging through CBridge\n/// @custom:version 1.0.0\ncontract CBridgeFacet is ILiFi, ReentrancyGuard, SwapperV2, Validatable {\n /// Storage ///\n\n /// @notice The contract address of the cbridge on the source chain.\n ICBridge private immutable cBridge;\n\n /// Types ///\n\n /// @param maxSlippage The max slippage accepted, given as percentage in point (pip).\n /// @param nonce A number input to guarantee uniqueness of transferId.\n /// Can be timestamp in practice.\n struct CBridgeData {\n uint32 maxSlippage;\n uint64 nonce;\n }\n\n /// Events ///\n event CBridgeRefund(\n address indexed _assetAddress,\n address indexed _to,\n uint256 amount\n );\n\n /// Constructor ///\n\n /// @notice Initialize the contract.\n /// @param _cBridge The contract address of the cbridge on the source chain.\n constructor(ICBridge _cBridge) {\n cBridge = _cBridge;\n }\n\n /// External Methods ///\n\n /// @notice Bridges tokens via CBridge\n /// @param _bridgeData the core information needed for bridging\n /// @param _cBridgeData data specific to CBridge\n function startBridgeTokensViaCBridge(\n ILiFi.BridgeData memory _bridgeData,\n CBridgeData calldata _cBridgeData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n doesNotContainSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n LibAsset.depositAsset(\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount\n );\n _startBridge(_bridgeData, _cBridgeData);\n }\n\n /// @notice Performs a swap before bridging via CBridge\n /// @param _bridgeData the core information needed for bridging\n /// @param _swapData an array of swap related data for performing swaps before bridging\n /// @param _cBridgeData data specific to CBridge\n function swapAndStartBridgeTokensViaCBridge(\n ILiFi.BridgeData memory _bridgeData,\n LibSwap.SwapData[] calldata _swapData,\n CBridgeData calldata _cBridgeData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n containsSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n _bridgeData.minAmount = _depositAndSwap(\n _bridgeData.transactionId,\n _bridgeData.minAmount,\n _swapData,\n payable(msg.sender)\n );\n _startBridge(_bridgeData, _cBridgeData);\n }\n\n /// @notice Triggers a cBridge refund with calldata produced by cBridge API\n /// @param _callTo The address to execute the calldata on\n /// @param _callData The data to execute\n /// @param _assetAddress Asset to be withdrawn\n /// @param _to Address to withdraw to\n /// @param _amount Amount of asset to withdraw\n function triggerRefund(\n address payable _callTo,\n bytes calldata _callData,\n address _assetAddress,\n address _to,\n uint256 _amount\n ) external {\n if (msg.sender != LibDiamond.contractOwner()) {\n LibAccess.enforceAccessControl();\n }\n\n // make sure that callTo address is either of the cBridge addresses\n if (address(cBridge) != _callTo) {\n revert ContractCallNotAllowed();\n }\n\n // call contract\n bool success;\n (success, ) = _callTo.call(_callData);\n if (!success) {\n revert ExternalCallFailed();\n }\n\n // forward funds to _to address and emit event\n address sendTo = (LibUtil.isZeroAddress(_to)) ? msg.sender : _to;\n LibAsset.transferAsset(_assetAddress, payable(sendTo), _amount);\n emit CBridgeRefund(_assetAddress, sendTo, _amount);\n }\n\n /// Private Methods ///\n\n /// @dev Contains the business logic for the bridge via CBridge\n /// @param _bridgeData the core information needed for bridging\n /// @param _cBridgeData data specific to CBridge\n function _startBridge(\n ILiFi.BridgeData memory _bridgeData,\n CBridgeData calldata _cBridgeData\n ) private {\n if (LibAsset.isNativeAsset(_bridgeData.sendingAssetId)) {\n cBridge.sendNative{ value: _bridgeData.minAmount }(\n _bridgeData.receiver,\n _bridgeData.minAmount,\n uint64(_bridgeData.destinationChainId),\n _cBridgeData.nonce,\n _cBridgeData.maxSlippage\n );\n } else {\n // Give CBridge approval to bridge tokens\n LibAsset.maxApproveERC20(\n IERC20(_bridgeData.sendingAssetId),\n address(cBridge),\n _bridgeData.minAmount\n );\n // solhint-disable check-send-result\n cBridge.send(\n _bridgeData.receiver,\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount,\n uint64(_bridgeData.destinationChainId),\n _cBridgeData.nonce,\n _cBridgeData.maxSlippage\n );\n }\n\n emit LiFiTransferStarted(_bridgeData);\n }\n}\n" + }, + "src/Facets/CBridgeFacetPacked.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { ICBridge } from \"../Interfaces/ICBridge.sol\";\nimport { CBridgeFacet } from \"./CBridgeFacet.sol\";\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { ERC20, SafeTransferLib } from \"../../lib/solmate/src/utils/SafeTransferLib.sol\";\nimport { LibAsset, IERC20 } from \"../Libraries/LibAsset.sol\";\nimport { LibDiamond } from \"../Libraries/LibDiamond.sol\";\nimport { ContractCallNotAllowed, ExternalCallFailed } from \"../Errors/GenericErrors.sol\";\nimport { LibUtil } from \"../Libraries/LibUtil.sol\";\nimport { TransferrableOwnership } from \"../Helpers/TransferrableOwnership.sol\";\n\n/// @title CBridge Facet Packed\n/// @author LI.FI (https://li.fi)\n/// @notice Provides functionality for bridging through CBridge\n/// @custom:version 1.0.3\ncontract CBridgeFacetPacked is ILiFi, TransferrableOwnership {\n using SafeTransferLib for ERC20;\n\n /// Storage ///\n\n /// @notice The contract address of the cbridge on the source chain.\n ICBridge private immutable cBridge;\n\n /// Events ///\n\n event LiFiCBridgeTransfer(bytes8 _transactionId);\n\n event CBridgeRefund(\n address indexed _assetAddress,\n address indexed _to,\n uint256 amount\n );\n\n /// Constructor ///\n\n /// @notice Initialize the contract.\n /// @param _cBridge The contract address of the cbridge on the source chain.\n constructor(\n ICBridge _cBridge,\n address _owner\n ) TransferrableOwnership(_owner) {\n cBridge = _cBridge;\n }\n\n /// External Methods ///\n\n /// @dev Only meant to be called outside of the context of the diamond\n /// @notice Sets approval for the CBridge Router to spend the specified token\n /// @param tokensToApprove The tokens to approve to the CBridge Router\n function setApprovalForBridge(\n address[] calldata tokensToApprove\n ) external onlyOwner {\n for (uint256 i; i < tokensToApprove.length; i++) {\n // Give CBridge approval to bridge tokens\n LibAsset.maxApproveERC20(\n IERC20(tokensToApprove[i]),\n address(cBridge),\n type(uint256).max\n );\n }\n }\n\n // This is needed to receive native asset if a refund asset is a native asset\n receive() external payable {}\n\n /// @notice Triggers a cBridge refund with calldata produced by cBridge API\n /// @param _callTo The address to execute the calldata on\n /// @param _callData The data to execute\n /// @param _assetAddress Asset to be withdrawn\n /// @param _to Address to withdraw to\n /// @param _amount Amount of asset to withdraw\n function triggerRefund(\n address payable _callTo,\n bytes calldata _callData,\n address _assetAddress,\n address _to,\n uint256 _amount\n ) external onlyOwner {\n // make sure that callTo address is either of the cBridge addresses\n if (address(cBridge) != _callTo) {\n revert ContractCallNotAllowed();\n }\n\n // call contract\n bool success;\n (success, ) = _callTo.call(_callData);\n if (!success) {\n revert ExternalCallFailed();\n }\n\n // forward funds to _to address and emit event\n address sendTo = (LibUtil.isZeroAddress(_to)) ? msg.sender : _to;\n LibAsset.transferAsset(_assetAddress, payable(sendTo), _amount);\n emit CBridgeRefund(_assetAddress, sendTo, _amount);\n }\n\n /// @notice Bridges Native tokens via cBridge (packed)\n /// No params, all data will be extracted from manually encoded callData\n function startBridgeTokensViaCBridgeNativePacked() external payable {\n cBridge.sendNative{ value: msg.value }(\n address(bytes20(msg.data[12:32])), // receiver\n msg.value, // amount\n uint64(uint32(bytes4(msg.data[32:36]))), // destinationChainId\n uint64(uint32(bytes4(msg.data[36:40]))), // nonce\n uint32(bytes4(msg.data[40:44])) // maxSlippage\n );\n\n emit LiFiCBridgeTransfer(bytes8(msg.data[4:12])); // transactionId\n }\n\n /// @notice Bridges native tokens via cBridge\n /// @param transactionId Custom transaction ID for tracking\n /// @param receiver Receiving wallet address\n /// @param destinationChainId Receiving chain\n /// @param nonce A number input to guarantee uniqueness of transferId.\n /// @param maxSlippage Destination swap minimal accepted amount\n function startBridgeTokensViaCBridgeNativeMin(\n bytes32 transactionId,\n address receiver,\n uint64 destinationChainId,\n uint64 nonce,\n uint32 maxSlippage\n ) external payable {\n cBridge.sendNative{ value: msg.value }(\n receiver,\n msg.value,\n destinationChainId,\n nonce,\n maxSlippage\n );\n\n emit LiFiCBridgeTransfer(bytes8(transactionId));\n }\n\n /// @notice Bridges ERC20 tokens via cBridge\n /// No params, all data will be extracted from manually encoded callData\n function startBridgeTokensViaCBridgeERC20Packed() external {\n address sendingAssetId = address(bytes20(msg.data[36:56]));\n uint256 amount = uint256(uint128(bytes16(msg.data[56:72])));\n\n // Deposit assets\n ERC20(sendingAssetId).safeTransferFrom(\n msg.sender,\n address(this),\n amount\n );\n\n // Bridge assets\n // solhint-disable-next-line check-send-result\n cBridge.send(\n address(bytes20(msg.data[12:32])), // receiver\n sendingAssetId, // sendingAssetId\n amount, // amount\n uint64(uint32(bytes4(msg.data[32:36]))), // destinationChainId\n uint64(uint32(bytes4(msg.data[72:76]))), // nonce\n uint32(bytes4(msg.data[76:80])) // maxSlippage\n );\n\n emit LiFiCBridgeTransfer(bytes8(msg.data[4:12]));\n }\n\n /// @notice Bridges ERC20 tokens via cBridge\n /// @param transactionId Custom transaction ID for tracking\n /// @param receiver Receiving wallet address\n /// @param destinationChainId Receiving chain\n /// @param sendingAssetId Address of the source asset to bridge\n /// @param amount Amount of the source asset to bridge\n /// @param nonce A number input to guarantee uniqueness of transferId\n /// @param maxSlippage Destination swap minimal accepted amount\n function startBridgeTokensViaCBridgeERC20Min(\n bytes32 transactionId,\n address receiver,\n uint64 destinationChainId,\n address sendingAssetId,\n uint256 amount,\n uint64 nonce,\n uint32 maxSlippage\n ) external {\n // Deposit assets\n ERC20(sendingAssetId).safeTransferFrom(\n msg.sender,\n address(this),\n amount\n );\n\n // Bridge assets\n // solhint-disable-next-line check-send-result\n cBridge.send(\n receiver,\n sendingAssetId,\n amount,\n destinationChainId,\n nonce,\n maxSlippage\n );\n\n emit LiFiCBridgeTransfer(bytes8(transactionId));\n }\n\n /// Encoder/Decoders ///\n\n /// @notice Encodes calldata for startBridgeTokensViaCBridgeNativePacked\n /// @param transactionId Custom transaction ID for tracking\n /// @param receiver Receiving wallet address\n /// @param destinationChainId Receiving chain\n /// @param nonce A number input to guarantee uniqueness of transferId.\n /// @param maxSlippage Destination swap minimal accepted amount\n function encode_startBridgeTokensViaCBridgeNativePacked(\n bytes32 transactionId,\n address receiver,\n uint64 destinationChainId,\n uint64 nonce,\n uint32 maxSlippage\n ) external pure returns (bytes memory) {\n require(\n destinationChainId <= type(uint32).max,\n \"destinationChainId value passed too big to fit in uint32\"\n );\n require(\n nonce <= type(uint32).max,\n \"nonce value passed too big to fit in uint32\"\n );\n\n return\n bytes.concat(\n CBridgeFacetPacked\n .startBridgeTokensViaCBridgeNativePacked\n .selector,\n bytes8(transactionId),\n bytes20(receiver),\n bytes4(uint32(destinationChainId)),\n bytes4(uint32(nonce)),\n bytes4(maxSlippage)\n );\n }\n\n /// @notice Decodes calldata for startBridgeTokensViaCBridgeNativePacked\n /// @param _data the calldata to decode\n function decode_startBridgeTokensViaCBridgeNativePacked(\n bytes calldata _data\n )\n external\n pure\n returns (BridgeData memory, CBridgeFacet.CBridgeData memory)\n {\n require(\n _data.length >= 44,\n \"data passed in is not the correct length\"\n );\n\n BridgeData memory bridgeData;\n CBridgeFacet.CBridgeData memory cBridgeData;\n\n bridgeData.transactionId = bytes32(bytes8(_data[4:12]));\n bridgeData.receiver = address(bytes20(_data[12:32]));\n bridgeData.destinationChainId = uint64(uint32(bytes4(_data[32:36])));\n cBridgeData.nonce = uint64(uint32(bytes4(_data[36:40])));\n cBridgeData.maxSlippage = uint32(bytes4(_data[40:44]));\n\n return (bridgeData, cBridgeData);\n }\n\n /// @notice Encodes calldata for startBridgeTokensViaCBridgeERC20Packed\n /// @param transactionId Custom transaction ID for tracking\n /// @param receiver Receiving wallet address\n /// @param destinationChainId Receiving chain\n /// @param sendingAssetId Address of the source asset to bridge\n /// @param minAmount Amount of the source asset to bridge\n /// @param nonce A number input to guarantee uniqueness of transferId\n /// @param maxSlippage Destination swap minimal accepted amount\n function encode_startBridgeTokensViaCBridgeERC20Packed(\n bytes32 transactionId,\n address receiver,\n uint64 destinationChainId,\n address sendingAssetId,\n uint256 minAmount,\n uint64 nonce,\n uint32 maxSlippage\n ) external pure returns (bytes memory) {\n require(\n destinationChainId <= type(uint32).max,\n \"destinationChainId value passed too big to fit in uint32\"\n );\n require(\n minAmount <= type(uint128).max,\n \"amount value passed too big to fit in uint128\"\n );\n require(\n nonce <= type(uint32).max,\n \"nonce value passed too big to fit in uint32\"\n );\n\n return\n bytes.concat(\n CBridgeFacetPacked\n .startBridgeTokensViaCBridgeERC20Packed\n .selector,\n bytes8(transactionId),\n bytes20(receiver),\n bytes4(uint32(destinationChainId)),\n bytes20(sendingAssetId),\n bytes16(uint128(minAmount)),\n bytes4(uint32(nonce)),\n bytes4(maxSlippage)\n );\n }\n\n function decode_startBridgeTokensViaCBridgeERC20Packed(\n bytes calldata _data\n )\n external\n pure\n returns (BridgeData memory, CBridgeFacet.CBridgeData memory)\n {\n require(_data.length >= 80, \"data passed is not the correct length\");\n\n BridgeData memory bridgeData;\n CBridgeFacet.CBridgeData memory cBridgeData;\n\n bridgeData.transactionId = bytes32(bytes8(_data[4:12]));\n bridgeData.receiver = address(bytes20(_data[12:32]));\n bridgeData.destinationChainId = uint64(uint32(bytes4(_data[32:36])));\n bridgeData.sendingAssetId = address(bytes20(_data[36:56]));\n bridgeData.minAmount = uint256(uint128(bytes16(_data[56:72])));\n cBridgeData.nonce = uint64(uint32(bytes4(_data[72:76])));\n cBridgeData.maxSlippage = uint32(bytes4(_data[76:80]));\n\n return (bridgeData, cBridgeData);\n }\n}\n" + }, + "src/Facets/CelerCircleBridgeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { ICircleBridgeProxy } from \"../Interfaces/ICircleBridgeProxy.sol\";\nimport { LibAsset, IERC20 } from \"../Libraries/LibAsset.sol\";\nimport { ReentrancyGuard } from \"../Helpers/ReentrancyGuard.sol\";\nimport { SwapperV2, LibSwap } from \"../Helpers/SwapperV2.sol\";\nimport { Validatable } from \"../Helpers/Validatable.sol\";\n\n/// @title CelerCircleBridge Facet\n/// @author LI.FI (https://li.fi)\n/// @notice Provides functionality for bridging through CelerCircleBridge\n/// @custom:version 1.0.1\ncontract CelerCircleBridgeFacet is\n ILiFi,\n ReentrancyGuard,\n SwapperV2,\n Validatable\n{\n /// Storage ///\n\n /// @notice The address of the CircleBridgeProxy on the current chain.\n ICircleBridgeProxy private immutable circleBridgeProxy;\n\n /// @notice The USDC address on the current chain.\n address private immutable usdc;\n\n /// Constructor ///\n\n /// @notice Initialize the contract.\n /// @param _circleBridgeProxy The address of the CircleBridgeProxy on the current chain.\n /// @param _usdc The address of USDC on the current chain.\n constructor(ICircleBridgeProxy _circleBridgeProxy, address _usdc) {\n circleBridgeProxy = _circleBridgeProxy;\n usdc = _usdc;\n }\n\n /// External Methods ///\n\n /// @notice Bridges tokens via CelerCircleBridge\n /// @param _bridgeData Data containing core information for bridging\n function startBridgeTokensViaCelerCircleBridge(\n BridgeData calldata _bridgeData\n )\n external\n nonReentrant\n doesNotContainSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n onlyAllowSourceToken(_bridgeData, usdc)\n {\n LibAsset.depositAsset(usdc, _bridgeData.minAmount);\n _startBridge(_bridgeData);\n }\n\n /// @notice Performs a swap before bridging via CelerCircleBridge\n /// @param _bridgeData The core information needed for bridging\n /// @param _swapData An array of swap related data for performing swaps before bridging\n function swapAndStartBridgeTokensViaCelerCircleBridge(\n BridgeData memory _bridgeData,\n LibSwap.SwapData[] calldata _swapData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n containsSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n onlyAllowSourceToken(_bridgeData, usdc)\n {\n _bridgeData.minAmount = _depositAndSwap(\n _bridgeData.transactionId,\n _bridgeData.minAmount,\n _swapData,\n payable(msg.sender)\n );\n _startBridge(_bridgeData);\n }\n\n /// Private Methods ///\n\n /// @dev Contains the business logic for the bridge via CelerCircleBridge\n /// @param _bridgeData The core information needed for bridging\n function _startBridge(BridgeData memory _bridgeData) private {\n require(\n _bridgeData.destinationChainId <= type(uint64).max,\n \"_bridgeData.destinationChainId passed is too big to fit in uint64\"\n );\n\n // give max approval for token to CelerCircleBridge bridge, if not already\n LibAsset.maxApproveERC20(\n IERC20(usdc),\n address(circleBridgeProxy),\n _bridgeData.minAmount\n );\n\n // initiate bridge transaction\n circleBridgeProxy.depositForBurn(\n _bridgeData.minAmount,\n uint64(_bridgeData.destinationChainId),\n bytes32(uint256(uint160(_bridgeData.receiver))),\n usdc\n );\n\n emit LiFiTransferStarted(_bridgeData);\n }\n}\n" + }, + "src/Facets/CelerIMFacetImmutable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { CelerIMFacetBase, IMessageBus, MsgDataTypes, IERC20, CelerIM } from \"../Helpers/CelerIMFacetBase.sol\";\n\n/// @title CelerIMFacetImmutable\n/// @author LI.FI (https://li.fi)\n/// @notice Provides functionality for bridging tokens and data through CBridge\n/// @notice This contract is exclusively used for immutable diamond contracts\n/// @custom:version 2.0.0\ncontract CelerIMFacetImmutable is CelerIMFacetBase {\n /// Constructor ///\n\n /// @notice Initialize the contract.\n /// @param _messageBus The contract address of the cBridge Message Bus\n /// @param _relayerOwner The address that will become the owner of the RelayerCelerIM contract\n /// @param _diamondAddress The address of the diamond contract that will be connected with the RelayerCelerIM\n /// @param _cfUSDC The contract address of the Celer Flow USDC\n constructor(\n IMessageBus _messageBus,\n address _relayerOwner,\n address _diamondAddress,\n address _cfUSDC\n ) CelerIMFacetBase(_messageBus, _relayerOwner, _diamondAddress, _cfUSDC) {}\n}\n" + }, + "src/Facets/CelerIMFacetMutable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { CelerIMFacetBase, IMessageBus, MsgDataTypes, IERC20, CelerIM } from \"../Helpers/CelerIMFacetBase.sol\";\n\n/// @title CelerIMFacetMutable\n/// @author LI.FI (https://li.fi)\n/// @notice Provides functionality for bridging tokens and data through CBridge\n/// @notice This contract is exclusively used for mutable diamond contracts\n/// @custom:version 2.0.0\ncontract CelerIMFacetMutable is CelerIMFacetBase {\n /// Constructor ///\n\n /// @notice Initialize the contract.\n /// @param _messageBus The contract address of the cBridge Message Bus\n /// @param _relayerOwner The address that will become the owner of the RelayerCelerIM contract\n /// @param _diamondAddress The address of the diamond contract that will be connected with the RelayerCelerIM\n /// @param _cfUSDC The contract address of the Celer Flow USDC\n constructor(\n IMessageBus _messageBus,\n address _relayerOwner,\n address _diamondAddress,\n address _cfUSDC\n ) CelerIMFacetBase(_messageBus, _relayerOwner, _diamondAddress, _cfUSDC) {}\n}\n" + }, + "src/Facets/CircleBridgeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { ITokenMessenger } from \"../Interfaces/ITokenMessenger.sol\";\nimport { LibAsset, IERC20 } from \"../Libraries/LibAsset.sol\";\nimport { ReentrancyGuard } from \"../Helpers/ReentrancyGuard.sol\";\nimport { SwapperV2, LibSwap } from \"../Helpers/SwapperV2.sol\";\nimport { Validatable } from \"../Helpers/Validatable.sol\";\n\n/// @title CircleBridge Facet\n/// @author LI.FI (https://li.fi)\n/// @notice Provides functionality for bridging through CircleBridge\n/// @custom:version 1.0.0\ncontract CircleBridgeFacet is ILiFi, ReentrancyGuard, SwapperV2, Validatable {\n /// Storage ///\n\n /// @notice The address of the TokenMessenger on the source chain.\n ITokenMessenger private immutable tokenMessenger;\n\n /// @notice The USDC address on the source chain.\n address private immutable usdc;\n\n /// @param dstDomain The CircleBridge-specific domainId of the destination chain\n struct CircleBridgeData {\n uint32 dstDomain;\n }\n\n /// Constructor ///\n\n /// @notice Initialize the contract.\n /// @param _tokenMessenger The address of the TokenMessenger on the source chain.\n /// @param _usdc The address of USDC on the source chain.\n constructor(ITokenMessenger _tokenMessenger, address _usdc) {\n tokenMessenger = _tokenMessenger;\n usdc = _usdc;\n }\n\n /// External Methods ///\n\n /// @notice Bridges tokens via CircleBridge\n /// @param _bridgeData Data containing core information for bridging\n /// @param _circleBridgeData Data specific to bridge\n function startBridgeTokensViaCircleBridge(\n BridgeData calldata _bridgeData,\n CircleBridgeData calldata _circleBridgeData\n )\n external\n nonReentrant\n doesNotContainSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n onlyAllowSourceToken(_bridgeData, usdc)\n {\n LibAsset.depositAsset(usdc, _bridgeData.minAmount);\n _startBridge(_bridgeData, _circleBridgeData);\n }\n\n /// @notice Performs a swap before bridging via CircleBridge\n /// @param _bridgeData The core information needed for bridging\n /// @param _swapData An array of swap related data for performing swaps before bridging\n /// @param _circleBridgeData Data specific to CircleBridge\n function swapAndStartBridgeTokensViaCircleBridge(\n BridgeData memory _bridgeData,\n LibSwap.SwapData[] calldata _swapData,\n CircleBridgeData calldata _circleBridgeData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n containsSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n onlyAllowSourceToken(_bridgeData, usdc)\n {\n _bridgeData.minAmount = _depositAndSwap(\n _bridgeData.transactionId,\n _bridgeData.minAmount,\n _swapData,\n payable(msg.sender)\n );\n _startBridge(_bridgeData, _circleBridgeData);\n }\n\n /// Private Methods ///\n\n /// @dev Contains the business logic for the bridge via CircleBridge\n /// @param _bridgeData The core information needed for bridging\n /// @param _circleBridgeData Data specific to CircleBridge\n function _startBridge(\n BridgeData memory _bridgeData,\n CircleBridgeData calldata _circleBridgeData\n ) private {\n // give max approval for token to CircleBridge bridge, if not already\n LibAsset.maxApproveERC20(\n IERC20(usdc),\n address(tokenMessenger),\n _bridgeData.minAmount\n );\n\n // initiate bridge transaction\n tokenMessenger.depositForBurn(\n _bridgeData.minAmount,\n _circleBridgeData.dstDomain,\n bytes32(uint256(uint160(_bridgeData.receiver))),\n usdc\n );\n\n emit LiFiTransferStarted(_bridgeData);\n }\n}\n" + }, + "src/Facets/DeBridgeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { IDeBridgeGate } from \"../Interfaces/IDeBridgeGate.sol\";\nimport { LibAsset, IERC20 } from \"../Libraries/LibAsset.sol\";\nimport { ReentrancyGuard } from \"../Helpers/ReentrancyGuard.sol\";\nimport { SwapperV2, LibSwap } from \"../Helpers/SwapperV2.sol\";\nimport { InformationMismatch, InvalidAmount } from \"../Errors/GenericErrors.sol\";\nimport { Validatable } from \"../Helpers/Validatable.sol\";\n\n/// @title DeBridge Facet\n/// @author LI.FI (https://li.fi)\n/// @notice Provides functionality for bridging through DeBridge Protocol\n/// @custom:version 1.0.0\ncontract DeBridgeFacet is ILiFi, ReentrancyGuard, SwapperV2, Validatable {\n /// Storage ///\n\n /// @notice The contract address of the DeBridge Gate on the source chain.\n IDeBridgeGate private immutable deBridgeGate;\n\n /// Types ///\n\n /// @param executionFee Fee paid to the transaction executor.\n /// @param flags Flags set specific flows for call data execution.\n /// @param fallbackAddress Receiver of the tokens if the call fails.\n /// @param data Message/Call data to be passed to the receiver\n /// on the destination chain during the external call execution.\n struct SubmissionAutoParamsTo {\n uint256 executionFee;\n uint256 flags;\n bytes fallbackAddress;\n bytes data;\n }\n\n /// @param nativeFee Native fee for the bridging when useAssetFee is false.\n /// @param useAssetFee Use assets fee for pay protocol fix (work only for specials token)\n /// @param referralCode Referral code.\n /// @param autoParams Structure that enables passing arbitrary messages and call data.\n struct DeBridgeData {\n uint256 nativeFee;\n bool useAssetFee;\n uint32 referralCode;\n SubmissionAutoParamsTo autoParams;\n }\n\n /// Constructor ///\n\n /// @notice Initialize the contract.\n /// @param _deBridgeGate The contract address of the DeBridgeGate on the source chain.\n constructor(IDeBridgeGate _deBridgeGate) {\n deBridgeGate = _deBridgeGate;\n }\n\n /// External Methods ///\n\n /// @notice Bridges tokens via DeBridge\n /// @param _bridgeData the core information needed for bridging\n /// @param _deBridgeData data specific to DeBridge\n function startBridgeTokensViaDeBridge(\n ILiFi.BridgeData calldata _bridgeData,\n DeBridgeData calldata _deBridgeData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n validateBridgeData(_bridgeData)\n doesNotContainSourceSwaps(_bridgeData)\n {\n validateDestinationCallFlag(_bridgeData, _deBridgeData);\n\n LibAsset.depositAsset(\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount\n );\n _startBridge(_bridgeData, _deBridgeData);\n }\n\n /// @notice Performs a swap before bridging via DeBridge\n /// @param _bridgeData the core information needed for bridging\n /// @param _swapData an array of swap related data for performing swaps before bridging\n /// @param _deBridgeData data specific to DeBridge\n function swapAndStartBridgeTokensViaDeBridge(\n ILiFi.BridgeData memory _bridgeData,\n LibSwap.SwapData[] calldata _swapData,\n DeBridgeData calldata _deBridgeData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n containsSourceSwaps(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n validateDestinationCallFlag(_bridgeData, _deBridgeData);\n\n _bridgeData.minAmount = _depositAndSwap(\n _bridgeData.transactionId,\n _bridgeData.minAmount,\n _swapData,\n payable(msg.sender),\n _deBridgeData.nativeFee\n );\n\n _startBridge(_bridgeData, _deBridgeData);\n }\n\n /// Internal Methods ///\n\n /// @dev Contains the business logic for the bridge via DeBridge\n /// @param _bridgeData the core information needed for bridging\n /// @param _deBridgeData data specific to DeBridge\n function _startBridge(\n ILiFi.BridgeData memory _bridgeData,\n DeBridgeData calldata _deBridgeData\n ) internal {\n IDeBridgeGate.ChainSupportInfo memory config = deBridgeGate\n .getChainToConfig(_bridgeData.destinationChainId);\n uint256 nativeFee = config.fixedNativeFee == 0\n ? deBridgeGate.globalFixedNativeFee()\n : config.fixedNativeFee;\n\n if (_deBridgeData.nativeFee != nativeFee) {\n revert InvalidAmount();\n }\n\n bool isNative = LibAsset.isNativeAsset(_bridgeData.sendingAssetId);\n uint256 nativeAssetAmount = _deBridgeData.nativeFee;\n\n if (isNative) {\n nativeAssetAmount += _bridgeData.minAmount;\n } else {\n LibAsset.maxApproveERC20(\n IERC20(_bridgeData.sendingAssetId),\n address(deBridgeGate),\n _bridgeData.minAmount\n );\n }\n\n // solhint-disable-next-line check-send-result\n deBridgeGate.send{ value: nativeAssetAmount }(\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount,\n _bridgeData.destinationChainId,\n abi.encodePacked(_bridgeData.receiver),\n \"\",\n _deBridgeData.useAssetFee,\n _deBridgeData.referralCode,\n abi.encode(_deBridgeData.autoParams)\n );\n\n emit LiFiTransferStarted(_bridgeData);\n }\n\n function validateDestinationCallFlag(\n ILiFi.BridgeData memory _bridgeData,\n DeBridgeData calldata _deBridgeData\n ) private pure {\n if (\n (_deBridgeData.autoParams.data.length > 0) !=\n _bridgeData.hasDestinationCall\n ) {\n revert InformationMismatch();\n }\n }\n}\n" + }, + "src/Facets/DexManagerFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { LibDiamond } from \"../Libraries/LibDiamond.sol\";\nimport { LibAccess } from \"../Libraries/LibAccess.sol\";\nimport { LibAllowList } from \"../Libraries/LibAllowList.sol\";\nimport { CannotAuthoriseSelf } from \"../Errors/GenericErrors.sol\";\n\n/// @title Dex Manager Facet\n/// @author LI.FI (https://li.fi)\n/// @notice Facet contract for managing approved DEXs to be used in swaps.\n/// @custom:version 1.0.0\ncontract DexManagerFacet {\n /// Events ///\n\n event DexAdded(address indexed dexAddress);\n event DexRemoved(address indexed dexAddress);\n event FunctionSignatureApprovalChanged(\n bytes4 indexed functionSignature,\n bool indexed approved\n );\n\n /// External Methods ///\n\n /// @notice Register the address of a DEX contract to be approved for swapping.\n /// @param _dex The address of the DEX contract to be approved.\n function addDex(address _dex) external {\n if (msg.sender != LibDiamond.contractOwner()) {\n LibAccess.enforceAccessControl();\n }\n\n if (_dex == address(this)) {\n revert CannotAuthoriseSelf();\n }\n\n LibAllowList.addAllowedContract(_dex);\n\n emit DexAdded(_dex);\n }\n\n /// @notice Batch register the address of DEX contracts to be approved for swapping.\n /// @param _dexs The addresses of the DEX contracts to be approved.\n function batchAddDex(address[] calldata _dexs) external {\n if (msg.sender != LibDiamond.contractOwner()) {\n LibAccess.enforceAccessControl();\n }\n uint256 length = _dexs.length;\n\n for (uint256 i = 0; i < length; ) {\n address dex = _dexs[i];\n if (dex == address(this)) {\n revert CannotAuthoriseSelf();\n }\n if (LibAllowList.contractIsAllowed(dex)) continue;\n LibAllowList.addAllowedContract(dex);\n emit DexAdded(dex);\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Unregister the address of a DEX contract approved for swapping.\n /// @param _dex The address of the DEX contract to be unregistered.\n function removeDex(address _dex) external {\n if (msg.sender != LibDiamond.contractOwner()) {\n LibAccess.enforceAccessControl();\n }\n LibAllowList.removeAllowedContract(_dex);\n emit DexRemoved(_dex);\n }\n\n /// @notice Batch unregister the addresses of DEX contracts approved for swapping.\n /// @param _dexs The addresses of the DEX contracts to be unregistered.\n function batchRemoveDex(address[] calldata _dexs) external {\n if (msg.sender != LibDiamond.contractOwner()) {\n LibAccess.enforceAccessControl();\n }\n uint256 length = _dexs.length;\n for (uint256 i = 0; i < length; ) {\n LibAllowList.removeAllowedContract(_dexs[i]);\n emit DexRemoved(_dexs[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Adds/removes a specific function signature to/from the allowlist\n /// @param _signature the function signature to allow/disallow\n /// @param _approval whether the function signature should be allowed\n function setFunctionApprovalBySignature(\n bytes4 _signature,\n bool _approval\n ) external {\n if (msg.sender != LibDiamond.contractOwner()) {\n LibAccess.enforceAccessControl();\n }\n\n if (_approval) {\n LibAllowList.addAllowedSelector(_signature);\n } else {\n LibAllowList.removeAllowedSelector(_signature);\n }\n\n emit FunctionSignatureApprovalChanged(_signature, _approval);\n }\n\n /// @notice Batch Adds/removes a specific function signature to/from the allowlist\n /// @param _signatures the function signatures to allow/disallow\n /// @param _approval whether the function signatures should be allowed\n function batchSetFunctionApprovalBySignature(\n bytes4[] calldata _signatures,\n bool _approval\n ) external {\n if (msg.sender != LibDiamond.contractOwner()) {\n LibAccess.enforceAccessControl();\n }\n uint256 length = _signatures.length;\n for (uint256 i = 0; i < length; ) {\n bytes4 _signature = _signatures[i];\n if (_approval) {\n LibAllowList.addAllowedSelector(_signature);\n } else {\n LibAllowList.removeAllowedSelector(_signature);\n }\n emit FunctionSignatureApprovalChanged(_signature, _approval);\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Returns whether a function signature is approved\n /// @param _signature the function signature to query\n /// @return approved Approved or not\n function isFunctionApproved(\n bytes4 _signature\n ) public view returns (bool approved) {\n return LibAllowList.selectorIsAllowed(_signature);\n }\n\n /// @notice Returns a list of all approved DEX addresses.\n /// @return addresses List of approved DEX addresses\n function approvedDexs()\n external\n view\n returns (address[] memory addresses)\n {\n return LibAllowList.getAllowedContracts();\n }\n}\n" + }, + "src/Facets/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { IDiamondCut } from \"../Interfaces/IDiamondCut.sol\";\nimport { LibDiamond } from \"../Libraries/LibDiamond.sol\";\n\n/// @title Diamond Cut Facet\n/// @author LI.FI (https://li.fi)\n/// @notice Core EIP-2535 Facet for upgrading Diamond Proxies.\n/// @custom:version 1.0.0\ncontract DiamondCutFacet is IDiamondCut {\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external override {\n LibDiamond.enforceIsContractOwner();\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\n }\n}\n" + }, + "src/Facets/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { LibDiamond } from \"../Libraries/LibDiamond.sol\";\nimport { IDiamondLoupe } from \"../Interfaces/IDiamondLoupe.sol\";\nimport { IERC165 } from \"../Interfaces/IERC165.sol\";\n\n/// @title Diamond Loupe Facet\n/// @author LI.FI (https://li.fi)\n/// @notice Core EIP-2535 Facet for inspecting Diamond Proxies.\n/// @custom:version 1.0.0\ncontract DiamondLoupeFacet is IDiamondLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools.\n //\n // struct Facet {\n // address facetAddress;\n // bytes4[] functionSelectors;\n // }\n\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets() external view override returns (Facet[] memory facets_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i = 0; i < numFacets; ) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds\n .facetFunctionSelectors[facetAddress_]\n .functionSelectors;\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Gets all the function selectors provided by a facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n )\n external\n view\n override\n returns (bytes4[] memory facetFunctionSelectors_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetFunctionSelectors_ = ds\n .facetFunctionSelectors[_facet]\n .functionSelectors;\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = ds.facetAddresses;\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddress_ = ds\n .selectorToFacetAndPosition[_functionSelector]\n .facetAddress;\n }\n\n // This implements ERC-165.\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n return ds.supportedInterfaces[_interfaceId];\n }\n}\n" + }, + "src/Facets/GenericSwapFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { LibAsset } from \"../Libraries/LibAsset.sol\";\nimport { ReentrancyGuard } from \"../Helpers/ReentrancyGuard.sol\";\nimport { SwapperV2, LibSwap } from \"../Helpers/SwapperV2.sol\";\nimport { Validatable } from \"../Helpers/Validatable.sol\";\nimport { LibUtil } from \"../Libraries/LibUtil.sol\";\nimport { InvalidReceiver } from \"../Errors/GenericErrors.sol\";\n\n/// @title Generic Swap Facet\n/// @author LI.FI (https://li.fi)\n/// @notice Provides functionality for swapping through ANY APPROVED DEX\n/// @dev Uses calldata to execute APPROVED arbitrary methods on DEXs\n/// @custom:version 1.0.0\ncontract GenericSwapFacet is ILiFi, ReentrancyGuard, SwapperV2, Validatable {\n /// External Methods ///\n\n /// @notice Performs multiple swaps in one transaction\n /// @param _transactionId the transaction id associated with the operation\n /// @param _integrator the name of the integrator\n /// @param _referrer the address of the referrer\n /// @param _receiver the address to receive the swapped tokens into (also excess tokens)\n /// @param _minAmount the minimum amount of the final asset to receive\n /// @param _swapData an object containing swap related data to perform swaps before bridging\n function swapTokensGeneric(\n bytes32 _transactionId,\n string calldata _integrator,\n string calldata _referrer,\n address payable _receiver,\n uint256 _minAmount,\n LibSwap.SwapData[] calldata _swapData\n ) external payable nonReentrant refundExcessNative(_receiver) {\n if (LibUtil.isZeroAddress(_receiver)) {\n revert InvalidReceiver();\n }\n\n uint256 postSwapBalance = _depositAndSwap(\n _transactionId,\n _minAmount,\n _swapData,\n _receiver\n );\n address receivingAssetId = _swapData[_swapData.length - 1]\n .receivingAssetId;\n LibAsset.transferAsset(receivingAssetId, _receiver, postSwapBalance);\n\n emit LiFiGenericSwapCompleted(\n _transactionId,\n _integrator,\n _referrer,\n _receiver,\n _swapData[0].sendingAssetId,\n receivingAssetId,\n _swapData[0].fromAmount,\n postSwapBalance\n );\n }\n}\n" + }, + "src/Facets/GnosisBridgeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { IXDaiBridge } from \"../Interfaces/IXDaiBridge.sol\";\nimport { LibAsset, IERC20 } from \"../Libraries/LibAsset.sol\";\nimport { ReentrancyGuard } from \"../Helpers/ReentrancyGuard.sol\";\nimport { InvalidSendingToken, NoSwapDataProvided } from \"../Errors/GenericErrors.sol\";\nimport { SwapperV2, LibSwap } from \"../Helpers/SwapperV2.sol\";\nimport { Validatable } from \"../Helpers/Validatable.sol\";\n\n/// @title Gnosis Bridge Facet\n/// @author LI.FI (https://li.fi)\n/// @notice Provides functionality for bridging through XDaiBridge\n/// @custom:version 1.0.0\ncontract GnosisBridgeFacet is ILiFi, ReentrancyGuard, SwapperV2, Validatable {\n /// Storage ///\n\n /// @notice The DAI address on the source chain.\n address private constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;\n\n /// @notice The chain id of Gnosis.\n uint64 private constant GNOSIS_CHAIN_ID = 100;\n\n /// @notice The contract address of the xdai bridge on the source chain.\n IXDaiBridge private immutable xDaiBridge;\n\n /// Constructor ///\n\n /// @notice Initialize the contract.\n /// @param _xDaiBridge The contract address of the xdai bridge on the source chain.\n constructor(IXDaiBridge _xDaiBridge) {\n xDaiBridge = _xDaiBridge;\n }\n\n /// External Methods ///\n\n /// @notice Bridges tokens via XDaiBridge\n /// @param _bridgeData the core information needed for bridging\n function startBridgeTokensViaXDaiBridge(\n ILiFi.BridgeData memory _bridgeData\n )\n external\n nonReentrant\n doesNotContainSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n onlyAllowDestinationChain(_bridgeData, GNOSIS_CHAIN_ID)\n onlyAllowSourceToken(_bridgeData, DAI)\n {\n LibAsset.depositAsset(DAI, _bridgeData.minAmount);\n _startBridge(_bridgeData);\n }\n\n /// @notice Performs a swap before bridging via XDaiBridge\n /// @param _bridgeData the core information needed for bridging\n /// @param _swapData an object containing swap related data to perform swaps before bridging\n function swapAndStartBridgeTokensViaXDaiBridge(\n ILiFi.BridgeData memory _bridgeData,\n LibSwap.SwapData[] calldata _swapData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n containsSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n onlyAllowDestinationChain(_bridgeData, GNOSIS_CHAIN_ID)\n onlyAllowSourceToken(_bridgeData, DAI)\n {\n _bridgeData.minAmount = _depositAndSwap(\n _bridgeData.transactionId,\n _bridgeData.minAmount,\n _swapData,\n payable(msg.sender)\n );\n\n _startBridge(_bridgeData);\n }\n\n /// Private Methods ///\n\n /// @dev Contains the business logic for the bridge via XDaiBridge\n /// @param _bridgeData the core information needed for bridging\n function _startBridge(ILiFi.BridgeData memory _bridgeData) private {\n LibAsset.maxApproveERC20(\n IERC20(DAI),\n address(xDaiBridge),\n _bridgeData.minAmount\n );\n xDaiBridge.relayTokens(_bridgeData.receiver, _bridgeData.minAmount);\n emit LiFiTransferStarted(_bridgeData);\n }\n}\n" + }, + "src/Facets/GnosisBridgeL2Facet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { IXDaiBridgeL2 } from \"../Interfaces/IXDaiBridgeL2.sol\";\nimport { LibAsset, IERC20 } from \"../Libraries/LibAsset.sol\";\nimport { ReentrancyGuard } from \"../Helpers/ReentrancyGuard.sol\";\nimport { InvalidSendingToken, NoSwapDataProvided } from \"../Errors/GenericErrors.sol\";\nimport { SwapperV2, LibSwap } from \"../Helpers/SwapperV2.sol\";\nimport { Validatable } from \"../Helpers/Validatable.sol\";\n\n/// @title Gnosis Bridge Facet on Gnosis Chain\n/// @author LI.FI (https://li.fi)\n/// @notice Provides functionality for bridging through XDaiBridge\n/// @custom:version 1.0.0\ncontract GnosisBridgeL2Facet is\n ILiFi,\n ReentrancyGuard,\n SwapperV2,\n Validatable\n{\n /// Storage ///\n\n /// @notice The xDAI address on the source chain.\n address private constant XDAI = address(0);\n\n /// @notice The chain id of Ethereum Mainnet.\n uint64 private constant ETHEREUM_CHAIN_ID = 1;\n\n /// @notice The contract address of the xdai bridge on the source chain.\n IXDaiBridgeL2 private immutable xDaiBridge;\n\n /// Constructor ///\n\n /// @notice Initialize the contract.\n /// @param _xDaiBridge The contract address of the xdai bridge on the source chain.\n constructor(IXDaiBridgeL2 _xDaiBridge) {\n xDaiBridge = _xDaiBridge;\n }\n\n /// External Methods ///\n\n /// @notice Bridges tokens via XDaiBridge\n /// @param _bridgeData the core information needed for bridging\n function startBridgeTokensViaXDaiBridge(\n ILiFi.BridgeData memory _bridgeData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n doesNotContainSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n onlyAllowDestinationChain(_bridgeData, ETHEREUM_CHAIN_ID)\n onlyAllowSourceToken(_bridgeData, XDAI)\n {\n _startBridge(_bridgeData);\n }\n\n /// @notice Performs a swap before bridging via XDaiBridge\n /// @param _bridgeData the core information needed for bridging\n /// @param _swapData an object containing swap related data to perform swaps before bridging\n function swapAndStartBridgeTokensViaXDaiBridge(\n ILiFi.BridgeData memory _bridgeData,\n LibSwap.SwapData[] calldata _swapData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n containsSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n onlyAllowDestinationChain(_bridgeData, ETHEREUM_CHAIN_ID)\n onlyAllowSourceToken(_bridgeData, XDAI)\n {\n _bridgeData.minAmount = _depositAndSwap(\n _bridgeData.transactionId,\n _bridgeData.minAmount,\n _swapData,\n payable(msg.sender)\n );\n\n _startBridge(_bridgeData);\n }\n\n /// Private Methods ///\n\n /// @dev Contains the business logic for the bridge via XDaiBridge\n /// @param _bridgeData the core information needed for bridging\n function _startBridge(ILiFi.BridgeData memory _bridgeData) private {\n xDaiBridge.relayTokens{ value: _bridgeData.minAmount }(\n _bridgeData.receiver\n );\n emit LiFiTransferStarted(_bridgeData);\n }\n}\n" + }, + "src/Facets/HopFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { IHopBridge } from \"../Interfaces/IHopBridge.sol\";\nimport { LibAsset, IERC20 } from \"../Libraries/LibAsset.sol\";\nimport { LibDiamond } from \"../Libraries/LibDiamond.sol\";\nimport { ReentrancyGuard } from \"../Helpers/ReentrancyGuard.sol\";\nimport { InvalidConfig, AlreadyInitialized, NotInitialized } from \"../Errors/GenericErrors.sol\";\nimport { SwapperV2, LibSwap } from \"../Helpers/SwapperV2.sol\";\nimport { Validatable } from \"../Helpers/Validatable.sol\";\n\n/// @title Hop Facet\n/// @author LI.FI (https://li.fi)\n/// @notice Provides functionality for bridging through Hop\n/// @custom:version 2.0.0\ncontract HopFacet is ILiFi, ReentrancyGuard, SwapperV2, Validatable {\n /// Storage ///\n\n bytes32 internal constant NAMESPACE = keccak256(\"com.lifi.facets.hop\");\n\n /// Types ///\n\n struct Storage {\n mapping(address => IHopBridge) bridges;\n bool initialized; // no longer used but kept here to maintain the same storage layout\n }\n\n struct Config {\n address assetId;\n address bridge;\n }\n\n struct HopData {\n uint256 bonderFee;\n uint256 amountOutMin;\n uint256 deadline;\n uint256 destinationAmountOutMin;\n uint256 destinationDeadline;\n address relayer;\n uint256 relayerFee;\n uint256 nativeFee;\n }\n\n /// Events ///\n\n event HopInitialized(Config[] configs);\n event HopBridgeRegistered(address indexed assetId, address bridge);\n\n /// Init ///\n\n /// @notice Initialize local variables for the Hop Facet\n /// @param configs Bridge configuration data\n function initHop(Config[] calldata configs) external {\n LibDiamond.enforceIsContractOwner();\n\n Storage storage s = getStorage();\n\n for (uint256 i = 0; i < configs.length; i++) {\n if (configs[i].bridge == address(0)) {\n revert InvalidConfig();\n }\n s.bridges[configs[i].assetId] = IHopBridge(configs[i].bridge);\n }\n\n emit HopInitialized(configs);\n }\n\n /// External Methods ///\n\n /// @notice Register token and bridge\n /// @param assetId Address of token\n /// @param bridge Address of bridge for asset\n function registerBridge(address assetId, address bridge) external {\n LibDiamond.enforceIsContractOwner();\n\n Storage storage s = getStorage();\n\n if (bridge == address(0)) {\n revert InvalidConfig();\n }\n\n s.bridges[assetId] = IHopBridge(bridge);\n\n emit HopBridgeRegistered(assetId, bridge);\n }\n\n /// @notice Bridges tokens via Hop Protocol\n /// @param _bridgeData the core information needed for bridging\n /// @param _hopData data specific to Hop Protocol\n function startBridgeTokensViaHop(\n ILiFi.BridgeData memory _bridgeData,\n HopData calldata _hopData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n doesNotContainSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n LibAsset.depositAsset(\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount\n );\n _startBridge(_bridgeData, _hopData);\n }\n\n /// @notice Performs a swap before bridging via Hop Protocol\n /// @param _bridgeData the core information needed for bridging\n /// @param _swapData an array of swap related data for performing swaps before bridging\n /// @param _hopData data specific to Hop Protocol\n function swapAndStartBridgeTokensViaHop(\n ILiFi.BridgeData memory _bridgeData,\n LibSwap.SwapData[] calldata _swapData,\n HopData calldata _hopData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n containsSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n _bridgeData.minAmount = _depositAndSwap(\n _bridgeData.transactionId,\n _bridgeData.minAmount,\n _swapData,\n payable(msg.sender),\n _hopData.nativeFee\n );\n _startBridge(_bridgeData, _hopData);\n }\n\n /// private Methods ///\n\n /// @dev Contains the business logic for the bridge via Hop Protocol\n /// @param _bridgeData the core information needed for bridging\n /// @param _hopData data specific to Hop Protocol\n function _startBridge(\n ILiFi.BridgeData memory _bridgeData,\n HopData calldata _hopData\n ) private {\n address sendingAssetId = _bridgeData.sendingAssetId;\n Storage storage s = getStorage();\n IHopBridge bridge = s.bridges[sendingAssetId];\n\n // Give Hop approval to bridge tokens\n LibAsset.maxApproveERC20(\n IERC20(sendingAssetId),\n address(bridge),\n _bridgeData.minAmount\n );\n\n uint256 value = LibAsset.isNativeAsset(address(sendingAssetId))\n ? _hopData.nativeFee + _bridgeData.minAmount\n : _hopData.nativeFee;\n\n if (block.chainid == 1 || block.chainid == 5) {\n // Ethereum L1\n bridge.sendToL2{ value: value }(\n _bridgeData.destinationChainId,\n _bridgeData.receiver,\n _bridgeData.minAmount,\n _hopData.destinationAmountOutMin,\n _hopData.destinationDeadline,\n _hopData.relayer,\n _hopData.relayerFee\n );\n } else {\n // L2\n // solhint-disable-next-line check-send-result\n bridge.swapAndSend{ value: value }(\n _bridgeData.destinationChainId,\n _bridgeData.receiver,\n _bridgeData.minAmount,\n _hopData.bonderFee,\n _hopData.amountOutMin,\n _hopData.deadline,\n _hopData.destinationAmountOutMin,\n _hopData.destinationDeadline\n );\n }\n emit LiFiTransferStarted(_bridgeData);\n }\n\n /// @dev fetch local storage\n function getStorage() private pure returns (Storage storage s) {\n bytes32 namespace = NAMESPACE;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n s.slot := namespace\n }\n }\n}\n" + }, + "src/Facets/HopFacetOptimized.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { IHopBridge } from \"../Interfaces/IHopBridge.sol\";\nimport { LibAsset, IERC20 } from \"../Libraries/LibAsset.sol\";\nimport { SwapperV2, LibSwap } from \"../Helpers/SwapperV2.sol\";\nimport { LibDiamond } from \"../Libraries/LibDiamond.sol\";\n\n/// @title Hop Facet (Optimized)\n/// @author LI.FI (https://li.fi)\n/// @notice Provides functionality for bridging through Hop\n/// @custom:version 2.0.0\ncontract HopFacetOptimized is ILiFi, SwapperV2 {\n /// Types ///\n\n struct HopData {\n uint256 bonderFee;\n uint256 amountOutMin;\n uint256 deadline;\n uint256 destinationAmountOutMin;\n uint256 destinationDeadline;\n IHopBridge hopBridge;\n address relayer;\n uint256 relayerFee;\n uint256 nativeFee;\n }\n\n /// External Methods ///\n\n /// @notice Sets approval for the Hop Bridge to spend the specified token\n /// @param bridges The Hop Bridges to approve\n /// @param tokensToApprove The tokens to approve to approve to the Hop Bridges\n function setApprovalForBridges(\n address[] calldata bridges,\n address[] calldata tokensToApprove\n ) external {\n LibDiamond.enforceIsContractOwner();\n for (uint256 i; i < bridges.length; i++) {\n // Give Hop approval to bridge tokens\n LibAsset.maxApproveERC20(\n IERC20(tokensToApprove[i]),\n address(bridges[i]),\n type(uint256).max\n );\n }\n }\n\n /// @notice Bridges ERC20 tokens via Hop Protocol from L1\n /// @param _bridgeData the core information needed for bridging\n /// @param _hopData data specific to Hop Protocol\n function startBridgeTokensViaHopL1ERC20(\n ILiFi.BridgeData calldata _bridgeData,\n HopData calldata _hopData\n ) external payable {\n // Deposit assets\n LibAsset.transferFromERC20(\n _bridgeData.sendingAssetId,\n msg.sender,\n address(this),\n _bridgeData.minAmount\n );\n // Bridge assets\n _hopData.hopBridge.sendToL2{ value: _hopData.nativeFee }(\n _bridgeData.destinationChainId,\n _bridgeData.receiver,\n _bridgeData.minAmount,\n _hopData.destinationAmountOutMin,\n _hopData.destinationDeadline,\n _hopData.relayer,\n _hopData.relayerFee\n );\n emit LiFiTransferStarted(_bridgeData);\n }\n\n /// @notice Bridges Native tokens via Hop Protocol from L1\n /// @param _bridgeData the core information needed for bridging\n /// @param _hopData data specific to Hop Protocol\n function startBridgeTokensViaHopL1Native(\n ILiFi.BridgeData calldata _bridgeData,\n HopData calldata _hopData\n ) external payable {\n // Bridge assets\n _hopData.hopBridge.sendToL2{\n value: _bridgeData.minAmount + _hopData.nativeFee\n }(\n _bridgeData.destinationChainId,\n _bridgeData.receiver,\n _bridgeData.minAmount,\n _hopData.destinationAmountOutMin,\n _hopData.destinationDeadline,\n _hopData.relayer,\n _hopData.relayerFee\n );\n emit LiFiTransferStarted(_bridgeData);\n }\n\n /// @notice Performs a swap before bridging ERC20 tokens via Hop Protocol from L1\n /// @param _bridgeData the core information needed for bridging\n /// @param _swapData an array of swap related data for performing swaps before bridging\n /// @param _hopData data specific to Hop Protocol\n function swapAndStartBridgeTokensViaHopL1ERC20(\n ILiFi.BridgeData memory _bridgeData,\n LibSwap.SwapData[] calldata _swapData,\n HopData calldata _hopData\n ) external payable {\n // Deposit and swap assets\n _bridgeData.minAmount = _depositAndSwap(\n _bridgeData.transactionId,\n _bridgeData.minAmount,\n _swapData,\n payable(msg.sender),\n _hopData.nativeFee\n );\n\n // Bridge assets\n _hopData.hopBridge.sendToL2{ value: _hopData.nativeFee }(\n _bridgeData.destinationChainId,\n _bridgeData.receiver,\n _bridgeData.minAmount,\n _hopData.destinationAmountOutMin,\n _hopData.destinationDeadline,\n _hopData.relayer,\n _hopData.relayerFee\n );\n emit LiFiTransferStarted(_bridgeData);\n }\n\n /// @notice Performs a swap before bridging Native tokens via Hop Protocol from L1\n /// @param _bridgeData the core information needed for bridging\n /// @param _swapData an array of swap related data for performing swaps before bridging\n /// @param _hopData data specific to Hop Protocol\n function swapAndStartBridgeTokensViaHopL1Native(\n ILiFi.BridgeData memory _bridgeData,\n LibSwap.SwapData[] calldata _swapData,\n HopData calldata _hopData\n ) external payable {\n // Deposit and swap assets\n _bridgeData.minAmount = _depositAndSwap(\n _bridgeData.transactionId,\n _bridgeData.minAmount,\n _swapData,\n payable(msg.sender),\n _hopData.nativeFee\n );\n\n // Bridge assets\n _hopData.hopBridge.sendToL2{\n value: _bridgeData.minAmount + _hopData.nativeFee\n }(\n _bridgeData.destinationChainId,\n _bridgeData.receiver,\n _bridgeData.minAmount,\n _hopData.destinationAmountOutMin,\n _hopData.destinationDeadline,\n _hopData.relayer,\n _hopData.relayerFee\n );\n\n emit LiFiTransferStarted(_bridgeData);\n }\n\n /// @notice Bridges ERC20 tokens via Hop Protocol from L2\n /// @param _bridgeData the core information needed for bridging\n /// @param _hopData data specific to Hop Protocol\n function startBridgeTokensViaHopL2ERC20(\n ILiFi.BridgeData calldata _bridgeData,\n HopData calldata _hopData\n ) external {\n // Deposit assets\n LibAsset.transferFromERC20(\n _bridgeData.sendingAssetId,\n msg.sender,\n address(this),\n _bridgeData.minAmount\n );\n // Bridge assets\n _hopData.hopBridge.swapAndSend(\n _bridgeData.destinationChainId,\n _bridgeData.receiver,\n _bridgeData.minAmount,\n _hopData.bonderFee,\n _hopData.amountOutMin,\n _hopData.deadline,\n _hopData.destinationAmountOutMin,\n _hopData.destinationDeadline\n );\n emit LiFiTransferStarted(_bridgeData);\n }\n\n /// @notice Bridges Native tokens via Hop Protocol from L2\n /// @param _bridgeData the core information needed for bridging\n /// @param _hopData data specific to Hop Protocol\n function startBridgeTokensViaHopL2Native(\n ILiFi.BridgeData calldata _bridgeData,\n HopData calldata _hopData\n ) external payable {\n // Bridge assets\n _hopData.hopBridge.swapAndSend{ value: _bridgeData.minAmount }(\n _bridgeData.destinationChainId,\n _bridgeData.receiver,\n _bridgeData.minAmount,\n _hopData.bonderFee,\n _hopData.amountOutMin,\n _hopData.deadline,\n _hopData.destinationAmountOutMin,\n _hopData.destinationDeadline\n );\n emit LiFiTransferStarted(_bridgeData);\n }\n\n /// @notice Performs a swap before bridging ERC20 tokens via Hop Protocol from L2\n /// @param _bridgeData the core information needed for bridging\n /// @param _swapData an array of swap related data for performing swaps before bridging\n /// @param _hopData data specific to Hop Protocol\n function swapAndStartBridgeTokensViaHopL2ERC20(\n ILiFi.BridgeData memory _bridgeData,\n LibSwap.SwapData[] calldata _swapData,\n HopData calldata _hopData\n ) external payable {\n // Deposit and swap assets\n _bridgeData.minAmount = _depositAndSwap(\n _bridgeData.transactionId,\n _bridgeData.minAmount,\n _swapData,\n payable(msg.sender)\n );\n // Bridge assets\n _hopData.hopBridge.swapAndSend(\n _bridgeData.destinationChainId,\n _bridgeData.receiver,\n _bridgeData.minAmount,\n _hopData.bonderFee,\n _hopData.amountOutMin,\n _hopData.deadline,\n _hopData.destinationAmountOutMin,\n _hopData.destinationDeadline\n );\n emit LiFiTransferStarted(_bridgeData);\n }\n\n /// @notice Performs a swap before bridging Native tokens via Hop Protocol from L2\n /// @param _bridgeData the core information needed for bridging\n /// @param _swapData an array of swap related data for performing swaps before bridging\n /// @param _hopData data specific to Hop Protocol\n function swapAndStartBridgeTokensViaHopL2Native(\n ILiFi.BridgeData memory _bridgeData,\n LibSwap.SwapData[] calldata _swapData,\n HopData calldata _hopData\n ) external payable {\n // Deposit and swap assets\n _bridgeData.minAmount = _depositAndSwap(\n _bridgeData.transactionId,\n _bridgeData.minAmount,\n _swapData,\n payable(msg.sender)\n );\n // Bridge assets\n _hopData.hopBridge.swapAndSend{ value: _bridgeData.minAmount }(\n _bridgeData.destinationChainId,\n _bridgeData.receiver,\n _bridgeData.minAmount,\n _hopData.bonderFee,\n _hopData.amountOutMin,\n _hopData.deadline,\n _hopData.destinationAmountOutMin,\n _hopData.destinationDeadline\n );\n emit LiFiTransferStarted(_bridgeData);\n }\n}\n" + }, + "src/Facets/HopFacetPacked.sol": { + "content": "// // SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { IHopBridge, IL2AmmWrapper, ISwap } from \"../Interfaces/IHopBridge.sol\";\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { ERC20, SafeTransferLib } from \"../../lib/solmate/src/utils/SafeTransferLib.sol\";\nimport { LibAsset, IERC20 } from \"../Libraries/LibAsset.sol\";\nimport { TransferrableOwnership } from \"../Helpers/TransferrableOwnership.sol\";\nimport { HopFacetOptimized } from \"../../src/Facets/HopFacetOptimized.sol\";\nimport { WETH } from \"../../lib/solmate/src/tokens/WETH.sol\";\n\n/// @title Hop Facet (Optimized for Rollups)\n/// @author LI.FI (https://li.fi)\n/// @notice Provides functionality for bridging through Hop\n/// @custom:version 1.0.6\ncontract HopFacetPacked is ILiFi, TransferrableOwnership {\n using SafeTransferLib for ERC20;\n\n /// Storage ///\n\n address public immutable nativeBridge;\n address public immutable nativeL2CanonicalToken;\n address public immutable nativeHToken;\n address public immutable nativeExchangeAddress;\n\n /// Errors ///\n\n error Invalid();\n\n /// Events ///\n\n event LiFiHopTransfer(bytes8 _transactionId);\n\n /// Constructor ///\n\n /// @notice Initialize the contract.\n /// @param _owner The contract owner to approve tokens.\n /// @param _wrapper The address of Hop L2_AmmWrapper for native asset.\n constructor(\n address _owner,\n address _wrapper\n ) TransferrableOwnership(_owner) {\n bool wrapperIsSet = _wrapper != address(0);\n\n if (block.chainid == 1 && wrapperIsSet) {\n revert Invalid();\n }\n\n nativeL2CanonicalToken = wrapperIsSet\n ? IL2AmmWrapper(_wrapper).l2CanonicalToken()\n : address(0);\n nativeHToken = wrapperIsSet\n ? IL2AmmWrapper(_wrapper).hToken()\n : address(0);\n nativeExchangeAddress = wrapperIsSet\n ? IL2AmmWrapper(_wrapper).exchangeAddress()\n : address(0);\n nativeBridge = wrapperIsSet\n ? IL2AmmWrapper(_wrapper).bridge()\n : address(0);\n }\n\n /// External Methods ///\n\n /// @dev Only meant to be called outside of the context of the diamond\n /// @notice Sets approval for the Hop Bridge to spend the specified token\n /// @param bridges The Hop Bridges to approve\n /// @param tokensToApprove The tokens to approve to approve to the Hop Bridges\n function setApprovalForHopBridges(\n address[] calldata bridges,\n address[] calldata tokensToApprove\n ) external onlyOwner {\n uint256 numBridges = bridges.length;\n\n for (uint256 i; i < numBridges; i++) {\n // Give Hop approval to bridge tokens\n LibAsset.maxApproveERC20(\n IERC20(tokensToApprove[i]),\n address(bridges[i]),\n type(uint256).max\n );\n }\n }\n\n /// @notice Bridges Native tokens via Hop Protocol from L2\n /// No params, all data will be extracted from manually encoded callData\n function startBridgeTokensViaHopL2NativePacked() external payable {\n // first 4 bytes are function signature\n // transactionId: bytes8(msg.data[4:12]),\n // receiver: address(bytes20(msg.data[12:32])),\n // destinationChainId: uint256(uint32(bytes4(msg.data[32:36]))),\n // bonderFee: uint256(uint128(bytes16(msg.data[36:52]))),\n // amountOutMin: uint256(uint128(bytes16(msg.data[52:68])))\n // => total calldata length required: 68\n\n uint256 destinationChainId = uint256(uint32(bytes4(msg.data[32:36])));\n uint256 amountOutMin = uint256(uint128(bytes16(msg.data[52:68])));\n bool toL1 = destinationChainId == 1;\n\n // Wrap ETH\n WETH(payable(nativeL2CanonicalToken)).deposit{ value: msg.value }();\n\n // Exchange WETH for hToken\n uint256 swapAmount = ISwap(nativeExchangeAddress).swap(\n 0,\n 1,\n msg.value,\n amountOutMin,\n block.timestamp\n );\n\n // Bridge assets\n // solhint-disable-next-line check-send-result\n IHopBridge(nativeBridge).send(\n destinationChainId,\n address(bytes20(msg.data[12:32])), // receiver\n swapAmount,\n uint256(uint128(bytes16(msg.data[36:52]))), // bonderFee\n toL1 ? 0 : amountOutMin,\n toL1 ? 0 : block.timestamp + 7 * 24 * 60 * 60\n );\n\n emit LiFiHopTransfer(\n bytes8(msg.data[4:12]) // transactionId\n );\n }\n\n /// @notice Bridges Native tokens via Hop Protocol from L2\n /// @param transactionId Custom transaction ID for tracking\n /// @param receiver Receiving wallet address\n /// @param destinationChainId Receiving chain\n /// @param bonderFee Fees payed to hop bonder\n /// @param amountOutMin Source swap minimal accepted amount\n /// @param destinationAmountOutMin Destination swap minimal accepted amount\n /// @param destinationDeadline Destination swap maximal time\n /// @param hopBridge Address of the Hop L2_AmmWrapper\n function startBridgeTokensViaHopL2NativeMin(\n bytes8 transactionId,\n address receiver,\n uint256 destinationChainId,\n uint256 bonderFee,\n uint256 amountOutMin,\n uint256 destinationAmountOutMin,\n uint256 destinationDeadline,\n address hopBridge\n ) external payable {\n // Bridge assets\n IHopBridge(hopBridge).swapAndSend{ value: msg.value }(\n destinationChainId,\n receiver,\n msg.value,\n bonderFee,\n amountOutMin,\n block.timestamp,\n destinationAmountOutMin,\n destinationDeadline\n );\n\n emit LiFiHopTransfer(transactionId);\n }\n\n /// @notice Bridges Native tokens via Hop Protocol from L2\n /// @param transactionId Custom transaction ID for tracking\n /// @param receiver Receiving wallet address\n /// @param destinationChainId Receiving chain\n /// @param bonderFee Fees payed to hop bonder\n /// @param amountOutMin Source swap minimal accepted amount\n function encode_startBridgeTokensViaHopL2NativePacked(\n bytes8 transactionId,\n address receiver,\n uint256 destinationChainId,\n uint256 bonderFee,\n uint256 amountOutMin\n ) external pure returns (bytes memory) {\n require(\n destinationChainId <= type(uint32).max,\n \"destinationChainId value passed too big to fit in uint32\"\n );\n require(\n bonderFee <= type(uint128).max,\n \"bonderFee value passed too big to fit in uint128\"\n );\n require(\n amountOutMin <= type(uint128).max,\n \"amountOutMin value passed too big to fit in uint128\"\n );\n\n return\n bytes.concat(\n HopFacetPacked.startBridgeTokensViaHopL2NativePacked.selector,\n bytes8(transactionId),\n bytes20(receiver),\n bytes4(uint32(destinationChainId)),\n bytes16(uint128(bonderFee)),\n bytes16(uint128(amountOutMin))\n );\n }\n\n /// @notice Decodes calldata for startBridgeTokensViaHopL2NativePacked\n /// @param _data the calldata to decode\n function decode_startBridgeTokensViaHopL2NativePacked(\n bytes calldata _data\n )\n external\n pure\n returns (BridgeData memory, HopFacetOptimized.HopData memory)\n {\n require(\n _data.length >= 68,\n \"data passed in is not the correct length\"\n );\n\n BridgeData memory bridgeData;\n HopFacetOptimized.HopData memory hopData;\n\n bridgeData.transactionId = bytes32(bytes8(_data[4:12]));\n bridgeData.receiver = address(bytes20(_data[12:32]));\n bridgeData.destinationChainId = uint256(uint32(bytes4(_data[32:36])));\n hopData.bonderFee = uint256(uint128(bytes16(_data[36:52])));\n hopData.amountOutMin = uint256(uint128(bytes16(_data[52:68])));\n\n return (bridgeData, hopData);\n }\n\n /// @notice Bridges ERC20 tokens via Hop Protocol from L2\n /// No params, all data will be extracted from manually encoded callData\n function startBridgeTokensViaHopL2ERC20Packed() external {\n // first 4 bytes are function signature\n // transactionId: bytes8(msg.data[4:12]),\n // receiver: address(bytes20(msg.data[12:32])),\n // destinationChainId: uint256(uint32(bytes4(msg.data[32:36]))),\n // sendingAssetId: address(bytes20(msg.data[36:56])),\n // amount: uint256(uint128(bytes16(msg.data[56:72]))),\n // bonderFee: uint256(uint128(bytes16(msg.data[72:88]))),\n // amountOutMin: uint256(uint128(bytes16(msg.data[88:104]))),\n // destinationAmountOutMin: uint256(uint128(bytes16(msg.data[104:120]))),\n // destinationDeadline: uint256(uint32(bytes4(msg.data[120:124]))),\n // wrapper: address(bytes20(msg.data[124:144]))\n // => total calldata length required: 144\n\n uint256 destinationChainId = uint256(uint32(bytes4(msg.data[32:36])));\n uint256 amount = uint256(uint128(bytes16(msg.data[56:72])));\n uint256 amountOutMin = uint256(uint128(bytes16(msg.data[88:104])));\n bool toL1 = destinationChainId == 1;\n\n IL2AmmWrapper wrapper = IL2AmmWrapper(\n address(bytes20(msg.data[124:144]))\n );\n\n // Deposit assets\n ERC20(address(bytes20(msg.data[36:56]))).safeTransferFrom(\n msg.sender,\n address(this),\n amount\n );\n\n // Exchange sending asset to hToken\n uint256 swapAmount = ISwap(wrapper.exchangeAddress()).swap(\n 0,\n 1,\n amount,\n amountOutMin,\n block.timestamp\n );\n\n // Bridge assets\n // solhint-disable-next-line check-send-result\n IHopBridge(wrapper.bridge()).send(\n destinationChainId,\n address(bytes20(msg.data[12:32])),\n swapAmount,\n uint256(uint128(bytes16(msg.data[72:88]))),\n toL1 ? 0 : uint256(uint128(bytes16(msg.data[104:120]))),\n toL1 ? 0 : uint256(uint32(bytes4(msg.data[120:124])))\n );\n\n emit LiFiHopTransfer(bytes8(msg.data[4:12]));\n }\n\n /// @notice Bridges ERC20 tokens via Hop Protocol from L2\n /// @param transactionId Custom transaction ID for tracking\n /// @param receiver Receiving wallet address\n /// @param destinationChainId Receiving chain\n /// @param sendingAssetId Address of the source asset to bridge\n /// @param minAmount Amount of the source asset to bridge\n /// @param bonderFee Fees payed to hop bonder\n /// @param amountOutMin Source swap minimal accepted amount\n /// @param destinationAmountOutMin Destination swap minimal accepted amount\n /// @param destinationDeadline Destination swap maximal time\n /// @param hopBridge Address of the Hop L2_AmmWrapper\n function startBridgeTokensViaHopL2ERC20Min(\n bytes8 transactionId,\n address receiver,\n uint256 destinationChainId,\n address sendingAssetId,\n uint256 minAmount,\n uint256 bonderFee,\n uint256 amountOutMin,\n uint256 destinationAmountOutMin,\n uint256 destinationDeadline,\n address hopBridge\n ) external {\n // Deposit assets\n ERC20(sendingAssetId).safeTransferFrom(\n msg.sender,\n address(this),\n minAmount\n );\n\n // Bridge assets\n IHopBridge(hopBridge).swapAndSend(\n destinationChainId,\n receiver,\n minAmount,\n bonderFee,\n amountOutMin,\n block.timestamp,\n destinationAmountOutMin,\n destinationDeadline\n );\n\n emit LiFiHopTransfer(transactionId);\n }\n\n /// @notice Bridges ERC20 tokens via Hop Protocol from L2\n /// @param transactionId Custom transaction ID for tracking\n /// @param receiver Receiving wallet address\n /// @param destinationChainId Receiving chain\n /// @param sendingAssetId Address of the source asset to bridge\n /// @param minAmount Amount of the source asset to bridge\n /// @param bonderFee Fees payed to hop bonder\n /// @param amountOutMin Source swap minimal accepted amount\n /// @param destinationAmountOutMin Destination swap minimal accepted amount\n /// @param destinationDeadline Destination swap maximal time\n /// @param wrapper Address of the Hop L2_AmmWrapper\n function encode_startBridgeTokensViaHopL2ERC20Packed(\n bytes32 transactionId,\n address receiver,\n uint256 destinationChainId,\n address sendingAssetId,\n uint256 minAmount,\n uint256 bonderFee,\n uint256 amountOutMin,\n uint256 destinationAmountOutMin,\n uint256 destinationDeadline,\n address wrapper\n ) external pure returns (bytes memory) {\n require(\n destinationChainId <= type(uint32).max,\n \"destinationChainId value passed too big to fit in uint32\"\n );\n require(\n minAmount <= type(uint128).max,\n \"amount value passed too big to fit in uint128\"\n );\n require(\n bonderFee <= type(uint128).max,\n \"bonderFee value passed too big to fit in uint128\"\n );\n require(\n amountOutMin <= type(uint128).max,\n \"amountOutMin value passed too big to fit in uint128\"\n );\n require(\n destinationAmountOutMin <= type(uint128).max,\n \"destinationAmountOutMin value passed too big to fit in uint128\"\n );\n require(\n destinationDeadline <= type(uint32).max,\n \"destinationDeadline value passed too big to fit in uint32\"\n );\n\n return\n bytes.concat(\n HopFacetPacked.startBridgeTokensViaHopL2ERC20Packed.selector,\n bytes8(transactionId),\n bytes20(receiver),\n bytes4(uint32(destinationChainId)),\n bytes20(sendingAssetId),\n bytes16(uint128(minAmount)),\n bytes16(uint128(bonderFee)),\n bytes16(uint128(amountOutMin)),\n bytes16(uint128(destinationAmountOutMin)),\n bytes4(uint32(destinationDeadline)),\n bytes20(wrapper)\n );\n }\n\n /// @notice Decodes calldata for startBridgeTokensViaHopL2ERC20Packed\n /// @param _data the calldata to decode\n function decode_startBridgeTokensViaHopL2ERC20Packed(\n bytes calldata _data\n )\n external\n pure\n returns (BridgeData memory, HopFacetOptimized.HopData memory)\n {\n require(\n _data.length >= 144,\n \"data passed in is not the correct length\"\n );\n\n BridgeData memory bridgeData;\n HopFacetOptimized.HopData memory hopData;\n\n bridgeData.transactionId = bytes32(bytes8(_data[4:12]));\n bridgeData.receiver = address(bytes20(_data[12:32]));\n bridgeData.destinationChainId = uint256(uint32(bytes4(_data[32:36])));\n bridgeData.sendingAssetId = address(bytes20(_data[36:56]));\n bridgeData.minAmount = uint256(uint128(bytes16(_data[56:72])));\n hopData.bonderFee = uint256(uint128(bytes16(_data[72:88])));\n hopData.amountOutMin = uint256(uint128(bytes16(_data[88:104])));\n hopData.destinationAmountOutMin = uint256(\n uint128(bytes16(_data[104:120]))\n );\n hopData.destinationDeadline = uint256(uint32(bytes4(_data[120:124])));\n hopData.hopBridge = IHopBridge(address(bytes20(_data[124:144])));\n\n return (bridgeData, hopData);\n }\n\n /// @notice Bridges Native tokens via Hop Protocol from L1\n /// No params, all data will be extracted from manually encoded callData\n function startBridgeTokensViaHopL1NativePacked() external payable {\n // first 4 bytes are function signature\n // transactionId: bytes8(msg.data[4:12]),\n // receiver: address(bytes20(msg.data[12:32])),\n // destinationChainId: uint256(uint32(bytes4(msg.data[32:36]))),\n // destinationAmountOutMin: uint256(uint128(bytes16(msg.data[36:52]))),\n // relayer: address(bytes20(msg.data[52:72])),\n // relayerFee: uint256(uint128(bytes16(msg.data[72:88]))),\n // hopBridge: address(bytes20(msg.data[88:108]))\n // => total calldata length required: 108\n\n // Bridge assets\n IHopBridge(address(bytes20(msg.data[88:108]))).sendToL2{\n value: msg.value\n }(\n uint256(uint32(bytes4(msg.data[32:36]))),\n address(bytes20(msg.data[12:32])),\n msg.value,\n uint256(uint128(bytes16(msg.data[36:52]))),\n block.timestamp + 7 * 24 * 60 * 60,\n address(bytes20(msg.data[52:72])),\n uint256(uint128(bytes16(msg.data[72:88])))\n );\n\n emit LiFiHopTransfer(bytes8(msg.data[4:12]));\n }\n\n /// @notice Bridges Native tokens via Hop Protocol from L1\n /// @param transactionId Custom transaction ID for tracking\n /// @param receiver Receiving wallet address\n /// @param destinationChainId Receiving chain\n /// @param destinationAmountOutMin Destination swap minimal accepted amount\n /// @param relayer needed for gas spikes\n /// @param relayerFee needed for gas spikes\n /// @param hopBridge Address of the Hop Bridge\n function startBridgeTokensViaHopL1NativeMin(\n bytes8 transactionId,\n address receiver,\n uint256 destinationChainId,\n uint256 destinationAmountOutMin,\n address relayer,\n uint256 relayerFee,\n address hopBridge\n ) external payable {\n // Bridge assets\n IHopBridge(hopBridge).sendToL2{ value: msg.value }(\n destinationChainId,\n receiver,\n msg.value,\n destinationAmountOutMin,\n block.timestamp + 7 * 24 * 60 * 60,\n relayer,\n relayerFee\n );\n\n emit LiFiHopTransfer(transactionId);\n }\n\n /// @notice Bridges Native tokens via Hop Protocol from L1\n /// @param transactionId Custom transaction ID for tracking\n /// @param receiver Receiving wallet address\n /// @param destinationChainId Receiving chain\n /// @param destinationAmountOutMin Destination swap minimal accepted amount\n /// @param relayer needed for gas spikes\n /// @param relayerFee needed for gas spikes\n /// @param hopBridge Address of the Hop Bridge\n function encode_startBridgeTokensViaHopL1NativePacked(\n bytes8 transactionId,\n address receiver,\n uint256 destinationChainId,\n uint256 destinationAmountOutMin,\n address relayer,\n uint256 relayerFee,\n address hopBridge\n ) external pure returns (bytes memory) {\n require(\n destinationChainId <= type(uint32).max,\n \"destinationChainId value passed too big to fit in uint32\"\n );\n require(\n destinationAmountOutMin <= type(uint128).max,\n \"destinationAmountOutMin value passed too big to fit in uint128\"\n );\n require(\n relayerFee <= type(uint128).max,\n \"relayerFee value passed too big to fit in uint128\"\n );\n\n return\n bytes.concat(\n HopFacetPacked.startBridgeTokensViaHopL1NativePacked.selector,\n bytes8(transactionId),\n bytes20(receiver),\n bytes4(uint32(destinationChainId)),\n bytes16(uint128(destinationAmountOutMin)),\n bytes20(relayer),\n bytes16(uint128(relayerFee)),\n bytes20(hopBridge)\n );\n }\n\n /// @notice Decodes calldata for startBridgeTokensViaHopL1NativePacked\n /// @param _data the calldata to decode\n function decode_startBridgeTokensViaHopL1NativePacked(\n bytes calldata _data\n )\n external\n pure\n returns (BridgeData memory, HopFacetOptimized.HopData memory)\n {\n require(\n _data.length >= 108,\n \"data passed in is not the correct length\"\n );\n\n BridgeData memory bridgeData;\n HopFacetOptimized.HopData memory hopData;\n\n bridgeData.transactionId = bytes32(bytes8(_data[4:12]));\n bridgeData.receiver = address(bytes20(_data[12:32]));\n bridgeData.destinationChainId = uint256(uint32(bytes4(_data[32:36])));\n hopData.destinationAmountOutMin = uint256(\n uint128(bytes16(_data[36:52]))\n );\n // relayer = address(bytes20(_data[52:72]));\n // relayerFee = uint256(uint128(bytes16(_data[72:88])));\n hopData.hopBridge = IHopBridge(address(bytes20(_data[88:108])));\n\n return (bridgeData, hopData);\n }\n\n /// @notice Bridges Native tokens via Hop Protocol from L1\n /// No params, all data will be extracted from manually encoded callData\n function startBridgeTokensViaHopL1ERC20Packed() external payable {\n // first 4 bytes are function signature\n // transactionId: bytes8(msg.data[4:12]),\n // receiver: address(bytes20(msg.data[12:32])),\n // destinationChainId: uint256(uint32(bytes4(msg.data[32:36]))),\n // sendingAssetId: address(bytes20(msg.data[36:56])),\n // amount: uint256(uint128(bytes16(msg.data[56:72]))),\n // destinationAmountOutMin: uint256(uint128(bytes16(msg.data[72:88]))),\n // relayer: address(bytes20(msg.data[88:108])),\n // relayerFee: uint256(uint128(bytes16(msg.data[108:124]))),\n // hopBridge: address(bytes20(msg.data[124:144]))\n // => total calldata length required: 144\n\n uint256 amount = uint256(uint128(bytes16(msg.data[56:72])));\n\n // Deposit assets\n ERC20(address(bytes20(msg.data[36:56]))).safeTransferFrom(\n msg.sender,\n address(this),\n amount\n );\n\n // Bridge assets\n IHopBridge(address(bytes20(msg.data[124:144]))).sendToL2(\n uint256(uint32(bytes4(msg.data[32:36]))),\n address(bytes20(msg.data[12:32])),\n amount,\n uint256(uint128(bytes16(msg.data[72:88]))),\n block.timestamp + 7 * 24 * 60 * 60,\n address(bytes20(msg.data[88:108])),\n uint256(uint128(bytes16(msg.data[108:124])))\n );\n\n emit LiFiHopTransfer(bytes8(msg.data[4:12]));\n }\n\n /// @notice Bridges ERC20 tokens via Hop Protocol from L1\n /// @param transactionId Custom transaction ID for tracking\n /// @param receiver Receiving wallet address\n /// @param destinationChainId Receiving chain\n /// @param sendingAssetId Address of the source asset to bridge\n /// @param minAmount Amount of the source asset to bridge\n /// @param destinationAmountOutMin Destination swap minimal accepted amount\n /// @param relayer needed for gas spikes\n /// @param relayerFee needed for gas spikes\n /// @param hopBridge Address of the Hop Bridge\n function startBridgeTokensViaHopL1ERC20Min(\n bytes8 transactionId,\n address receiver,\n uint256 destinationChainId,\n address sendingAssetId,\n uint256 minAmount,\n uint256 destinationAmountOutMin,\n address relayer,\n uint256 relayerFee,\n address hopBridge\n ) external {\n // Deposit assets\n ERC20(sendingAssetId).safeTransferFrom(\n msg.sender,\n address(this),\n minAmount\n );\n\n // Bridge assets\n IHopBridge(hopBridge).sendToL2(\n destinationChainId,\n receiver,\n minAmount,\n destinationAmountOutMin,\n block.timestamp + 7 * 24 * 60 * 60,\n relayer,\n relayerFee\n );\n\n emit LiFiHopTransfer(transactionId);\n }\n\n /// @notice Bridges ERC20 tokens via Hop Protocol from L1\n /// @param transactionId Custom transaction ID for tracking\n /// @param receiver Receiving wallet address\n /// @param destinationChainId Receiving chain\n /// @param sendingAssetId Address of the source asset to bridge\n /// @param minAmount Amount of the source asset to bridge\n /// @param destinationAmountOutMin Destination swap minimal accepted amount\n /// @param relayer needed for gas spikes\n /// @param relayerFee needed for gas spikes\n /// @param hopBridge Address of the Hop Bridge\n function encode_startBridgeTokensViaHopL1ERC20Packed(\n bytes8 transactionId,\n address receiver,\n uint256 destinationChainId,\n address sendingAssetId,\n uint256 minAmount,\n uint256 destinationAmountOutMin,\n address relayer,\n uint256 relayerFee,\n address hopBridge\n ) external pure returns (bytes memory) {\n require(\n destinationChainId <= type(uint32).max,\n \"destinationChainId value passed too big to fit in uint32\"\n );\n require(\n minAmount <= type(uint128).max,\n \"amount value passed too big to fit in uint128\"\n );\n require(\n destinationAmountOutMin <= type(uint128).max,\n \"destinationAmountOutMin value passed too big to fit in uint128\"\n );\n require(\n relayerFee <= type(uint128).max,\n \"relayerFee value passed too big to fit in uint128\"\n );\n\n return\n bytes.concat(\n HopFacetPacked.startBridgeTokensViaHopL1ERC20Packed.selector,\n bytes8(transactionId),\n bytes20(receiver),\n bytes4(uint32(destinationChainId)),\n bytes20(sendingAssetId),\n bytes16(uint128(minAmount)),\n bytes16(uint128(destinationAmountOutMin)),\n bytes20(relayer),\n bytes16(uint128(relayerFee)),\n bytes20(hopBridge)\n );\n }\n\n /// @notice Decodes calldata for startBridgeTokensViaHopL1ERC20Packed\n /// @param _data the calldata to decode\n function decode_startBridgeTokensViaHopL1ERC20Packed(\n bytes calldata _data\n )\n external\n pure\n returns (BridgeData memory, HopFacetOptimized.HopData memory)\n {\n require(\n _data.length >= 144,\n \"data passed in is not the correct length\"\n );\n\n BridgeData memory bridgeData;\n HopFacetOptimized.HopData memory hopData;\n\n bridgeData.transactionId = bytes32(bytes8(_data[4:12]));\n bridgeData.receiver = address(bytes20(_data[12:32]));\n bridgeData.destinationChainId = uint256(uint32(bytes4(_data[32:36])));\n bridgeData.sendingAssetId = address(bytes20(_data[36:56]));\n bridgeData.minAmount = uint256(uint128(bytes16(_data[56:72])));\n hopData.destinationAmountOutMin = uint256(\n uint128(bytes16(_data[72:88]))\n );\n // relayer = address(bytes20(_data[88:108]));\n // relayerFee = uint256(uint128(bytes16(_data[108:124])));\n hopData.hopBridge = IHopBridge(address(bytes20(_data[124:144])));\n\n return (bridgeData, hopData);\n }\n}\n" + }, + "src/Facets/HyphenFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { IHyphenRouter } from \"../Interfaces/IHyphenRouter.sol\";\nimport { LibAsset, IERC20 } from \"../Libraries/LibAsset.sol\";\nimport { ReentrancyGuard } from \"../Helpers/ReentrancyGuard.sol\";\nimport { SwapperV2, LibSwap } from \"../Helpers/SwapperV2.sol\";\nimport { Validatable } from \"../Helpers/Validatable.sol\";\n\n/// @title Hyphen Facet\n/// @author LI.FI (https://li.fi)\n/// @notice Provides functionality for bridging through Hyphen\n/// @custom:version 1.0.0\ncontract HyphenFacet is ILiFi, ReentrancyGuard, SwapperV2, Validatable {\n /// Storage ///\n\n /// @notice The contract address of the router on the source chain.\n IHyphenRouter private immutable router;\n\n /// Constructor ///\n\n /// @notice Initialize the contract.\n /// @param _router The contract address of the router on the source chain.\n constructor(IHyphenRouter _router) {\n router = _router;\n }\n\n /// External Methods ///\n\n /// @notice Bridges tokens via Hyphen\n /// @param _bridgeData the core information needed for bridging\n function startBridgeTokensViaHyphen(\n ILiFi.BridgeData memory _bridgeData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n doesNotContainSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n LibAsset.depositAsset(\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount\n );\n _startBridge(_bridgeData);\n }\n\n /// @notice Performs a swap before bridging via Hyphen\n /// @param _bridgeData the core information needed for bridging\n /// @param _swapData an array of swap related data for performing swaps before bridging\n function swapAndStartBridgeTokensViaHyphen(\n ILiFi.BridgeData memory _bridgeData,\n LibSwap.SwapData[] calldata _swapData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n containsSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n _bridgeData.minAmount = _depositAndSwap(\n _bridgeData.transactionId,\n _bridgeData.minAmount,\n _swapData,\n payable(msg.sender)\n );\n _startBridge(_bridgeData);\n }\n\n /// Private Methods ///\n\n /// @dev Contains the business logic for the bridge via Hyphen\n /// @param _bridgeData the core information needed for bridging\n function _startBridge(ILiFi.BridgeData memory _bridgeData) private {\n if (!LibAsset.isNativeAsset(_bridgeData.sendingAssetId)) {\n // Give the Hyphen router approval to bridge tokens\n LibAsset.maxApproveERC20(\n IERC20(_bridgeData.sendingAssetId),\n address(router),\n _bridgeData.minAmount\n );\n\n router.depositErc20(\n _bridgeData.destinationChainId,\n _bridgeData.sendingAssetId,\n _bridgeData.receiver,\n _bridgeData.minAmount,\n \"LIFI\"\n );\n } else {\n router.depositNative{ value: _bridgeData.minAmount }(\n _bridgeData.receiver,\n _bridgeData.destinationChainId,\n \"LIFI\"\n );\n }\n\n emit LiFiTransferStarted(_bridgeData);\n }\n}\n" + }, + "src/Facets/LIFuelFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { ServiceFeeCollector } from \"../Periphery/ServiceFeeCollector.sol\";\nimport { LibAsset, IERC20 } from \"../Libraries/LibAsset.sol\";\nimport { ReentrancyGuard } from \"../Helpers/ReentrancyGuard.sol\";\nimport { SwapperV2, LibSwap } from \"../Helpers/SwapperV2.sol\";\nimport { Validatable } from \"../Helpers/Validatable.sol\";\n\n/// @title LIFuel Facet\n/// @author Li.Finance (https://li.finance)\n/// @notice Provides functionality for bridging gas through LIFuel\n/// @custom:version 1.0.0\ncontract LIFuelFacet is ILiFi, ReentrancyGuard, SwapperV2, Validatable {\n /// Storage ///\n\n bytes32 internal constant NAMESPACE =\n keccak256(\"com.lifi.facets.periphery_registry\");\n string internal constant FEE_COLLECTOR_NAME = \"ServiceFeeCollector\";\n\n /// Types ///\n\n struct Storage {\n mapping(string => address) contracts;\n }\n\n /// External Methods ///\n\n /// @notice Bridges tokens via LIFuel Bridge\n /// @param _bridgeData Data used purely for tracking and analytics\n function startBridgeTokensViaLIFuel(\n ILiFi.BridgeData memory _bridgeData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n doesNotContainSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n LibAsset.depositAsset(\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount\n );\n _startBridge(_bridgeData);\n }\n\n /// @notice Performs a swap before bridging via LIFuel Bridge\n /// @param _bridgeData Data used purely for tracking and analytics\n /// @param _swapData An array of swap related data for performing swaps before bridging\n function swapAndStartBridgeTokensViaLIFuel(\n ILiFi.BridgeData memory _bridgeData,\n LibSwap.SwapData[] calldata _swapData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n containsSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n _bridgeData.minAmount = _depositAndSwap(\n _bridgeData.transactionId,\n _bridgeData.minAmount,\n _swapData,\n payable(msg.sender)\n );\n\n _startBridge(_bridgeData);\n }\n\n /// Private Methods ///\n\n /// @dev Contains the business logic for the bridge via LIFuel Bridge\n /// @param _bridgeData Data used purely for tracking and analytics\n function _startBridge(ILiFi.BridgeData memory _bridgeData) private {\n ServiceFeeCollector serviceFeeCollector = ServiceFeeCollector(\n getStorage().contracts[FEE_COLLECTOR_NAME]\n );\n\n if (LibAsset.isNativeAsset(_bridgeData.sendingAssetId)) {\n serviceFeeCollector.collectNativeGasFees{\n value: _bridgeData.minAmount\n }(_bridgeData.destinationChainId, _bridgeData.receiver);\n } else {\n LibAsset.maxApproveERC20(\n IERC20(_bridgeData.sendingAssetId),\n address(serviceFeeCollector),\n _bridgeData.minAmount\n );\n\n serviceFeeCollector.collectTokenGasFees(\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount,\n _bridgeData.destinationChainId,\n _bridgeData.receiver\n );\n }\n\n emit LiFiTransferStarted(_bridgeData);\n }\n\n /// @dev fetch local storage\n function getStorage() private pure returns (Storage storage s) {\n bytes32 namespace = NAMESPACE;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n s.slot := namespace\n }\n }\n}\n" + }, + "src/Facets/MakerTeleportFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport \"../../lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\";\nimport \"../../lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol\";\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { ITeleportGateway } from \"../Interfaces/ITeleportGateway.sol\";\nimport { LibAsset } from \"../Libraries/LibAsset.sol\";\nimport { LibSwap } from \"../Libraries/LibSwap.sol\";\nimport { ReentrancyGuard } from \"../Helpers/ReentrancyGuard.sol\";\nimport { SwapperV2 } from \"../Helpers/SwapperV2.sol\";\nimport { Validatable } from \"../Helpers/Validatable.sol\";\nimport { InvalidSendingToken, NoSwapDataProvided } from \"../Errors/GenericErrors.sol\";\n\n/// @title MakerTeleport Facet\n/// @author LI.FI (https://li.fi)\n/// @notice Provides functionality for bridging through Maker Teleport\n/// @custom:version 1.0.0\ncontract MakerTeleportFacet is ILiFi, ReentrancyGuard, SwapperV2, Validatable {\n using SafeCast for uint256;\n\n /// Storage ///\n\n /// @notice The address of Teleport Gateway.\n ITeleportGateway private immutable teleportGateway;\n\n /// @notice The address of DAI on the source chain.\n address private immutable dai;\n\n /// @notice The chain id of destination chain.\n uint256 private immutable dstChainId;\n\n /// @notice The domain of l1 network.\n bytes32 private immutable l1Domain;\n\n /// Constructor ///\n\n /// @notice Initialize the contract.\n /// @param _teleportGateway The address of Teleport Gateway.\n /// @param _dai The address of DAI on the source chain.\n /// @param _dstChainId The chain id of destination chain.\n /// @param _l1Domain The domain of l1 network.\n constructor(\n ITeleportGateway _teleportGateway,\n address _dai,\n uint256 _dstChainId,\n bytes32 _l1Domain\n ) {\n dstChainId = _dstChainId;\n teleportGateway = _teleportGateway;\n dai = _dai;\n l1Domain = _l1Domain;\n }\n\n /// External Methods ///\n\n /// @notice Bridges tokens via Maker Teleport\n /// @param _bridgeData The core information needed for bridging\n function startBridgeTokensViaMakerTeleport(\n ILiFi.BridgeData memory _bridgeData\n )\n external\n nonReentrant\n validateBridgeData(_bridgeData)\n doesNotContainSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n onlyAllowDestinationChain(_bridgeData, dstChainId)\n onlyAllowSourceToken(_bridgeData, dai)\n {\n LibAsset.depositAsset(dai, _bridgeData.minAmount);\n _startBridge(_bridgeData);\n }\n\n /// @notice Performs a swap before bridging via Maker Teleport\n /// @param _bridgeData The core information needed for bridging\n /// @param _swapData An array of swap related data for performing swaps before bridging\n function swapAndStartBridgeTokensViaMakerTeleport(\n ILiFi.BridgeData memory _bridgeData,\n LibSwap.SwapData[] calldata _swapData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n validateBridgeData(_bridgeData)\n containsSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n onlyAllowDestinationChain(_bridgeData, dstChainId)\n onlyAllowSourceToken(_bridgeData, dai)\n {\n _bridgeData.minAmount = _depositAndSwap(\n _bridgeData.transactionId,\n _bridgeData.minAmount,\n _swapData,\n payable(msg.sender)\n );\n\n _startBridge(_bridgeData);\n }\n\n /// Internal Methods ///\n\n /// @dev Contains the business logic for the bridge via Maker Teleport\n /// @param _bridgeData The core information needed for bridging\n function _startBridge(ILiFi.BridgeData memory _bridgeData) internal {\n LibAsset.maxApproveERC20(\n IERC20(dai),\n address(teleportGateway),\n _bridgeData.minAmount\n );\n\n teleportGateway.initiateTeleport(\n l1Domain,\n _bridgeData.receiver,\n _bridgeData.minAmount.toUint128()\n );\n\n emit LiFiTransferStarted(_bridgeData);\n }\n}\n" + }, + "src/Facets/MultichainFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { LibAsset, IERC20 } from \"../Libraries/LibAsset.sol\";\nimport { LibDiamond } from \"../Libraries/LibDiamond.sol\";\nimport { IMultichainRouter } from \"../Interfaces/IMultichainRouter.sol\";\nimport { ReentrancyGuard } from \"../Helpers/ReentrancyGuard.sol\";\nimport { InvalidConfig, AlreadyInitialized, NotInitialized } from \"../Errors/GenericErrors.sol\";\nimport { SwapperV2, LibSwap } from \"../Helpers/SwapperV2.sol\";\nimport { Validatable } from \"../Helpers/Validatable.sol\";\n\ninterface IMultichainERC20 {\n function Swapout(uint256 amount, address bindaddr) external returns (bool);\n}\n\n/// @title Multichain Facet\n/// @author LI.FI (https://li.fi)\n/// @notice Provides functionality for bridging through Multichain (Prev. AnySwap)\n/// @custom:version 1.0.1\ncontract MultichainFacet is ILiFi, SwapperV2, ReentrancyGuard, Validatable {\n /// Storage ///\n\n bytes32 internal constant NAMESPACE =\n keccak256(\"com.lifi.facets.multichain\");\n\n /// Types ///\n\n struct Storage {\n mapping(address => bool) allowedRouters;\n bool initialized; // no longer used but kept here to maintain the same storage layout\n address anyNative;\n mapping(address => address) anyTokenAddresses;\n }\n\n struct MultichainData {\n address router;\n }\n\n struct AnyMapping {\n address tokenAddress;\n address anyTokenAddress;\n }\n\n /// Errors ///\n\n error InvalidRouter();\n\n /// Events ///\n\n event MultichainInitialized();\n event MultichainRoutersUpdated(address[] routers, bool[] allowed);\n event AnyMappingUpdated(AnyMapping[] mappings);\n\n /// Init ///\n\n /// @notice Initialize local variables for the Multichain Facet\n /// @param anyNative The address of the anyNative (e.g. anyETH) token\n /// @param routers Allowed Multichain Routers\n function initMultichain(\n address anyNative,\n address[] calldata routers\n ) external {\n LibDiamond.enforceIsContractOwner();\n\n Storage storage s = getStorage();\n\n s.anyNative = anyNative;\n\n uint256 len = routers.length;\n for (uint256 i = 0; i < len; ) {\n if (routers[i] == address(0)) {\n revert InvalidConfig();\n }\n s.allowedRouters[routers[i]] = true;\n unchecked {\n ++i;\n }\n }\n\n emit MultichainInitialized();\n }\n\n /// External Methods ///\n\n /// @notice Updates the tokenAddress > anyTokenAddress storage\n /// @param mappings A mapping of tokenAddress(es) to anyTokenAddress(es)\n function updateAddressMappings(AnyMapping[] calldata mappings) external {\n LibDiamond.enforceIsContractOwner();\n\n Storage storage s = getStorage();\n\n for (uint64 i; i < mappings.length; ) {\n s.anyTokenAddresses[mappings[i].tokenAddress] = mappings[i]\n .anyTokenAddress;\n unchecked {\n ++i;\n }\n }\n\n emit AnyMappingUpdated(mappings);\n }\n\n /// @notice (Batch) register routers\n /// @param routers Router addresses\n /// @param allowed Array of whether the addresses are allowed or not\n function registerRouters(\n address[] calldata routers,\n bool[] calldata allowed\n ) external {\n LibDiamond.enforceIsContractOwner();\n\n Storage storage s = getStorage();\n\n uint256 len = routers.length;\n for (uint256 i = 0; i < len; ) {\n if (routers[i] == address(0)) {\n revert InvalidConfig();\n }\n s.allowedRouters[routers[i]] = allowed[i];\n\n unchecked {\n ++i;\n }\n }\n emit MultichainRoutersUpdated(routers, allowed);\n }\n\n /// @notice Bridges tokens via Multichain\n /// @param _bridgeData the core information needed for bridging\n /// @param _multichainData data specific to Multichain\n function startBridgeTokensViaMultichain(\n ILiFi.BridgeData memory _bridgeData,\n MultichainData calldata _multichainData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n doesNotContainSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n Storage storage s = getStorage();\n if (!s.allowedRouters[_multichainData.router]) {\n revert InvalidRouter();\n }\n if (!LibAsset.isNativeAsset(_bridgeData.sendingAssetId))\n LibAsset.depositAsset(\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount\n );\n\n _startBridge(_bridgeData, _multichainData);\n }\n\n /// @notice Performs a swap before bridging via Multichain\n /// @param _bridgeData the core information needed for bridging\n /// @param _swapData an array of swap related data for performing swaps before bridging\n /// @param _multichainData data specific to Multichain\n function swapAndStartBridgeTokensViaMultichain(\n ILiFi.BridgeData memory _bridgeData,\n LibSwap.SwapData[] calldata _swapData,\n MultichainData calldata _multichainData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n containsSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n Storage storage s = getStorage();\n\n if (!s.allowedRouters[_multichainData.router]) {\n revert InvalidRouter();\n }\n\n _bridgeData.minAmount = _depositAndSwap(\n _bridgeData.transactionId,\n _bridgeData.minAmount,\n _swapData,\n payable(msg.sender)\n );\n _startBridge(_bridgeData, _multichainData);\n }\n\n /// Private Methods ///\n\n /// @dev Contains the business logic for the bridge via Multichain\n /// @param _bridgeData the core information needed for bridging\n /// @param _multichainData data specific to Multichain\n function _startBridge(\n ILiFi.BridgeData memory _bridgeData,\n MultichainData calldata _multichainData\n ) private {\n // check if sendingAsset is a Multichain token that needs to be called directly in order to bridge it\n if (_multichainData.router == _bridgeData.sendingAssetId) {\n IMultichainERC20(_bridgeData.sendingAssetId).Swapout(\n _bridgeData.minAmount,\n _bridgeData.receiver\n );\n } else {\n Storage storage s = getStorage();\n if (LibAsset.isNativeAsset(_bridgeData.sendingAssetId)) {\n // call native asset bridge function\n IMultichainRouter(_multichainData.router).anySwapOutNative{\n value: _bridgeData.minAmount\n }(\n s.anyNative,\n _bridgeData.receiver,\n _bridgeData.destinationChainId\n );\n } else {\n // Give Multichain router approval to pull tokens\n LibAsset.maxApproveERC20(\n IERC20(_bridgeData.sendingAssetId),\n _multichainData.router,\n _bridgeData.minAmount\n );\n\n address anyToken = s.anyTokenAddresses[\n _bridgeData.sendingAssetId\n ];\n\n // replace tokenAddress with anyTokenAddress (if mapping found) and call ERC20 asset bridge function\n IMultichainRouter(_multichainData.router).anySwapOutUnderlying(\n anyToken != address(0)\n ? anyToken\n : _bridgeData.sendingAssetId,\n _bridgeData.receiver,\n _bridgeData.minAmount,\n _bridgeData.destinationChainId\n );\n }\n }\n\n emit LiFiTransferStarted(_bridgeData);\n }\n\n /// @dev fetch local storage\n function getStorage() private pure returns (Storage storage s) {\n bytes32 namespace = NAMESPACE;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n s.slot := namespace\n }\n }\n}\n" + }, + "src/Facets/OmniBridgeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { IOmniBridge } from \"../Interfaces/IOmniBridge.sol\";\nimport { LibAsset, IERC20 } from \"../Libraries/LibAsset.sol\";\nimport { ReentrancyGuard } from \"../Helpers/ReentrancyGuard.sol\";\nimport { SwapperV2, LibSwap } from \"../Helpers/SwapperV2.sol\";\nimport { Validatable } from \"../Helpers/Validatable.sol\";\n\n/// @title OmniBridge Facet\n/// @author LI.FI (https://li.fi)\n/// @notice Provides functionality for bridging through OmniBridge\n/// @custom:version 1.0.0\ncontract OmniBridgeFacet is ILiFi, ReentrancyGuard, SwapperV2, Validatable {\n /// Storage ///\n\n /// @notice The contract address of the foreign omni bridge on the source chain.\n IOmniBridge private immutable foreignOmniBridge;\n\n /// @notice The contract address of the weth omni bridge on the source chain.\n IOmniBridge private immutable wethOmniBridge;\n\n /// Constructor ///\n\n /// @notice Initialize the contract.\n /// @param _foreignOmniBridge The contract address of the foreign omni bridge on the source chain.\n /// @param _wethOmniBridge The contract address of the weth omni bridge on the source chain.\n constructor(IOmniBridge _foreignOmniBridge, IOmniBridge _wethOmniBridge) {\n foreignOmniBridge = _foreignOmniBridge;\n wethOmniBridge = _wethOmniBridge;\n }\n\n /// External Methods ///\n\n /// @notice Bridges tokens via OmniBridge\n /// @param _bridgeData Data contaning core information for bridging\n function startBridgeTokensViaOmniBridge(\n ILiFi.BridgeData memory _bridgeData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n doesNotContainSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n LibAsset.depositAsset(\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount\n );\n _startBridge(_bridgeData);\n }\n\n /// @notice Performs a swap before bridging via OmniBridge\n /// @param _bridgeData Data contaning core information for bridging\n /// @param _swapData An array of swap related data for performing swaps before bridging\n function swapAndStartBridgeTokensViaOmniBridge(\n ILiFi.BridgeData memory _bridgeData,\n LibSwap.SwapData[] calldata _swapData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n containsSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n _bridgeData.minAmount = _depositAndSwap(\n _bridgeData.transactionId,\n _bridgeData.minAmount,\n _swapData,\n payable(msg.sender)\n );\n _startBridge(_bridgeData);\n }\n\n /// Private Methods ///\n\n /// @dev Contains the business logic for the bridge via OmniBridge\n /// @param _bridgeData Data contaning core information for bridging\n function _startBridge(ILiFi.BridgeData memory _bridgeData) private {\n if (LibAsset.isNativeAsset(_bridgeData.sendingAssetId)) {\n wethOmniBridge.wrapAndRelayTokens{ value: _bridgeData.minAmount }(\n _bridgeData.receiver\n );\n } else {\n LibAsset.maxApproveERC20(\n IERC20(_bridgeData.sendingAssetId),\n address(foreignOmniBridge),\n _bridgeData.minAmount\n );\n foreignOmniBridge.relayTokens(\n _bridgeData.sendingAssetId,\n _bridgeData.receiver,\n _bridgeData.minAmount\n );\n }\n\n emit LiFiTransferStarted(_bridgeData);\n }\n}\n" + }, + "src/Facets/OptimismBridgeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { IL1StandardBridge } from \"../Interfaces/IL1StandardBridge.sol\";\nimport { LibAsset, IERC20 } from \"../Libraries/LibAsset.sol\";\nimport { LibDiamond } from \"../Libraries/LibDiamond.sol\";\nimport { ReentrancyGuard } from \"../Helpers/ReentrancyGuard.sol\";\nimport { InvalidConfig, AlreadyInitialized, NotInitialized } from \"../Errors/GenericErrors.sol\";\nimport { SwapperV2, LibSwap } from \"../Helpers/SwapperV2.sol\";\nimport { Validatable } from \"../Helpers/Validatable.sol\";\nimport { LibUtil } from \"../Libraries/LibUtil.sol\";\n\n/// @title Optimism Bridge Facet\n/// @author Li.Finance (https://li.finance)\n/// @notice Provides functionality for bridging through Optimism Bridge\n/// @custom:version 1.0.0\ncontract OptimismBridgeFacet is\n ILiFi,\n ReentrancyGuard,\n SwapperV2,\n Validatable\n{\n /// Storage ///\n\n bytes32 internal constant NAMESPACE =\n keccak256(\"com.lifi.facets.optimism\");\n\n /// Types ///\n\n struct Storage {\n mapping(address => IL1StandardBridge) bridges;\n IL1StandardBridge standardBridge;\n bool initialized;\n }\n\n struct Config {\n address assetId;\n address bridge;\n }\n\n struct OptimismData {\n address assetIdOnL2;\n uint32 l2Gas;\n bool isSynthetix;\n }\n\n /// Events ///\n\n event OptimismInitialized(Config[] configs);\n event OptimismBridgeRegistered(address indexed assetId, address bridge);\n\n /// Init ///\n\n /// @notice Initialize local variables for the Optimism Bridge Facet\n /// @param configs Bridge configuration data\n function initOptimism(\n Config[] calldata configs,\n IL1StandardBridge standardBridge\n ) external {\n LibDiamond.enforceIsContractOwner();\n\n Storage storage s = getStorage();\n\n if (s.initialized) {\n revert AlreadyInitialized();\n }\n\n for (uint256 i = 0; i < configs.length; i++) {\n if (configs[i].bridge == address(0)) {\n revert InvalidConfig();\n }\n s.bridges[configs[i].assetId] = IL1StandardBridge(\n configs[i].bridge\n );\n }\n\n s.standardBridge = standardBridge;\n s.initialized = true;\n\n emit OptimismInitialized(configs);\n }\n\n /// External Methods ///\n\n /// @notice Register token and bridge\n /// @param assetId Address of token\n /// @param bridge Address of bridge for asset\n function registerOptimismBridge(address assetId, address bridge) external {\n LibDiamond.enforceIsContractOwner();\n\n Storage storage s = getStorage();\n\n if (!s.initialized) revert NotInitialized();\n\n if (bridge == address(0)) {\n revert InvalidConfig();\n }\n\n s.bridges[assetId] = IL1StandardBridge(bridge);\n\n emit OptimismBridgeRegistered(assetId, bridge);\n }\n\n /// @notice Bridges tokens via Optimism Bridge\n /// @param _bridgeData Data contaning core information for bridging\n /// @param _bridgeData Data specific to Optimism Bridge\n function startBridgeTokensViaOptimismBridge(\n ILiFi.BridgeData memory _bridgeData,\n OptimismData calldata _optimismData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n doesNotContainSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n LibAsset.depositAsset(\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount\n );\n _startBridge(_bridgeData, _optimismData);\n }\n\n /// @notice Performs a swap before bridging via Optimism Bridge\n /// @param _bridgeData Data contaning core information for bridging\n /// @param _swapData An array of swap related data for performing swaps before bridging\n /// @param _bridgeData Data specific to Optimism Bridge\n function swapAndStartBridgeTokensViaOptimismBridge(\n ILiFi.BridgeData memory _bridgeData,\n LibSwap.SwapData[] calldata _swapData,\n OptimismData calldata _optimismData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n containsSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n _bridgeData.minAmount = _depositAndSwap(\n _bridgeData.transactionId,\n _bridgeData.minAmount,\n _swapData,\n payable(msg.sender)\n );\n _startBridge(_bridgeData, _optimismData);\n }\n\n /// Private Methods ///\n\n /// @dev Contains the business logic for the bridge via Optimism Bridge\n /// @param _bridgeData Data contaning core information for bridging\n /// @param _bridgeData Data specific to Optimism Bridge\n function _startBridge(\n ILiFi.BridgeData memory _bridgeData,\n OptimismData calldata _optimismData\n ) private {\n Storage storage s = getStorage();\n IL1StandardBridge nonStandardBridge = s.bridges[\n _bridgeData.sendingAssetId\n ];\n IL1StandardBridge bridge = LibUtil.isZeroAddress(\n address(nonStandardBridge)\n )\n ? s.standardBridge\n : nonStandardBridge;\n\n if (LibAsset.isNativeAsset(_bridgeData.sendingAssetId)) {\n bridge.depositETHTo{ value: _bridgeData.minAmount }(\n _bridgeData.receiver,\n _optimismData.l2Gas,\n \"\"\n );\n } else {\n LibAsset.maxApproveERC20(\n IERC20(_bridgeData.sendingAssetId),\n address(bridge),\n _bridgeData.minAmount\n );\n\n if (_optimismData.isSynthetix) {\n bridge.depositTo(_bridgeData.receiver, _bridgeData.minAmount);\n } else {\n bridge.depositERC20To(\n _bridgeData.sendingAssetId,\n _optimismData.assetIdOnL2,\n _bridgeData.receiver,\n _bridgeData.minAmount,\n _optimismData.l2Gas,\n \"\"\n );\n }\n }\n\n emit LiFiTransferStarted(_bridgeData);\n }\n\n /// @dev fetch local storage\n function getStorage() private pure returns (Storage storage s) {\n bytes32 namespace = NAMESPACE;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n s.slot := namespace\n }\n }\n}\n" + }, + "src/Facets/OwnershipFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { LibDiamond } from \"../Libraries/LibDiamond.sol\";\nimport { IERC173 } from \"../Interfaces/IERC173.sol\";\nimport { LibUtil } from \"../Libraries/LibUtil.sol\";\nimport { LibAsset } from \"../Libraries/LibAsset.sol\";\n\n/// @title Ownership Facet\n/// @author LI.FI (https://li.fi)\n/// @notice Manages ownership of the LiFi Diamond contract for admin purposes\n/// @custom:version 1.0.0\ncontract OwnershipFacet is IERC173 {\n /// Storage ///\n\n bytes32 internal constant NAMESPACE =\n keccak256(\"com.lifi.facets.ownership\");\n\n /// Types ///\n\n struct Storage {\n address newOwner;\n }\n\n /// Errors ///\n\n error NoNullOwner();\n error NewOwnerMustNotBeSelf();\n error NoPendingOwnershipTransfer();\n error NotPendingOwner();\n\n /// Events ///\n\n event OwnershipTransferRequested(\n address indexed _from,\n address indexed _to\n );\n\n /// External Methods ///\n\n /// @notice Initiates transfer of ownership to a new address\n /// @param _newOwner the address to transfer ownership to\n function transferOwnership(address _newOwner) external override {\n LibDiamond.enforceIsContractOwner();\n Storage storage s = getStorage();\n\n if (LibUtil.isZeroAddress(_newOwner)) revert NoNullOwner();\n\n if (_newOwner == LibDiamond.contractOwner())\n revert NewOwnerMustNotBeSelf();\n\n s.newOwner = _newOwner;\n emit OwnershipTransferRequested(msg.sender, s.newOwner);\n }\n\n /// @notice Cancel transfer of ownership\n function cancelOwnershipTransfer() external {\n LibDiamond.enforceIsContractOwner();\n Storage storage s = getStorage();\n\n if (LibUtil.isZeroAddress(s.newOwner))\n revert NoPendingOwnershipTransfer();\n s.newOwner = address(0);\n }\n\n /// @notice Confirms transfer of ownership to the calling address (msg.sender)\n function confirmOwnershipTransfer() external {\n Storage storage s = getStorage();\n address _pendingOwner = s.newOwner;\n if (msg.sender != _pendingOwner) revert NotPendingOwner();\n emit OwnershipTransferred(LibDiamond.contractOwner(), _pendingOwner);\n LibDiamond.setContractOwner(_pendingOwner);\n s.newOwner = LibAsset.NULL_ADDRESS;\n }\n\n /// @notice Return the current owner address\n /// @return owner_ The current owner address\n function owner() external view override returns (address owner_) {\n owner_ = LibDiamond.contractOwner();\n }\n\n /// Private Methods ///\n\n /// @dev fetch local storage\n function getStorage() private pure returns (Storage storage s) {\n bytes32 namespace = NAMESPACE;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n s.slot := namespace\n }\n }\n}\n" + }, + "src/Facets/PeripheryRegistryFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { LibDiamond } from \"../Libraries/LibDiamond.sol\";\n\n/// @title Periphery Registry Facet\n/// @author LI.FI (https://li.fi)\n/// @notice A simple registry to track LIFI periphery contracts\n/// @custom:version 1.0.0\ncontract PeripheryRegistryFacet {\n /// Storage ///\n\n bytes32 internal constant NAMESPACE =\n keccak256(\"com.lifi.facets.periphery_registry\");\n\n /// Types ///\n\n struct Storage {\n mapping(string => address) contracts;\n }\n\n /// Events ///\n\n event PeripheryContractRegistered(string name, address contractAddress);\n\n /// External Methods ///\n\n /// @notice Registers a periphery contract address with a specified name\n /// @param _name the name to register the contract address under\n /// @param _contractAddress the address of the contract to register\n function registerPeripheryContract(\n string calldata _name,\n address _contractAddress\n ) external {\n LibDiamond.enforceIsContractOwner();\n Storage storage s = getStorage();\n s.contracts[_name] = _contractAddress;\n emit PeripheryContractRegistered(_name, _contractAddress);\n }\n\n /// @notice Returns the registered contract address by its name\n /// @param _name the registered name of the contract\n function getPeripheryContract(\n string calldata _name\n ) external view returns (address) {\n return getStorage().contracts[_name];\n }\n\n /// @dev fetch local storage\n function getStorage() private pure returns (Storage storage s) {\n bytes32 namespace = NAMESPACE;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n s.slot := namespace\n }\n }\n}\n" + }, + "src/Facets/PolygonBridgeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { IRootChainManager } from \"../Interfaces/IRootChainManager.sol\";\nimport { LibAsset, IERC20 } from \"../Libraries/LibAsset.sol\";\nimport { ReentrancyGuard } from \"../Helpers/ReentrancyGuard.sol\";\nimport { SwapperV2, LibSwap } from \"../Helpers/SwapperV2.sol\";\nimport { Validatable } from \"../Helpers/Validatable.sol\";\n\n/// @title Polygon Bridge Facet\n/// @author Li.Finance (https://li.finance)\n/// @notice Provides functionality for bridging through Polygon Bridge\n/// @custom:version 1.0.0\ncontract PolygonBridgeFacet is ILiFi, ReentrancyGuard, SwapperV2, Validatable {\n /// Storage ///\n\n /// @notice The contract address of the RootChainManager on the source chain.\n IRootChainManager private immutable rootChainManager;\n\n /// @notice The contract address of the ERC20Predicate on the source chain.\n address private immutable erc20Predicate;\n\n /// Constructor ///\n\n /// @notice Initialize the contract.\n /// @param _rootChainManager The contract address of the RootChainManager on the source chain.\n /// @param _erc20Predicate The contract address of the ERC20Predicate on the source chain.\n constructor(IRootChainManager _rootChainManager, address _erc20Predicate) {\n rootChainManager = _rootChainManager;\n erc20Predicate = _erc20Predicate;\n }\n\n /// External Methods ///\n\n /// @notice Bridges tokens via Polygon Bridge\n /// @param _bridgeData Data containing core information for bridging\n function startBridgeTokensViaPolygonBridge(\n ILiFi.BridgeData memory _bridgeData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n doesNotContainSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n LibAsset.depositAsset(\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount\n );\n _startBridge(_bridgeData);\n }\n\n /// @notice Performs a swap before bridging via Polygon Bridge\n /// @param _bridgeData Data containing core information for bridging\n /// @param _swapData An array of swap related data for performing swaps before bridging\n function swapAndStartBridgeTokensViaPolygonBridge(\n ILiFi.BridgeData memory _bridgeData,\n LibSwap.SwapData[] calldata _swapData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n containsSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n _bridgeData.minAmount = _depositAndSwap(\n _bridgeData.transactionId,\n _bridgeData.minAmount,\n _swapData,\n payable(msg.sender)\n );\n _startBridge(_bridgeData);\n }\n\n /// Private Methods ///\n\n /// @dev Contains the business logic for the bridge via Polygon Bridge\n /// @param _bridgeData Data containing core information for bridging\n function _startBridge(ILiFi.BridgeData memory _bridgeData) private {\n address childToken;\n\n if (LibAsset.isNativeAsset(_bridgeData.sendingAssetId)) {\n rootChainManager.depositEtherFor{ value: _bridgeData.minAmount }(\n _bridgeData.receiver\n );\n } else {\n childToken = rootChainManager.rootToChildToken(\n _bridgeData.sendingAssetId\n );\n\n LibAsset.maxApproveERC20(\n IERC20(_bridgeData.sendingAssetId),\n erc20Predicate,\n _bridgeData.minAmount\n );\n\n bytes memory depositData = abi.encode(_bridgeData.minAmount);\n rootChainManager.depositFor(\n _bridgeData.receiver,\n _bridgeData.sendingAssetId,\n depositData\n );\n }\n\n emit LiFiTransferStarted(_bridgeData);\n }\n}\n" + }, + "src/Facets/StandardizedCallFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { LibDiamond } from \"../Libraries/LibDiamond.sol\";\n\n/// @title Standardized Call Facet\n/// @author LIFI https://li.finance ed@li.finance\n/// @notice Allows calling different facet methods through a single standardized entrypoint\n/// @custom:version 1.0.0\ncontract StandardizedCallFacet {\n /// External Methods ///\n\n /// @notice Make a standardized call to a facet\n /// @param callData The calldata to forward to the facet\n function standardizedCall(bytes memory callData) external payable {\n // Fetch the facetAddress from the dimaond's internal storage\n // Cheaper than calling the external facetAddress(selector) method directly\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n address facetAddress = ds\n .selectorToFacetAndPosition[bytes4(callData)]\n .facetAddress;\n\n if (facetAddress == address(0)) {\n revert LibDiamond.FunctionDoesNotExist();\n }\n\n // Execute external function from facet using delegatecall and return any value.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // execute function call using the facet\n let result := delegatecall(\n gas(),\n facetAddress,\n add(callData, 0x20),\n mload(callData),\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/Facets/StargateFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { IStargateRouter } from \"../Interfaces/IStargateRouter.sol\";\nimport { LibAsset, IERC20 } from \"../Libraries/LibAsset.sol\";\nimport { LibDiamond } from \"../Libraries/LibDiamond.sol\";\nimport { ReentrancyGuard } from \"../Helpers/ReentrancyGuard.sol\";\nimport { InformationMismatch, AlreadyInitialized, NotInitialized } from \"../Errors/GenericErrors.sol\";\nimport { SwapperV2, LibSwap } from \"../Helpers/SwapperV2.sol\";\nimport { Validatable } from \"../Helpers/Validatable.sol\";\n\n/// @title Stargate Facet\n/// @author Li.Finance (https://li.finance)\n/// @notice Provides functionality for bridging through Stargate\n/// @custom:version 2.0.1\ncontract StargateFacet is ILiFi, ReentrancyGuard, SwapperV2, Validatable {\n /// CONSTANTS ///\n\n /// @notice The contract address of the stargate router on the source chain.\n IStargateRouter private immutable router;\n /// @notice The contract address of the native stargate router on the source chain.\n IStargateRouter private immutable nativeRouter;\n\n /// Storage ///\n\n bytes32 internal constant NAMESPACE =\n keccak256(\"com.lifi.facets.stargate\");\n\n /// Types ///\n\n struct Storage {\n mapping(uint256 => uint16) layerZeroChainId;\n bool initialized;\n }\n\n struct ChainIdConfig {\n uint256 chainId;\n uint16 layerZeroChainId;\n }\n\n /// @param srcPoolId Source pool id.\n /// @param dstPoolId Dest pool id.\n /// @param minAmountLD The min qty you would accept on the destination.\n /// @param dstGasForCall Additional gas fee for extral call on the destination.\n /// @param lzFee Estimated message fee.\n /// @param refundAddress Refund adddress. Extra gas (if any) is returned to this address\n /// @param callTo The address to send the tokens to on the destination.\n /// @param callData Additional payload.\n struct StargateData {\n uint256 srcPoolId;\n uint256 dstPoolId;\n uint256 minAmountLD;\n uint256 dstGasForCall;\n uint256 lzFee;\n address payable refundAddress;\n bytes callTo;\n bytes callData;\n }\n\n /// Errors ///\n\n error UnknownLayerZeroChain();\n\n /// Events ///\n\n event StargateInitialized(ChainIdConfig[] chainIdConfigs);\n\n event LayerZeroChainIdSet(\n uint256 indexed chainId,\n uint16 layerZeroChainId\n );\n\n /// @notice Emit to get credited for referral\n /// @dev Our partner id is 0x0006\n event PartnerSwap(bytes2 partnerId);\n\n /// Constructor ///\n\n /// @notice Initialize the contract.\n /// @param _router The contract address of the stargate router on the source chain.\n /// @param _nativeRouter The contract address of the native token stargate router on the source chain.\n constructor(IStargateRouter _router, IStargateRouter _nativeRouter) {\n router = _router;\n nativeRouter = _nativeRouter;\n }\n\n /// Init ///\n\n /// @notice Initialize local variables for the Stargate Facet\n /// @param chainIdConfigs Chain Id configuration data\n function initStargate(ChainIdConfig[] calldata chainIdConfigs) external {\n LibDiamond.enforceIsContractOwner();\n\n Storage storage sm = getStorage();\n\n if (sm.initialized) {\n revert AlreadyInitialized();\n }\n\n for (uint256 i = 0; i < chainIdConfigs.length; i++) {\n sm.layerZeroChainId[chainIdConfigs[i].chainId] = chainIdConfigs[i]\n .layerZeroChainId;\n }\n\n sm.initialized = true;\n\n emit StargateInitialized(chainIdConfigs);\n }\n\n /// External Methods ///\n\n /// @notice Bridges tokens via Stargate Bridge\n /// @param _bridgeData Data used purely for tracking and analytics\n /// @param _stargateData Data specific to Stargate Bridge\n function startBridgeTokensViaStargate(\n ILiFi.BridgeData calldata _bridgeData,\n StargateData calldata _stargateData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n doesNotContainSourceSwaps(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n validateDestinationCallFlag(_bridgeData, _stargateData);\n LibAsset.depositAsset(\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount\n );\n _startBridge(_bridgeData, _stargateData);\n }\n\n /// @notice Performs a swap before bridging via Stargate Bridge\n /// @param _bridgeData Data used purely for tracking and analytics\n /// @param _swapData An array of swap related data for performing swaps before bridging\n /// @param _stargateData Data specific to Stargate Bridge\n function swapAndStartBridgeTokensViaStargate(\n ILiFi.BridgeData memory _bridgeData,\n LibSwap.SwapData[] calldata _swapData,\n StargateData calldata _stargateData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n containsSourceSwaps(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n validateDestinationCallFlag(_bridgeData, _stargateData);\n _bridgeData.minAmount = _depositAndSwap(\n _bridgeData.transactionId,\n _bridgeData.minAmount,\n _swapData,\n payable(msg.sender),\n LibAsset.isNativeAsset(_bridgeData.sendingAssetId)\n ? 0\n : _stargateData.lzFee\n );\n\n _startBridge(_bridgeData, _stargateData);\n }\n\n function quoteLayerZeroFee(\n uint256 _destinationChainId,\n StargateData calldata _stargateData\n ) external view returns (uint256, uint256) {\n return\n router.quoteLayerZeroFee(\n getLayerZeroChainId(_destinationChainId),\n 1, // TYPE_SWAP_REMOTE on Bridge\n _stargateData.callTo,\n _stargateData.callData,\n IStargateRouter.lzTxObj(\n _stargateData.dstGasForCall,\n 0,\n toBytes(address(0))\n )\n );\n }\n\n /// Private Methods ///\n\n /// @dev Contains the business logic for the bridge via Stargate Bridge\n /// @param _bridgeData Data used purely for tracking and analytics\n /// @param _stargateData Data specific to Stargate Bridge\n function _startBridge(\n ILiFi.BridgeData memory _bridgeData,\n StargateData calldata _stargateData\n ) private {\n if (LibAsset.isNativeAsset(_bridgeData.sendingAssetId)) {\n nativeRouter.swapETHAndCall{ value: _bridgeData.minAmount }(\n getLayerZeroChainId(_bridgeData.destinationChainId),\n _stargateData.refundAddress,\n _stargateData.callTo,\n IStargateRouter.SwapAmount(\n _bridgeData.minAmount - _stargateData.lzFee,\n _stargateData.minAmountLD\n ),\n IStargateRouter.lzTxObj(\n _stargateData.dstGasForCall,\n 0,\n toBytes(address(0))\n ),\n _stargateData.callData\n );\n } else {\n LibAsset.maxApproveERC20(\n IERC20(_bridgeData.sendingAssetId),\n address(router),\n _bridgeData.minAmount\n );\n\n router.swap{ value: _stargateData.lzFee }(\n getLayerZeroChainId(_bridgeData.destinationChainId),\n _stargateData.srcPoolId,\n _stargateData.dstPoolId,\n _stargateData.refundAddress,\n _bridgeData.minAmount,\n _stargateData.minAmountLD,\n IStargateRouter.lzTxObj(\n _stargateData.dstGasForCall,\n 0,\n toBytes(address(0))\n ),\n _stargateData.callTo,\n _stargateData.callData\n );\n }\n\n emit PartnerSwap(0x0006);\n\n emit LiFiTransferStarted(_bridgeData);\n }\n\n function validateDestinationCallFlag(\n ILiFi.BridgeData memory _bridgeData,\n StargateData calldata _stargateData\n ) private pure {\n if (\n (_stargateData.callData.length > 0) !=\n _bridgeData.hasDestinationCall\n ) {\n revert InformationMismatch();\n }\n }\n\n /// Mappings management ///\n\n /// @notice Sets the Layer 0 chain ID for a given chain ID\n /// @param _chainId uint16 of the chain ID\n /// @param _layerZeroChainId uint16 of the Layer 0 chain ID\n /// @dev This is used to map a chain ID to its Layer 0 chain ID\n function setLayerZeroChainId(\n uint256 _chainId,\n uint16 _layerZeroChainId\n ) external {\n LibDiamond.enforceIsContractOwner();\n Storage storage sm = getStorage();\n\n if (!sm.initialized) {\n revert NotInitialized();\n }\n\n sm.layerZeroChainId[_chainId] = _layerZeroChainId;\n emit LayerZeroChainIdSet(_chainId, _layerZeroChainId);\n }\n\n /// @notice Gets the Layer 0 chain ID for a given chain ID\n /// @param _chainId uint256 of the chain ID\n /// @return uint16 of the Layer 0 chain ID\n function getLayerZeroChainId(\n uint256 _chainId\n ) private view returns (uint16) {\n Storage storage sm = getStorage();\n uint16 chainId = sm.layerZeroChainId[_chainId];\n if (chainId == 0) revert UnknownLayerZeroChain();\n return chainId;\n }\n\n function toBytes(address _address) private pure returns (bytes memory) {\n return abi.encodePacked(_address);\n }\n\n /// @dev fetch local storage\n function getStorage() private pure returns (Storage storage s) {\n bytes32 namespace = NAMESPACE;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n s.slot := namespace\n }\n }\n}\n" + }, + "src/Facets/SynapseBridgeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { ISynapseRouter } from \"../Interfaces/ISynapseRouter.sol\";\nimport { LibAsset, IERC20 } from \"../Libraries/LibAsset.sol\";\nimport { ReentrancyGuard } from \"../Helpers/ReentrancyGuard.sol\";\nimport { SwapperV2, LibSwap } from \"../Helpers/SwapperV2.sol\";\nimport { Validatable } from \"../Helpers/Validatable.sol\";\n\n/// @title SynapseBridge Facet\n/// @author LI.FI (https://li.fi)\n/// @notice Provides functionality for bridging through SynapseBridge\n/// @custom:version 1.0.0\ncontract SynapseBridgeFacet is ILiFi, ReentrancyGuard, SwapperV2, Validatable {\n /// Storage ///\n\n address internal constant NETH_ADDRESS =\n 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n /// @notice The contract address of the SynapseRouter on the source chain.\n ISynapseRouter private immutable synapseRouter;\n\n /// Types ///\n\n /// @param originQuery Origin swap query. Empty struct indicates no swap is required.\n /// @param destQuery Destination swap query. Empty struct indicates no swap is required.\n struct SynapseData {\n ISynapseRouter.SwapQuery originQuery;\n ISynapseRouter.SwapQuery destQuery;\n }\n\n /// Constructor ///\n\n /// @notice Initialize the contract.\n /// @param _synapseRouter The contract address of the SynapseRouter on the source chain.\n constructor(ISynapseRouter _synapseRouter) {\n synapseRouter = _synapseRouter;\n }\n\n /// External Methods ///\n\n /// @notice Bridges tokens via Synapse Bridge\n /// @param _bridgeData the core information needed for bridging\n /// @param _synapseData data specific to Synapse Bridge\n function startBridgeTokensViaSynapseBridge(\n ILiFi.BridgeData calldata _bridgeData,\n SynapseData calldata _synapseData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n validateBridgeData(_bridgeData)\n doesNotContainSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n {\n LibAsset.depositAsset(\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount\n );\n\n _startBridge(_bridgeData, _synapseData);\n }\n\n /// @notice Performs a swap before bridging via Synapse Bridge\n /// @param _bridgeData the core information needed for bridging\n /// @param _swapData an array of swap related data for performing swaps before bridging\n /// @param _synapseData data specific to Synapse Bridge\n function swapAndStartBridgeTokensViaSynapseBridge(\n ILiFi.BridgeData memory _bridgeData,\n LibSwap.SwapData[] calldata _swapData,\n SynapseData calldata _synapseData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n containsSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n _bridgeData.minAmount = _depositAndSwap(\n _bridgeData.transactionId,\n _bridgeData.minAmount,\n _swapData,\n payable(msg.sender)\n );\n\n _startBridge(_bridgeData, _synapseData);\n }\n\n /// Internal Methods ///\n\n /// @dev Contains the business logic for the bridge via Synapse Bridge\n /// @param _bridgeData the core information needed for bridging\n /// @param _synapseData data specific to Synapse Bridge\n function _startBridge(\n ILiFi.BridgeData memory _bridgeData,\n SynapseData calldata _synapseData\n ) internal {\n uint256 nativeAssetAmount;\n address sendingAssetId = _bridgeData.sendingAssetId;\n\n if (LibAsset.isNativeAsset(_bridgeData.sendingAssetId)) {\n nativeAssetAmount = _bridgeData.minAmount;\n sendingAssetId = NETH_ADDRESS;\n } else {\n LibAsset.maxApproveERC20(\n IERC20(_bridgeData.sendingAssetId),\n address(synapseRouter),\n _bridgeData.minAmount\n );\n }\n\n synapseRouter.bridge{ value: nativeAssetAmount }(\n _bridgeData.receiver,\n _bridgeData.destinationChainId,\n sendingAssetId,\n _bridgeData.minAmount,\n _synapseData.originQuery,\n _synapseData.destQuery\n );\n\n emit LiFiTransferStarted(_bridgeData);\n }\n}\n" + }, + "src/Facets/WithdrawFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { LibDiamond } from \"../Libraries/LibDiamond.sol\";\nimport { LibUtil } from \"../Libraries/LibUtil.sol\";\nimport { LibAsset } from \"../Libraries/LibAsset.sol\";\nimport { LibAccess } from \"../Libraries/LibAccess.sol\";\nimport { NotAContract } from \"../Errors/GenericErrors.sol\";\n\n/// @title Withdraw Facet\n/// @author LI.FI (https://li.fi)\n/// @notice Allows admin to withdraw funds that are kept in the contract by accident\n/// @custom:version 1.0.0\ncontract WithdrawFacet {\n /// Errors ///\n\n error WithdrawFailed();\n\n /// Events ///\n\n event LogWithdraw(\n address indexed _assetAddress,\n address _to,\n uint256 amount\n );\n\n /// External Methods ///\n\n /// @notice Execute call data and withdraw asset.\n /// @param _callTo The address to execute the calldata on.\n /// @param _callData The data to execute.\n /// @param _assetAddress Asset to be withdrawn.\n /// @param _to address to withdraw to.\n /// @param _amount amount of asset to withdraw.\n function executeCallAndWithdraw(\n address payable _callTo,\n bytes calldata _callData,\n address _assetAddress,\n address _to,\n uint256 _amount\n ) external {\n if (msg.sender != LibDiamond.contractOwner()) {\n LibAccess.enforceAccessControl();\n }\n\n // Check if the _callTo is a contract\n bool success;\n bool isContract = LibAsset.isContract(_callTo);\n if (!isContract) revert NotAContract();\n\n // solhint-disable-next-line avoid-low-level-calls\n (success, ) = _callTo.call(_callData);\n\n if (success) {\n _withdrawAsset(_assetAddress, _to, _amount);\n } else {\n revert WithdrawFailed();\n }\n }\n\n /// @notice Withdraw asset.\n /// @param _assetAddress Asset to be withdrawn.\n /// @param _to address to withdraw to.\n /// @param _amount amount of asset to withdraw.\n function withdraw(\n address _assetAddress,\n address _to,\n uint256 _amount\n ) external {\n if (msg.sender != LibDiamond.contractOwner()) {\n LibAccess.enforceAccessControl();\n }\n _withdrawAsset(_assetAddress, _to, _amount);\n }\n\n /// Internal Methods ///\n\n /// @notice Withdraw asset.\n /// @param _assetAddress Asset to be withdrawn.\n /// @param _to address to withdraw to.\n /// @param _amount amount of asset to withdraw.\n function _withdrawAsset(\n address _assetAddress,\n address _to,\n uint256 _amount\n ) internal {\n address sendTo = (LibUtil.isZeroAddress(_to)) ? msg.sender : _to;\n LibAsset.transferAsset(_assetAddress, payable(sendTo), _amount);\n emit LogWithdraw(_assetAddress, sendTo, _amount);\n }\n}\n" + }, + "src/Facets/WormholeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport \"../../lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\";\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { IWormholeRouter } from \"../Interfaces/IWormholeRouter.sol\";\nimport { LibDiamond } from \"../Libraries/LibDiamond.sol\";\nimport { LibAsset } from \"../Libraries/LibAsset.sol\";\nimport { LibSwap } from \"../Libraries/LibSwap.sol\";\nimport { ReentrancyGuard } from \"../Helpers/ReentrancyGuard.sol\";\nimport { UnsupportedChainId, AlreadyInitialized, NotInitialized } from \"../Errors/GenericErrors.sol\";\nimport { SwapperV2 } from \"../Helpers/SwapperV2.sol\";\nimport { Validatable } from \"../Helpers/Validatable.sol\";\n\n/// @title Wormhole Facet\n/// @author LI.FI (https://li.fi)\n/// @notice Provides functionality for bridging through Wormhole\n/// @custom:version 1.0.0\ncontract WormholeFacet is ILiFi, ReentrancyGuard, SwapperV2, Validatable {\n /// Storage ///\n\n bytes32 internal constant NAMESPACE =\n keccak256(\"com.lifi.facets.wormhole\");\n address internal constant NON_EVM_ADDRESS =\n 0x11f111f111f111F111f111f111F111f111f111F1;\n\n /// @notice The contract address of the wormhole router on the source chain.\n IWormholeRouter private immutable router;\n\n /// Types ///\n\n struct Storage {\n mapping(uint256 => uint16) wormholeChainId;\n bool initialized;\n }\n\n struct Config {\n uint256 chainId;\n uint16 wormholeChainId;\n }\n\n /// @param receiver The address of the token receiver after bridging.\n /// @param arbiterFee The amount of token to pay a relayer (can be zero if no relayer is used).\n /// @param nonce A random nonce to associate with the tx.\n struct WormholeData {\n bytes32 receiver;\n uint256 arbiterFee;\n uint32 nonce;\n }\n\n /// Events ///\n\n event WormholeInitialized(Config[] configs);\n event WormholeChainIdMapped(\n uint256 indexed lifiChainId,\n uint256 indexed wormholeChainId\n );\n event WormholeChainIdsMapped(Config[] configs);\n event BridgeToNonEVMChain(\n bytes32 indexed transactionId,\n uint256 indexed wormholeChainId,\n bytes32 receiver\n );\n\n /// Constructor ///\n\n /// @notice Initialize the contract.\n /// @param _router The contract address of the wormhole router on the source chain.\n constructor(IWormholeRouter _router) {\n router = _router;\n }\n\n /// Init ///\n\n /// @notice Initialize local variables for the Wormhole Facet\n /// @param configs Bridge configuration data\n function initWormhole(Config[] calldata configs) external {\n LibDiamond.enforceIsContractOwner();\n\n Storage storage sm = getStorage();\n\n if (sm.initialized) {\n revert AlreadyInitialized();\n }\n\n uint256 numConfigs = configs.length;\n for (uint256 i = 0; i < numConfigs; i++) {\n sm.wormholeChainId[configs[i].chainId] = configs[i]\n .wormholeChainId;\n }\n\n sm.initialized = true;\n\n emit WormholeInitialized(configs);\n }\n\n /// External Methods ///\n\n /// @notice Bridges tokens via Wormhole\n /// @param _bridgeData the core information needed for bridging\n /// @param _wormholeData data specific to Wormhole\n function startBridgeTokensViaWormhole(\n ILiFi.BridgeData memory _bridgeData,\n WormholeData calldata _wormholeData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n doesNotContainSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n LibAsset.depositAsset(\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount\n );\n _startBridge(_bridgeData, _wormholeData);\n }\n\n /// @notice Performs a swap before bridging via Wormhole\n /// @param _bridgeData the core information needed for bridging\n /// @param _swapData an array of swap related data for performing swaps before bridging\n /// @param _wormholeData data specific to Wormhole\n function swapAndStartBridgeTokensViaWormhole(\n ILiFi.BridgeData memory _bridgeData,\n LibSwap.SwapData[] calldata _swapData,\n WormholeData calldata _wormholeData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n containsSourceSwaps(_bridgeData)\n doesNotContainDestinationCalls(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n _bridgeData.minAmount = _depositAndSwap(\n _bridgeData.transactionId,\n _bridgeData.minAmount,\n _swapData,\n payable(msg.sender)\n );\n _startBridge(_bridgeData, _wormholeData);\n }\n\n /// @notice Creates a mapping between a lifi chain id and a wormhole chain id\n /// @param _lifiChainId lifi chain id\n /// @param _wormholeChainId wormhole chain id\n function setWormholeChainId(\n uint256 _lifiChainId,\n uint16 _wormholeChainId\n ) external {\n LibDiamond.enforceIsContractOwner();\n Storage storage sm = getStorage();\n sm.wormholeChainId[_lifiChainId] = _wormholeChainId;\n emit WormholeChainIdMapped(_lifiChainId, _wormholeChainId);\n }\n\n /// @notice Creates mappings between chain ids and wormhole chain ids\n /// @param configs Bridge configuration data\n function setWormholeChainIds(Config[] calldata configs) external {\n LibDiamond.enforceIsContractOwner();\n\n Storage storage sm = getStorage();\n\n if (!sm.initialized) {\n revert NotInitialized();\n }\n\n uint256 numConfigs = configs.length;\n for (uint256 i = 0; i < numConfigs; i++) {\n sm.wormholeChainId[configs[i].chainId] = configs[i]\n .wormholeChainId;\n }\n\n emit WormholeChainIdsMapped(configs);\n }\n\n /// Private Methods ///\n\n /// @dev Contains the business logic for the bridge via Wormhole\n /// @param _bridgeData the core information needed for bridging\n /// @param _wormholeData data specific to Wormhole\n function _startBridge(\n ILiFi.BridgeData memory _bridgeData,\n WormholeData calldata _wormholeData\n ) private {\n uint16 toWormholeChainId = getWormholeChainId(\n _bridgeData.destinationChainId\n );\n uint16 fromWormholeChainId = getWormholeChainId(block.chainid);\n\n {\n if (toWormholeChainId == 0)\n revert UnsupportedChainId(_bridgeData.destinationChainId);\n if (fromWormholeChainId == 0)\n revert UnsupportedChainId(block.chainid);\n }\n\n LibAsset.maxApproveERC20(\n IERC20(_bridgeData.sendingAssetId),\n address(router),\n _bridgeData.minAmount\n );\n\n if (LibAsset.isNativeAsset(_bridgeData.sendingAssetId)) {\n router.wrapAndTransferETH{ value: _bridgeData.minAmount }(\n toWormholeChainId,\n _wormholeData.receiver,\n _wormholeData.arbiterFee,\n _wormholeData.nonce\n );\n } else {\n router.transferTokens(\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount,\n toWormholeChainId,\n _wormholeData.receiver,\n _wormholeData.arbiterFee,\n _wormholeData.nonce\n );\n }\n\n if (_bridgeData.receiver == NON_EVM_ADDRESS) {\n emit BridgeToNonEVMChain(\n _bridgeData.transactionId,\n toWormholeChainId,\n _wormholeData.receiver\n );\n }\n\n emit LiFiTransferStarted(_bridgeData);\n }\n\n /// @notice Gets the wormhole chain id for a given lifi chain id\n /// @param _lifiChainId uint256 of the lifi chain ID\n /// @return uint16 of the wormhole chain id\n function getWormholeChainId(\n uint256 _lifiChainId\n ) private view returns (uint16) {\n Storage storage sm = getStorage();\n uint16 wormholeChainId = sm.wormholeChainId[_lifiChainId];\n if (wormholeChainId == 0) revert UnsupportedChainId(_lifiChainId);\n return wormholeChainId;\n }\n\n /// @dev fetch local storage\n function getStorage() private pure returns (Storage storage s) {\n bytes32 namespace = NAMESPACE;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n s.slot := namespace\n }\n }\n}\n" + }, + "src/Helpers/CelerIMFacetBase.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport \"../../lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { LibAsset, IERC20 } from \"../Libraries/LibAsset.sol\";\nimport { ERC20 } from \"../../lib/solmate/src/tokens/ERC20.sol\";\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { ReentrancyGuard } from \"../Helpers/ReentrancyGuard.sol\";\nimport { SwapperV2, LibSwap } from \"../Helpers/SwapperV2.sol\";\nimport { InvalidAmount, InformationMismatch } from \"../Errors/GenericErrors.sol\";\nimport { Validatable } from \"../Helpers/Validatable.sol\";\nimport { MessageSenderLib, MsgDataTypes, IMessageBus } from \"../../lib/sgn-v2-contracts/contracts/message/libraries/MessageSenderLib.sol\";\nimport { RelayerCelerIM } from \"../../src/Periphery/RelayerCelerIM.sol\";\n\ninterface CelerToken {\n function canonical() external returns (address);\n}\n\ninterface CelerIM {\n /// @param maxSlippage The max slippage accepted, given as percentage in point (pip).\n /// @param nonce A number input to guarantee uniqueness of transferId. Can be timestamp in practice.\n /// @param callTo The address of the contract to be called at destination.\n /// @param callData The encoded calldata with below data\n /// bytes32 transactionId,\n /// LibSwap.SwapData[] memory swapData,\n /// address receiver,\n /// address refundAddress\n /// @param messageBusFee The fee to be paid to CBridge message bus for relaying the message\n /// @param bridgeType Defines the bridge operation type (must be one of the values of CBridge library MsgDataTypes.BridgeSendType)\n struct CelerIMData {\n uint32 maxSlippage;\n uint64 nonce;\n bytes callTo;\n bytes callData;\n uint256 messageBusFee;\n MsgDataTypes.BridgeSendType bridgeType;\n }\n}\n\n/// @title CelerIM Facet Base\n/// @author LI.FI (https://li.fi)\n/// @notice Provides functionality for bridging tokens and data through CBridge\n/// @notice Used to differentiate between contract instances for mutable and immutable diamond as these cannot be shared\n/// @custom:version 2.0.0\nabstract contract CelerIMFacetBase is\n ILiFi,\n ReentrancyGuard,\n SwapperV2,\n Validatable\n{\n /// Storage ///\n\n /// @dev The contract address of the cBridge Message Bus\n IMessageBus private immutable cBridgeMessageBus;\n\n /// @dev The contract address of the RelayerCelerIM\n RelayerCelerIM public immutable relayer;\n\n /// @dev The contract address of the Celer Flow USDC\n address private immutable cfUSDC;\n\n /// Constructor ///\n\n /// @notice Initialize the contract.\n /// @param _messageBus The contract address of the cBridge Message Bus\n /// @param _relayerOwner The address that will become the owner of the RelayerCelerIM contract\n /// @param _diamondAddress The address of the diamond contract that will be connected with the RelayerCelerIM\n /// @param _cfUSDC The contract address of the Celer Flow USDC\n constructor(\n IMessageBus _messageBus,\n address _relayerOwner,\n address _diamondAddress,\n address _cfUSDC\n ) {\n // deploy RelayerCelerIM\n relayer = new RelayerCelerIM(\n address(_messageBus),\n _relayerOwner,\n _diamondAddress\n );\n\n // store arguments in variables\n cBridgeMessageBus = _messageBus;\n cfUSDC = _cfUSDC;\n }\n\n /// External Methods ///\n\n /// @notice Bridges tokens via CBridge\n /// @param _bridgeData The core information needed for bridging\n /// @param _celerIMData Data specific to CelerIM\n function startBridgeTokensViaCelerIM(\n ILiFi.BridgeData memory _bridgeData,\n CelerIM.CelerIMData calldata _celerIMData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n doesNotContainSourceSwaps(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n validateDestinationCallFlag(_bridgeData, _celerIMData);\n if (!LibAsset.isNativeAsset(_bridgeData.sendingAssetId)) {\n // Transfer ERC20 tokens directly to relayer\n IERC20 asset = _getRightAsset(_bridgeData.sendingAssetId);\n\n // Deposit ERC20 token\n uint256 prevBalance = asset.balanceOf(address(relayer));\n SafeERC20.safeTransferFrom(\n asset,\n msg.sender,\n address(relayer),\n _bridgeData.minAmount\n );\n\n if (\n asset.balanceOf(address(relayer)) - prevBalance !=\n _bridgeData.minAmount\n ) {\n revert InvalidAmount();\n }\n }\n\n _startBridge(_bridgeData, _celerIMData);\n }\n\n /// @notice Performs a swap before bridging via CBridge\n /// @param _bridgeData The core information needed for bridging\n /// @param _swapData An array of swap related data for performing swaps before bridging\n /// @param _celerIMData Data specific to CelerIM\n function swapAndStartBridgeTokensViaCelerIM(\n ILiFi.BridgeData memory _bridgeData,\n LibSwap.SwapData[] calldata _swapData,\n CelerIM.CelerIMData calldata _celerIMData\n )\n external\n payable\n nonReentrant\n refundExcessNative(payable(msg.sender))\n containsSourceSwaps(_bridgeData)\n validateBridgeData(_bridgeData)\n {\n validateDestinationCallFlag(_bridgeData, _celerIMData);\n\n _bridgeData.minAmount = _depositAndSwap(\n _bridgeData.transactionId,\n _bridgeData.minAmount,\n _swapData,\n payable(msg.sender),\n _celerIMData.messageBusFee\n );\n\n if (!LibAsset.isNativeAsset(_bridgeData.sendingAssetId)) {\n // Transfer ERC20 tokens directly to relayer\n IERC20 asset = _getRightAsset(_bridgeData.sendingAssetId);\n\n // Deposit ERC20 token\n uint256 prevBalance = asset.balanceOf(address(relayer));\n SafeERC20.safeTransfer(\n asset,\n address(relayer),\n _bridgeData.minAmount\n );\n\n if (\n asset.balanceOf(address(relayer)) - prevBalance !=\n _bridgeData.minAmount\n ) {\n revert InvalidAmount();\n }\n }\n\n _startBridge(_bridgeData, _celerIMData);\n }\n\n /// Private Methods ///\n\n /// @dev Contains the business logic for the bridge via CBridge\n /// @param _bridgeData The core information needed for bridging\n /// @param _celerIMData Data specific to CBridge\n function _startBridge(\n ILiFi.BridgeData memory _bridgeData,\n CelerIM.CelerIMData calldata _celerIMData\n ) private {\n // Assuming messageBusFee is pre-calculated off-chain and available in _celerIMData\n // Determine correct native asset amount to be forwarded (if so) and send funds to relayer\n uint256 msgValue = LibAsset.isNativeAsset(_bridgeData.sendingAssetId)\n ? _bridgeData.minAmount\n : 0;\n\n // Check if transaction contains a destination call\n if (!_bridgeData.hasDestinationCall) {\n // Case 'no': Simple bridge transfer - Send to receiver\n relayer.sendTokenTransfer{ value: msgValue }(\n _bridgeData,\n _celerIMData\n );\n } else {\n // Case 'yes': Bridge + Destination call - Send to relayer\n\n // save address of original recipient\n address receiver = _bridgeData.receiver;\n\n // Set relayer as a receiver\n _bridgeData.receiver = address(relayer);\n\n // send token transfer\n (bytes32 transferId, address bridgeAddress) = relayer\n .sendTokenTransfer{ value: msgValue }(\n _bridgeData,\n _celerIMData\n );\n\n // Call message bus via relayer incl messageBusFee\n relayer.forwardSendMessageWithTransfer{\n value: _celerIMData.messageBusFee\n }(\n _bridgeData.receiver,\n uint64(_bridgeData.destinationChainId),\n bridgeAddress,\n transferId,\n _celerIMData.callData\n );\n\n // Reset receiver of bridge data for event emission\n _bridgeData.receiver = receiver;\n }\n\n // emit LiFi event\n emit LiFiTransferStarted(_bridgeData);\n }\n\n /// @dev Get right asset to transfer to relayer.\n /// @param _sendingAssetId The address of asset to bridge.\n /// @return _asset The address of asset to transfer to relayer.\n function _getRightAsset(\n address _sendingAssetId\n ) private returns (IERC20 _asset) {\n if (_sendingAssetId == cfUSDC) {\n // special case for cfUSDC token\n _asset = IERC20(CelerToken(_sendingAssetId).canonical());\n } else {\n // any other ERC20 token\n _asset = IERC20(_sendingAssetId);\n }\n }\n\n function validateDestinationCallFlag(\n ILiFi.BridgeData memory _bridgeData,\n CelerIM.CelerIMData calldata _celerIMData\n ) private pure {\n if (\n (_celerIMData.callData.length > 0) !=\n _bridgeData.hasDestinationCall\n ) {\n revert InformationMismatch();\n }\n }\n}\n" + }, + "src/Helpers/ExcessivelySafeCall.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\n// This contract has been taken from: https://github.com/nomad-xyz/ExcessivelySafeCall\npragma solidity 0.8.17;\n\nimport { InvalidCallData } from \"../Errors/GenericErrors.sol\";\n\n// solhint-disable no-inline-assembly\nlibrary ExcessivelySafeCall {\n uint256 private constant LOW_28_MASK =\n 0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\n\n /// @notice Use when you _really_ really _really_ don't trust the called\n /// contract. This prevents the called contract from causing reversion of\n /// the caller in as many ways as we can.\n /// @dev The main difference between this and a solidity low-level call is\n /// that we limit the number of bytes that the callee can cause to be\n /// copied to caller memory. This prevents stupid things like malicious\n /// contracts returning 10,000,000 bytes causing a local OOG when copying\n /// to memory.\n /// @param _target The address to call\n /// @param _gas The amount of gas to forward to the remote contract\n /// @param _value The value in wei to send to the remote contract\n /// @param _maxCopy The maximum number of bytes of returndata to copy\n /// to memory.\n /// @param _calldata The data to send to the remote contract\n /// @return success and returndata, as `.call()`. Returndata is capped to\n /// `_maxCopy` bytes.\n function excessivelySafeCall(\n address _target,\n uint256 _gas,\n uint256 _value,\n uint16 _maxCopy,\n bytes memory _calldata\n ) internal returns (bool, bytes memory) {\n // set up for assembly call\n uint256 _toCopy;\n bool _success;\n bytes memory _returnData = new bytes(_maxCopy);\n // dispatch message to recipient\n // by assembly calling \"handle\" function\n // we call via assembly to avoid memcopying a very large returndata\n // returned by a malicious contract\n assembly {\n _success := call(\n _gas, // gas\n _target, // recipient\n _value, // ether value\n add(_calldata, 0x20), // inloc\n mload(_calldata), // inlen\n 0, // outloc\n 0 // outlen\n )\n // limit our copy to 256 bytes\n _toCopy := returndatasize()\n if gt(_toCopy, _maxCopy) {\n _toCopy := _maxCopy\n }\n // Store the length of the copied bytes\n mstore(_returnData, _toCopy)\n // copy the bytes from returndata[0:_toCopy]\n returndatacopy(add(_returnData, 0x20), 0, _toCopy)\n }\n return (_success, _returnData);\n }\n\n /// @notice Use when you _really_ really _really_ don't trust the called\n /// contract. This prevents the called contract from causing reversion of\n /// the caller in as many ways as we can.\n /// @dev The main difference between this and a solidity low-level call is\n /// that we limit the number of bytes that the callee can cause to be\n /// copied to caller memory. This prevents stupid things like malicious\n /// contracts returning 10,000,000 bytes causing a local OOG when copying\n /// to memory.\n /// @param _target The address to call\n /// @param _gas The amount of gas to forward to the remote contract\n /// @param _maxCopy The maximum number of bytes of returndata to copy\n /// to memory.\n /// @param _calldata The data to send to the remote contract\n /// @return success and returndata, as `.call()`. Returndata is capped to\n /// `_maxCopy` bytes.\n function excessivelySafeStaticCall(\n address _target,\n uint256 _gas,\n uint16 _maxCopy,\n bytes memory _calldata\n ) internal view returns (bool, bytes memory) {\n // set up for assembly call\n uint256 _toCopy;\n bool _success;\n bytes memory _returnData = new bytes(_maxCopy);\n // dispatch message to recipient\n // by assembly calling \"handle\" function\n // we call via assembly to avoid memcopying a very large returndata\n // returned by a malicious contract\n assembly {\n _success := staticcall(\n _gas, // gas\n _target, // recipient\n add(_calldata, 0x20), // inloc\n mload(_calldata), // inlen\n 0, // outloc\n 0 // outlen\n )\n // limit our copy to 256 bytes\n _toCopy := returndatasize()\n if gt(_toCopy, _maxCopy) {\n _toCopy := _maxCopy\n }\n // Store the length of the copied bytes\n mstore(_returnData, _toCopy)\n // copy the bytes from returndata[0:_toCopy]\n returndatacopy(add(_returnData, 0x20), 0, _toCopy)\n }\n return (_success, _returnData);\n }\n\n /**\n * @notice Swaps function selectors in encoded contract calls\n * @dev Allows reuse of encoded calldata for functions with identical\n * argument types but different names. It simply swaps out the first 4 bytes\n * for the new selector. This function modifies memory in place, and should\n * only be used with caution.\n * @param _newSelector The new 4-byte selector\n * @param _buf The encoded contract args\n */\n function swapSelector(\n bytes4 _newSelector,\n bytes memory _buf\n ) internal pure {\n if (_buf.length < 4) {\n revert InvalidCallData();\n }\n uint256 _mask = LOW_28_MASK;\n assembly {\n // load the first word of\n let _word := mload(add(_buf, 0x20))\n // mask out the top 4 bytes\n // /x\n _word := and(_word, _mask)\n _word := or(_newSelector, _word)\n mstore(add(_buf, 0x20), _word)\n }\n }\n}\n" + }, + "src/Helpers/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.17;\n\n/// @title Reentrancy Guard\n/// @author LI.FI (https://li.fi)\n/// @notice Abstract contract to provide protection against reentrancy\nabstract contract ReentrancyGuard {\n /// Storage ///\n\n bytes32 private constant NAMESPACE = keccak256(\"com.lifi.reentrancyguard\");\n\n /// Types ///\n\n struct ReentrancyStorage {\n uint256 status;\n }\n\n /// Errors ///\n\n error ReentrancyError();\n\n /// Constants ///\n\n uint256 private constant _NOT_ENTERED = 0;\n uint256 private constant _ENTERED = 1;\n\n /// Modifiers ///\n\n modifier nonReentrant() {\n ReentrancyStorage storage s = reentrancyStorage();\n if (s.status == _ENTERED) revert ReentrancyError();\n s.status = _ENTERED;\n _;\n s.status = _NOT_ENTERED;\n }\n\n /// Private Methods ///\n\n /// @dev fetch local storage\n function reentrancyStorage()\n private\n pure\n returns (ReentrancyStorage storage data)\n {\n bytes32 position = NAMESPACE;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n data.slot := position\n }\n }\n}\n" + }, + "src/Helpers/SwapperV2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { LibSwap } from \"../Libraries/LibSwap.sol\";\nimport { LibAsset } from \"../Libraries/LibAsset.sol\";\nimport { LibAllowList } from \"../Libraries/LibAllowList.sol\";\nimport { ContractCallNotAllowed, NoSwapDataProvided, CumulativeSlippageTooHigh } from \"../Errors/GenericErrors.sol\";\n\n/// @title Swapper\n/// @author LI.FI (https://li.fi)\n/// @notice Abstract contract to provide swap functionality\ncontract SwapperV2 is ILiFi {\n /// Types ///\n\n /// @dev only used to get around \"Stack Too Deep\" errors\n struct ReserveData {\n bytes32 transactionId;\n address payable leftoverReceiver;\n uint256 nativeReserve;\n }\n\n /// Modifiers ///\n\n /// @dev Sends any leftover balances back to the user\n /// @notice Sends any leftover balances to the user\n /// @param _swaps Swap data array\n /// @param _leftoverReceiver Address to send leftover tokens to\n /// @param _initialBalances Array of initial token balances\n modifier noLeftovers(\n LibSwap.SwapData[] calldata _swaps,\n address payable _leftoverReceiver,\n uint256[] memory _initialBalances\n ) {\n uint256 numSwaps = _swaps.length;\n if (numSwaps != 1) {\n address finalAsset = _swaps[numSwaps - 1].receivingAssetId;\n uint256 curBalance;\n\n _;\n\n for (uint256 i = 0; i < numSwaps - 1; ) {\n address curAsset = _swaps[i].receivingAssetId;\n // Handle multi-to-one swaps\n if (curAsset != finalAsset) {\n curBalance =\n LibAsset.getOwnBalance(curAsset) -\n _initialBalances[i];\n if (curBalance > 0) {\n LibAsset.transferAsset(\n curAsset,\n _leftoverReceiver,\n curBalance\n );\n }\n }\n unchecked {\n ++i;\n }\n }\n } else {\n _;\n }\n }\n\n /// @dev Sends any leftover balances back to the user reserving native tokens\n /// @notice Sends any leftover balances to the user\n /// @param _swaps Swap data array\n /// @param _leftoverReceiver Address to send leftover tokens to\n /// @param _initialBalances Array of initial token balances\n modifier noLeftoversReserve(\n LibSwap.SwapData[] calldata _swaps,\n address payable _leftoverReceiver,\n uint256[] memory _initialBalances,\n uint256 _nativeReserve\n ) {\n uint256 numSwaps = _swaps.length;\n if (numSwaps != 1) {\n address finalAsset = _swaps[numSwaps - 1].receivingAssetId;\n uint256 curBalance;\n\n _;\n\n for (uint256 i = 0; i < numSwaps - 1; ) {\n address curAsset = _swaps[i].receivingAssetId;\n // Handle multi-to-one swaps\n if (curAsset != finalAsset) {\n curBalance =\n LibAsset.getOwnBalance(curAsset) -\n _initialBalances[i];\n uint256 reserve = LibAsset.isNativeAsset(curAsset)\n ? _nativeReserve\n : 0;\n if (curBalance > 0) {\n LibAsset.transferAsset(\n curAsset,\n _leftoverReceiver,\n curBalance - reserve\n );\n }\n }\n unchecked {\n ++i;\n }\n }\n } else {\n _;\n }\n }\n\n /// @dev Refunds any excess native asset sent to the contract after the main function\n /// @notice Refunds any excess native asset sent to the contract after the main function\n /// @param _refundReceiver Address to send refunds to\n modifier refundExcessNative(address payable _refundReceiver) {\n uint256 initialBalance = address(this).balance - msg.value;\n _;\n uint256 finalBalance = address(this).balance;\n\n if (finalBalance > initialBalance) {\n LibAsset.transferAsset(\n LibAsset.NATIVE_ASSETID,\n _refundReceiver,\n finalBalance - initialBalance\n );\n }\n }\n\n /// Internal Methods ///\n\n /// @dev Deposits value, executes swaps, and performs minimum amount check\n /// @param _transactionId the transaction id associated with the operation\n /// @param _minAmount the minimum amount of the final asset to receive\n /// @param _swaps Array of data used to execute swaps\n /// @param _leftoverReceiver The address to send leftover funds to\n /// @return uint256 result of the swap\n function _depositAndSwap(\n bytes32 _transactionId,\n uint256 _minAmount,\n LibSwap.SwapData[] calldata _swaps,\n address payable _leftoverReceiver\n ) internal returns (uint256) {\n uint256 numSwaps = _swaps.length;\n\n if (numSwaps == 0) {\n revert NoSwapDataProvided();\n }\n\n address finalTokenId = _swaps[numSwaps - 1].receivingAssetId;\n uint256 initialBalance = LibAsset.getOwnBalance(finalTokenId);\n\n if (LibAsset.isNativeAsset(finalTokenId)) {\n initialBalance -= msg.value;\n }\n\n uint256[] memory initialBalances = _fetchBalances(_swaps);\n\n LibAsset.depositAssets(_swaps);\n _executeSwaps(\n _transactionId,\n _swaps,\n _leftoverReceiver,\n initialBalances\n );\n\n uint256 newBalance = LibAsset.getOwnBalance(finalTokenId) -\n initialBalance;\n\n if (newBalance < _minAmount) {\n revert CumulativeSlippageTooHigh(_minAmount, newBalance);\n }\n\n return newBalance;\n }\n\n /// @dev Deposits value, executes swaps, and performs minimum amount check and reserves native token for fees\n /// @param _transactionId the transaction id associated with the operation\n /// @param _minAmount the minimum amount of the final asset to receive\n /// @param _swaps Array of data used to execute swaps\n /// @param _leftoverReceiver The address to send leftover funds to\n /// @param _nativeReserve Amount of native token to prevent from being swept back to the caller\n function _depositAndSwap(\n bytes32 _transactionId,\n uint256 _minAmount,\n LibSwap.SwapData[] calldata _swaps,\n address payable _leftoverReceiver,\n uint256 _nativeReserve\n ) internal returns (uint256) {\n uint256 numSwaps = _swaps.length;\n\n if (numSwaps == 0) {\n revert NoSwapDataProvided();\n }\n\n address finalTokenId = _swaps[numSwaps - 1].receivingAssetId;\n uint256 initialBalance = LibAsset.getOwnBalance(finalTokenId);\n\n if (LibAsset.isNativeAsset(finalTokenId)) {\n initialBalance -= msg.value;\n }\n\n uint256[] memory initialBalances = _fetchBalances(_swaps);\n\n LibAsset.depositAssets(_swaps);\n ReserveData memory rd = ReserveData(\n _transactionId,\n _leftoverReceiver,\n _nativeReserve\n );\n _executeSwaps(rd, _swaps, initialBalances);\n\n uint256 newBalance = LibAsset.getOwnBalance(finalTokenId) -\n initialBalance;\n\n if (LibAsset.isNativeAsset(finalTokenId)) {\n newBalance -= _nativeReserve;\n }\n\n if (newBalance < _minAmount) {\n revert CumulativeSlippageTooHigh(_minAmount, newBalance);\n }\n\n return newBalance;\n }\n\n /// Private Methods ///\n\n /// @dev Executes swaps and checks that DEXs used are in the allowList\n /// @param _transactionId the transaction id associated with the operation\n /// @param _swaps Array of data used to execute swaps\n /// @param _leftoverReceiver Address to send leftover tokens to\n /// @param _initialBalances Array of initial balances\n function _executeSwaps(\n bytes32 _transactionId,\n LibSwap.SwapData[] calldata _swaps,\n address payable _leftoverReceiver,\n uint256[] memory _initialBalances\n ) internal noLeftovers(_swaps, _leftoverReceiver, _initialBalances) {\n uint256 numSwaps = _swaps.length;\n for (uint256 i = 0; i < numSwaps; ) {\n LibSwap.SwapData calldata currentSwap = _swaps[i];\n\n if (\n !((LibAsset.isNativeAsset(currentSwap.sendingAssetId) ||\n LibAllowList.contractIsAllowed(currentSwap.approveTo)) &&\n LibAllowList.contractIsAllowed(currentSwap.callTo) &&\n LibAllowList.selectorIsAllowed(\n bytes4(currentSwap.callData[:4])\n ))\n ) revert ContractCallNotAllowed();\n\n LibSwap.swap(_transactionId, currentSwap);\n\n unchecked {\n ++i;\n }\n }\n }\n\n /// @dev Executes swaps and checks that DEXs used are in the allowList\n /// @param _reserveData Data passed used to reserve native tokens\n /// @param _swaps Array of data used to execute swaps\n function _executeSwaps(\n ReserveData memory _reserveData,\n LibSwap.SwapData[] calldata _swaps,\n uint256[] memory _initialBalances\n )\n internal\n noLeftoversReserve(\n _swaps,\n _reserveData.leftoverReceiver,\n _initialBalances,\n _reserveData.nativeReserve\n )\n {\n uint256 numSwaps = _swaps.length;\n for (uint256 i = 0; i < numSwaps; ) {\n LibSwap.SwapData calldata currentSwap = _swaps[i];\n\n if (\n !((LibAsset.isNativeAsset(currentSwap.sendingAssetId) ||\n LibAllowList.contractIsAllowed(currentSwap.approveTo)) &&\n LibAllowList.contractIsAllowed(currentSwap.callTo) &&\n LibAllowList.selectorIsAllowed(\n bytes4(currentSwap.callData[:4])\n ))\n ) revert ContractCallNotAllowed();\n\n LibSwap.swap(_reserveData.transactionId, currentSwap);\n\n unchecked {\n ++i;\n }\n }\n }\n\n /// @dev Fetches balances of tokens to be swapped before swapping.\n /// @param _swaps Array of data used to execute swaps\n /// @return uint256[] Array of token balances.\n function _fetchBalances(\n LibSwap.SwapData[] calldata _swaps\n ) private view returns (uint256[] memory) {\n uint256 numSwaps = _swaps.length;\n uint256[] memory balances = new uint256[](numSwaps);\n address asset;\n for (uint256 i = 0; i < numSwaps; ) {\n asset = _swaps[i].receivingAssetId;\n balances[i] = LibAsset.getOwnBalance(asset);\n\n if (LibAsset.isNativeAsset(asset)) {\n balances[i] -= msg.value;\n }\n\n unchecked {\n ++i;\n }\n }\n\n return balances;\n }\n}\n" + }, + "src/Helpers/TransferrableOwnership.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { IERC173 } from \"../Interfaces/IERC173.sol\";\nimport { LibAsset } from \"../Libraries/LibAsset.sol\";\n\ncontract TransferrableOwnership is IERC173 {\n address public owner;\n address public pendingOwner;\n\n /// Errors ///\n error UnAuthorized();\n error NoNullOwner();\n error NewOwnerMustNotBeSelf();\n error NoPendingOwnershipTransfer();\n error NotPendingOwner();\n\n /// Events ///\n event OwnershipTransferRequested(\n address indexed _from,\n address indexed _to\n );\n\n constructor(address initialOwner) {\n owner = initialOwner;\n }\n\n modifier onlyOwner() {\n if (msg.sender != owner) revert UnAuthorized();\n _;\n }\n\n /// @notice Initiates transfer of ownership to a new address\n /// @param _newOwner the address to transfer ownership to\n function transferOwnership(address _newOwner) external onlyOwner {\n if (_newOwner == LibAsset.NULL_ADDRESS) revert NoNullOwner();\n if (_newOwner == msg.sender) revert NewOwnerMustNotBeSelf();\n pendingOwner = _newOwner;\n emit OwnershipTransferRequested(msg.sender, pendingOwner);\n }\n\n /// @notice Cancel transfer of ownership\n function cancelOwnershipTransfer() external onlyOwner {\n if (pendingOwner == LibAsset.NULL_ADDRESS)\n revert NoPendingOwnershipTransfer();\n pendingOwner = LibAsset.NULL_ADDRESS;\n }\n\n /// @notice Confirms transfer of ownership to the calling address (msg.sender)\n function confirmOwnershipTransfer() external {\n address _pendingOwner = pendingOwner;\n if (msg.sender != _pendingOwner) revert NotPendingOwner();\n emit OwnershipTransferred(owner, _pendingOwner);\n owner = _pendingOwner;\n pendingOwner = LibAsset.NULL_ADDRESS;\n }\n}\n" + }, + "src/Helpers/Validatable.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.17;\n\nimport { LibAsset } from \"../Libraries/LibAsset.sol\";\nimport { LibUtil } from \"../Libraries/LibUtil.sol\";\nimport { InvalidReceiver, InformationMismatch, InvalidSendingToken, InvalidAmount, NativeAssetNotSupported, InvalidDestinationChain, CannotBridgeToSameNetwork } from \"../Errors/GenericErrors.sol\";\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { LibSwap } from \"../Libraries/LibSwap.sol\";\n\ncontract Validatable {\n modifier validateBridgeData(ILiFi.BridgeData memory _bridgeData) {\n if (LibUtil.isZeroAddress(_bridgeData.receiver)) {\n revert InvalidReceiver();\n }\n if (_bridgeData.minAmount == 0) {\n revert InvalidAmount();\n }\n if (_bridgeData.destinationChainId == block.chainid) {\n revert CannotBridgeToSameNetwork();\n }\n _;\n }\n\n modifier noNativeAsset(ILiFi.BridgeData memory _bridgeData) {\n if (LibAsset.isNativeAsset(_bridgeData.sendingAssetId)) {\n revert NativeAssetNotSupported();\n }\n _;\n }\n\n modifier onlyAllowSourceToken(\n ILiFi.BridgeData memory _bridgeData,\n address _token\n ) {\n if (_bridgeData.sendingAssetId != _token) {\n revert InvalidSendingToken();\n }\n _;\n }\n\n modifier onlyAllowDestinationChain(\n ILiFi.BridgeData memory _bridgeData,\n uint256 _chainId\n ) {\n if (_bridgeData.destinationChainId != _chainId) {\n revert InvalidDestinationChain();\n }\n _;\n }\n\n modifier containsSourceSwaps(ILiFi.BridgeData memory _bridgeData) {\n if (!_bridgeData.hasSourceSwaps) {\n revert InformationMismatch();\n }\n _;\n }\n\n modifier doesNotContainSourceSwaps(ILiFi.BridgeData memory _bridgeData) {\n if (_bridgeData.hasSourceSwaps) {\n revert InformationMismatch();\n }\n _;\n }\n\n modifier doesNotContainDestinationCalls(\n ILiFi.BridgeData memory _bridgeData\n ) {\n if (_bridgeData.hasDestinationCall) {\n revert InformationMismatch();\n }\n _;\n }\n}\n" + }, + "src/Interfaces/IAcrossSpokePool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\ninterface IAcrossSpokePool {\n function deposit(\n address recipient, // Recipient address\n address originToken, // Address of the token\n uint256 amount, // Token amount\n uint256 destinationChainId, // ⛓ id\n int64 relayerFeePct, // see #Fees Calculation\n uint32 quoteTimestamp, // Timestamp for the quote creation\n bytes memory message, // Arbitrary data that can be used to pass additional information to the recipient along with the tokens.\n uint256 maxCount // Used to protect the depositor from frontrunning to guarantee their quote remains valid.\n ) external payable;\n}\n" + }, + "src/Interfaces/IAllBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\n/// @title AllBridge Interface\ninterface IAllBridge {\n /// @dev AllBridge Messenger Protocol Enum\n enum MessengerProtocol {\n None,\n Allbridge,\n Wormhole,\n LayerZero\n }\n\n function pools(bytes32 addr) external returns (address);\n\n function swapAndBridge(\n bytes32 token,\n uint256 amount,\n bytes32 recipient,\n uint256 destinationChainId,\n bytes32 receiveToken,\n uint256 nonce,\n MessengerProtocol messenger,\n uint256 feeTokenAmount\n ) external payable;\n\n function getTransactionCost(\n uint256 chainId\n ) external view returns (uint256);\n\n function getMessageCost(\n uint256 chainId,\n MessengerProtocol protocol\n ) external view returns (uint256);\n\n function getBridgingCostInTokens(\n uint256 destinationChainId,\n MessengerProtocol messenger,\n address tokenAddress\n ) external view returns (uint256);\n}\n" + }, + "src/Interfaces/ICBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\ninterface ICBridge {\n /// @notice Send a cross-chain transfer via the liquidity pool-based bridge.\n /// @dev This function DOES NOT SUPPORT fee-on-transfer / rebasing tokens.\n /// @param _receiver The address of the receiver.\n /// @param _token The address of the token.\n /// @param _amount The amount of the transfer.\n /// @param _dstChainId The destination chain ID.\n /// @param _nonce A number input to guarantee uniqueness of transferId. Can be timestamp in practice.\n /// @param _maxSlippage The max slippage accepted, given as percentage in point (pip).\n /// Eg. 5000 means 0.5%. Must be greater than minimalMaxSlippage.\n /// Receiver is guaranteed to receive at least (100% - max slippage percentage) * amount\n /// or the transfer can be refunded.\n function send(\n address _receiver,\n address _token,\n uint256 _amount,\n uint64 _dstChainId,\n uint64 _nonce,\n uint32 _maxSlippage\n ) external;\n\n /// @notice Send a cross-chain transfer via the liquidity pool-based bridge using the native token.\n /// @param _receiver The address of the receiver.\n /// @param _amount The amount of the transfer.\n /// @param _dstChainId The destination chain ID.\n /// @param _nonce A unique number. Can be timestamp in practice.\n /// @param _maxSlippage The max slippage accepted, given as percentage in point (pip).\n /// Eg. 5000 means 0.5%. Must be greater than minimalMaxSlippage.\n /// Receiver is guaranteed to receive at least (100% - max slippage percentage) * amount\n /// or the transfer can be refunded.\n function sendNative(\n address _receiver,\n uint256 _amount,\n uint64 _dstChainId,\n uint64 _nonce,\n uint32 _maxSlippage\n ) external payable;\n}\n" + }, + "src/Interfaces/ICircleBridgeProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\ninterface ICircleBridgeProxy {\n /// @notice Deposits and burns tokens from sender to be minted on destination domain.\n /// @dev reverts if:\n /// - given burnToken is not supported.\n /// - given destinationDomain has no TokenMessenger registered.\n /// - transferFrom() reverts. For example, if sender's burnToken balance\n /// or approved allowance to this contract is less than `amount`.\n /// - burn() reverts. For example, if `amount` is 0.\n /// - MessageTransmitter returns false or reverts.\n /// @param _amount Amount of tokens to burn.\n /// @param _dstChid Destination domain.\n /// @param _mintRecipient Address of mint recipient on destination domain.\n /// @param _burnToken Address of contract to burn deposited tokens, on local domain.\n /// @return nonce Unique nonce reserved by message.\n function depositForBurn(\n uint256 _amount,\n uint64 _dstChid,\n bytes32 _mintRecipient,\n address _burnToken\n ) external returns (uint64 nonce);\n}\n" + }, + "src/Interfaces/IConnextHandler.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\ninterface IConnextHandler {\n /// @notice These are the call parameters that will remain constant between the\n /// two chains. They are supplied on `xcall` and should be asserted on `execute`\n /// @property to - The account that receives funds, in the event of a crosschain call,\n /// will receive funds if the call fails.\n /// @param to - The address you are sending funds (and potentially data) to\n /// @param callData - The data to execute on the receiving chain. If no crosschain call is needed, then leave empty.\n /// @param originDomain - The originating domain (i.e. where `xcall` is called). Must match nomad domain schema\n /// @param destinationDomain - The final domain (i.e. where `execute` / `reconcile` are called). Must match nomad domain schema\n /// @param agent - An address who can execute txs on behalf of `to`, in addition to allowing relayers\n /// @param recovery - The address to send funds to if your `Executor.execute call` fails\n /// @param forceSlow - If true, will take slow liquidity path even if it is not a permissioned call\n /// @param receiveLocal - If true, will use the local nomad asset on the destination instead of adopted.\n /// @param callback - The address on the origin domain of the callback contract\n /// @param callbackFee - The relayer fee to execute the callback\n /// @param relayerFee - The amount of relayer fee the tx called xcall with\n /// @param slippageTol - Max bps of original due to slippage (i.e. would be 9995 to tolerate .05% slippage)\n struct CallParams {\n address to;\n bytes callData;\n uint32 originDomain;\n uint32 destinationDomain;\n address agent;\n address recovery;\n bool forceSlow;\n bool receiveLocal;\n address callback;\n uint256 callbackFee;\n uint256 relayerFee;\n uint256 slippageTol;\n }\n\n /// @notice The arguments you supply to the `xcall` function called by user on origin domain\n /// @param params - The CallParams. These are consistent across sending and receiving chains\n /// @param transactingAsset - The asset the caller sent with the transfer. Can be the adopted, canonical,\n /// or the representational asset\n /// @param transactingAmount - The amount of transferring asset supplied by the user in the `xcall`\n /// @param originMinOut - Minimum amount received on swaps for adopted <> local on origin chain\n struct XCallArgs {\n CallParams params;\n address transactingAsset; // Could be adopted, local, or wrapped\n uint256 transactingAmount;\n uint256 originMinOut;\n }\n\n function xcall(\n uint32 destination,\n address recipient,\n address tokenAddress,\n address delegate,\n uint256 amount,\n uint256 slippage,\n bytes memory callData\n ) external payable returns (bytes32);\n\n function xcall(\n uint32 destination,\n address recipient,\n address tokenAddress,\n address delegate,\n uint256 amount,\n uint256 slippage,\n bytes memory callData,\n uint256 _relayerFee\n ) external returns (bytes32);\n}\n" + }, + "src/Interfaces/IDeBridgeGate.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\ninterface IDeBridgeGate {\n /// @param fixedNativeFee Transfer fixed fee.\n /// @param isSupported Whether the chain for the asset is supported.\n /// @param transferFeeBps Transfer fee rate nominated in basis points (1/10000)\n /// of transferred amount.\n struct ChainSupportInfo {\n uint256 fixedNativeFee;\n bool isSupported;\n uint16 transferFeeBps;\n }\n\n /// @dev Fallback fixed fee in native asset, used if a chain fixed fee is set to 0\n function globalFixedNativeFee() external view returns (uint256);\n\n /// @dev Whether the chain for the asset is supported to send\n function getChainToConfig(\n uint256\n ) external view returns (ChainSupportInfo memory);\n\n /// @dev This method is used for the transfer of assets.\n /// It locks an asset in the smart contract in the native chain\n /// and enables minting of deAsset on the secondary chain.\n /// @param _tokenAddress Asset identifier.\n /// @param _amount Amount to be transferred (note: the fee can be applied).\n /// @param _chainIdTo Chain id of the target chain.\n /// @param _receiver Receiver address.\n /// @param _permit deadline + signature for approving the spender by signature.\n /// @param _useAssetFee use assets fee for pay protocol fix (work only for specials token)\n /// @param _referralCode Referral code\n /// @param _autoParams Auto params for external call in target network\n function send(\n address _tokenAddress,\n uint256 _amount,\n uint256 _chainIdTo,\n bytes memory _receiver,\n bytes memory _permit,\n bool _useAssetFee,\n uint32 _referralCode,\n bytes calldata _autoParams\n ) external payable;\n}\n" + }, + "src/Interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\ninterface IDiamondCut {\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n" + }, + "src/Interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\n}\n" + }, + "src/Interfaces/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(\n bytes4 interfaceId\n ) external view returns (bool);\n}\n" + }, + "src/Interfaces/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "src/Interfaces/IERC20Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\ninterface IERC20Proxy {\n function transferFrom(\n address tokenAddress,\n address from,\n address to,\n uint256 amount\n ) external;\n}\n" + }, + "src/Interfaces/IExecutor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { LibSwap } from \"../Libraries/LibSwap.sol\";\n\n/// @title Interface for Executor\n/// @author LI.FI (https://li.fi)\ninterface IExecutor {\n /// @notice Performs a swap before completing a cross-chain transaction\n /// @param _transactionId the transaction id associated with the operation\n /// @param _swapData array of data needed for swaps\n /// @param transferredAssetId token received from the other chain\n /// @param receiver address that will receive tokens in the end\n function swapAndCompleteBridgeTokens(\n bytes32 _transactionId,\n LibSwap.SwapData[] calldata _swapData,\n address transferredAssetId,\n address payable receiver\n ) external payable;\n}\n" + }, + "src/Interfaces/IGatewayRouter.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.17;\n\ninterface IGatewayRouter {\n /// @notice Transfer non-native assets\n /// @param _token L1 address of ERC20\n /// @param _to Account to be credited with the tokens in the L2 (can be the user's L2 account or a contract)\n /// @param _amount Token Amount\n /// @param _maxGas Max gas deducted from user's L2 balance to cover L2 execution\n /// @param _gasPriceBid Gas price for L2 execution\n /// @param _data Encoded data from router and user\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 memory);\n\n /// @dev Advanced usage only (does not rewrite aliases for excessFeeRefundAddress and callValueRefundAddress). createRetryableTicket method is the recommended standard.\n /// @param _destAddr destination L2 contract address\n /// @param _l2CallValue call value for retryable L2 message\n /// @param _maxSubmissionCost Max gas deducted from user's L2 balance to cover base submission fee\n /// @param _excessFeeRefundAddress maxgas x gasprice - execution cost gets credited here on L2 balance\n /// @param _callValueRefundAddress l2Callvalue gets credited here on L2 if retryable txn times out or gets cancelled\n /// @param _maxGas Max gas deducted from user's L2 balance to cover L2 execution\n /// @param _gasPriceBid price bid for L2 execution\n /// @param _data ABI encoded data of L2 message\n /// @return unique id for retryable transaction (keccak256(requestID, uint(0) )\n function unsafeCreateRetryableTicket(\n address _destAddr,\n uint256 _l2CallValue,\n uint256 _maxSubmissionCost,\n address _excessFeeRefundAddress,\n address _callValueRefundAddress,\n uint256 _maxGas,\n uint256 _gasPriceBid,\n bytes calldata _data\n ) external payable returns (uint256);\n\n /// @notice Returns receiving token address on L2\n /// @param _token Sending token address on L1\n /// @return Receiving token address on L2\n function calculateL2TokenAddress(\n address _token\n ) external view returns (address);\n\n /// @notice Returns exact gateway router address for token\n /// @param _token Sending token address on L1\n /// @return Gateway router address for sending token\n function getGateway(address _token) external view returns (address);\n}\n" + }, + "src/Interfaces/IHopBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\ninterface IHopBridge {\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 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 function send(\n uint256 chainId,\n address recipient,\n uint256 amount,\n uint256 bonderFee,\n uint256 amountOutMin,\n uint256 deadline\n ) external;\n}\n\ninterface IL2AmmWrapper {\n function bridge() external view returns (address);\n\n function l2CanonicalToken() external view returns (address);\n\n function hToken() external view returns (address);\n\n function exchangeAddress() external view returns (address);\n}\n\ninterface ISwap {\n function swap(\n uint8 tokenIndexFrom,\n uint8 tokenIndexTo,\n uint256 dx,\n uint256 minDy,\n uint256 deadline\n ) external returns (uint256);\n}\n" + }, + "src/Interfaces/IHyphenRouter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\n// https://github.com/bcnmy/hyphen-contract/blob/master/contracts/hyphen/LiquidityPool.sol\ninterface IHyphenRouter {\n function depositErc20(\n uint256 toChainId,\n address tokenAddress,\n address receiver,\n uint256 amount,\n string calldata tag\n ) external;\n\n function depositNative(\n address receiver,\n uint256 toChainId,\n string calldata tag\n ) external payable;\n}\n" + }, + "src/Interfaces/IL1StandardBridge.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.17;\n\ninterface IL1StandardBridge {\n /// @notice Deposit an amount of ETH to a recipient's balance on L2.\n /// @param _to L2 address to credit the withdrawal to.\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 function depositETHTo(\n address _to,\n uint32 _l2Gas,\n bytes calldata _data\n ) external payable;\n\n /// @notice Deposit an amount of the ERC20 to the caller'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 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 /// @notice Deposit an amount of the ERC20 to the caller's balance on L2.\n /// @dev This function is implemented on SynthetixBridgeToOptimism contract.\n /// @param _to L2 address to credit the withdrawal to.\n /// @param _amount Amount of the ERC20 to deposit\n function depositTo(address _to, uint256 _amount) external;\n}\n" + }, + "src/Interfaces/ILiFi.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\ninterface ILiFi {\n /// Structs ///\n\n struct BridgeData {\n bytes32 transactionId;\n string bridge;\n string integrator;\n address referrer;\n address sendingAssetId;\n address receiver;\n uint256 minAmount;\n uint256 destinationChainId;\n bool hasSourceSwaps;\n bool hasDestinationCall;\n }\n\n /// Events ///\n\n event LiFiTransferStarted(ILiFi.BridgeData bridgeData);\n\n event LiFiTransferCompleted(\n bytes32 indexed transactionId,\n address receivingAssetId,\n address receiver,\n uint256 amount,\n uint256 timestamp\n );\n\n event LiFiTransferRecovered(\n bytes32 indexed transactionId,\n address receivingAssetId,\n address receiver,\n uint256 amount,\n uint256 timestamp\n );\n\n event LiFiGenericSwapCompleted(\n bytes32 indexed transactionId,\n string integrator,\n string referrer,\n address receiver,\n address fromAssetId,\n address toAssetId,\n uint256 fromAmount,\n uint256 toAmount\n );\n\n // Deprecated but kept here to include in ABI to parse historic events\n event LiFiSwappedGeneric(\n bytes32 indexed transactionId,\n string integrator,\n string referrer,\n address fromAssetId,\n address toAssetId,\n uint256 fromAmount,\n uint256 toAmount\n );\n}\n" + }, + "src/Interfaces/IMultichainRouter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\ninterface IMultichainRouter {\n function anySwapOutUnderlying(\n address token,\n address to,\n uint256 amount,\n uint256 toChainID\n ) external;\n\n function anySwapOut(\n address token,\n address to,\n uint256 amount,\n uint256 toChainID\n ) external;\n\n function anySwapOutNative(\n address token,\n address to,\n uint256 toChainID\n ) external payable;\n\n function wNATIVE() external returns (address);\n}\n" + }, + "src/Interfaces/IMultichainToken.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\ninterface IMultichainToken {\n function underlying() external returns (address);\n}\n" + }, + "src/Interfaces/IOmniBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\ninterface IOmniBridge {\n /// @dev Initiate the bridge operation for some amount of tokens from msg.sender.\n /// @param token bridged token contract address.\n /// @param receiver Receiver address\n /// @param amount Dai amount\n function relayTokens(\n address token,\n address receiver,\n uint256 amount\n ) external;\n\n /// @dev Wraps native assets and relays wrapped ERC20 tokens to the other chain.\n /// @param receiver Bridged assets receiver on the other side of the bridge.\n function wrapAndRelayTokens(address receiver) external payable;\n}\n" + }, + "src/Interfaces/IRootChainManager.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.17;\n\ninterface IRootChainManager {\n /// @notice Move ether from root to child chain, accepts ether transfer\n /// @dev 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 function depositEtherFor(address user) external payable;\n\n /// @notice Move tokens from root to child chain\n /// @dev This mechanism supports arbitrary tokens as long as\n /// its predicate has been registered and the token is mapped\n /// @param user address of account that should receive this deposit on child chain\n /// @param rootToken address of token that is being deposited\n /// @param depositData bytes data that is sent to predicate and\n /// child token contracts to handle deposit\n function depositFor(\n address user,\n address rootToken,\n bytes calldata depositData\n ) external;\n\n /// @notice Returns child token address for root token\n /// @param rootToken Root token address\n /// @return childToken Child token address\n function rootToChildToken(\n address rootToken\n ) external view returns (address childToken);\n}\n" + }, + "src/Interfaces/IStargateRouter.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.17;\n\n// solhint-disable contract-name-camelcase\ninterface IStargateRouter {\n struct lzTxObj {\n uint256 dstGasForCall;\n uint256 dstNativeAmount;\n bytes dstNativeAddr;\n }\n\n /// @notice SwapAmount struct\n /// @param amountLD The amount, in Local Decimals, to be swapped\n /// @param minAmountLD The minimum amount accepted out on destination\n struct SwapAmount {\n uint256 amountLD;\n uint256 minAmountLD;\n }\n\n /// @notice Returns factory address used for creating pools.\n function factory() external view returns (address);\n\n /// @notice Swap assets cross-chain.\n /// @dev Pass (0, 0, \"0x\") to lzTxParams\n /// for 0 additional gasLimit increase, 0 airdrop, at 0x address.\n /// @param dstChainId Destination chainId\n /// @param srcPoolId Source pool id\n /// @param dstPoolId Dest pool id\n /// @param refundAddress Refund adddress. extra gas (if any) is returned to this address\n /// @param amountLD Quantity to swap\n /// @param minAmountLD The min qty you would accept on the destination\n /// @param lzTxParams Additional gas, airdrop data\n /// @param to The address to send the tokens to on the destination\n /// @param payload Additional payload. You can abi.encode() them here\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 Swap native assets cross-chain.\n /// @param _dstChainId Destination Stargate chainId\n /// @param _refundAddress Refunds additional messageFee to this address\n /// @param _toAddress The receiver of the destination ETH\n /// @param _swapAmount The amount and the minimum swap amount\n /// @param _lzTxParams The LZ tx params\n /// @param _payload The payload to send to the destination\n function swapETHAndCall(\n uint16 _dstChainId,\n address payable _refundAddress,\n bytes calldata _toAddress,\n SwapAmount memory _swapAmount,\n IStargateRouter.lzTxObj memory _lzTxParams,\n bytes calldata _payload\n ) external payable;\n\n /// @notice Returns the native gas fee required for swap.\n function quoteLayerZeroFee(\n uint16 dstChainId,\n uint8 functionType,\n bytes calldata toAddress,\n bytes calldata transferAndCallPayload,\n lzTxObj memory lzTxParams\n ) external view returns (uint256 nativeFee, uint256 zroFee);\n}\n" + }, + "src/Interfaces/ISynapseRouter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\ninterface ISynapseRouter {\n /// @notice Struct representing a request for SynapseRouter.\n /// @dev tokenIn is supplied separately.\n /// @param swapAdapter Adapter address that will perform the swap.\n /// Address(0) specifies a \"no swap\" query.\n /// @param tokenOut Token address to swap to.\n /// @param minAmountOut Minimum amount of tokens to receive after the swap,\n /// or tx will be reverted.\n /// @param deadline Latest timestamp for when the transaction needs to be executed,\n /// or tx will be reverted.\n /// @param rawParams ABI-encoded params for the swap that will be passed to `swapAdapter`.\n /// Should be SynapseParams for swaps via SynapseAdapter.\n struct SwapQuery {\n address swapAdapter;\n address tokenOut;\n uint256 minAmountOut;\n uint256 deadline;\n bytes rawParams;\n }\n\n /// @notice Struct representing a request for a swap quote from a bridge token.\n /// @dev tokenOut is passed externally.\n /// @param symbol Bridge token symbol: unique token ID consistent among all chains.\n /// @param amountIn Amount of bridge token to start with, before the bridge fee is applied.\n struct DestRequest {\n string symbol;\n uint256 amountIn;\n }\n\n /// @notice Struct representing a bridge token.\n /// Used as the return value in view functions.\n /// @param symbol Bridge token symbol: unique token ID consistent among all chains.\n /// @param token Bridge token address.\n struct BridgeToken {\n string symbol;\n address token;\n }\n\n /// @notice Initiate a bridge transaction with an optional swap on both origin\n /// and destination chains.\n /// @dev Note This method is payable.\n /// If token is ETH_ADDRESS, this method should be invoked with `msg.value = amountIn`.\n /// If token is ERC20, the tokens will be pulled from msg.sender (use `msg.value = 0`).\n /// Make sure to approve this contract for spending `token` beforehand.\n /// originQuery.tokenOut should never be ETH_ADDRESS, bridge only works with ERC20 tokens.\n ///\n /// `token` is always a token user is sending.\n /// In case token requires a wrapper token to be bridge,\n /// use underlying address for `token` instead of the wrapper one.\n ///\n /// `originQuery` contains instructions for the swap on origin chain.\n /// As above, originQuery.tokenOut should always use the underlying address.\n /// In other words, the concept of wrapper token is fully abstracted away from the end user.\n ///\n /// `originQuery` is supposed to be fetched using SynapseRouter.getOriginAmountOut().\n /// Alternatively one could use an external adapter for more complex swaps on the origin chain.\n ///\n /// `destQuery` is supposed to be fetched using SynapseRouter.getDestinationAmountOut().\n /// Complex swaps on destination chain are not supported for the time being.\n /// Check contract description above for more details.\n /// @param to Address to receive tokens on destination chain.\n /// @param chainId Destination chain id.\n /// @param token Initial token for the bridge transaction to be pulled from the user.\n /// @param amount Amount of the initial tokens for the bridge transaction.\n /// @param originQuery Origin swap query. Empty struct indicates no swap is required.\n /// @param destQuery Destination swap query. Empty struct indicates no swap is required.\n function bridge(\n address to,\n uint256 chainId,\n address token,\n uint256 amount,\n SwapQuery memory originQuery,\n SwapQuery memory destQuery\n ) external payable;\n\n /// @notice Finds the best path between `tokenIn` and every supported bridge token\n /// from the given list, treating the swap as \"origin swap\",\n /// without putting any restrictions on the swap.\n /// @dev Will NOT revert if any of the tokens are not supported,\n /// instead will return an empty query for that symbol.\n /// Check (query.minAmountOut != 0): this is true only if the swap is possible\n /// and bridge token is supported.\n /// The returned queries with minAmountOut != 0 could be used as `originQuery`\n /// with SynapseRouter.\n /// Note: It is possible to form a SwapQuery off-chain using alternative SwapAdapter\n /// for the origin swap.\n /// @param tokenIn Initial token that user wants to bridge/swap.\n /// @param tokenSymbols List of symbols representing bridge tokens.\n /// @param amountIn Amount of tokens user wants to bridge/swap.\n /// @return originQueries List of structs that could be used as `originQuery` in SynapseRouter.\n /// minAmountOut and deadline fields will need to be adjusted\n /// based on the user settings.\n function getOriginAmountOut(\n address tokenIn,\n string[] memory tokenSymbols,\n uint256 amountIn\n ) external view returns (SwapQuery[] memory originQueries);\n\n /// @notice Finds the best path between every supported bridge token from\n /// the given list and `tokenOut`, treating the swap as \"destination swap\",\n /// limiting possible actions to those available for every bridge token.\n /// @dev Will NOT revert if any of the tokens are not supported,\n /// instead will return an empty query for that symbol.\n /// Note: It is NOT possible to form a SwapQuery off-chain using alternative SwapAdapter\n /// for the destination swap.\n /// For the time being, only swaps through the Synapse-supported pools\n /// are available on destination chain.\n /// @param requests List of structs with following information:\n /// - symbol: unique token ID consistent among all chains.\n /// - amountIn: amount of bridge token to start with,\n /// before the bridge fee is applied.\n /// @param tokenOut Token user wants to receive on destination chain.\n /// @return destQueries List of structs that could be used as `destQuery` in SynapseRouter.\n /// minAmountOut and deadline fields will need to be adjusted based\n /// on the user settings.\n function getDestinationAmountOut(\n DestRequest[] memory requests,\n address tokenOut\n ) external view returns (SwapQuery[] memory destQueries);\n\n /// @notice Gets the list of all bridge tokens (and their symbols),\n /// such that destination swap from a bridge token to `tokenOut` is possible.\n /// @param tokenOut Token address to swap to on destination chain\n /// @return tokens List of structs with following information:\n /// - symbol: unique token ID consistent among all chains\n /// - token: bridge token address\n function getConnectedBridgeTokens(\n address tokenOut\n ) external view returns (BridgeToken[] memory tokens);\n}\n" + }, + "src/Interfaces/ITeleportGateway.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\ninterface ITeleportGateway {\n /// @notice Initiate DAI transfer.\n /// @param targetDomain Domain of destination chain.\n /// @param receiver Receiver address.\n /// @param amount The amount of DAI to transfer.\n function initiateTeleport(\n bytes32 targetDomain,\n address receiver,\n uint128 amount\n ) external;\n}\n" + }, + "src/Interfaces/ITokenMessenger.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\ninterface ITokenMessenger {\n /// @notice Deposits and burns tokens from sender to be minted on destination domain.\n /// @dev reverts if:\n /// - given burnToken is not supported.\n /// - given destinationDomain has no TokenMessenger registered.\n /// - transferFrom() reverts. For example, if sender's burnToken balance\n /// or approved allowance to this contract is less than `amount`.\n /// - burn() reverts. For example, if `amount` is 0.\n /// - MessageTransmitter returns false or reverts.\n /// @param amount Amount of tokens to burn.\n /// @param destinationDomain Destination domain.\n /// @param mintRecipient Address of mint recipient on destination domain.\n /// @param burnToken Address of contract to burn deposited tokens, on local domain.\n /// @return nonce Unique nonce reserved by message.\n function depositForBurn(\n uint256 amount,\n uint32 destinationDomain,\n bytes32 mintRecipient,\n address burnToken\n ) external returns (uint64 nonce);\n}\n" + }, + "src/Interfaces/ITransactionManager.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.17;\n\ninterface ITransactionManager {\n // Structs\n\n // Holds all data that is constant between sending and\n // receiving chains. The hash of this is what gets signed\n // to ensure the signature can be used on both chains.\n struct InvariantTransactionData {\n address receivingChainTxManagerAddress;\n address user;\n address router;\n address initiator; // msg.sender of sending side\n address sendingAssetId;\n address receivingAssetId;\n address sendingChainFallback; // funds sent here on cancel\n address receivingAddress;\n address callTo;\n uint256 sendingChainId;\n uint256 receivingChainId;\n bytes32 callDataHash; // hashed to prevent free option\n bytes32 transactionId;\n }\n\n // All Transaction data, constant and variable\n struct TransactionData {\n address receivingChainTxManagerAddress;\n address user;\n address router;\n address initiator; // msg.sender of sending side\n address sendingAssetId;\n address receivingAssetId;\n address sendingChainFallback;\n address receivingAddress;\n address callTo;\n bytes32 callDataHash;\n bytes32 transactionId;\n uint256 sendingChainId;\n uint256 receivingChainId;\n uint256 amount;\n uint256 expiry;\n uint256 preparedBlockNumber; // Needed for removal of active blocks on fulfill/cancel\n }\n\n /**\n * Arguments for calling prepare()\n * @param invariantData The data for a crosschain transaction that will\n * not change between sending and receiving chains.\n * The hash of this data is used as the key to store\n * the inforamtion that does change between chains\n * (amount,expiry,preparedBlock) for verification\n * @param amount The amount of the transaction on this chain\n * @param expiry The block.timestamp when the transaction will no longer be\n * fulfillable and is freely cancellable on this chain\n * @param encryptedCallData The calldata to be executed when the tx is\n * fulfilled. Used in the function to allow the user\n * to reconstruct the tx from events. Hash is stored\n * onchain to prevent shenanigans.\n * @param encodedBid The encoded bid that was accepted by the user for this\n * crosschain transfer. It is supplied as a param to the\n * function but is only used in event emission\n * @param bidSignature The signature of the bidder on the encoded bid for\n * this transaction. Only used within the function for\n * event emission. The validity of the bid and\n * bidSignature are enforced offchain\n * @param encodedMeta The meta for the function\n */\n struct PrepareArgs {\n InvariantTransactionData invariantData;\n uint256 amount;\n uint256 expiry;\n bytes encryptedCallData;\n bytes encodedBid;\n bytes bidSignature;\n bytes encodedMeta;\n }\n\n // called in the following order (in happy case)\n // 1. prepare by user on sending chain\n function prepare(\n PrepareArgs calldata args\n ) external payable returns (TransactionData memory);\n}\n" + }, + "src/Interfaces/IWormholeRouter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\ninterface IWormholeRouter {\n function transferTokens(\n address token,\n uint256 amount,\n uint16 recipientChain,\n bytes32 recipient,\n uint256 arbiterFee,\n uint32 nonce\n ) external;\n\n function wrapAndTransferETH(\n uint16 recipientChain,\n bytes32 recipient,\n uint256 arbiterFee,\n uint32 nonce\n ) external payable returns (uint64 sequence);\n}\n" + }, + "src/Interfaces/IXDaiBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\ninterface IXDaiBridge {\n /// @notice Bridge Dai to xDai and sends to receiver\n /// @dev It's implemented in xDaiBridge on only Ethereum\n /// @param receiver Receiver address\n /// @param amount Dai amount\n function relayTokens(address receiver, uint256 amount) external;\n}\n" + }, + "src/Interfaces/IXDaiBridgeL2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\ninterface IXDaiBridgeL2 {\n /// @notice Bridge xDai to DAI and sends to receiver\n /// @dev It's implemented in xDaiBridge on only Gnosis\n /// @param receiver Receiver address\n function relayTokens(address receiver) external payable;\n}\n" + }, + "src/Libraries/LibAccess.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { CannotAuthoriseSelf, UnAuthorized } from \"../Errors/GenericErrors.sol\";\n\n/// @title Access Library\n/// @author LI.FI (https://li.fi)\n/// @notice Provides functionality for managing method level access control\nlibrary LibAccess {\n /// Types ///\n bytes32 internal constant NAMESPACE =\n keccak256(\"com.lifi.library.access.management\");\n\n /// Storage ///\n struct AccessStorage {\n mapping(bytes4 => mapping(address => bool)) execAccess;\n }\n\n /// Events ///\n event AccessGranted(address indexed account, bytes4 indexed method);\n event AccessRevoked(address indexed account, bytes4 indexed method);\n\n /// @dev Fetch local storage\n function accessStorage()\n internal\n pure\n returns (AccessStorage storage accStor)\n {\n bytes32 position = NAMESPACE;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n accStor.slot := position\n }\n }\n\n /// @notice Gives an address permission to execute a method\n /// @param selector The method selector to execute\n /// @param executor The address to grant permission to\n function addAccess(bytes4 selector, address executor) internal {\n if (executor == address(this)) {\n revert CannotAuthoriseSelf();\n }\n AccessStorage storage accStor = accessStorage();\n accStor.execAccess[selector][executor] = true;\n emit AccessGranted(executor, selector);\n }\n\n /// @notice Revokes permission to execute a method\n /// @param selector The method selector to execute\n /// @param executor The address to revoke permission from\n function removeAccess(bytes4 selector, address executor) internal {\n AccessStorage storage accStor = accessStorage();\n accStor.execAccess[selector][executor] = false;\n emit AccessRevoked(executor, selector);\n }\n\n /// @notice Enforces access control by reverting if `msg.sender`\n /// has not been given permission to execute `msg.sig`\n function enforceAccessControl() internal view {\n AccessStorage storage accStor = accessStorage();\n if (accStor.execAccess[msg.sig][msg.sender] != true)\n revert UnAuthorized();\n }\n}\n" + }, + "src/Libraries/LibAllowList.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { InvalidContract } from \"../Errors/GenericErrors.sol\";\n\n/// @title Lib Allow List\n/// @author LI.FI (https://li.fi)\n/// @notice Library for managing and accessing the conract address allow list\nlibrary LibAllowList {\n /// Storage ///\n bytes32 internal constant NAMESPACE =\n keccak256(\"com.lifi.library.allow.list\");\n\n struct AllowListStorage {\n mapping(address => bool) allowlist;\n mapping(bytes4 => bool) selectorAllowList;\n address[] contracts;\n }\n\n /// @dev Adds a contract address to the allow list\n /// @param _contract the contract address to add\n function addAllowedContract(address _contract) internal {\n _checkAddress(_contract);\n\n AllowListStorage storage als = _getStorage();\n\n if (als.allowlist[_contract]) return;\n\n als.allowlist[_contract] = true;\n als.contracts.push(_contract);\n }\n\n /// @dev Checks whether a contract address has been added to the allow list\n /// @param _contract the contract address to check\n function contractIsAllowed(\n address _contract\n ) internal view returns (bool) {\n return _getStorage().allowlist[_contract];\n }\n\n /// @dev Remove a contract address from the allow list\n /// @param _contract the contract address to remove\n function removeAllowedContract(address _contract) internal {\n AllowListStorage storage als = _getStorage();\n\n if (!als.allowlist[_contract]) {\n return;\n }\n\n als.allowlist[_contract] = false;\n\n uint256 length = als.contracts.length;\n // Find the contract in the list\n for (uint256 i = 0; i < length; i++) {\n if (als.contracts[i] == _contract) {\n // Move the last element into the place to delete\n als.contracts[i] = als.contracts[length - 1];\n // Remove the last element\n als.contracts.pop();\n break;\n }\n }\n }\n\n /// @dev Fetch contract addresses from the allow list\n function getAllowedContracts() internal view returns (address[] memory) {\n return _getStorage().contracts;\n }\n\n /// @dev Add a selector to the allow list\n /// @param _selector the selector to add\n function addAllowedSelector(bytes4 _selector) internal {\n _getStorage().selectorAllowList[_selector] = true;\n }\n\n /// @dev Removes a selector from the allow list\n /// @param _selector the selector to remove\n function removeAllowedSelector(bytes4 _selector) internal {\n _getStorage().selectorAllowList[_selector] = false;\n }\n\n /// @dev Returns if selector has been added to the allow list\n /// @param _selector the selector to check\n function selectorIsAllowed(bytes4 _selector) internal view returns (bool) {\n return _getStorage().selectorAllowList[_selector];\n }\n\n /// @dev Fetch local storage struct\n function _getStorage()\n internal\n pure\n returns (AllowListStorage storage als)\n {\n bytes32 position = NAMESPACE;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n als.slot := position\n }\n }\n\n /// @dev Contains business logic for validating a contract address.\n /// @param _contract address of the dex to check\n function _checkAddress(address _contract) private view {\n if (_contract == address(0)) revert InvalidContract();\n\n if (_contract.code.length == 0) revert InvalidContract();\n }\n}\n" + }, + "src/Libraries/LibAsset.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.17;\nimport { InsufficientBalance, NullAddrIsNotAnERC20Token, NullAddrIsNotAValidSpender, NoTransferToNullAddress, InvalidAmount, NativeAssetTransferFailed } from \"../Errors/GenericErrors.sol\";\nimport \"../../lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"../../lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\";\nimport { LibSwap } from \"./LibSwap.sol\";\n\n/// @title LibAsset\n/// @notice This library contains helpers for dealing with onchain transfers\n/// of assets, including accounting for the native asset `assetId`\n/// conventions and any noncompliant ERC20 transfers\nlibrary LibAsset {\n uint256 private constant MAX_UINT = type(uint256).max;\n\n address internal constant NULL_ADDRESS = address(0);\n\n /// @dev All native assets use the empty address for their asset id\n /// by convention\n\n address internal constant NATIVE_ASSETID = NULL_ADDRESS; //address(0)\n\n /// @notice Gets the balance of the inheriting contract for the given asset\n /// @param assetId The asset identifier to get the balance of\n /// @return Balance held by contracts using this library\n function getOwnBalance(address assetId) internal view returns (uint256) {\n return\n isNativeAsset(assetId)\n ? address(this).balance\n : IERC20(assetId).balanceOf(address(this));\n }\n\n /// @notice Transfers ether from the inheriting contract to a given\n /// recipient\n /// @param recipient Address to send ether to\n /// @param amount Amount to send to given recipient\n function transferNativeAsset(\n address payable recipient,\n uint256 amount\n ) private {\n if (recipient == NULL_ADDRESS) revert NoTransferToNullAddress();\n if (amount > address(this).balance)\n revert InsufficientBalance(amount, address(this).balance);\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, ) = recipient.call{ value: amount }(\"\");\n if (!success) revert NativeAssetTransferFailed();\n }\n\n /// @notice If the current allowance is insufficient, the allowance for a given spender\n /// is set to MAX_UINT.\n /// @param assetId Token address to transfer\n /// @param spender Address to give spend approval to\n /// @param amount Amount to approve for spending\n function maxApproveERC20(\n IERC20 assetId,\n address spender,\n uint256 amount\n ) internal {\n if (isNativeAsset(address(assetId))) {\n return;\n }\n if (spender == NULL_ADDRESS) {\n revert NullAddrIsNotAValidSpender();\n }\n\n if (assetId.allowance(address(this), spender) < amount) {\n SafeERC20.safeApprove(IERC20(assetId), spender, 0);\n SafeERC20.safeApprove(IERC20(assetId), spender, MAX_UINT);\n }\n }\n\n /// @notice Transfers tokens from the inheriting contract to a given\n /// recipient\n /// @param assetId Token address to transfer\n /// @param recipient Address to send token to\n /// @param amount Amount to send to given recipient\n function transferERC20(\n address assetId,\n address recipient,\n uint256 amount\n ) private {\n if (isNativeAsset(assetId)) {\n revert NullAddrIsNotAnERC20Token();\n }\n if (recipient == NULL_ADDRESS) {\n revert NoTransferToNullAddress();\n }\n\n uint256 assetBalance = IERC20(assetId).balanceOf(address(this));\n if (amount > assetBalance) {\n revert InsufficientBalance(amount, assetBalance);\n }\n SafeERC20.safeTransfer(IERC20(assetId), recipient, amount);\n }\n\n /// @notice Transfers tokens from a sender to a given recipient\n /// @param assetId Token address to transfer\n /// @param from Address of sender/owner\n /// @param to Address of recipient/spender\n /// @param amount Amount to transfer from owner to spender\n function transferFromERC20(\n address assetId,\n address from,\n address to,\n uint256 amount\n ) internal {\n if (isNativeAsset(assetId)) {\n revert NullAddrIsNotAnERC20Token();\n }\n if (to == NULL_ADDRESS) {\n revert NoTransferToNullAddress();\n }\n\n IERC20 asset = IERC20(assetId);\n uint256 prevBalance = asset.balanceOf(to);\n SafeERC20.safeTransferFrom(asset, from, to, amount);\n if (asset.balanceOf(to) - prevBalance != amount) {\n revert InvalidAmount();\n }\n }\n\n function depositAsset(address assetId, uint256 amount) internal {\n if (amount == 0) revert InvalidAmount();\n if (isNativeAsset(assetId)) {\n if (msg.value < amount) revert InvalidAmount();\n } else {\n uint256 balance = IERC20(assetId).balanceOf(msg.sender);\n if (balance < amount) revert InsufficientBalance(amount, balance);\n transferFromERC20(assetId, msg.sender, address(this), amount);\n }\n }\n\n function depositAssets(LibSwap.SwapData[] calldata swaps) internal {\n for (uint256 i = 0; i < swaps.length; ) {\n LibSwap.SwapData calldata swap = swaps[i];\n if (swap.requiresDeposit) {\n depositAsset(swap.sendingAssetId, swap.fromAmount);\n }\n unchecked {\n i++;\n }\n }\n }\n\n /// @notice Determines whether the given assetId is the native asset\n /// @param assetId The asset identifier to evaluate\n /// @return Boolean indicating if the asset is the native asset\n function isNativeAsset(address assetId) internal pure returns (bool) {\n return assetId == NATIVE_ASSETID;\n }\n\n /// @notice Wrapper function to transfer a given asset (native or erc20) to\n /// some recipient. Should handle all non-compliant return value\n /// tokens as well by using the SafeERC20 contract by open zeppelin.\n /// @param assetId Asset id for transfer (address(0) for native asset,\n /// token address for erc20s)\n /// @param recipient Address to send asset to\n /// @param amount Amount to send to given recipient\n function transferAsset(\n address assetId,\n address payable recipient,\n uint256 amount\n ) internal {\n isNativeAsset(assetId)\n ? transferNativeAsset(recipient, amount)\n : transferERC20(assetId, recipient, amount);\n }\n\n /// @dev Checks whether the given address is a contract and contains code\n function isContract(address _contractAddr) internal view returns (bool) {\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n size := extcodesize(_contractAddr)\n }\n return size > 0;\n }\n}\n" + }, + "src/Libraries/LibBytes.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nlibrary LibBytes {\n // solhint-disable no-inline-assembly\n\n // LibBytes specific errors\n error SliceOverflow();\n error SliceOutOfBounds();\n error AddressOutOfBounds();\n\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n\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) revert SliceOverflow();\n if (_bytes.length < _start + _length) revert SliceOutOfBounds();\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 function toAddress(\n bytes memory _bytes,\n uint256 _start\n ) internal pure returns (address) {\n if (_bytes.length < _start + 20) {\n revert AddressOutOfBounds();\n }\n address tempAddress;\n\n assembly {\n tempAddress := div(\n mload(add(add(_bytes, 0x20), _start)),\n 0x1000000000000000000000000\n )\n }\n\n return tempAddress;\n }\n\n /// Copied from OpenZeppelin's `Strings.sol` utility library.\n /// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/8335676b0e99944eef6a742e16dcd9ff6e68e609/contracts/utils/Strings.sol\n function toHexString(\n uint256 value,\n uint256 length\n ) 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" + }, + "src/Libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { IDiamondCut } from \"../Interfaces/IDiamondCut.sol\";\nimport { LibUtil } from \"../Libraries/LibUtil.sol\";\nimport { OnlyContractOwner } from \"../Errors/GenericErrors.sol\";\n\n/// Implementation of EIP-2535 Diamond Standard\n/// https://eips.ethereum.org/EIPS/eip-2535\nlibrary LibDiamond {\n bytes32 internal constant DIAMOND_STORAGE_POSITION =\n keccak256(\"diamond.standard.diamond.storage\");\n\n // Diamond specific errors\n error IncorrectFacetCutAction();\n error NoSelectorsInFace();\n error FunctionAlreadyExists();\n error FacetAddressIsZero();\n error FacetAddressIsNotZero();\n error FacetContainsNoCode();\n error FunctionDoesNotExist();\n error FunctionIsImmutable();\n error InitZeroButCalldataNotEmpty();\n error CalldataEmptyButInitNotZero();\n error InitReverted();\n // ----------------\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // owner of the contract\n address contractOwner;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n ds.slot := position\n }\n }\n\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n function setContractOwner(address _newOwner) internal {\n DiamondStorage storage ds = diamondStorage();\n address previousOwner = ds.contractOwner;\n ds.contractOwner = _newOwner;\n emit OwnershipTransferred(previousOwner, _newOwner);\n }\n\n function contractOwner() internal view returns (address contractOwner_) {\n contractOwner_ = diamondStorage().contractOwner;\n }\n\n function enforceIsContractOwner() internal view {\n if (msg.sender != diamondStorage().contractOwner)\n revert OnlyContractOwner();\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert IncorrectFacetCutAction();\n }\n unchecked {\n ++facetIndex;\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n if (_functionSelectors.length == 0) {\n revert NoSelectorsInFace();\n }\n DiamondStorage storage ds = diamondStorage();\n if (LibUtil.isZeroAddress(_facetAddress)) {\n revert FacetAddressIsZero();\n }\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < _functionSelectors.length;\n\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n if (!LibUtil.isZeroAddress(oldFacetAddress)) {\n revert FunctionAlreadyExists();\n }\n addFunction(ds, selector, selectorPosition, _facetAddress);\n unchecked {\n ++selectorPosition;\n ++selectorIndex;\n }\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n if (_functionSelectors.length == 0) {\n revert NoSelectorsInFace();\n }\n DiamondStorage storage ds = diamondStorage();\n if (LibUtil.isZeroAddress(_facetAddress)) {\n revert FacetAddressIsZero();\n }\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < _functionSelectors.length;\n\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n if (oldFacetAddress == _facetAddress) {\n revert FunctionAlreadyExists();\n }\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n unchecked {\n ++selectorPosition;\n ++selectorIndex;\n }\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n if (_functionSelectors.length == 0) {\n revert NoSelectorsInFace();\n }\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n if (!LibUtil.isZeroAddress(_facetAddress)) {\n revert FacetAddressIsNotZero();\n }\n for (\n uint256 selectorIndex;\n selectorIndex < _functionSelectors.length;\n\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n unchecked {\n ++selectorIndex;\n }\n }\n }\n\n function addFacet(\n DiamondStorage storage ds,\n address _facetAddress\n ) internal {\n enforceHasContractCode(_facetAddress);\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n if (LibUtil.isZeroAddress(_facetAddress)) {\n revert FunctionDoesNotExist();\n }\n // an immutable function is a function defined directly in a diamond\n if (_facetAddress == address(this)) {\n revert FunctionIsImmutable();\n }\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (LibUtil.isZeroAddress(_init)) {\n if (_calldata.length != 0) {\n revert InitZeroButCalldataNotEmpty();\n }\n } else {\n if (_calldata.length == 0) {\n revert CalldataEmptyButInitNotZero();\n }\n if (_init != address(this)) {\n enforceHasContractCode(_init);\n }\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up the error\n revert(string(error));\n } else {\n revert InitReverted();\n }\n }\n }\n }\n\n function enforceHasContractCode(address _contract) internal view {\n uint256 contractSize;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n contractSize := extcodesize(_contract)\n }\n if (contractSize == 0) {\n revert FacetContainsNoCode();\n }\n }\n}\n" + }, + "src/Libraries/LibSwap.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { LibAsset } from \"./LibAsset.sol\";\nimport { LibUtil } from \"./LibUtil.sol\";\nimport { InvalidContract, NoSwapFromZeroBalance, InsufficientBalance } from \"../Errors/GenericErrors.sol\";\nimport { IERC20 } from \"../../lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\";\n\nlibrary LibSwap {\n struct SwapData {\n address callTo;\n address approveTo;\n address sendingAssetId;\n address receivingAssetId;\n uint256 fromAmount;\n bytes callData;\n bool requiresDeposit;\n }\n\n event AssetSwapped(\n bytes32 transactionId,\n address dex,\n address fromAssetId,\n address toAssetId,\n uint256 fromAmount,\n uint256 toAmount,\n uint256 timestamp\n );\n\n function swap(bytes32 transactionId, SwapData calldata _swap) internal {\n if (!LibAsset.isContract(_swap.callTo)) revert InvalidContract();\n uint256 fromAmount = _swap.fromAmount;\n if (fromAmount == 0) revert NoSwapFromZeroBalance();\n uint256 nativeValue = LibAsset.isNativeAsset(_swap.sendingAssetId)\n ? _swap.fromAmount\n : 0;\n uint256 initialSendingAssetBalance = LibAsset.getOwnBalance(\n _swap.sendingAssetId\n );\n uint256 initialReceivingAssetBalance = LibAsset.getOwnBalance(\n _swap.receivingAssetId\n );\n\n if (nativeValue == 0) {\n LibAsset.maxApproveERC20(\n IERC20(_swap.sendingAssetId),\n _swap.approveTo,\n _swap.fromAmount\n );\n }\n\n if (initialSendingAssetBalance < _swap.fromAmount) {\n revert InsufficientBalance(\n _swap.fromAmount,\n initialSendingAssetBalance\n );\n }\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory res) = _swap.callTo.call{\n value: nativeValue\n }(_swap.callData);\n if (!success) {\n string memory reason = LibUtil.getRevertMsg(res);\n revert(reason);\n }\n\n uint256 newBalance = LibAsset.getOwnBalance(_swap.receivingAssetId);\n\n emit AssetSwapped(\n transactionId,\n _swap.callTo,\n _swap.sendingAssetId,\n _swap.receivingAssetId,\n _swap.fromAmount,\n newBalance > initialReceivingAssetBalance\n ? newBalance - initialReceivingAssetBalance\n : newBalance,\n block.timestamp\n );\n }\n}\n" + }, + "src/Libraries/LibUtil.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport \"./LibBytes.sol\";\n\nlibrary LibUtil {\n using LibBytes for bytes;\n\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) return \"Transaction reverted silently\";\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 /// @notice Determines whether the given address is the zero address\n /// @param addr The address to verify\n /// @return Boolean indicating if the address is the zero address\n function isZeroAddress(address addr) internal pure returns (bool) {\n return addr == address(0);\n }\n}\n" + }, + "src/LiFiDiamond.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { LibDiamond } from \"./Libraries/LibDiamond.sol\";\nimport { IDiamondCut } from \"./Interfaces/IDiamondCut.sol\";\nimport { LibUtil } from \"./Libraries/LibUtil.sol\";\n\n/// @title LIFI Diamond\n/// @author LI.FI (https://li.fi)\n/// @notice Base EIP-2535 Diamond Proxy Contract.\n/// @custom:version 1.0.0\ncontract LiFiDiamond {\n constructor(address _contractOwner, address _diamondCutFacet) payable {\n LibDiamond.setContractOwner(_contractOwner);\n\n // Add the diamondCut external function from the diamondCutFacet\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n // Find facet for function that is called and execute the\n // function if a facet is found and return any value.\n // solhint-disable-next-line no-complex-fallback\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n\n // get diamond storage\n // solhint-disable-next-line no-inline-assembly\n assembly {\n ds.slot := position\n }\n\n // get facet from function selector\n address facet = ds.selectorToFacetAndPosition[msg.sig].facetAddress;\n\n if (facet == address(0)) {\n revert LibDiamond.FunctionDoesNotExist();\n }\n\n // Execute external function from facet using delegatecall and return any value.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\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 // Able to receive ether\n // solhint-disable-next-line no-empty-blocks\n receive() external payable {}\n}\n" + }, + "src/LiFiDiamondImmutable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { LibDiamond } from \"./Libraries/LibDiamond.sol\";\nimport { IDiamondCut } from \"./Interfaces/IDiamondCut.sol\";\nimport { LibUtil } from \"./Libraries/LibUtil.sol\";\n\n/// @title LIFI Diamond Immutable\n/// @author LI.FI (https://li.fi)\n/// @notice (Immutable) Base EIP-2535 Diamond Proxy Contract.\n/// @custom:version 1.0.0\ncontract LiFiDiamondImmutable {\n constructor(address _contractOwner, address _diamondCutFacet) payable {\n LibDiamond.setContractOwner(_contractOwner);\n\n // Add the diamondCut external function from the diamondCutFacet\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n // Find facet for function that is called and execute the\n // function if a facet is found and return any value.\n // solhint-disable-next-line no-complex-fallback\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n\n // get diamond storage\n // solhint-disable-next-line no-inline-assembly\n assembly {\n ds.slot := position\n }\n\n // get facet from function selector\n address facet = ds.selectorToFacetAndPosition[msg.sig].facetAddress;\n\n if (facet == address(0)) {\n revert LibDiamond.FunctionDoesNotExist();\n }\n\n // Execute external function from facet using delegatecall and return any value.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\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 // Able to receive ether\n // solhint-disable-next-line no-empty-blocks\n receive() external payable {}\n}\n" + }, + "src/Periphery/ERC20Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { Ownable } from \"../../lib/openzeppelin-contracts/contracts/access/Ownable.sol\";\nimport { LibAsset } from \"../Libraries/LibAsset.sol\";\n\n/// @title ERC20 Proxy\n/// @author LI.FI (https://li.fi)\n/// @notice Proxy contract for safely transferring ERC20 tokens for swaps/executions\n/// @custom:version 1.0.0\ncontract ERC20Proxy is Ownable {\n /// Storage ///\n mapping(address => bool) public authorizedCallers;\n\n /// Errors ///\n error UnAuthorized();\n\n /// Events ///\n event AuthorizationChanged(address indexed caller, bool authorized);\n\n /// Constructor\n constructor(address _owner) {\n transferOwnership(_owner);\n }\n\n /// @notice Sets whether or not a specified caller is authorized to call this contract\n /// @param caller the caller to change authorization for\n /// @param authorized specifies whether the caller is authorized (true/false)\n function setAuthorizedCaller(\n address caller,\n bool authorized\n ) external onlyOwner {\n authorizedCallers[caller] = authorized;\n emit AuthorizationChanged(caller, authorized);\n }\n\n /// @notice Transfers tokens from one address to another specified address\n /// @param tokenAddress the ERC20 contract address of the token to send\n /// @param from the address to transfer from\n /// @param to the address to transfer to\n /// @param amount the amount of tokens to send\n function transferFrom(\n address tokenAddress,\n address from,\n address to,\n uint256 amount\n ) external {\n if (!authorizedCallers[msg.sender]) revert UnAuthorized();\n\n LibAsset.transferFromERC20(tokenAddress, from, to, amount);\n }\n}\n" + }, + "src/Periphery/Executor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { ReentrancyGuard } from \"../Helpers/ReentrancyGuard.sol\";\nimport { LibSwap } from \"../Libraries/LibSwap.sol\";\nimport { LibAsset } from \"../Libraries/LibAsset.sol\";\nimport { UnAuthorized } from \"../../src/Errors/GenericErrors.sol\";\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { IERC20Proxy } from \"../Interfaces/IERC20Proxy.sol\";\nimport { ERC1155Holder } from \"../../lib/openzeppelin-contracts/contracts/token/ERC1155/utils/ERC1155Holder.sol\";\nimport { ERC721Holder } from \"../../lib/openzeppelin-contracts/contracts/token/ERC721/utils/ERC721Holder.sol\";\nimport { IERC20 } from \"../../lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\";\n\n/// @title Executor\n/// @author LI.FI (https://li.fi)\n/// @notice Arbitrary execution contract used for cross-chain swaps and message passing\n/// @custom:version 2.0.0\ncontract Executor is ILiFi, ReentrancyGuard, ERC1155Holder, ERC721Holder {\n /// Storage ///\n\n /// @notice The address of the ERC20Proxy contract\n IERC20Proxy public erc20Proxy;\n\n /// Events ///\n event ERC20ProxySet(address indexed proxy);\n\n /// Modifiers ///\n\n /// @dev Sends any leftover balances back to the user\n modifier noLeftovers(\n LibSwap.SwapData[] calldata _swaps,\n address payable _leftoverReceiver\n ) {\n uint256 numSwaps = _swaps.length;\n if (numSwaps != 1) {\n uint256[] memory initialBalances = _fetchBalances(_swaps);\n address finalAsset = _swaps[numSwaps - 1].receivingAssetId;\n uint256 curBalance = 0;\n\n _;\n\n for (uint256 i = 0; i < numSwaps - 1; ) {\n address curAsset = _swaps[i].receivingAssetId;\n // Handle multi-to-one swaps\n if (curAsset != finalAsset) {\n curBalance = LibAsset.getOwnBalance(curAsset);\n if (curBalance > initialBalances[i]) {\n LibAsset.transferAsset(\n curAsset,\n _leftoverReceiver,\n curBalance - initialBalances[i]\n );\n }\n }\n unchecked {\n ++i;\n }\n }\n } else {\n _;\n }\n }\n\n /// Constructor\n /// @notice Initialize local variables for the Executor\n /// @param _erc20Proxy The address of the ERC20Proxy contract\n constructor(address _erc20Proxy) {\n erc20Proxy = IERC20Proxy(_erc20Proxy);\n emit ERC20ProxySet(_erc20Proxy);\n }\n\n /// External Methods ///\n\n /// @notice Performs a swap before completing a cross-chain transaction\n /// @param _transactionId the transaction id for the swap\n /// @param _swapData array of data needed for swaps\n /// @param _transferredAssetId token received from the other chain\n /// @param _receiver address that will receive tokens in the end\n function swapAndCompleteBridgeTokens(\n bytes32 _transactionId,\n LibSwap.SwapData[] calldata _swapData,\n address _transferredAssetId,\n address payable _receiver\n ) external payable nonReentrant {\n _processSwaps(\n _transactionId,\n _swapData,\n _transferredAssetId,\n _receiver,\n 0,\n true\n );\n }\n\n /// @notice Performs a series of swaps or arbitrary executions\n /// @param _transactionId the transaction id for the swap\n /// @param _swapData array of data needed for swaps\n /// @param _transferredAssetId token received from the other chain\n /// @param _receiver address that will receive tokens in the end\n /// @param _amount amount of token for swaps or arbitrary executions\n function swapAndExecute(\n bytes32 _transactionId,\n LibSwap.SwapData[] calldata _swapData,\n address _transferredAssetId,\n address payable _receiver,\n uint256 _amount\n ) external payable nonReentrant {\n _processSwaps(\n _transactionId,\n _swapData,\n _transferredAssetId,\n _receiver,\n _amount,\n false\n );\n }\n\n /// Private Methods ///\n\n /// @notice Performs a series of swaps or arbitrary executions\n /// @param _transactionId the transaction id for the swap\n /// @param _swapData array of data needed for swaps\n /// @param _transferredAssetId token received from the other chain\n /// @param _receiver address that will receive tokens in the end\n /// @param _amount amount of token for swaps or arbitrary executions\n /// @param _depositAllowance If deposit approved amount of token\n function _processSwaps(\n bytes32 _transactionId,\n LibSwap.SwapData[] calldata _swapData,\n address _transferredAssetId,\n address payable _receiver,\n uint256 _amount,\n bool _depositAllowance\n ) private {\n uint256 startingBalance;\n uint256 finalAssetStartingBalance;\n address finalAssetId = _swapData[_swapData.length - 1]\n .receivingAssetId;\n if (!LibAsset.isNativeAsset(finalAssetId)) {\n finalAssetStartingBalance = LibAsset.getOwnBalance(finalAssetId);\n } else {\n finalAssetStartingBalance =\n LibAsset.getOwnBalance(finalAssetId) -\n msg.value;\n }\n\n if (!LibAsset.isNativeAsset(_transferredAssetId)) {\n startingBalance = LibAsset.getOwnBalance(_transferredAssetId);\n if (_depositAllowance) {\n uint256 allowance = IERC20(_transferredAssetId).allowance(\n msg.sender,\n address(this)\n );\n LibAsset.depositAsset(_transferredAssetId, allowance);\n } else {\n erc20Proxy.transferFrom(\n _transferredAssetId,\n msg.sender,\n address(this),\n _amount\n );\n }\n } else {\n startingBalance =\n LibAsset.getOwnBalance(_transferredAssetId) -\n msg.value;\n }\n\n _executeSwaps(_transactionId, _swapData, _receiver);\n\n uint256 postSwapBalance = LibAsset.getOwnBalance(_transferredAssetId);\n if (postSwapBalance > startingBalance) {\n LibAsset.transferAsset(\n _transferredAssetId,\n _receiver,\n postSwapBalance - startingBalance\n );\n }\n\n uint256 finalAssetPostSwapBalance = LibAsset.getOwnBalance(\n finalAssetId\n );\n\n if (finalAssetPostSwapBalance > finalAssetStartingBalance) {\n LibAsset.transferAsset(\n finalAssetId,\n _receiver,\n finalAssetPostSwapBalance - finalAssetStartingBalance\n );\n }\n\n emit LiFiTransferCompleted(\n _transactionId,\n _transferredAssetId,\n _receiver,\n finalAssetPostSwapBalance,\n block.timestamp\n );\n }\n\n /// @dev Executes swaps one after the other\n /// @param _transactionId the transaction id for the swap\n /// @param _swapData Array of data used to execute swaps\n /// @param _leftoverReceiver Address to receive lefover tokens\n function _executeSwaps(\n bytes32 _transactionId,\n LibSwap.SwapData[] calldata _swapData,\n address payable _leftoverReceiver\n ) private noLeftovers(_swapData, _leftoverReceiver) {\n uint256 numSwaps = _swapData.length;\n for (uint256 i = 0; i < numSwaps; ) {\n if (_swapData[i].callTo == address(erc20Proxy)) {\n revert UnAuthorized(); // Prevent calling ERC20 Proxy directly\n }\n\n LibSwap.SwapData calldata currentSwapData = _swapData[i];\n LibSwap.swap(_transactionId, currentSwapData);\n unchecked {\n ++i;\n }\n }\n }\n\n /// @dev Fetches balances of tokens to be swapped before swapping.\n /// @param _swapData Array of data used to execute swaps\n /// @return uint256[] Array of token balances.\n function _fetchBalances(\n LibSwap.SwapData[] calldata _swapData\n ) private view returns (uint256[] memory) {\n uint256 numSwaps = _swapData.length;\n uint256[] memory balances = new uint256[](numSwaps);\n address asset;\n for (uint256 i = 0; i < numSwaps; ) {\n asset = _swapData[i].receivingAssetId;\n balances[i] = LibAsset.getOwnBalance(asset);\n\n if (LibAsset.isNativeAsset(asset)) {\n balances[i] -= msg.value;\n }\n\n unchecked {\n ++i;\n }\n }\n\n return balances;\n }\n\n /// @dev required for receiving native assets from destination swaps\n // solhint-disable-next-line no-empty-blocks\n receive() external payable {}\n}\n" + }, + "src/Periphery/FeeCollector.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.17;\n\nimport { LibAsset } from \"../Libraries/LibAsset.sol\";\nimport { TransferrableOwnership } from \"../Helpers/TransferrableOwnership.sol\";\n\n/// @title Fee Collector\n/// @author LI.FI (https://li.fi)\n/// @notice Provides functionality for collecting integrator fees\n/// @custom:version 1.0.0\ncontract FeeCollector is TransferrableOwnership {\n /// State ///\n\n // Integrator -> TokenAddress -> Balance\n mapping(address => mapping(address => uint256)) private _balances;\n // TokenAddress -> Balance\n mapping(address => uint256) private _lifiBalances;\n\n /// Errors ///\n error TransferFailure();\n error NotEnoughNativeForFees();\n\n /// Events ///\n event FeesCollected(\n address indexed _token,\n address indexed _integrator,\n uint256 _integratorFee,\n uint256 _lifiFee\n );\n event FeesWithdrawn(\n address indexed _token,\n address indexed _to,\n uint256 _amount\n );\n event LiFiFeesWithdrawn(\n address indexed _token,\n address indexed _to,\n uint256 _amount\n );\n\n /// Constructor ///\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address _owner) TransferrableOwnership(_owner) {}\n\n /// External Methods ///\n\n /// @notice Collects fees for the integrator\n /// @param tokenAddress address of the token to collect fees for\n /// @param integratorFee amount of fees to collect going to the integrator\n /// @param lifiFee amount of fees to collect going to lifi\n /// @param integratorAddress address of the integrator\n function collectTokenFees(\n address tokenAddress,\n uint256 integratorFee,\n uint256 lifiFee,\n address integratorAddress\n ) external {\n LibAsset.depositAsset(tokenAddress, integratorFee + lifiFee);\n _balances[integratorAddress][tokenAddress] += integratorFee;\n _lifiBalances[tokenAddress] += lifiFee;\n emit FeesCollected(\n tokenAddress,\n integratorAddress,\n integratorFee,\n lifiFee\n );\n }\n\n /// @notice Collects fees for the integrator in native token\n /// @param integratorFee amount of fees to collect going to the integrator\n /// @param lifiFee amount of fees to collect going to lifi\n /// @param integratorAddress address of the integrator\n function collectNativeFees(\n uint256 integratorFee,\n uint256 lifiFee,\n address integratorAddress\n ) external payable {\n if (msg.value < integratorFee + lifiFee)\n revert NotEnoughNativeForFees();\n _balances[integratorAddress][LibAsset.NULL_ADDRESS] += integratorFee;\n _lifiBalances[LibAsset.NULL_ADDRESS] += lifiFee;\n uint256 remaining = msg.value - (integratorFee + lifiFee);\n // Prevent extra native token from being locked in the contract\n if (remaining > 0) {\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, ) = payable(msg.sender).call{ value: remaining }(\n \"\"\n );\n if (!success) {\n revert TransferFailure();\n }\n }\n emit FeesCollected(\n LibAsset.NULL_ADDRESS,\n integratorAddress,\n integratorFee,\n lifiFee\n );\n }\n\n /// @notice Withdraw fees and sends to the integrator\n /// @param tokenAddress address of the token to withdraw fees for\n function withdrawIntegratorFees(address tokenAddress) external {\n uint256 balance = _balances[msg.sender][tokenAddress];\n if (balance == 0) {\n return;\n }\n _balances[msg.sender][tokenAddress] = 0;\n LibAsset.transferAsset(tokenAddress, payable(msg.sender), balance);\n emit FeesWithdrawn(tokenAddress, msg.sender, balance);\n }\n\n /// @notice Batch withdraw fees and sends to the integrator\n /// @param tokenAddresses addresses of the tokens to withdraw fees for\n function batchWithdrawIntegratorFees(\n address[] memory tokenAddresses\n ) external {\n uint256 length = tokenAddresses.length;\n uint256 balance;\n for (uint256 i = 0; i < length; ) {\n balance = _balances[msg.sender][tokenAddresses[i]];\n if (balance != 0) {\n _balances[msg.sender][tokenAddresses[i]] = 0;\n LibAsset.transferAsset(\n tokenAddresses[i],\n payable(msg.sender),\n balance\n );\n emit FeesWithdrawn(tokenAddresses[i], msg.sender, balance);\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Withdraws fees and sends to lifi\n /// @param tokenAddress address of the token to withdraw fees for\n function withdrawLifiFees(address tokenAddress) external onlyOwner {\n uint256 balance = _lifiBalances[tokenAddress];\n if (balance == 0) {\n return;\n }\n _lifiBalances[tokenAddress] = 0;\n LibAsset.transferAsset(tokenAddress, payable(msg.sender), balance);\n emit LiFiFeesWithdrawn(tokenAddress, msg.sender, balance);\n }\n\n /// @notice Batch withdraws fees and sends to lifi\n /// @param tokenAddresses addresses of the tokens to withdraw fees for\n function batchWithdrawLifiFees(\n address[] memory tokenAddresses\n ) external onlyOwner {\n uint256 length = tokenAddresses.length;\n uint256 balance;\n for (uint256 i = 0; i < length; ) {\n balance = _lifiBalances[tokenAddresses[i]];\n _lifiBalances[tokenAddresses[i]] = 0;\n LibAsset.transferAsset(\n tokenAddresses[i],\n payable(msg.sender),\n balance\n );\n emit LiFiFeesWithdrawn(tokenAddresses[i], msg.sender, balance);\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Returns the balance of the integrator\n /// @param integratorAddress address of the integrator\n /// @param tokenAddress address of the token to get the balance of\n function getTokenBalance(\n address integratorAddress,\n address tokenAddress\n ) external view returns (uint256) {\n return _balances[integratorAddress][tokenAddress];\n }\n\n /// @notice Returns the balance of lifi\n /// @param tokenAddress address of the token to get the balance of\n function getLifiTokenBalance(\n address tokenAddress\n ) external view returns (uint256) {\n return _lifiBalances[tokenAddress];\n }\n}\n" + }, + "src/Periphery/Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { IERC20, SafeERC20 } from \"../../lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { ReentrancyGuard } from \"../Helpers/ReentrancyGuard.sol\";\nimport { LibSwap } from \"../Libraries/LibSwap.sol\";\nimport { LibAsset } from \"../Libraries/LibAsset.sol\";\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { IExecutor } from \"../Interfaces/IExecutor.sol\";\nimport { TransferrableOwnership } from \"../Helpers/TransferrableOwnership.sol\";\nimport { ExternalCallFailed, UnAuthorized } from \"../Errors/GenericErrors.sol\";\n\n/// @title Receiver\n/// @author LI.FI (https://li.fi)\n/// @notice Arbitrary execution contract used for cross-chain swaps and message passing\n/// @custom:version 2.0.0\ncontract Receiver is ILiFi, ReentrancyGuard, TransferrableOwnership {\n using SafeERC20 for IERC20;\n\n /// Storage ///\n address public sgRouter;\n IExecutor public executor;\n uint256 public recoverGas;\n address public amarokRouter;\n\n /// Events ///\n event StargateRouterSet(address indexed router);\n event AmarokRouterSet(address indexed router);\n event ExecutorSet(address indexed executor);\n event RecoverGasSet(uint256 indexed recoverGas);\n\n /// Modifiers ///\n modifier onlySGRouter() {\n if (msg.sender != sgRouter) {\n revert UnAuthorized();\n }\n _;\n }\n modifier onlyAmarokRouter() {\n if (msg.sender != amarokRouter) {\n revert UnAuthorized();\n }\n _;\n }\n\n /// Constructor\n constructor(\n address _owner,\n address _sgRouter,\n address _amarokRouter,\n address _executor,\n uint256 _recoverGas\n ) TransferrableOwnership(_owner) {\n owner = _owner;\n sgRouter = _sgRouter;\n amarokRouter = _amarokRouter;\n executor = IExecutor(_executor);\n recoverGas = _recoverGas;\n emit StargateRouterSet(_sgRouter);\n emit AmarokRouterSet(_amarokRouter);\n emit RecoverGasSet(_recoverGas);\n }\n\n /// External Methods ///\n\n /// @notice Completes a cross-chain transaction with calldata via Amarok facet on the receiving chain.\n /// @dev This function is called from Amarok Router.\n /// @param _transferId The unique ID of this transaction (assigned by Amarok)\n /// @param _amount the amount of bridged tokens\n /// @param _asset the address of the bridged token\n /// @param * (unused) the sender of the transaction\n /// @param * (unused) the domain ID of the src chain\n /// @param _callData The data to execute\n function xReceive(\n bytes32 _transferId,\n uint256 _amount,\n address _asset,\n address,\n uint32,\n bytes memory _callData\n ) external nonReentrant onlyAmarokRouter {\n (LibSwap.SwapData[] memory swapData, address receiver) = abi.decode(\n _callData,\n (LibSwap.SwapData[], address)\n );\n\n _swapAndCompleteBridgeTokens(\n _transferId,\n swapData,\n _asset,\n payable(receiver),\n _amount,\n false\n );\n }\n\n /// @notice Completes a cross-chain transaction on the receiving chain.\n /// @dev This function is called from Stargate Router.\n /// @param * (unused) The remote chainId sending the tokens\n /// @param * (unused) The remote Bridge address\n /// @param * (unused) Nonce\n /// @param * (unused) The token contract on the local chain\n /// @param _amountLD The amount of tokens received through bridging\n /// @param _payload The data to execute\n function sgReceive(\n uint16, // _srcChainId unused\n bytes memory, // _srcAddress unused\n uint256, // _nonce unused\n address _token,\n uint256 _amountLD,\n bytes memory _payload\n ) external nonReentrant onlySGRouter {\n (\n bytes32 transactionId,\n LibSwap.SwapData[] memory swapData,\n ,\n address receiver\n ) = abi.decode(\n _payload,\n (bytes32, LibSwap.SwapData[], address, address)\n );\n\n _swapAndCompleteBridgeTokens(\n transactionId,\n swapData,\n _token,\n payable(receiver),\n _amountLD,\n true\n );\n }\n\n /// @notice Performs a swap before completing a cross-chain transaction\n /// @param _transactionId the transaction id associated with the operation\n /// @param _swapData array of data needed for swaps\n /// @param assetId token received from the other chain\n /// @param receiver address that will receive tokens in the end\n function swapAndCompleteBridgeTokens(\n bytes32 _transactionId,\n LibSwap.SwapData[] memory _swapData,\n address assetId,\n address payable receiver\n ) external payable nonReentrant {\n if (LibAsset.isNativeAsset(assetId)) {\n _swapAndCompleteBridgeTokens(\n _transactionId,\n _swapData,\n assetId,\n receiver,\n msg.value,\n false\n );\n } else {\n uint256 allowance = IERC20(assetId).allowance(\n msg.sender,\n address(this)\n );\n LibAsset.depositAsset(assetId, allowance);\n _swapAndCompleteBridgeTokens(\n _transactionId,\n _swapData,\n assetId,\n receiver,\n allowance,\n false\n );\n }\n }\n\n /// @notice Send remaining token to receiver\n /// @param assetId token received from the other chain\n /// @param receiver address that will receive tokens in the end\n /// @param amount amount of token\n function pullToken(\n address assetId,\n address payable receiver,\n uint256 amount\n ) external onlyOwner {\n if (LibAsset.isNativeAsset(assetId)) {\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, ) = receiver.call{ value: amount }(\"\");\n if (!success) revert ExternalCallFailed();\n } else {\n IERC20(assetId).safeTransfer(receiver, amount);\n }\n }\n\n /// Private Methods ///\n\n /// @notice Performs a swap before completing a cross-chain transaction\n /// @param _transactionId the transaction id associated with the operation\n /// @param _swapData array of data needed for swaps\n /// @param assetId token received from the other chain\n /// @param receiver address that will receive tokens in the end\n /// @param amount amount of token\n /// @param reserveRecoverGas whether we need a gas buffer to recover\n function _swapAndCompleteBridgeTokens(\n bytes32 _transactionId,\n LibSwap.SwapData[] memory _swapData,\n address assetId,\n address payable receiver,\n uint256 amount,\n bool reserveRecoverGas\n ) private {\n uint256 _recoverGas = reserveRecoverGas ? recoverGas : 0;\n\n if (LibAsset.isNativeAsset(assetId)) {\n // case 1: native asset\n uint256 cacheGasLeft = gasleft();\n if (reserveRecoverGas && cacheGasLeft < _recoverGas) {\n // case 1a: not enough gas left to execute calls\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, ) = receiver.call{ value: amount }(\"\");\n if (!success) revert ExternalCallFailed();\n\n emit LiFiTransferRecovered(\n _transactionId,\n assetId,\n receiver,\n amount,\n block.timestamp\n );\n return;\n }\n\n // case 1b: enough gas left to execute calls\n // solhint-disable no-empty-blocks\n try\n executor.swapAndCompleteBridgeTokens{\n value: amount,\n gas: cacheGasLeft - _recoverGas\n }(_transactionId, _swapData, assetId, receiver)\n {} catch {\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, ) = receiver.call{ value: amount }(\"\");\n if (!success) revert ExternalCallFailed();\n\n emit LiFiTransferRecovered(\n _transactionId,\n assetId,\n receiver,\n amount,\n block.timestamp\n );\n }\n } else {\n // case 2: ERC20 asset\n uint256 cacheGasLeft = gasleft();\n IERC20 token = IERC20(assetId);\n token.safeApprove(address(executor), 0);\n\n if (reserveRecoverGas && cacheGasLeft < _recoverGas) {\n // case 2a: not enough gas left to execute calls\n token.safeTransfer(receiver, amount);\n\n emit LiFiTransferRecovered(\n _transactionId,\n assetId,\n receiver,\n amount,\n block.timestamp\n );\n return;\n }\n\n // case 2b: enough gas left to execute calls\n token.safeIncreaseAllowance(address(executor), amount);\n try\n executor.swapAndCompleteBridgeTokens{\n gas: cacheGasLeft - _recoverGas\n }(_transactionId, _swapData, assetId, receiver)\n {} catch {\n token.safeTransfer(receiver, amount);\n emit LiFiTransferRecovered(\n _transactionId,\n assetId,\n receiver,\n amount,\n block.timestamp\n );\n }\n\n token.safeApprove(address(executor), 0);\n }\n }\n\n /// @notice Receive native asset directly.\n /// @dev Some bridges may send native asset before execute external calls.\n // solhint-disable-next-line no-empty-blocks\n receive() external payable {}\n}\n" + }, + "src/Periphery/RelayerCelerIM.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport { IERC20, SafeERC20 } from \"../../lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { LibSwap } from \"../Libraries/LibSwap.sol\";\nimport { ContractCallNotAllowed, ExternalCallFailed, InvalidConfig, UnAuthorized, WithdrawFailed } from \"../Errors/GenericErrors.sol\";\nimport { LibAsset } from \"../Libraries/LibAsset.sol\";\nimport { LibUtil } from \"../Libraries/LibUtil.sol\";\nimport { ILiFi } from \"../Interfaces/ILiFi.sol\";\nimport { PeripheryRegistryFacet } from \"../Facets/PeripheryRegistryFacet.sol\";\nimport { IExecutor } from \"../Interfaces/IExecutor.sol\";\nimport { TransferrableOwnership } from \"../Helpers/TransferrableOwnership.sol\";\nimport { IMessageReceiverApp } from \"../../lib/sgn-v2-contracts/contracts/message/interfaces/IMessageReceiverApp.sol\";\nimport { CelerIM } from \"../../src/Helpers/CelerIMFacetBase.sol\";\nimport { MessageSenderLib, MsgDataTypes, IMessageBus, IOriginalTokenVault, IPeggedTokenBridge, IOriginalTokenVaultV2, IPeggedTokenBridgeV2 } from \"../../lib/sgn-v2-contracts/contracts/message/libraries/MessageSenderLib.sol\";\nimport { IBridge as ICBridge } from \"../../lib/sgn-v2-contracts/contracts/interfaces/IBridge.sol\";\n\n/// @title RelayerCelerIM\n/// @author LI.FI (https://li.fi)\n/// @notice Relayer contract for CelerIM that forwards calls and handles refunds on src side and acts receiver on dest\n/// @custom:version 2.0.0\ncontract RelayerCelerIM is ILiFi, TransferrableOwnership {\n using SafeERC20 for IERC20;\n\n /// Storage ///\n\n IMessageBus public cBridgeMessageBus;\n address public diamondAddress;\n\n /// Events ///\n\n event LogWithdraw(\n address indexed _assetAddress,\n address indexed _to,\n uint256 amount\n );\n\n /// Modifiers ///\n\n modifier onlyCBridgeMessageBus() {\n if (msg.sender != address(cBridgeMessageBus)) revert UnAuthorized();\n _;\n }\n modifier onlyDiamond() {\n if (msg.sender != diamondAddress) revert UnAuthorized();\n _;\n }\n\n /// Constructor\n\n constructor(\n address _cBridgeMessageBusAddress,\n address _owner,\n address _diamondAddress\n ) TransferrableOwnership(_owner) {\n owner = _owner;\n cBridgeMessageBus = IMessageBus(_cBridgeMessageBusAddress);\n diamondAddress = _diamondAddress;\n }\n\n /// External Methods ///\n\n /**\n * @notice Called by MessageBus to execute a message with an associated token transfer.\n * The Receiver is guaranteed to have received the right amount of tokens before this function is called.\n * @param * (unused) The address of the source app contract\n * @param _token The address of the token that comes out of the bridge\n * @param _amount The amount of tokens received at this contract through the cross-chain bridge.\n * @param * (unused) The source chain ID where the transfer is originated from\n * @param _message Arbitrary message bytes originated from and encoded by the source app contract\n * @param * (unused) Address who called the MessageBus execution function\n */\n function executeMessageWithTransfer(\n address,\n address _token,\n uint256 _amount,\n uint64,\n bytes calldata _message,\n address\n )\n external\n payable\n onlyCBridgeMessageBus\n returns (IMessageReceiverApp.ExecutionStatus)\n {\n // decode message\n (\n bytes32 transactionId,\n LibSwap.SwapData[] memory swapData,\n address receiver,\n address refundAddress\n ) = abi.decode(\n _message,\n (bytes32, LibSwap.SwapData[], address, address)\n );\n\n _swapAndCompleteBridgeTokens(\n transactionId,\n swapData,\n _token,\n payable(receiver),\n _amount,\n refundAddress\n );\n\n return IMessageReceiverApp.ExecutionStatus.Success;\n }\n\n /**\n * @notice Called by MessageBus to process refund of the original transfer from this contract.\n * The contract is guaranteed to have received the refund before this function is called.\n * @param _token The token address of the original transfer\n * @param _amount The amount of the original transfer\n * @param _message The same message associated with the original transfer\n * @param * (unused) Address who called the MessageBus execution function\n */\n function executeMessageWithTransferRefund(\n address _token,\n uint256 _amount,\n bytes calldata _message,\n address\n )\n external\n payable\n onlyCBridgeMessageBus\n returns (IMessageReceiverApp.ExecutionStatus)\n {\n (bytes32 transactionId, , , address refundAddress) = abi.decode(\n _message,\n (bytes32, LibSwap.SwapData[], address, address)\n );\n\n // return funds to cBridgeData.refundAddress\n LibAsset.transferAsset(_token, payable(refundAddress), _amount);\n\n emit LiFiTransferRecovered(\n transactionId,\n _token,\n refundAddress,\n _amount,\n block.timestamp\n );\n\n return IMessageReceiverApp.ExecutionStatus.Success;\n }\n\n /**\n * @notice Forwards a call to transfer tokens to cBridge (sent via this contract to ensure that potential refunds are sent here)\n * @param _bridgeData the core information needed for bridging\n * @param _celerIMData data specific to CelerIM\n */\n // solhint-disable-next-line code-complexity\n function sendTokenTransfer(\n ILiFi.BridgeData memory _bridgeData,\n CelerIM.CelerIMData calldata _celerIMData\n )\n external\n payable\n onlyDiamond\n returns (bytes32 transferId, address bridgeAddress)\n {\n // approve to and call correct bridge depending on BridgeSendType\n // @dev copied and slightly adapted from Celer MessageSenderLib\n if (_celerIMData.bridgeType == MsgDataTypes.BridgeSendType.Liquidity) {\n bridgeAddress = cBridgeMessageBus.liquidityBridge();\n if (LibAsset.isNativeAsset(_bridgeData.sendingAssetId)) {\n // case: native asset bridging\n ICBridge(bridgeAddress).sendNative{\n value: _bridgeData.minAmount\n }(\n _bridgeData.receiver,\n _bridgeData.minAmount,\n uint64(_bridgeData.destinationChainId),\n _celerIMData.nonce,\n _celerIMData.maxSlippage\n );\n } else {\n // case: ERC20 asset bridging\n LibAsset.maxApproveERC20(\n IERC20(_bridgeData.sendingAssetId),\n bridgeAddress,\n _bridgeData.minAmount\n );\n // solhint-disable-next-line check-send-result\n ICBridge(bridgeAddress).send(\n _bridgeData.receiver,\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount,\n uint64(_bridgeData.destinationChainId),\n _celerIMData.nonce,\n _celerIMData.maxSlippage\n );\n }\n transferId = MessageSenderLib.computeLiqBridgeTransferId(\n _bridgeData.receiver,\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount,\n uint64(_bridgeData.destinationChainId),\n _celerIMData.nonce\n );\n } else if (\n _celerIMData.bridgeType == MsgDataTypes.BridgeSendType.PegDeposit\n ) {\n bridgeAddress = cBridgeMessageBus.pegVault();\n LibAsset.maxApproveERC20(\n IERC20(_bridgeData.sendingAssetId),\n bridgeAddress,\n _bridgeData.minAmount\n );\n IOriginalTokenVault(bridgeAddress).deposit(\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount,\n uint64(_bridgeData.destinationChainId),\n _bridgeData.receiver,\n _celerIMData.nonce\n );\n transferId = MessageSenderLib.computePegV1DepositId(\n _bridgeData.receiver,\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount,\n uint64(_bridgeData.destinationChainId),\n _celerIMData.nonce\n );\n } else if (\n _celerIMData.bridgeType == MsgDataTypes.BridgeSendType.PegBurn\n ) {\n bridgeAddress = cBridgeMessageBus.pegBridge();\n LibAsset.maxApproveERC20(\n IERC20(_bridgeData.sendingAssetId),\n bridgeAddress,\n _bridgeData.minAmount\n );\n IPeggedTokenBridge(bridgeAddress).burn(\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount,\n _bridgeData.receiver,\n _celerIMData.nonce\n );\n transferId = MessageSenderLib.computePegV1BurnId(\n _bridgeData.receiver,\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount,\n _celerIMData.nonce\n );\n } else if (\n _celerIMData.bridgeType == MsgDataTypes.BridgeSendType.PegV2Deposit\n ) {\n bridgeAddress = cBridgeMessageBus.pegVaultV2();\n if (LibAsset.isNativeAsset(_bridgeData.sendingAssetId)) {\n // case: native asset bridging\n transferId = IOriginalTokenVaultV2(bridgeAddress)\n .depositNative{ value: _bridgeData.minAmount }(\n _bridgeData.minAmount,\n uint64(_bridgeData.destinationChainId),\n _bridgeData.receiver,\n _celerIMData.nonce\n );\n } else {\n // case: ERC20 bridging\n LibAsset.maxApproveERC20(\n IERC20(_bridgeData.sendingAssetId),\n bridgeAddress,\n _bridgeData.minAmount\n );\n transferId = IOriginalTokenVaultV2(bridgeAddress).deposit(\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount,\n uint64(_bridgeData.destinationChainId),\n _bridgeData.receiver,\n _celerIMData.nonce\n );\n }\n } else if (\n _celerIMData.bridgeType == MsgDataTypes.BridgeSendType.PegV2Burn\n ) {\n bridgeAddress = cBridgeMessageBus.pegBridgeV2();\n LibAsset.maxApproveERC20(\n IERC20(_bridgeData.sendingAssetId),\n bridgeAddress,\n _bridgeData.minAmount\n );\n transferId = IPeggedTokenBridgeV2(bridgeAddress).burn(\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount,\n uint64(_bridgeData.destinationChainId),\n _bridgeData.receiver,\n _celerIMData.nonce\n );\n } else if (\n _celerIMData.bridgeType ==\n MsgDataTypes.BridgeSendType.PegV2BurnFrom\n ) {\n bridgeAddress = cBridgeMessageBus.pegBridgeV2();\n LibAsset.maxApproveERC20(\n IERC20(_bridgeData.sendingAssetId),\n bridgeAddress,\n _bridgeData.minAmount\n );\n transferId = IPeggedTokenBridgeV2(bridgeAddress).burnFrom(\n _bridgeData.sendingAssetId,\n _bridgeData.minAmount,\n uint64(_bridgeData.destinationChainId),\n _bridgeData.receiver,\n _celerIMData.nonce\n );\n } else {\n revert InvalidConfig();\n }\n }\n\n /**\n * @notice Forwards a call to the CBridge Messagebus\n * @param _receiver The address of the destination app contract.\n * @param _dstChainId The destination chain ID.\n * @param _srcBridge The bridge contract to send the transfer with.\n * @param _srcTransferId The transfer ID.\n * @param _dstChainId The destination chain ID.\n * @param _message Arbitrary message bytes to be decoded by the destination app contract.\n */\n function forwardSendMessageWithTransfer(\n address _receiver,\n uint256 _dstChainId,\n address _srcBridge,\n bytes32 _srcTransferId,\n bytes calldata _message\n ) external payable onlyDiamond {\n cBridgeMessageBus.sendMessageWithTransfer{ value: msg.value }(\n _receiver,\n _dstChainId,\n _srcBridge,\n _srcTransferId,\n _message\n );\n }\n\n // ------------------------------------------------------------------------------------------------\n\n /// Private Methods ///\n\n /// @notice Performs a swap before completing a cross-chain transaction\n /// @param _transactionId the transaction id associated with the operation\n /// @param _swapData array of data needed for swaps\n /// @param assetId token received from the other chain\n /// @param receiver address that will receive tokens in the end\n /// @param amount amount of token\n function _swapAndCompleteBridgeTokens(\n bytes32 _transactionId,\n LibSwap.SwapData[] memory _swapData,\n address assetId,\n address payable receiver,\n uint256 amount,\n address refundAddress\n ) private {\n bool success;\n IExecutor executor = IExecutor(\n PeripheryRegistryFacet(diamondAddress).getPeripheryContract(\n \"Executor\"\n )\n );\n if (LibAsset.isNativeAsset(assetId)) {\n try\n executor.swapAndCompleteBridgeTokens{ value: amount }(\n _transactionId,\n _swapData,\n assetId,\n receiver\n )\n {\n success = true;\n } catch {\n // solhint-disable-next-line avoid-low-level-calls\n (bool fundsSent, ) = refundAddress.call{ value: amount }(\"\");\n if (!fundsSent) {\n revert ExternalCallFailed();\n }\n }\n } else {\n IERC20 token = IERC20(assetId);\n token.safeApprove(address(executor), 0);\n token.safeIncreaseAllowance(address(executor), amount);\n\n try\n executor.swapAndCompleteBridgeTokens(\n _transactionId,\n _swapData,\n assetId,\n receiver\n )\n {\n success = true;\n } catch {\n token.safeTransfer(refundAddress, amount);\n }\n token.safeApprove(address(executor), 0);\n }\n\n if (!success) {\n emit LiFiTransferRecovered(\n _transactionId,\n assetId,\n refundAddress,\n amount,\n block.timestamp\n );\n }\n }\n\n /// @notice Sends remaining token to given receiver address (for refund cases)\n /// @param assetId Address of the token to be withdrawn\n /// @param receiver Address that will receive tokens\n /// @param amount Amount of tokens to be withdrawn\n function withdraw(\n address assetId,\n address payable receiver,\n uint256 amount\n ) external onlyOwner {\n if (LibAsset.isNativeAsset(assetId)) {\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, ) = receiver.call{ value: amount }(\"\");\n if (!success) {\n revert WithdrawFailed();\n }\n } else {\n IERC20(assetId).safeTransfer(receiver, amount);\n }\n emit LogWithdraw(assetId, receiver, amount);\n }\n\n /// @notice Triggers a cBridge refund with calldata produced by cBridge API\n /// @param _callTo The address to execute the calldata on\n /// @param _callData The data to execute\n /// @param _assetAddress Asset to be withdrawn\n /// @param _to Address to withdraw to\n /// @param _amount Amount of asset to withdraw\n function triggerRefund(\n address payable _callTo,\n bytes calldata _callData,\n address _assetAddress,\n address _to,\n uint256 _amount\n ) external onlyOwner {\n bool success;\n\n // make sure that callTo address is either of the cBridge addresses\n if (\n cBridgeMessageBus.liquidityBridge() != _callTo &&\n cBridgeMessageBus.pegBridge() != _callTo &&\n cBridgeMessageBus.pegBridgeV2() != _callTo &&\n cBridgeMessageBus.pegVault() != _callTo &&\n cBridgeMessageBus.pegVaultV2() != _callTo\n ) {\n revert ContractCallNotAllowed();\n }\n\n // call contract\n // solhint-disable-next-line avoid-low-level-calls\n (success, ) = _callTo.call(_callData);\n\n // forward funds to _to address and emit event, if cBridge refund successful\n if (success) {\n address sendTo = (LibUtil.isZeroAddress(_to)) ? msg.sender : _to;\n LibAsset.transferAsset(_assetAddress, payable(sendTo), _amount);\n emit LogWithdraw(_assetAddress, sendTo, _amount);\n } else {\n revert WithdrawFailed();\n }\n }\n\n // required in order to receive native tokens from cBridge facet\n // solhint-disable-next-line no-empty-blocks\n receive() external payable {}\n}\n" + }, + "src/Periphery/ServiceFeeCollector.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.17;\n\nimport { LibAsset } from \"../Libraries/LibAsset.sol\";\nimport { TransferrableOwnership } from \"../Helpers/TransferrableOwnership.sol\";\n\n/// @title Service Fee Collector\n/// @author LI.FI (https://li.fi)\n/// @notice Provides functionality for collecting service fees (gas/insurance)\n/// @custom:version 1.0.0\ncontract ServiceFeeCollector is TransferrableOwnership {\n /// Errors ///\n error TransferFailure();\n error NotEnoughNativeForFees();\n\n /// Events ///\n event GasFeesCollected(\n address indexed token,\n uint256 indexed chainId,\n address indexed receiver,\n uint256 feeAmount\n );\n\n event InsuranceFeesCollected(\n address indexed token,\n address indexed receiver,\n uint256 feeAmount\n );\n\n event FeesWithdrawn(\n address indexed token,\n address indexed to,\n uint256 amount\n );\n\n /// Constructor ///\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address _owner) TransferrableOwnership(_owner) {}\n\n /// External Methods ///\n\n /// @notice Collects gas fees\n /// @param tokenAddress The address of the token to collect\n /// @param feeAmount The amount of fees to collect\n /// @param chainId The chain id of the destination chain\n /// @param receiver The address to send gas to on the destination chain\n function collectTokenGasFees(\n address tokenAddress,\n uint256 feeAmount,\n uint256 chainId,\n address receiver\n ) external {\n LibAsset.depositAsset(tokenAddress, feeAmount);\n emit GasFeesCollected(tokenAddress, chainId, receiver, feeAmount);\n }\n\n /// @notice Collects gas fees in native token\n /// @param chainId The chain id of the destination chain\n /// @param receiver The address to send gas to on destination chain\n function collectNativeGasFees(\n uint256 chainId,\n address receiver\n ) external payable {\n emit GasFeesCollected(\n LibAsset.NULL_ADDRESS,\n chainId,\n receiver,\n msg.value\n );\n }\n\n /// @notice Collects insurance fees\n /// @param tokenAddress The address of the token to collect\n /// @param feeAmount The amount of fees to collect\n /// @param receiver The address to insure\n function collectTokenInsuranceFees(\n address tokenAddress,\n uint256 feeAmount,\n address receiver\n ) external {\n LibAsset.depositAsset(tokenAddress, feeAmount);\n emit InsuranceFeesCollected(tokenAddress, receiver, feeAmount);\n }\n\n /// @notice Collects insurance fees in native token\n /// @param receiver The address to insure\n function collectNativeInsuranceFees(address receiver) external payable {\n emit InsuranceFeesCollected(\n LibAsset.NULL_ADDRESS,\n receiver,\n msg.value\n );\n }\n\n /// @notice Withdraws fees\n /// @param tokenAddress The address of the token to withdraw fees for\n function withdrawFees(address tokenAddress) external onlyOwner {\n uint256 balance = LibAsset.getOwnBalance(tokenAddress);\n LibAsset.transferAsset(tokenAddress, payable(msg.sender), balance);\n emit FeesWithdrawn(tokenAddress, msg.sender, balance);\n }\n\n /// @notice Batch withdraws fees\n /// @param tokenAddresses The addresses of the tokens to withdraw fees for\n function batchWithdrawFees(\n address[] calldata tokenAddresses\n ) external onlyOwner {\n uint256 length = tokenAddresses.length;\n uint256 balance;\n for (uint256 i = 0; i < length; ) {\n balance = LibAsset.getOwnBalance(tokenAddresses[i]);\n LibAsset.transferAsset(\n tokenAddresses[i],\n payable(msg.sender),\n balance\n );\n emit FeesWithdrawn(tokenAddresses[i], msg.sender, balance);\n unchecked {\n ++i;\n }\n }\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "mode": "3" + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.methodIdentifiers", + "storageLayout" + ], + "": [ + "ast" + ] + } + }, + "libraries": { + "": { + "__CACHE_BREAKER__": "0x0000000000000031363933333934373837313133" + } + } + } +} \ No newline at end of file From 424ce97dcd52c87cd8e0ecc03c169e5892ddf40c Mon Sep 17 00:00:00 2001 From: Max Klenk Date: Thu, 31 Aug 2023 17:40:58 +0200 Subject: [PATCH 3/5] feat(serviceFeeCollector): whiteliste new ServiceFeeCollector (#515) --- config/dexs.json | 24 ++++++++++++++++++++++++ config/sigs.json | 2 ++ 2 files changed, 26 insertions(+) diff --git a/config/dexs.json b/config/dexs.json index fc89e4afb..92ba32ea8 100644 --- a/config/dexs.json +++ b/config/dexs.json @@ -1,5 +1,6 @@ { "mainnet": [ + "0xC85c2B19958D116d79C654ecE73b359c08802A76", "0xf068cc770f32042Ff4a8fD196045641234dFaa47", "0x894b3e1e30Be0727eb138d2cceb0A99d2Fc4C55D", "0x4b0B89b90fF83247aEa12469CeA9A6222e09d54c", @@ -23,6 +24,7 @@ "0xB4B0ea46Fe0E9e8EAB4aFb765b527739F2718671" ], "arbitrum": [ + "0xC85c2B19958D116d79C654ecE73b359c08802A76", "0x9cc3164f01ED3796Fdf7Da538484D634608D2203", "0xf068cc770f32042Ff4a8fD196045641234dFaa47", "0x894b3e1e30Be0727eb138d2cceb0A99d2Fc4C55D", @@ -47,6 +49,7 @@ "0xe05dd51e4eb5636f4f0e8e7fbe82ea31a2ecef16" ], "aurora": [ + "0xC85c2B19958D116d79C654ecE73b359c08802A76", "0xf068cc770f32042Ff4a8fD196045641234dFaa47", "0x894b3e1e30Be0727eb138d2cceb0A99d2Fc4C55D", "0x4b0B89b90fF83247aEa12469CeA9A6222e09d54c", @@ -62,6 +65,7 @@ "0x7449Cd63C2b1A06C36945eD83f0626D303781B6E" ], "avalanche": [ + "0xC85c2B19958D116d79C654ecE73b359c08802A76", "0x9cc3164f01ED3796Fdf7Da538484D634608D2203", "0xf068cc770f32042Ff4a8fD196045641234dFaa47", "0x894b3e1e30Be0727eb138d2cceb0A99d2Fc4C55D", @@ -86,6 +90,7 @@ "0x1F076a800005c758a505E759720eb6737136e893" ], "boba": [ + "0xC85c2B19958D116d79C654ecE73b359c08802A76", "0xf068cc770f32042Ff4a8fD196045641234dFaa47", "0x894b3e1e30Be0727eb138d2cceb0A99d2Fc4C55D", "0x4b0B89b90fF83247aEa12469CeA9A6222e09d54c", @@ -100,6 +105,7 @@ "0x64842A3EbC09bB69429c1a34ae181375fea5f17F" ], "bsc": [ + "0xC85c2B19958D116d79C654ecE73b359c08802A76", "0xf068cc770f32042Ff4a8fD196045641234dFaa47", "0x894b3e1e30Be0727eb138d2cceb0A99d2Fc4C55D", "0x4b0B89b90fF83247aEa12469CeA9A6222e09d54c", @@ -125,6 +131,7 @@ "0x0656fD85364d03b103CEEda192FB2D3906A6ac15" ], "celo": [ + "0xC85c2B19958D116d79C654ecE73b359c08802A76", "0xf068cc770f32042Ff4a8fD196045641234dFaa47", "0x894b3e1e30Be0727eb138d2cceb0A99d2Fc4C55D", "0x4b0B89b90fF83247aEa12469CeA9A6222e09d54c", @@ -137,6 +144,7 @@ "0xE3D8bd6Aed4F159bc8000a9cD47CffDb95F96121" ], "cronos": [ + "0xC85c2B19958D116d79C654ecE73b359c08802A76", "0xf068cc770f32042Ff4a8fD196045641234dFaa47", "0x894b3e1e30Be0727eb138d2cceb0A99d2Fc4C55D", "0x4b0B89b90fF83247aEa12469CeA9A6222e09d54c", @@ -150,6 +158,7 @@ "0x145863Eb42Cf62847A6Ca784e6416C1682b1b2Ae" ], "evmos": [ + "0xC85c2B19958D116d79C654ecE73b359c08802A76", "0x9cc3164f01ED3796Fdf7Da538484D634608D2203", "0xf068cc770f32042Ff4a8fD196045641234dFaa47", "0x894b3e1e30Be0727eb138d2cceb0A99d2Fc4C55D", @@ -163,6 +172,7 @@ "0x64C3b10636baBb3Ef46a7E2E5248b0dE43198fCB" ], "fantom": [ + "0xC85c2B19958D116d79C654ecE73b359c08802A76", "0xf068cc770f32042Ff4a8fD196045641234dFaa47", "0x894b3e1e30Be0727eb138d2cceb0A99d2Fc4C55D", "0x4b0B89b90fF83247aEa12469CeA9A6222e09d54c", @@ -182,6 +192,7 @@ "0x6D0176C5ea1e44b08D3dd001b0784cE42F47a3A7" ], "fuse": [ + "0xC85c2B19958D116d79C654ecE73b359c08802A76", "0xf068cc770f32042Ff4a8fD196045641234dFaa47", "0x894b3e1e30Be0727eb138d2cceb0A99d2Fc4C55D", "0x4b0B89b90fF83247aEa12469CeA9A6222e09d54c", @@ -192,6 +203,7 @@ "0xE3F85aAd0c8DD7337427B9dF5d0fB741d65EEEB5" ], "gnosis": [ + "0xC85c2B19958D116d79C654ecE73b359c08802A76", "0x9cc3164f01ED3796Fdf7Da538484D634608D2203", "0xf068cc770f32042Ff4a8fD196045641234dFaa47", "0x894b3e1e30Be0727eb138d2cceb0A99d2Fc4C55D", @@ -210,6 +222,7 @@ "0xe43e60736b1cb4a75ad25240e2f9a62bff65c0c0" ], "harmony": [ + "0xC85c2B19958D116d79C654ecE73b359c08802A76", "0x9cc3164f01ED3796Fdf7Da538484D634608D2203", "0xf068cc770f32042Ff4a8fD196045641234dFaa47", "0x894b3e1e30Be0727eb138d2cceb0A99d2Fc4C55D", @@ -223,6 +236,7 @@ "0xf012702a5f0e54015362cBCA26a26fc90AA832a3" ], "heco": [ + "0xC85c2B19958D116d79C654ecE73b359c08802A76", "0x9cc3164f01ED3796Fdf7Da538484D634608D2203", "0xf068cc770f32042Ff4a8fD196045641234dFaa47", "0x894b3e1e30Be0727eb138d2cceb0A99d2Fc4C55D", @@ -238,6 +252,7 @@ "0xbc3a8f63f311f3b005ff8afc1a26272faaba8d36" ], "metis": [ + "0xC85c2B19958D116d79C654ecE73b359c08802A76", "0x9cc3164f01ED3796Fdf7Da538484D634608D2203", "0xf068cc770f32042Ff4a8fD196045641234dFaa47", "0x894b3e1e30Be0727eb138d2cceb0A99d2Fc4C55D", @@ -249,6 +264,7 @@ "0x6352a56caadc4f1e25cd6c75970fa768a3304e64" ], "moonbeam": [ + "0xC85c2B19958D116d79C654ecE73b359c08802A76", "0xf068cc770f32042Ff4a8fD196045641234dFaa47", "0x894b3e1e30Be0727eb138d2cceb0A99d2Fc4C55D", "0x4b0B89b90fF83247aEa12469CeA9A6222e09d54c", @@ -259,6 +275,7 @@ "0xd0a01ec574d1fc6652edf79cb2f880fd47d34ab1" ], "moonriver": [ + "0xC85c2B19958D116d79C654ecE73b359c08802A76", "0xf068cc770f32042Ff4a8fD196045641234dFaa47", "0x894b3e1e30Be0727eb138d2cceb0A99d2Fc4C55D", "0x4b0B89b90fF83247aEa12469CeA9A6222e09d54c", @@ -274,6 +291,7 @@ "0x003B18357460e789e711849749A793c430d14f97" ], "nova": [ + "0xC85c2B19958D116d79C654ecE73b359c08802A76", "0x9cc3164f01ED3796Fdf7Da538484D634608D2203", "0xf068cc770f32042Ff4a8fD196045641234dFaa47", "0x894b3e1e30Be0727eb138d2cceb0A99d2Fc4C55D", @@ -285,6 +303,7 @@ "0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506" ], "okx": [ + "0xC85c2B19958D116d79C654ecE73b359c08802A76", "0xf068cc770f32042Ff4a8fD196045641234dFaa47", "0x894b3e1e30Be0727eb138d2cceb0A99d2Fc4C55D", "0x4b0B89b90fF83247aEa12469CeA9A6222e09d54c", @@ -302,6 +321,7 @@ "0x5381382257c761dac6f1509b1ba1b70ddaa6862a" ], "optimism": [ + "0xC85c2B19958D116d79C654ecE73b359c08802A76", "0xf068cc770f32042Ff4a8fD196045641234dFaa47", "0x894b3e1e30Be0727eb138d2cceb0A99d2Fc4C55D", "0x4b0B89b90fF83247aEa12469CeA9A6222e09d54c", @@ -321,6 +341,7 @@ "0x716fcc67dcA500A91B4a28c9255262c398D8f971" ], "polygon": [ + "0xC85c2B19958D116d79C654ecE73b359c08802A76", "0x9cc3164f01ED3796Fdf7Da538484D634608D2203", "0xf068cc770f32042Ff4a8fD196045641234dFaa47", "0x894b3e1e30Be0727eb138d2cceb0A99d2Fc4C55D", @@ -353,6 +374,7 @@ "0x39E3e49C99834C9573c9FC7Ff5A4B226cD7B0E63" ], "polygonzkevm": [ + "0xC85c2B19958D116d79C654ecE73b359c08802A76", "0xf068cc770f32042Ff4a8fD196045641234dFaa47", "0x4b0B89b90fF83247aEa12469CeA9A6222e09d54c", "0x9ca271A532392230EAe919Fb5460aEa9D9718424", @@ -374,6 +396,7 @@ "0x5aEaF2883FBf30f3D62471154eDa3C0c1b05942d" ], "velas": [ + "0xC85c2B19958D116d79C654ecE73b359c08802A76", "0xf068cc770f32042Ff4a8fD196045641234dFaa47", "0x894b3e1e30Be0727eb138d2cceb0A99d2Fc4C55D", "0x4b0B89b90fF83247aEa12469CeA9A6222e09d54c", @@ -385,6 +408,7 @@ "0xdef1c0ded9bec7f1a1670819833240f027b25eff" ], "goerli": [ + "0xC85c2B19958D116d79C654ecE73b359c08802A76", "0x353a5303dD2a39aB59aEd09fb971D359b94658C7", "0xd2981E8c29be81a8a6655764c2a60825bf1BB631", "0x7a250d5630b4cf539739df2c5dacb4c659f2488d", diff --git a/config/sigs.json b/config/sigs.json index 8bf3080df..6e6a52131 100644 --- a/config/sigs.json +++ b/config/sigs.json @@ -4,6 +4,8 @@ "0xdd343700", "0x04204ceb", "0xc6aabf84", + "0xf8be52e1", + "0x1eacd35f", "0x91695586", "0xa5be382e", "0xfc374157", From 0f49df3d02de73c3ea6e9ccb306916f14c326719 Mon Sep 17 00:00:00 2001 From: Ed Zynda Date: Fri, 1 Sep 2023 12:19:29 +0300 Subject: [PATCH 4/5] chore: Update dexs and sigs (#514) * update dexs and sigs * fixes --- config/dexs.json | 23 ++++++++++++++++------- config/sigs.json | 4 +++- networks | 1 + 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/config/dexs.json b/config/dexs.json index 92ba32ea8..f8c000c7f 100644 --- a/config/dexs.json +++ b/config/dexs.json @@ -21,7 +21,8 @@ "0xbD6C7B0d2f68c2b7805d88388319cfB6EcB50eA9", "0x5f509a3C3F16dF2Fba7bF84dEE1eFbce6BB85587", "0x50f9bDe1c76bba997a5d6e7FEFff695ec8536194", - "0xB4B0ea46Fe0E9e8EAB4aFb765b527739F2718671" + "0xB4B0ea46Fe0E9e8EAB4aFb765b527739F2718671", + "0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD" ], "arbitrum": [ "0xC85c2B19958D116d79C654ecE73b359c08802A76", @@ -46,7 +47,8 @@ "0xD01319f4b65b79124549dE409D36F25e04B3e551", "0xdef1c0ded9bec7f1a1670819833240f027b25eff", "0x7d13268144adcdbEBDf94F654085CC15502849Ff", - "0xe05dd51e4eb5636f4f0e8e7fbe82ea31a2ecef16" + "0xe05dd51e4eb5636f4f0e8e7fbe82ea31a2ecef16", + "0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD" ], "aurora": [ "0xC85c2B19958D116d79C654ecE73b359c08802A76", @@ -128,7 +130,8 @@ "0x30aE282CF477E2eF28B14d0125aCEAd57Fe1d7a1", "0x1956005bA9690B7A00b09c78769675C0cE1457AF", "0xcF0feBd3f17CEf5b47b0cD257aCf6025c5BFf3b7", - "0x0656fD85364d03b103CEEda192FB2D3906A6ac15" + "0x0656fD85364d03b103CEEda192FB2D3906A6ac15", + "0x5302086A3a25d473aAbBd0356eFf8Dd811a4d89B" ], "celo": [ "0xC85c2B19958D116d79C654ecE73b359c08802A76", @@ -141,7 +144,8 @@ "0x6352a56caadc4f1e25cd6c75970fa768a3304e64", "0xdef1c0ded9bec7f1a1670819833240f027b25eff", "0x1421bDe4B10e8dd459b3BCb598810B1337D56842", - "0xE3D8bd6Aed4F159bc8000a9cD47CffDb95F96121" + "0xE3D8bd6Aed4F159bc8000a9cD47CffDb95F96121", + "0x5Dc88340E1c5c6366864Ee415d6034cadd1A9897" ], "cronos": [ "0xC85c2B19958D116d79C654ecE73b359c08802A76", @@ -338,7 +342,8 @@ "0xfD9D2827AD469B72B69329dAA325ba7AfbDb3C98", "0xE592427A0AEce92De3Edee1F18E0157C05861564", "0xa492d6eabcdc3e204676f15b950bbdd448080364", - "0x716fcc67dcA500A91B4a28c9255262c398D8f971" + "0x716fcc67dcA500A91B4a28c9255262c398D8f971", + "0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD" ], "polygon": [ "0xC85c2B19958D116d79C654ecE73b359c08802A76", @@ -371,7 +376,8 @@ "0x67dC2703D306F72E94DbB0cE0aa0CB86149EAc70", "0xC0788A3aD43d79aa53B09c2EaCc313A787d1d607", "0xe7F5FF6da6DdF45F43aE7c8217AEC3ec5a0569c5", - "0x39E3e49C99834C9573c9FC7Ff5A4B226cD7B0E63" + "0x39E3e49C99834C9573c9FC7Ff5A4B226cD7B0E63", + "0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD" ], "polygonzkevm": [ "0xC85c2B19958D116d79C654ecE73b359c08802A76", @@ -405,7 +411,9 @@ "0x3D1c58B6d4501E34DF37Cf0f664A58059a188F00" ], "base": [ - "0xdef1c0ded9bec7f1a1670819833240f027b25eff" + "0xdef1c0ded9bec7f1a1670819833240f027b25eff", + "0x1111111254eeb25477b68fb85ed929f73a960582", + "0x198EF79F1F515F02dFE9e3115eD9fC07183f02fC" ], "goerli": [ "0xC85c2B19958D116d79C654ecE73b359c08802A76", @@ -419,6 +427,7 @@ "avalancheFujiTestnet": [], "bscTestnet": ["0x1b02da8cb0d097eb8d57a175b88c7d8b47997506"], "localanvil": [], + "linea": ["0x8cFe327CEc66d1C090Dd72bd0FF11d690C33a2Eb"], "mumbai": [ "0xfD0af5274aA16C72B7c463B22a435C06DEBbe894", "0xf471d32cb40837bf24529fcf17418fc1a4807626", diff --git a/config/sigs.json b/config/sigs.json index 6e6a52131..32e596e40 100644 --- a/config/sigs.json +++ b/config/sigs.json @@ -83,6 +83,8 @@ "0xa8676443", "0x301a3720", "0x7a1eb1b9", - "0xb22f4db8" + "0xb22f4db8", + "0x3593564c", + "0x24856bc3" ] } diff --git a/networks b/networks index 1a1dd5597..31235cb1b 100644 --- a/networks +++ b/networks @@ -25,3 +25,4 @@ bsc-testnet lineatest mumbai sepolia +zksync From 716f7708e7bc46beaab7e279ee936d1a37648ee4 Mon Sep 17 00:00:00 2001 From: Ed Zynda Date: Fri, 1 Sep 2023 12:19:42 +0300 Subject: [PATCH 5/5] deploy to optimism (#516) --- config/celerCircle.json | 5 +++++ deployments/_deployments_log_file.json | 14 ++++++++++++++ deployments/optimism.diamond.json | 4 ++++ deployments/optimism.json | 3 ++- 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/config/celerCircle.json b/config/celerCircle.json index 8a5bb99b9..d536a6bf0 100644 --- a/config/celerCircle.json +++ b/config/celerCircle.json @@ -13,5 +13,10 @@ "circleBridgeProxy": "0x9744ae566c64B6B6f7F9A4dD50f7496Df6Fef990", "usdc": "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E", "domain": 1 + }, + "optimism": { + "circleBridgeProxy": "0x697aC93c9263346c5Ad0412F9356D5789a3AA687", + "usdc": "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85", + "domain": 2 } } diff --git a/deployments/_deployments_log_file.json b/deployments/_deployments_log_file.json index 00d84ae22..5633936e5 100644 --- a/deployments/_deployments_log_file.json +++ b/deployments/_deployments_log_file.json @@ -9963,6 +9963,20 @@ } ] } + }, + "optimism": { + "production": { + "1.0.1": [ + { + "ADDRESS": "0x16d7Cff1992F17E46fa98284CCaAC1A19788B6B9", + "OPTIMIZER_RUNS": "1000000", + "TIMESTAMP": "2023-08-31 12:35:19", + "CONSTRUCTOR_ARGS": "0x000000000000000000000000697ac93c9263346c5ad0412f9356d5789a3aa6870000000000000000000000000b2c639c533813f4aa9d7837caf62653d097ff85", + "SALT": "31082023", + "VERIFIED": "true" + } + ] + } } }, "WormholeFacet": { diff --git a/deployments/optimism.diamond.json b/deployments/optimism.diamond.json index c947d4682..302ae4f6e 100644 --- a/deployments/optimism.diamond.json +++ b/deployments/optimism.diamond.json @@ -84,6 +84,10 @@ "0x2E61751366B7e006f8D53becB4b697890B30144F": { "Name": "StandardizedCallFacet", "Version": "1.0.0" + }, + "0x16d7Cff1992F17E46fa98284CCaAC1A19788B6B9": { + "Name": "CelerCircleBridgeFacet", + "Version": "1.0.1" } }, "Periphery": { diff --git a/deployments/optimism.json b/deployments/optimism.json index 62b9bb7e6..fdfd2f5bd 100644 --- a/deployments/optimism.json +++ b/deployments/optimism.json @@ -32,5 +32,6 @@ "RelayerCelerIMMutable": "0x6a8b11bF29C0546991DEcD6E0Db8cC7Fda22bA97", "CelerIMFacetMutable": "0xF70A1Ed85EcC454a562A4B69ee40CBc6a4eB0b64", "RelayerCelerIM": "0x1C97BE47f6Da4d2e09B3A11B0A17C513dfD0e896", - "StandardizedCallFacet": "0x2E61751366B7e006f8D53becB4b697890B30144F" + "StandardizedCallFacet": "0x2E61751366B7e006f8D53becB4b697890B30144F", + "CelerCircleBridgeFacet": "0x16d7Cff1992F17E46fa98284CCaAC1A19788B6B9" } \ No newline at end of file