diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..df50115 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "cSpell.enableFiletypes": [ + "makefile" + ] +} \ No newline at end of file diff --git a/Makefile b/Makefile index 4bf4c2f..935477e 100644 --- a/Makefile +++ b/Makefile @@ -6,4 +6,41 @@ checkL1: checkL2: @echo "Setting environment variable LIVE_DEPLOY_READ_FILE_NAME to $(file)" - @export LIVE_DEPLOY_READ_FILE_NAME=$(file) && forge test --mp test/LiveDeploy.t.sol --fork-url=${L2_RPC_URL} \ No newline at end of file + @export LIVE_DEPLOY_READ_FILE_NAME=$(file) && forge test --mp test/LiveDeploy.t.sol --fork-url=${L2_RPC_URL} + +deployL1: + @echo "Setting environment variable LIVE_DEPLOY_READ_FILE_NAME to $(file)" + @export LIVE_DEPLOY_READ_FILE_NAME=$(file) && forge script script/deploy/deployAll.s.sol --sig "run(string)" $(file) --fork-url=${L1_RPC_URL} + +deployL2: + @echo "Setting environment variable LIVE_DEPLOY_READ_FILE_NAME to $(file)" + @export LIVE_DEPLOY_READ_FILE_NAME=$(file) && forge script script/deploy/deployAll.s.sol --sig "run(string)" $(file) --fork-url=${L1_RPC_URL} + +live-deployL1: + @echo "Setting environment variable LIVE_DEPLOY_READ_FILE_NAME to $(file)" + @export LIVE_DEPLOY_READ_FILE_NAME=$(file) && forge script script/deploy/deployAll.s.sol --sig "run(string)" $(file) --fork-url=${L1_RPC_URL} --private-key=$(PRIVATE_KEY) --broadcast --slow --verify + +live-deployL2: + @echo "Setting environment variable LIVE_DEPLOY_READ_FILE_NAME to $(file)" + @export LIVE_DEPLOY_READ_FILE_NAME=$(file) && forge script script/deploy/deployAll.s.sol --sig "run(string)" $(file) --fork-url=${L1_RPC_URL} --private-key=$(PRIVATE_KEY) --broadcast --slow --verify + +prettier: + prettier --write '**/*.{md,yml,yaml,ts,js}' + +solhint: + solhint -w 0 'src/**/*.sol' + +slither: + slither src + +prepare: + husky + +deploy-createx-l1: + forge script script/DeployCustomCreatex.s.sol --rpc-url $L1_RPC_URL --private-key $PRIVATE_KEY --slow --no-metadata + +deploy-createx-l2: + forge script script/DeployCustomCreatex.s.sol --rpc-url $L2_RPC_URL --private-key $PRIVATE_KEY --slow --no-metadata + +check-configs: + bun lzConfigCheck.cjs \ No newline at end of file diff --git a/deployment-config/boba-eth-l1-08-09-24.json b/deployment-config/boba-eth-l1-08-09-24.json index 0606039..33eda44 100644 --- a/deployment-config/boba-eth-l1-08-09-24.json +++ b/deployment-config/boba-eth-l1-08-09-24.json @@ -1,21 +1,20 @@ { "protocolAdmin": "0x0000000000417626Ef34D62C4DC189b021603f2F", - - "boringVault":{ + "base": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", + "boringVaultAndBaseDecimals": "18", + "boringVault": { "boringVaultSalt": "0x1000000000000000000000000000000000000000000000000000000000000001", - "boringVaultName": "Boba Native Yield Nucleus Token", + "boringVaultName": "Boba Native Yield Nucleus Token", "boringVaultSymbol": "bobaETH", - - "address": "0x0000000000000000000000000000000000000000" - }, - "manager":{ - "managerSalt": "0x2000000000000000000000000000000000000000000000000000000000000001", + "address": "0x0000000000000000000000000000000000000000" + }, + "manager": { + "managerSalt": "0x2000000000000000000000000000000000000000000000000000000000000001", "address": "0x0000000000000000000000000000000000000000" }, - - "accountant":{ + "accountant": { "accountantSalt": "0x3000000000000000000000000000000000000000000000000000000000000001", "payoutAddress": "0x0000000000417626Ef34D62C4DC189b021603f2F", "allowedExchangeRateChangeUpper": "10030", @@ -25,13 +24,13 @@ "address": "0x0000000000000000000000000000000000000000" }, - "teller": { - "tellerSalt": "0x4000000000000000000000000000000000000000000000000000000000000001", + "tellerSalt": "0x4000000000000000000000000000000000000000000000000000000000000002", "maxGasForPeer": 200000, "minGasForPeer": 60000, "peerEid": 0, "tellerContractName": "CrossChainOPTellerWithMultiAssetSupport", + "opMessenger": "0x6D4528d192dB72E282265D6092F4B872f9Dff69e", "assets": [ "0xcd5fe23c85820f7b72d0926fc9b05b43e359b7ee", "0xbf5495efe5db9ce00f80364c8b423567e58d2110", @@ -46,14 +45,10 @@ "rolesAuthoritySalt": "0x5000000000000000000000000000000000000000000000000000000000000001", "strategist": "0x0000000000417626Ef34D62C4DC189b021603f2F", "exchangeRateBot": "0x0000000000417626Ef34D62C4DC189b021603f2F", - "address": "0x0000000000000000000000000000000000000000" }, - "decoder": { "decoderSalt": "0x6000000000000000000000000000000000000000000000000000000000000001", - - "address": "0x0000000000000000000000000000000000000000" + "address": "0x0000000000000000000000000000000000000000" } - } \ No newline at end of file diff --git a/deployment-config/boba-eth-l2-08-09-24.json b/deployment-config/boba-eth-l2-08-09-24.json index 6110342..9aa29f4 100644 --- a/deployment-config/boba-eth-l2-08-09-24.json +++ b/deployment-config/boba-eth-l2-08-09-24.json @@ -1,21 +1,19 @@ { "protocolAdmin": "0x0888c3D797E13892C5e67cD802F93Ffe55Ea2826", - - "boringVault":{ + "base": "0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000", + "boringVaultAndBaseDecimals": "18", + "boringVault": { "boringVaultSalt": "0x1000000000000000000000000000000000000000000000000000000000000001", - "boringVaultName": "Boba Native Yield Nucleus Token", + "boringVaultName": "Boba Native Yield Nucleus Token", "boringVaultSymbol": "bobaETH", - - "address": "0x0000000000000000000000000000000000000000" - }, - "manager":{ + "address": "0x0000000000000000000000000000000000000000" + }, + "manager": { "managerSalt": "0x2000000000000000000000000000000000000000000000000000000000000001", - "address": "0x0000000000000000000000000000000000000000" }, - - "accountant":{ + "accountant": { "accountantSalt": "0x3000000000000000000000000000000000000000000000000000000000000001", "payoutAddress": "0x0888c3D797E13892C5e67cD802F93Ffe55Ea2826", "allowedExchangeRateChangeUpper": "10030", @@ -25,29 +23,25 @@ "address": "0x0000000000000000000000000000000000000000" }, - "teller": { - "tellerSalt": "0x4000000000000000000000000000000000000000000000000000000000000001", + "tellerSalt": "0x4000000000000000000000000000000000000000000000000000000000000002", "maxGasForPeer": 200000, "minGasForPeer": 60000, "peerEid": 0, "tellerContractName": "CrossChainOPTellerWithMultiAssetSupport", - "assets": [ - ], + "opMessenger": "0x4200000000000000000000000000000000000007", + "assets": [], + "address": "0x0000000000000000000000000000000000000000" }, "rolesAuthority": { "rolesAuthoritySalt": "0x5000000000000000000000000000000000000000000000000000000000000001", "strategist": "0x0888c3D797E13892C5e67cD802F93Ffe55Ea2826", "exchangeRateBot": "0x0888c3D797E13892C5e67cD802F93Ffe55Ea2826", - "address": "0x0000000000000000000000000000000000000000" }, - "decoder": { "decoderSalt": "0x6000000000000000000000000000000000000000000000000000000000000001", - - "address": "0x0000000000000000000000000000000000000000" + "address": "0x0000000000000000000000000000000000000000" } - } \ No newline at end of file diff --git a/deployment-config/chains/1.json b/deployment-config/chains/1.json index aad1b0f..5c2bcbb 100644 --- a/deployment-config/chains/1.json +++ b/deployment-config/chains/1.json @@ -1,5 +1,5 @@ { - "base": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", + "name": "Ethereum", "balancerVault": "0xBA12222222228d8Ba445958a75a0704d566BF2C8", "opMessenger": "0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1", "lzEndpoint": "0x1a44076050125825900e736c501f859c50fE728c", @@ -41,11 +41,23 @@ "priceFeedType": 1 }, "0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0": { - "priceFeed": "", + "priceFeed": "0x86392dC19c0b719886221c78AB11eb8Cf5c52812", "rateProvider": "0xa360Df495d0560bDDc5d681B54991629965ae170", "decimals": 18, - "description": "", + "description": "STETH / ETH", "priceFeedType": 0 + }, + "0x8db2350d78abc13f5673a411d4700bcf87864dde": { + "rateProvider": "0x318Da095d602C08eF41319f4c4bA0646d318C906", + "decimals": 8 + }, + "0x9ba021b0a9b958b5e75ce9f6dff97c7ee52cb3e6":{ + "priceFeed": "0x19219bc90f48dee4d5cf202e09c438faacfd8bea", + "rateProvider": "", + "decimals": 18, + "description": "apxETH/ETH", + "priceFeedType": 1 } + } } \ No newline at end of file diff --git a/deployment-config/chains/11155111.json b/deployment-config/chains/11155111.json new file mode 100644 index 0000000..e900a9a --- /dev/null +++ b/deployment-config/chains/11155111.json @@ -0,0 +1,5 @@ +{ + "name": "Ethereum Sepolia", + "balancerVault": "0xBA12222222228d8Ba445958a75a0704d566BF2C8", + "lzEndpoint": "0x6EDCE65403992e310A62460808c4b910D972f10f" + } \ No newline at end of file diff --git a/deployment-config/chains/1329.json b/deployment-config/chains/1329.json index c547e36..4596379 100644 --- a/deployment-config/chains/1329.json +++ b/deployment-config/chains/1329.json @@ -1,6 +1,5 @@ { - "base": "0x160345fC359604fC6e70E3c5fAcbdE5F7A9342d8", + "name": "Sei", "balancerVault": "0x0000000000000000000000000000000000000000", - "opMessenger": "0x0000000000000000000000000000000000000000", "lzEndpoint": "0x1a44076050125825900e736c501f859c50fE728c" } \ No newline at end of file diff --git a/deployment-config/chains/252.json b/deployment-config/chains/252.json new file mode 100644 index 0000000..b7c0c39 --- /dev/null +++ b/deployment-config/chains/252.json @@ -0,0 +1,5 @@ +{ + "name": "Fraxtal", + "balancerVault": "0x0000000000000000000000000000000000000000", + "lzEndpoint": "0x1a44076050125825900e736c501f859c50fE728c" +} \ No newline at end of file diff --git a/deployment-config/chains/288.json b/deployment-config/chains/288.json index d106ef3..21e0d49 100644 --- a/deployment-config/chains/288.json +++ b/deployment-config/chains/288.json @@ -1,6 +1,5 @@ { - "base": "0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000", + "name": "Boba", "balancerVault": "0x0000000000000000000000000000000000000000", - "opMessenger": "0x4200000000000000000000000000000000000010", "lzEndpoint": "0x0000000000000000000000000000000000000000" } \ No newline at end of file diff --git a/deployment-config/exampleL1.json b/deployment-config/exampleL1.json index 0f02959..9726e93 100644 --- a/deployment-config/exampleL1.json +++ b/deployment-config/exampleL1.json @@ -1,17 +1,19 @@ { - "protocolAdmin": "0xC2d99d76bb9D46BF8Ec9449E4DfAE48C30CF0839", + "base": "0xee44150250AfF3E6aC25539765F056EDb7F85D7B", + "protocolAdmin": "0x0000000000417626Ef34D62C4DC189b021603f2F", + "boringVaultAndBaseDecimals": "18", "boringVault": { - "boringVaultSalt": "0x1ddd634c506ad203da17ff00000000000000000000000000000000000000000e", + "boringVaultSalt": "0x1ddd634c506ad203da17ff00000000000000000000000000000000000000001c", "boringVaultName": "Nucleus Vault", "boringVaultSymbol": "NV", "address": "0x0000000000E7Ab44153eEBEF2343ba5289F65dAC" }, "manager": { - "managerSalt": "0x30432d4b4ec00003b4a25000000000000000000000000000000000000000000e", + "managerSalt": "0x30432d4b4ec00003b4a25000000000000000000000000000000000000000001c", "address": "0x0000000000fAd6Db23abdC1a85621B97bd1Dc82f" }, "accountant": { - "accountantSalt": "0x6a184dbea6f3cc0318679f00000000000000000000000000000000000000000e", + "accountantSalt": "0x6a184dbea6f3cc0318679f00000000000000000000000000000000000000001c", "payoutAddress": "0x0000000000417626Ef34D62C4DC189b021603f2F", "base": "0x5f207d42F869fd1c71d7f0f81a2A67Fc20FF7323", "allowedExchangeRateChangeUpper": "10003", @@ -21,14 +23,12 @@ "address": "0x00000000004F96C07B83e86600D86F9479bB43fa" }, "teller": { - "tellerSalt": "0x51f8968749a56d01202c9100000000000000000000000000000000000000000e", + "tellerSalt": "0x51f8968749a56d01202c9100000000000000000000000000000000000000001c", "maxGasForPeer": 100000, "minGasForPeer": 0, "peerEid": 30280, - "tellerContractName": "MultiChainLayerZeroTellerWithMultiAssetSupport", + "tellerContractName": "TellerWithMultiAssetSupport", "assets": [ - "0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee", - "0xbf5495Efe5DB9ce00f80364C8B423567e58d2110" ], "dvnIfNoDefault": { "required": [ @@ -46,13 +46,13 @@ "address": "0x00000000004F96C07B83e86600D86F0000000000" }, "rolesAuthority": { - "rolesAuthoritySalt": "0x66bbc3b3b3000b01466a3a00000000000000000000000000000000000000000e", + "rolesAuthoritySalt": "0x66bbc3b3b3000b01466a3a00000000000000000000000000000000000000001c", "strategist": "0xC2d99d76bb9D46BF8Ec9449E4DfAE48C30CF0839", "exchangeRateBot": "0x00000000004F96C07B83e86600D86F0000000000", "address": "0x00000000004F96C07B83e86600D86F0000000000" }, "decoder": { - "decoderSalt": "0x48b53893da2e0b0248268c00000000000000000000000000000000000000000e", + "decoderSalt": "0x48b53893da2e0b0248268c00000000000000000000000000000000000000001c", "address": "0x00000000004F96C07B83e86600D86F0000000000" } } \ No newline at end of file diff --git a/deployment-config/exampleL2.json b/deployment-config/exampleL2.json index cc8ba58..16fb01c 100644 --- a/deployment-config/exampleL2.json +++ b/deployment-config/exampleL2.json @@ -1,5 +1,6 @@ { "protocolAdmin": "0xF2dE1311C5b2C1BD94de996DA13F80010453e505", + "boringVaultAndBaseDecimals": "18", "boringVault": { "boringVaultSalt": "0x1ddd634c506ad203da17ff00000000000000000000000000000000000000000e", "boringVaultName": "Nucleus Vault", @@ -25,7 +26,7 @@ "maxGasForPeer": 100000, "minGasForPeer": 0, "peerEid": 30280, - "tellerContractName": "MultiChainLayerZeroTellerWithMultiAssetSupport", + "tellerContractName": "TellerWithMultiAssetSupport", "assets": [], "dvnIfNoDefault": { "required": [ diff --git a/deployment-config/form-btc-testnet-l1-08-30-24.json b/deployment-config/form-btc-testnet-l1-08-30-24.json new file mode 100644 index 0000000..5805959 --- /dev/null +++ b/deployment-config/form-btc-testnet-l1-08-30-24.json @@ -0,0 +1,57 @@ +{ + "base": "0x0893A950E8f80B21658ba35D39d9AB00cCa95589", + "protocolAdmin": "0x0000000000417626Ef34D62C4DC189b021603f2F", + "boringVaultAndBaseDecimals": "8", + "boringVault": { + "boringVaultSalt": "0x1ddd634c506ad203da17ff000000000000000000000000000000000000000011", + "boringVaultName": "Form BTC", + "boringVaultSymbol": "FBTC", + "address": "0x0000000000000000000000000000000000000000" + }, + "manager": { + "managerSalt": "0x30432d4b4ec00003b4a250000000000000000000000000000000000000000011", + "address": "0x0000000000000000000000000000000000000000" + }, + "accountant": { + "accountantSalt": "0x6a184dbea6f3cc0318679f000000000000000000000000000000000000000011", + "payoutAddress": "0x0000000000417626Ef34D62C4DC189b021603f2F", + "allowedExchangeRateChangeUpper": "10003", + "allowedExchangeRateChangeLower": "9998", + "minimumUpdateDelayInSeconds": "3600", + "managementFee": "0", + "address": "0x0000000000000000000000000000000000000000" + }, + "teller": { + "tellerSalt": "0x51f8968749a56d01202c91000000000000000000000000000000000000000011", + "maxGasForPeer": 100000, + "minGasForPeer": 0, + "peerEid": 40270, + "tellerContractName": "TellerWithMultiAssetSupport", + "opMessenger": "0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef", + "assets": [], + "dvnIfNoDefault": { + "required": [ + "0x589dEDbD617e0CBcB916A9223F4d1300c294236b" + ], + "optional": [ + "0x380275805876Ff19055EA900CDb2B46a94ecF20D", + "0x8FafAE7Dd957044088b3d0F67359C327c6200d18", + "0xa59BA433ac34D2927232918Ef5B2eaAfcF130BA5", + "0xe552485d02EDd3067FE7FCbD4dd56BB1D3A998D2" + ], + "blockConfirmationsRequiredIfNoDefault": 15, + "optionalThreshold": 1 + }, + "address": "0x0000000000000000000000000000000000000000" + }, + "rolesAuthority": { + "rolesAuthoritySalt": "0x66bbc3b3b3000b01466a3a000000000000000000000000000000000000000011", + "strategist": "0x0000000000417626Ef34D62C4DC189b021603f2F", + "exchangeRateBot": "0x0000000000417626Ef34D62C4DC189b021603f2F", + "address": "0x0000000000000000000000000000000000000000" + }, + "decoder": { + "decoderSalt": "0x48b53893da2e0b0248268c000000000000000000000000000000000000000011", + "address": "0x0000000000000000000000000000000000000000" + } +} \ No newline at end of file diff --git a/deployment-config/form-eth-testnet-l1-08-30-24.json b/deployment-config/form-eth-testnet-l1-08-30-24.json new file mode 100644 index 0000000..bcb0cb6 --- /dev/null +++ b/deployment-config/form-eth-testnet-l1-08-30-24.json @@ -0,0 +1,59 @@ +{ + "base": "0xee44150250AfF3E6aC25539765F056EDb7F85D7B", + "protocolAdmin": "0x0000000000417626Ef34D62C4DC189b021603f2F", + "boringVaultAndBaseDecimals": "18", + "boringVault": { + "boringVaultSalt": "0x1ddd634c506ad203da17ff00000000000000000000000000000000000000000e", + "boringVaultName": "Form ETH", + "boringVaultSymbol": "FETH", + "address": "0x0000000000000000000000000000000000000000" + }, + "manager": { + "managerSalt": "0x30432d4b4ec00003b4a25000000000000000000000000000000000000000000e", + "address": "0x0000000000000000000000000000000000000000" + }, + "accountant": { + "accountantSalt": "0x6a184dbea6f3cc0318679f00000000000000000000000000000000000000000e", + "payoutAddress": "0x0000000000417626Ef34D62C4DC189b021603f2F", + "allowedExchangeRateChangeUpper": "10003", + "allowedExchangeRateChangeLower": "9998", + "minimumUpdateDelayInSeconds": "3600", + "managementFee": "0", + "address": "0x0000000000000000000000000000000000000000" + }, + "teller": { + "tellerSalt": "0x51f8968749a56d01202c9100000000000000000000000000000000000000000e", + "maxGasForPeer": 100000, + "minGasForPeer": 0, + "peerEid": 40270, + "tellerContractName": "TellerWithMultiAssetSupport", + "opMessenger": "0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef", + "assets": [ + + ], + "dvnIfNoDefault": { + "required": [ + "0x589dEDbD617e0CBcB916A9223F4d1300c294236b" + ], + "optional": [ + "0x380275805876Ff19055EA900CDb2B46a94ecF20D", + "0x8FafAE7Dd957044088b3d0F67359C327c6200d18", + "0xa59BA433ac34D2927232918Ef5B2eaAfcF130BA5", + "0xe552485d02EDd3067FE7FCbD4dd56BB1D3A998D2" + ], + "blockConfirmationsRequiredIfNoDefault": 15, + "optionalThreshold": 1 + }, + "address": "0x0000000000000000000000000000000000000000" + }, + "rolesAuthority": { + "rolesAuthoritySalt": "0x66bbc3b3b3000b01466a3a00000000000000000000000000000000000000000e", + "strategist": "0x0000000000417626Ef34D62C4DC189b021603f2F", + "exchangeRateBot": "0x0000000000417626Ef34D62C4DC189b021603f2F", + "address": "0x0000000000000000000000000000000000000000" + }, + "decoder": { + "decoderSalt": "0x48b53893da2e0b0248268c00000000000000000000000000000000000000000e", + "address": "0x0000000000000000000000000000000000000000" + } + } \ No newline at end of file diff --git a/deployment-config/form-usd-testnet-l1-08-30-24.json b/deployment-config/form-usd-testnet-l1-08-30-24.json new file mode 100644 index 0000000..6206524 --- /dev/null +++ b/deployment-config/form-usd-testnet-l1-08-30-24.json @@ -0,0 +1,57 @@ +{ + "base": "0x66248001cdB1B26B66a89aA7227424Bb14937eCD", + "protocolAdmin": "0x0000000000417626Ef34D62C4DC189b021603f2F", + "boringVaultAndBaseDecimals": "6", + "boringVault": { + "boringVaultSalt": "0x1ddd634c506ad203da17ff000000000000000000000000000000000000000012", + "boringVaultName": "Form USDC", + "boringVaultSymbol": "FUSDC", + "address": "0x0000000000000000000000000000000000000000" + }, + "manager": { + "managerSalt": "0x30432d4b4ec00003b4a250000000000000000000000000000000000000000012", + "address": "0x0000000000000000000000000000000000000000" + }, + "accountant": { + "accountantSalt": "0x6a184dbea6f3cc0318679f000000000000000000000000000000000000000012", + "payoutAddress": "0x0000000000417626Ef34D62C4DC189b021603f2F", + "allowedExchangeRateChangeUpper": "10003", + "allowedExchangeRateChangeLower": "9998", + "minimumUpdateDelayInSeconds": "3600", + "managementFee": "0", + "address": "0x0000000000000000000000000000000000000000" + }, + "teller": { + "tellerSalt": "0x51f8968749a56d01202c91000000000000000000000000000000000000000012", + "maxGasForPeer": 100000, + "minGasForPeer": 0, + "peerEid": 40270, + "tellerContractName": "TellerWithMultiAssetSupport", + "opMessenger": "0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef", + "assets": [], + "dvnIfNoDefault": { + "required": [ + "0x589dEDbD617e0CBcB916A9223F4d1300c294236b" + ], + "optional": [ + "0x380275805876Ff19055EA900CDb2B46a94ecF20D", + "0x8FafAE7Dd957044088b3d0F67359C327c6200d18", + "0xa59BA433ac34D2927232918Ef5B2eaAfcF130BA5", + "0xe552485d02EDd3067FE7FCbD4dd56BB1D3A998D2" + ], + "blockConfirmationsRequiredIfNoDefault": 15, + "optionalThreshold": 1 + }, + "address": "0x0000000000000000000000000000000000000000" + }, + "rolesAuthority": { + "rolesAuthoritySalt": "0x66bbc3b3b3000b01466a3a000000000000000000000000000000000000000012", + "strategist": "0x0000000000417626Ef34D62C4DC189b021603f2F", + "exchangeRateBot": "0x0000000000417626Ef34D62C4DC189b021603f2F", + "address": "0x0000000000000000000000000000000000000000" + }, + "decoder": { + "decoderSalt": "0x48b53893da2e0b0248268c000000000000000000000000000000000000000012", + "address": "0x0000000000000000000000000000000000000000" + } +} \ No newline at end of file diff --git a/deployment-config/fraxtal-eth-l1-08-13-24.json b/deployment-config/fraxtal-eth-l1-08-13-24.json new file mode 100644 index 0000000..b57624c --- /dev/null +++ b/deployment-config/fraxtal-eth-l1-08-13-24.json @@ -0,0 +1,51 @@ +{ + "protocolAdmin": "0x0000000000417626Ef34D62C4DC189b021603f2F", + "base": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", + "boringVaultAndBaseDecimals": "18", + "boringVault": { + "boringVaultSalt": "0x1000000000000000000000000000000000000000000000000000000000000002", + "boringVaultName": "Fraxtal Native Yield Nucleus Token", + "boringVaultSymbol": "frxtlETH", + "address": "0x0000000000000000000000000000000000000000" + }, + "manager": { + "managerSalt": "0x2000000000000000000000000000000000000000000000000000000000000002", + "address": "0x0000000000000000000000000000000000000000" + }, + "accountant": { + "accountantSalt": "0x3000000000000000000000000000000000000000000000000000000000000002", + "payoutAddress": "0x0000000000417626Ef34D62C4DC189b021603f2F", + "allowedExchangeRateChangeUpper": "10030", + "allowedExchangeRateChangeLower": "9980", + "minimumUpdateDelayInSeconds": "3600", + "managementFee": "0", + "address": "0x0000000000000000000000000000000000000000" + }, + "teller": { + "tellerSalt": "0x4000000000000000000000000000000000000000000000000000000000000002", + "maxGasForPeer": 200000, + "minGasForPeer": 60000, + "peerEid": 30255, + "tellerContractName": "MultiChainLayerZeroTellerWithMultiAssetSupport", + "opMessenger": "0x126bcc31Bc076B3d515f60FBC81FddE0B0d542Ed", + "assets": [ + "0xcd5fe23c85820f7b72d0926fc9b05b43e359b7ee", + "0xbf5495efe5db9ce00f80364c8b423567e58d2110", + "0xA1290d69c65A6Fe4DF752f95823fae25cB99e5A7", + "0xFAe103DC9cf190eD75350761e95403b7b8aFa6c0", + "0xD9A442856C234a39a81a089C06451EBAa4306a72", + "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0" + ], + "address": "0x0000000000000000000000000000000000000000" + }, + "rolesAuthority": { + "rolesAuthoritySalt": "0x5000000000000000000000000000000000000000000000000000000000000002", + "strategist": "0x0000000000417626Ef34D62C4DC189b021603f2F", + "exchangeRateBot": "0x0000000000417626Ef34D62C4DC189b021603f2F", + "address": "0x0000000000000000000000000000000000000000" + }, + "decoder": { + "decoderSalt": "0x6000000000000000000000000000000000000000000000000000000000000002", + "address": "0x0000000000000000000000000000000000000000" + } +} \ No newline at end of file diff --git a/deployment-config/fraxtal-eth-l2-08-13-24.json b/deployment-config/fraxtal-eth-l2-08-13-24.json new file mode 100644 index 0000000..29fd832 --- /dev/null +++ b/deployment-config/fraxtal-eth-l2-08-13-24.json @@ -0,0 +1,44 @@ +{ + "protocolAdmin": "0x0888c3D797E13892C5e67cD802F93Ffe55Ea2826", + "base": "0xFC00000000000000000000000000000000000006", + "boringVaultAndBaseDecimals": "18", + "boringVault": { + "boringVaultSalt": "0x1000000000000000000000000000000000000000000000000000000000000002", + "boringVaultName": "Fraxtal Native Yield Nucleus Token", + "boringVaultSymbol": "frxtlETH", + "address": "0x0000000000000000000000000000000000000000" + }, + "manager": { + "managerSalt": "0x2000000000000000000000000000000000000000000000000000000000000002", + "address": "0x0000000000000000000000000000000000000000" + }, + "accountant": { + "accountantSalt": "0x3000000000000000000000000000000000000000000000000000000000000002", + "payoutAddress": "0x0888c3D797E13892C5e67cD802F93Ffe55Ea2826", + "allowedExchangeRateChangeUpper": "10030", + "allowedExchangeRateChangeLower": "9980", + "minimumUpdateDelayInSeconds": "3600", + "managementFee": "0", + "address": "0x0000000000000000000000000000000000000000" + }, + "teller": { + "tellerSalt": "0x4000000000000000000000000000000000000000000000000000000000000002", + "maxGasForPeer": 200000, + "minGasForPeer": 60000, + "peerEid": 30101, + "tellerContractName": "MultiChainLayerZeroTellerWithMultiAssetSupport", + "opMessenger": "0x4200000000000000000000000000000000000007", + "assets": [], + "address": "0x0000000000000000000000000000000000000000" + }, + "rolesAuthority": { + "rolesAuthoritySalt": "0x5000000000000000000000000000000000000000000000000000000000000002", + "strategist": "0x0888c3D797E13892C5e67cD802F93Ffe55Ea2826", + "exchangeRateBot": "0x0888c3D797E13892C5e67cD802F93Ffe55Ea2826", + "address": "0x0000000000000000000000000000000000000000" + }, + "decoder": { + "decoderSalt": "0x6000000000000000000000000000000000000000000000000000000000000002", + "address": "0x0000000000000000000000000000000000000000" + } +} \ No newline at end of file diff --git a/deployment-config/rates/DeployGenericRateProvider.json b/deployment-config/rates/DeployGenericRateProvider.json new file mode 100644 index 0000000..febfe7b --- /dev/null +++ b/deployment-config/rates/DeployGenericRateProvider.json @@ -0,0 +1,7 @@ +{ + "target": "0x8DB2350D78aBc13f5673A411D4700BCF87864dDE", + "signature": "pricePerShare()", + "expectedMin": "100000000", + "expectedMax": "100000000", + "salt": "0x1000000000000000000000000000000000000000000000000000000000000000" +} \ No newline at end of file diff --git a/deployment-config/sei-eth-l1-08-08-24.json b/deployment-config/sei-eth-l1-08-08-24.json index dffe844..97b662e 100644 --- a/deployment-config/sei-eth-l1-08-08-24.json +++ b/deployment-config/sei-eth-l1-08-08-24.json @@ -1,6 +1,7 @@ { "protocolAdmin": "0x0000000000417626Ef34D62C4DC189b021603f2F", - + "base": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", + "boringVaultAndBaseDecimals": "18", "boringVault":{ "boringVaultSalt": "0x100000000000000000000000000000000000000000000000000000000000000a", "boringVaultName": "Sei Native Yield Nucleus Token", @@ -32,6 +33,7 @@ "minGasForPeer": 60000, "peerEid": 30280, "tellerContractName": "MultiChainLayerZeroTellerWithMultiAssetSupport", + "opMessenger": "0x0000000000000000000000000000000000000000", "assets": [ "0xcd5fe23c85820f7b72d0926fc9b05b43e359b7ee", "0xbf5495efe5db9ce00f80364c8b423567e58d2110", diff --git a/deployment-config/sei-eth-l2-08-08-24.json b/deployment-config/sei-eth-l2-08-08-24.json index 1e5064e..93766a6 100644 --- a/deployment-config/sei-eth-l2-08-08-24.json +++ b/deployment-config/sei-eth-l2-08-08-24.json @@ -1,6 +1,7 @@ { "protocolAdmin": "0xF2dE1311C5b2C1BD94de996DA13F80010453e505", - + "base": "0x160345fC359604fC6e70E3c5fAcbdE5F7A9342d8", + "boringVaultAndBaseDecimals": "18", "boringVault":{ "boringVaultSalt": "0x1000000000000000000000000000000000000000000000000000000000000000", "boringVaultName": "Sei Native Yield Nucleus Token", @@ -32,6 +33,7 @@ "minGasForPeer": 60000, "peerEid": 30101, "tellerContractName": "MultiChainLayerZeroTellerWithMultiAssetSupport", + "opMessenger": "0x0000000000000000000000000000000000000000", "assets": [ ], "address": "0x0000000000000000000000000000000000000000" diff --git a/deployment-config/seidry.json b/deployment-config/seidry.json deleted file mode 100644 index cb4b46b..0000000 --- a/deployment-config/seidry.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "protocolAdmin": "0xbcef4940d7000e94c0048f071e28bfe91bc5066d", - - "boringVault":{ - "boringVaultSalt": "0x1ddd634c506ad203da17ff00000000000000000000000000000000000000000a", - "boringVaultName": "Ion Vault", - "boringVaultSymbol": "IVT", - - "address": "0x0000000000000000000000000000000000000000" - }, - - "manager":{ - "managerSalt": "0x30432d4b4ec00003b4a25000000000000000000000000000000000000000000a", - - "address": "0x0000000000000000000000000000000000000000" - }, - - "accountant":{ - "accountantSalt": "0x6a184dbea6f3cc0318679f00000000000000000000000000000000000000000a", - "payoutAddress": "0x0000000000417626Ef34D62C4DC189b021603f2F", - "allowedExchangeRateChangeUpper": "10003", - "allowedExchangeRateChangeLower": "9998", - "minimumUpdateDelayInSeconds": "3600", - "managementFee": "2000", - - "address": "0x0000000000000000000000000000000000000000" - }, - - "teller": { - "tellerSalt": "0x51f8968749a56d01202c9100000000000000000000000000000000000000000a", - "maxGasForPeer": 100000, - "minGasForPeer": 0, - "peerEid": 1, - "tellerContractName": "MultiChainLayerZeroTellerWithMultiAssetSupport", - "assets": [ - ], - "address": "0x0000000000000000000000000000000000000000" - }, - "rolesAuthority": { - "rolesAuthoritySalt": "0x66bbc3b3b3000b01466a3a00000000000000000000000000000000000000000a", - "strategist": "0xbcef4940d7000e94c0048f071e28bfe91bc5066d", - "exchangeRateBot": "0x00000000004F96C07B83e86600D86F0000000000", - - "address": "0x0000000000000000000000000000000000000000" - }, - - "decoder": { - "decoderSalt": "0x48b53893da2e0b0248268c00000000000000000000000000000000000000000a", - - "address": "0x0000000000000000000000000000000000000000" - }, - - "rateProvider": { - "maxTimeFromLastUpdate": "86400", - "rateProviderSalt": "0x0000000000000000000000000000000000000000000000000000000000000000", - - "address": "0x0000000000000000000000000000000000000000" - } -} \ No newline at end of file diff --git a/deployment-config/swell-btc-l1-08-22-24.json b/deployment-config/swell-btc-l1-08-22-24.json new file mode 100644 index 0000000..c84c007 --- /dev/null +++ b/deployment-config/swell-btc-l1-08-22-24.json @@ -0,0 +1,57 @@ +{ + "protocolAdmin": "0x0000000000417626Ef34D62C4DC189b021603f2F", + "base": "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599", + "boringVaultAndBaseDecimals": "8", + + "boringVault":{ + "boringVaultSalt": "0x100000000000000000000000000000000000000000000000000000000000000c", + "boringVaultName": "Swell BTC Native Yield Nucleus Token", + "boringVaultSymbol": "rswBTC", + + "address": "0x0000000000000000000000000000000000000000" + }, + + "manager":{ + "managerSalt": "0x200000000000000000000000000000000000000000000000000000000000000c", + + "address": "0x0000000000000000000000000000000000000000" + }, + + "accountant":{ + "accountantSalt": "0x300000000000000000000000000000000000000000000000000000000000000c", + "payoutAddress": "0x0000000000417626Ef34D62C4DC189b021603f2F", + "allowedExchangeRateChangeUpper": "10030", + "allowedExchangeRateChangeLower": "9980", + "minimumUpdateDelayInSeconds": "3600", + "managementFee": "0", + + "address": "0x0000000000000000000000000000000000000000" + }, + + "teller": { + "tellerSalt": "0x400000000000000000000000000000000000000000000000000000000000000c", + "maxGasForPeer": 200000, + "minGasForPeer": 60000, + "peerEid": 0, + "tellerContractName": "TellerWithMultiAssetSupport", + "opMessenger": "0x0000000000000000000000000000000000000000", + "assets": [ + "0x8DB2350D78aBc13f5673A411D4700BCF87864dDE" + ], + "address": "0x0000000000000000000000000000000000000000" + }, + "rolesAuthority": { + "rolesAuthoritySalt": "0x500000000000000000000000000000000000000000000000000000000000000c", + "strategist": "0x0000000000417626Ef34D62C4DC189b021603f2F", + "exchangeRateBot": "0x0000000000417626Ef34D62C4DC189b021603f2F", + + "address": "0x0000000000000000000000000000000000000000" + }, + + "decoder": { + "decoderSalt": "0x6000000000000000000000000000000000000000000000000000000000000000", + + "address": "0x0000000000000000000000000000000000000000" + } + +} \ No newline at end of file diff --git a/lib/ccip b/lib/ccip deleted file mode 160000 index 9eb2708..0000000 --- a/lib/ccip +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9eb2708908536544c26ad67a4be96b5974d2d9d0 diff --git a/package.json b/package.json index f6f8aaa..e3a1d39 100644 --- a/package.json +++ b/package.json @@ -8,8 +8,8 @@ "solhint": "solhint -w 0 'src/**/*.sol'", "slither": "slither src", "prepare": "husky", - "deploy-createx-l1": "forge script script/DeployCustomCreatex.s.sol --rpc-url $L1_RPC_URL --private-key $PRIVATE_KEY --slow", - "deploy-createx-l2": "forge script script/DeployCustomCreatex.s.sol --rpc-url $L2_RPC_URL --private-key $PRIVATE_KEY --slow", + "deploy-createx-l1": "forge script script/DeployCustomCreatex.s.sol --rpc-url $L1_RPC_URL --private-key $PRIVATE_KEY --slow --no-metadata", + "deploy-createx-l2": "forge script script/DeployCustomCreatex.s.sol --rpc-url $L2_RPC_URL --private-key $PRIVATE_KEY --slow --no-metadata", "deploy-l1": "forge script script/deploy/deployAll.s.sol -f $L1_RPC_URL --private-key=$PRIVATE_KEY --slow", "deploy-l2": "forge script script/deploy/deployAll.s.sol -f $L2_RPC_URL --private-key=$PRIVATE_KEY --slow", "check-configs": "bun lzConfigCheck.cjs" diff --git a/script/Base.s.sol b/script/Base.s.sol index b307a68..19426e9 100644 --- a/script/Base.s.sol +++ b/script/Base.s.sol @@ -6,10 +6,8 @@ import { ICreateX } from "lib/createx/src/ICreateX.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; import { Script, stdJson } from "@forge-std/Script.sol"; -import { console2 } from "@forge-std/console2.sol"; import { ConfigReader, IAuthority } from "./ConfigReader.s.sol"; -import { console } from "forge-std/Test.sol"; abstract contract BaseScript is Script { using stdJson for string; @@ -57,7 +55,6 @@ abstract contract BaseScript is Script { // if this chain doesn't have a CREATEX deployment, deploy it ourselves if (address(CREATEX).code.length == 0) { - console.log("Current Chain ID: ", block.chainid); revert("CREATEX Not Deployed on this chain. Use the DeployCustomCreatex script to deploy it"); } } @@ -74,7 +71,9 @@ abstract contract BaseScript is Script { vm.stopBroadcast(); } - function deploy(ConfigReader.Config memory config) public virtual returns (address); + function deploy(ConfigReader.Config memory config) public virtual returns (address) { + revert("deploy() Not Implemented"); + } function getConfig() public returns (ConfigReader.Config memory) { return ConfigReader.toConfig(requestConfigFileFromUser(), getChainConfigFile()); diff --git a/script/ConfigReader.s.sol b/script/ConfigReader.s.sol index b1c4659..9e8a74c 100644 --- a/script/ConfigReader.s.sol +++ b/script/ConfigReader.s.sol @@ -14,6 +14,8 @@ library ConfigReader { struct Config { address protocolAdmin; + address base; + uint8 boringVaultAndBaseDecimals; bytes32 accountantSalt; address boringVault; address payoutAddress; @@ -51,12 +53,13 @@ library ConfigReader { address[] assets; address[] rateProviders; address[] priceFeeds; - address base; } function toConfig(string memory _config, string memory _chainConfig) internal pure returns (Config memory config) { // Reading the 'protocolAdmin' config.protocolAdmin = _config.readAddress(".protocolAdmin"); + config.base = _config.readAddress(".base"); + config.boringVaultAndBaseDecimals = uint8(_config.readUint(".boringVaultAndBaseDecimals")); // Reading from the 'accountant' section config.accountant = _config.readAddress(".accountant.address"); @@ -103,9 +106,7 @@ library ConfigReader { config.decoder = _config.readAddress(".decoder.address"); // Reading from the 'chainConfig' section - config.base = _chainConfig.readAddress(".base"); config.balancerVault = _chainConfig.readAddress(".balancerVault"); - config.opMessenger = _chainConfig.readAddress(".opMessenger"); config.lzEndpoint = _chainConfig.readAddress(".lzEndpoint"); return config; diff --git a/script/DeployCustomCreatex.s.sol b/script/DeployCustomCreatex.s.sol index 2f91a17..cec0599 100644 --- a/script/DeployCustomCreatex.s.sol +++ b/script/DeployCustomCreatex.s.sol @@ -34,7 +34,6 @@ contract DeployCustomCreateX is Script { require(EXPECTED.code.length == 0, "Createx already exists on this chain"); CreateX createx = new CreateX{ salt: SALT }(); - console.log(address(createx)); require(address(createx) == EXPECTED, "address is not expected"); } diff --git a/script/deploy/DeployGenericRateProvider.s.sol b/script/deploy/DeployGenericRateProvider.s.sol new file mode 100644 index 0000000..c9e39a8 --- /dev/null +++ b/script/deploy/DeployGenericRateProvider.s.sol @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import { GenericRateProvider } from "./../../src/helper/GenericRateProvider.sol"; +import { BaseScript } from "../Base.s.sol"; +import { stdJson as StdJson } from "@forge-std/StdJson.sol"; +import { console2 } from "forge-std/console2.sol"; + +using StdJson for string; + +// NOTE Currently assumes that function signature arguments are empty. +contract DeployGenericRateProvider is BaseScript { + string configPath = "./deployment-config/rates/DeployGenericRateProvider.json"; + string config = vm.readFile(configPath); + + uint256 expectedMin = config.readUint(".expectedMin"); + uint256 expectedMax = config.readUint(".expectedMax"); + address target = config.readAddress(".target"); + string signature = config.readString(".signature"); + bytes32 salt = config.readBytes32(".salt"); + + function run() public broadcast returns (GenericRateProvider rateProvider) { + bytes4 functionSig = bytes4(keccak256(bytes(signature))); + console2.logBytes4(functionSig); + + bytes memory creationCode = type(GenericRateProvider).creationCode; + + rateProvider = GenericRateProvider( + CREATEX.deployCreate3( + salt, abi.encodePacked(creationCode, abi.encode(target, functionSig, 0, 0, 0, 0, 0, 0, 0, 0)) + ) + ); + + uint256 rate = rateProvider.getRate(); + + console2.log("rate: ", rate); + + require(rate != 0, "rate must not be zero"); + require(rate >= expectedMin, "rate must be greater than or equal to min"); + require(rate <= expectedMax, "rate must be less than or equal to max"); + } +} diff --git a/script/deploy/deployAll.s.sol b/script/deploy/deployAll.s.sol index 8b7f687..1db7134 100644 --- a/script/deploy/deployAll.s.sol +++ b/script/deploy/deployAll.s.sol @@ -90,6 +90,8 @@ contract DeployAll is BaseScript { teller = new DeployCrossChainOPTellerWithMultiAssetSupport().deploy(config); } else if (compareStrings(config.tellerContractName, "MultiChainLayerZeroTellerWithMultiAssetSupport")) { teller = new DeployMultiChainLayerZeroTellerWithMultiAssetSupport().deploy(config); + } else if (compareStrings(config.tellerContractName, "TellerWithMultiAssetSupport")) { + teller = new DeployTellerWithMultiAssetSupport().deploy(config); } else { revert INVALID_TELLER_CONTRACT_NAME(); } diff --git a/script/deploy/single/02_DeployBoringVault.s.sol b/script/deploy/single/02_DeployBoringVault.s.sol index ea4ddea..263eefe 100644 --- a/script/deploy/single/02_DeployBoringVault.s.sol +++ b/script/deploy/single/02_DeployBoringVault.s.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.21; import { BoringVault } from "./../../../src/base/BoringVault.sol"; import { BaseScript } from "./../../Base.s.sol"; import { ConfigReader } from "../../ConfigReader.s.sol"; +import { ERC20 } from "@solmate/tokens/ERC20.sol"; import { stdJson as StdJson } from "@forge-std/StdJson.sol"; contract DeployIonBoringVaultScript is BaseScript { @@ -31,7 +32,7 @@ contract DeployIonBoringVaultScript is BaseScript { broadcaster, config.boringVaultName, config.boringVaultSymbol, - 18 // decimals + config.boringVaultAndBaseDecimals // decimals ) ) ) @@ -41,7 +42,9 @@ contract DeployIonBoringVaultScript is BaseScript { // Post Deploy Checks require(boringVault.owner() == broadcaster, "owner should be the deployer"); require(address(boringVault.hook()) == address(0), "before transfer hook should be zero"); - + require( + boringVault.decimals() == ERC20(config.base).decimals(), "boringVault decimals should be the same as base" + ); return address(boringVault); } } diff --git a/script/deploy/single/04_DeployAccountantWithRateProviders.s.sol b/script/deploy/single/04_DeployAccountantWithRateProviders.s.sol index 2b5325e..90ae876 100644 --- a/script/deploy/single/04_DeployAccountantWithRateProviders.s.sol +++ b/script/deploy/single/04_DeployAccountantWithRateProviders.s.sol @@ -30,7 +30,10 @@ contract DeployAccountantWithRateProviders is BaseScript { require(config.allowedExchangeRateChangeLower >= 0.997e4, "allowedExchangeRateChangeLower lower bound"); require(config.minimumUpdateDelayInSeconds >= 3600, "minimumUpdateDelayInSeconds"); require(config.managementFee < 1e4, "managementFee"); - require(startingExchangeRate == 1e18, "starting exchange rate must be 1e18"); + require( + startingExchangeRate == 10 ** config.boringVaultAndBaseDecimals, + "starting exchange rate must be equal to the boringVault and base decimals" + ); } // Create Contract bytes memory creationCode = type(AccountantWithRateProviders).creationCode; diff --git a/script/deploy/single/06_DeployRolesAuthority.s.sol b/script/deploy/single/06_DeployRolesAuthority.s.sol index 09604d9..b2a2352 100644 --- a/script/deploy/single/06_DeployRolesAuthority.s.sol +++ b/script/deploy/single/06_DeployRolesAuthority.s.sol @@ -11,17 +11,18 @@ import { ConfigReader } from "../../ConfigReader.s.sol"; import { CrossChainTellerBase } from "../../../src/base/Roles/CrossChain/CrossChainTellerBase.sol"; import { stdJson as StdJson } from "@forge-std/StdJson.sol"; +uint8 constant STRATEGIST_ROLE = 1; +uint8 constant MANAGER_ROLE = 2; +uint8 constant TELLER_ROLE = 3; +uint8 constant UPDATE_EXCHANGE_RATE_ROLE = 4; +uint8 constant SOLVER_ROLE = 5; + /** * NOTE Deploys with `Authority` set to zero bytes. */ contract DeployRolesAuthority is BaseScript { using StdJson for string; - uint8 public constant STRATEGIST_ROLE = 1; - uint8 public constant MANAGER_ROLE = 2; - uint8 public constant TELLER_ROLE = 3; - uint8 public constant UPDATE_EXCHANGE_RATE_ROLE = 4; - function run() public virtual returns (address rolesAuthority) { return deploy(getConfig()); } diff --git a/script/deploy/upgrade/CheckTellerUpgrade.s.sol b/script/deploy/upgrade/CheckTellerUpgrade.s.sol new file mode 100644 index 0000000..a5ce8bb --- /dev/null +++ b/script/deploy/upgrade/CheckTellerUpgrade.s.sol @@ -0,0 +1,111 @@ +import { BaseScript } from "../../Base.s.sol"; +import { TELLER_ROLE, SOLVER_ROLE } from "../single/06_DeployRolesAuthority.s.sol"; + +import { TellerWithMultiAssetSupport } from "../../../src/base/Roles/TellerWithMultiAssetSupport.sol"; +import { CrossChainTellerBase } from "../../../src/base/Roles/CrossChain/CrossChainTellerBase.sol"; + +import { RolesAuthority } from "@solmate/auth/authorities/RolesAuthority.sol"; + +// forge script script/deploy/ --sig run(address, address) --rpc-url +contract CheckTellerUpgrade is BaseScript { + function run(address oldTeller, address newTeller) public { + require(oldTeller != address(0)); + require(newTeller != address(0)); + + TellerWithMultiAssetSupport typedOldTeller = TellerWithMultiAssetSupport(oldTeller); + TellerWithMultiAssetSupport typedNewTeller = TellerWithMultiAssetSupport(newTeller); + + RolesAuthority authority = RolesAuthority(address(typedOldTeller.authority())); + + require(authority == typedNewTeller.authority()); + require(typedOldTeller.vault() == typedNewTeller.vault()); + require(typedOldTeller.accountant() == typedNewTeller.accountant()); + + // --- Old Teller Must Be Disabled --- + + // Public capabilities. + + // functions that were previously public + require( + !authority.isCapabilityPublic(oldTeller, TellerWithMultiAssetSupport.deposit.selector), + "oldTeller deposit must not be public" + ); + require( + !authority.isCapabilityPublic(oldTeller, CrossChainTellerBase.bridge.selector), + "oldTeller bridge must not be public" + ); + require( + !authority.isCapabilityPublic(oldTeller, CrossChainTellerBase.depositAndBridge.selector), + "oldTeller depositAndBridge must not be public" + ); + + // functions that should never be public + require( + !authority.isCapabilityPublic(oldTeller, TellerWithMultiAssetSupport.refundDeposit.selector), + "oldTeller refundDeposit must not be public" + ); + require( + !authority.isCapabilityPublic(oldTeller, TellerWithMultiAssetSupport.depositWithPermit.selector), + "oldTeller depositWithPermit must not be public" + ); + require( + !authority.isCapabilityPublic(oldTeller, TellerWithMultiAssetSupport.bulkDeposit.selector), + "oldTeller bulkDeposit must not be public" + ); + require( + !authority.isCapabilityPublic(oldTeller, TellerWithMultiAssetSupport.bulkWithdraw.selector), + "oldTeller bulkWithdraw must not be public" + ); + + require(typedOldTeller.isPaused(), "oldTeller must be paused"); + + // roles + require(!authority.doesUserHaveRole(oldTeller, TELLER_ROLE), "oldTeller must not have the TELLER_ROLE"); + require( + !authority.doesRoleHaveCapability(SOLVER_ROLE, oldTeller, TellerWithMultiAssetSupport.bulkWithdraw.selector), + "SOLVER_ROLE must not be able to call oldTeller's bulkWithdraw" + ); + + // --- New Teller Must Be Enabled--- + // Public capabilities. + require( + authority.isCapabilityPublic(newTeller, TellerWithMultiAssetSupport.deposit.selector), + "newTeller deposit must be public" + ); + require( + authority.isCapabilityPublic(newTeller, CrossChainTellerBase.bridge.selector), + "newTeller bridge must be public" + ); + require( + authority.isCapabilityPublic(newTeller, CrossChainTellerBase.depositAndBridge.selector), + "newTeller depositAndBridge must be public" + ); + + // functions that should never be public + require( + !authority.isCapabilityPublic(newTeller, TellerWithMultiAssetSupport.refundDeposit.selector), + "newTeller refundDeposit must not be public" + ); + require( + !authority.isCapabilityPublic(newTeller, TellerWithMultiAssetSupport.depositWithPermit.selector), + "newTeller depositWithPermit must not be public" + ); + require( + !authority.isCapabilityPublic(newTeller, TellerWithMultiAssetSupport.bulkDeposit.selector), + "newTeller bulkDeposit must not be public" + ); + require( + !authority.isCapabilityPublic(newTeller, TellerWithMultiAssetSupport.bulkWithdraw.selector), + "newTeller bulkWithdraw must not be public" + ); + + require(!typedNewTeller.isPaused(), "newTeller must not be paused"); + + // roles + require(authority.doesUserHaveRole(newTeller, TELLER_ROLE), "newTeller must have the TELLER_ROLE"); + require( + authority.doesRoleHaveCapability(SOLVER_ROLE, newTeller, TellerWithMultiAssetSupport.bulkWithdraw.selector), + "SOLVER_ROLE must be able to call newTeller's bulkWithdraw" + ); + } +} diff --git a/src/helper/Constants.sol b/src/helper/Constants.sol index 9cd9048..17cc9cc 100644 --- a/src/helper/Constants.sol +++ b/src/helper/Constants.sol @@ -8,3 +8,6 @@ IPriceFeed constant ETH_PER_EZETH_CHAINLINK = IPriceFeed(0x636A000262F6aA9e1F094 IPriceFeed constant ETH_PER_RSETH_CHAINLINK = IPriceFeed(0x03c68933f7a3F76875C0bc670a58e69294cDFD01); IPriceFeed constant ETH_PER_RSWETH_CHAINLINK = IPriceFeed(0xb613CfebD0b6e95abDDe02677d6bC42394FdB857); IPriceFeed constant ETH_PER_PUFETH_REDSTONE = IPriceFeed(0x76A495b0bFfb53ef3F0E94ef0763e03cE410835C); + +address constant SWBTC = 0x8DB2350D78aBc13f5673A411D4700BCF87864dDE; +address constant WBTC_ETHEREUM = 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599; diff --git a/src/helper/GenericRateProvider.sol b/src/helper/GenericRateProvider.sol index 8f4a9e6..4e8d8da 100644 --- a/src/helper/GenericRateProvider.sol +++ b/src/helper/GenericRateProvider.sol @@ -32,7 +32,7 @@ contract GenericRateProvider is IRateProvider { constructor( address _target, - bytes4 _selctor, + bytes4 _selector, bytes32 _staticArgument0, bytes32 _staticArgument1, bytes32 _staticArgument2, @@ -43,7 +43,7 @@ contract GenericRateProvider is IRateProvider { bytes32 _staticArgument7 ) { target = _target; - selector = _selctor; + selector = _selector; staticArgument0 = _staticArgument0; staticArgument1 = _staticArgument1; staticArgument2 = _staticArgument2; diff --git a/test/CrossChain/CrossChainOPTellerWithMultiAssetSupport.t.sol b/test/CrossChain/CrossChainOPTellerWithMultiAssetSupport.t.sol index d4e5224..9dface7 100644 --- a/test/CrossChain/CrossChainOPTellerWithMultiAssetSupport.t.sol +++ b/test/CrossChain/CrossChainOPTellerWithMultiAssetSupport.t.sol @@ -88,6 +88,35 @@ contract CrossChainOPTellerWithMultiAssetSupportTest is CrossChainBaseTest { assertEq(boringVault.balanceOf(address(this)), balBefore - sharesToBridge, "Should have burned shares."); } + function testUniqueIDs() public virtual { + CrossChainOPTellerWithMultiAssetSupport sourceTeller = CrossChainOPTellerWithMultiAssetSupport(sourceTellerAddr); + CrossChainOPTellerWithMultiAssetSupport destinationTeller = + CrossChainOPTellerWithMultiAssetSupport(destinationTellerAddr); + + uint256 sharesToBridge = 12; + + // Bridge shares. + address to = vm.addr(1); + + BridgeData memory data = BridgeData({ + chainSelector: DESTINATION_SELECTOR, + destinationChainReceiver: to, + bridgeFeeToken: WETH, + messageGas: 80_000, + data: "" + }); + + uint256 quote = 0; + + uint256 balBefore = boringVault.balanceOf(address(this)); + bytes32 id1 = sourceTeller.bridge{ value: quote }(sharesToBridge, data); + + // perform the exact same bridge again and assert the ids are not the same + bytes32 id2 = sourceTeller.bridge{ value: quote }(sharesToBridge, data); + + assertNotEq(id1, id2, "Id's must be unique"); + } + function testDepositAndBridge(uint256 amount) external { CrossChainOPTellerWithMultiAssetSupport sourceTeller = CrossChainOPTellerWithMultiAssetSupport(sourceTellerAddr); CrossChainOPTellerWithMultiAssetSupport destinationTeller = diff --git a/test/ion/oracles/GenericRateProvider.t.sol b/test/ion/oracles/GenericRateProvider.t.sol new file mode 100644 index 0000000..0ddb4a0 --- /dev/null +++ b/test/ion/oracles/GenericRateProvider.t.sol @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import { GenericRateProvider } from "./../../../src/helper/GenericRateProvider.sol"; +import { SWBTC } from "./../../../src/helper/Constants.sol"; + +import "forge-std/Test.sol"; + +abstract contract GenericRateProviderTest is Test { + GenericRateProvider rateProvider; + address target; + bytes4 selector; + bytes32 staticArgument0; + bytes32 staticArgument1; + bytes32 staticArgument2; + bytes32 staticArgument3; + + uint8 decimals; + + function setUp() public virtual { + vm.createSelectFork(vm.envString(_getRpcUrl())); + + _initialize(); + + assertNotEq(address(rateProvider), address(0), "rate provider not set"); + assertGt(decimals, 0, "decimals not set"); + assertNotEq(target, address(0), "target not set"); + assertGt(bytes4(selector).length, 0, "selector not set"); + } + + function test_GetRateWithinExpectedBounds() public { + uint256 rate = rateProvider.getRate(); + (uint256 min, uint256 max) = _expectedRateMinMax(); + + assertGe(rate, min, "rate must be greater than or equal to min"); + assertLe(rate, max, "rate must be less than or equal to max"); + } + + function _initialize() public virtual; + + function _expectedRateMinMax() public virtual returns (uint256, uint256); + + function _getRpcUrl() public pure virtual returns (string memory); +} + +contract SwBtcRateProviderTest is GenericRateProviderTest { + function _initialize() public override { + target = SWBTC; + selector = bytes4(keccak256("pricePerShare()")); + decimals = 8; + staticArgument0 = bytes32(uint256(123)); + + rateProvider = new GenericRateProvider(target, selector, staticArgument0, 0, 0, 0, 0, 0, 0, 0); + } + + function _expectedRateMinMax() public view override returns (uint256 min, uint256 max) { + min = 1 * 10 ** decimals; + max = 1 * 10 ** decimals; + } + + function _getRpcUrl() public pure override returns (string memory) { + return "MAINNET_RPC_URL"; + } +}