diff --git a/config/chain138-pmm-pools.json b/config/chain138-pmm-pools.json new file mode 100644 index 0000000..0266160 --- /dev/null +++ b/config/chain138-pmm-pools.json @@ -0,0 +1,58 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "Desired-state pool spec for Chain 138 DODO PMM. Scripts should create and register only missing pools from this file, not redeploy contracts.", + "version": "1.0.0", + "updated": "2026-03-26", + "chainId": 138, + "defaults": { + "lpFeeRate": 3, + "initialPrice": "1000000000000000000", + "kFactor": "500000000000000000", + "enableTwap": false + }, + "tokens": { + "cUSDT": "0x93E66202A11B1772E55407B32B44e5Cd8eda7f22", + "cUSDC": "0xf22258f57794CC8E06237084b353Ab30fFfa640b", + "cEURC": "0x8085961F9cF02b4d800A3c6d386D31da4B34266a", + "cEURT": "0xdf4b71c61E5912712C1Bdd451416B9aC26949d72", + "cGBPC": "0x003960f16D9d34F2e98d62723B6721Fb92074aD2", + "cGBPT": "0x350f54e4D23795f86A9c03988c7135357CCaD97c", + "cAUDC": "0xD51482e567c03899eecE3CAe8a058161FD56069D", + "cJPYC": "0xEe269e1226a334182aace90056EE4ee5Cc8A6770", + "cCHFC": "0x873990849DDa5117d7C644f0aF24370797C03885", + "cCADC": "0x54dBd40cF05e15906A2C21f600937e96787f5679", + "cXAUC": "0x290E52a8819A4fbD0714E517225429aA2B70EC6b", + "cXAUT": "0x94e408E26c6FD8F4ee00b54dF19082FDA07dC96E", + "USDT": "0x004b63A7B5b0E06f6bB6adb4a5F9f590BF3182D1", + "USDC": "0x71D6687F38b93CCad569Fa6352c876eea967201b", + "WETH": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" + }, + "groups": { + "cStarSymbols": [ + "cUSDT", + "cUSDC", + "cEURC", + "cEURT", + "cGBPC", + "cGBPT", + "cAUDC", + "cJPYC", + "cCHFC", + "cCADC", + "cXAUC", + "cXAUT" + ], + "officialStableSymbols": [ + "USDT", + "USDC" + ], + "wethSymbol": "WETH", + "deploy": { + "cStarVsCStar": true, + "cStarVsOfficial": true, + "cStarVsWeth": true, + "officialVsWeth": true + } + }, + "explicitPairs": [] +} diff --git a/config/genesis-template-for-operator.json b/config/genesis-template-for-operator.json index ebaa5ff..9357b77 100644 --- a/config/genesis-template-for-operator.json +++ b/config/genesis-template-for-operator.json @@ -39,7 +39,8 @@ }, "0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f": { "balance": "0x0", - "code": "0x6080604052600436106101b05760003560e01c806370a08231116100ec578063b760faf91161008a578063d0e30db011610064578063d0e30db01461087b578063d505accf14610883578063d9d98ce4146108ee578063dd62ed3e1461093457610202565b8063b760faf914610794578063cae9ca51146107c7578063cd0d00961461086657610202565b80638b28d32f116100c65780638b28d32f146106d45780639555a942146106e957806395d89b4114610739578063a9059cbb1461074e57610202565b806370a082311461063f5780637ecebe001461067f5780638237e538146106bf57610202565b806330adf81f116101595780634000aea0116101335780634000aea0146104295780635cffe9de146104c85780635ddb7d7e14610572578063613255ab146105ff57610202565b806330adf81f146103d4578063313ce567146103e95780633644e5151461041457610202565b8063205c28781161018a578063205c28781461031257806323b872dd1461035a5780632e1a7d4d146103aa57610202565b806306fdde0314610207578063095ea7b31461029157806318160ddd146102eb57610202565b366102025733600081815260208181526040808320805434908101909155815190815290517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3005b600080fd5b34801561021357600080fd5b5061021c61097c565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561025657818101518382015260200161023e565b50505050905090810190601f1680156102835780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561029d57600080fd5b506102d7600480360360408110156102b457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356109b5565b604080519115158252519081900360200190f35b3480156102f757600080fd5b50610300610a28565b60408051918252519081900360200190f35b34801561031e57600080fd5b506103586004803603604081101561033557600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610a30565b005b34801561036657600080fd5b506102d76004803603606081101561037d57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610b82565b3480156103b657600080fd5b50610358600480360360208110156103cd57600080fd5b5035610f24565b3480156103e057600080fd5b5061030061105f565b3480156103f557600080fd5b506103fe611083565b6040805160ff9092168252519081900360200190f35b34801561042057600080fd5b50610300611088565b34801561043557600080fd5b506102d76004803603606081101561044c57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8235169160208101359181019060608101604082013564010000000081111561048957600080fd5b82018360208201111561049b57600080fd5b803590602001918460018302840111640100000000831117156104bd57600080fd5b5090925090506110e8565b3480156104d457600080fd5b506102d7600480360360808110156104eb57600080fd5b73ffffffffffffffffffffffffffffffffffffffff82358116926020810135909116916040820135919081019060808101606082013564010000000081111561053357600080fd5b82018360208201111561054557600080fd5b8035906020019184600183028401116401000000008311171561056757600080fd5b5090925090506113dc565b6102d76004803603604081101561058857600080fd5b73ffffffffffffffffffffffffffffffffffffffff82351691908101906040810160208201356401000000008111156105c057600080fd5b8201836020820111156105d257600080fd5b803590602001918460018302840111640100000000831117156105f457600080fd5b5090925090506118c1565b34801561060b57600080fd5b506103006004803603602081101561062257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611a02565b34801561064b57600080fd5b506103006004803603602081101561066257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611a42565b34801561068b57600080fd5b50610300600480360360208110156106a257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611a54565b3480156106cb57600080fd5b50610300611a66565b3480156106e057600080fd5b50610300611a8a565b3480156106f557600080fd5b506103586004803603606081101561070c57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135611a90565b34801561074557600080fd5b5061021c611d49565b34801561075a57600080fd5b506102d76004803603604081101561077157600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135611d82565b610358600480360360208110156107aa57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611fa5565b3480156107d357600080fd5b506102d7600480360360608110156107ea57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8235169160208101359181019060608101604082013564010000000081111561082757600080fd5b82018360208201111561083957600080fd5b8035906020019184600183028401116401000000008311171561085b57600080fd5b509092509050612009565b34801561087257600080fd5b50610300612117565b61035861213b565b34801561088f57600080fd5b50610358600480360360e08110156108a657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c00135612188565b3480156108fa57600080fd5b506103006004803603604081101561091157600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356124c3565b34801561094057600080fd5b506103006004803603604081101561095757600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516612538565b6040518060400160405280601181526020017f577261707065642045746865722076313000000000000000000000000000000081525081565b33600081815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b600354470190565b3360009081526020819052604090205481811015610a7f5760405162461bcd60e51b81526004018080602001828103825260218152602001806126a16021913960400191505060405180910390fd5b336000818152602081815260408083208686039055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a360405160009073ffffffffffffffffffffffffffffffffffffffff85169084908381818185875af1925050503d8060008114610b21576040519150601f19603f3d011682016040523d82523d6000602084013e610b26565b606091505b5050905080610b7c576040805162461bcd60e51b815260206004820152601960248201527f574554483a20455448207472616e73666572206661696c656400000000000000604482015290519081900360640190fd5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff84163314610cbe5773ffffffffffffffffffffffffffffffffffffffff841660009081526002602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610cbc5782811015610c4e576040805162461bcd60e51b815260206004820152601f60248201527f574554483a2072657175657374206578636565647320616c6c6f77616e636500604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff85166000818152600260209081526040808320338085529083529281902087860390819055815181815291519094927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a3505b505b73ffffffffffffffffffffffffffffffffffffffff831615610db55773ffffffffffffffffffffffffffffffffffffffff841660009081526020819052604090205482811015610d3f5760405162461bcd60e51b81526004018080602001828103825260258152602001806126586025913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8086166000818152602081815260408083208887039055938816808352918490208054880190558351878152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a350610f1a565b73ffffffffffffffffffffffffffffffffffffffff841660009081526020819052604090205482811015610e1a5760405162461bcd60e51b81526004018080602001828103825260218152602001806126a16021913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff85166000818152602081815260408083208786039055805187815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3604051600090339085908381818185875af1925050503d8060008114610ebc576040519150601f19603f3d011682016040523d82523d6000602084013e610ec1565b606091505b5050905080610f17576040805162461bcd60e51b815260206004820152601960248201527f574554483a20455448207472616e73666572206661696c656400000000000000604482015290519081900360640190fd5b50505b5060019392505050565b3360009081526020819052604090205481811015610f735760405162461bcd60e51b81526004018080602001828103825260218152602001806126a16021913960400191505060405180910390fd5b336000818152602081815260408083208686039055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3604051600090339084908381818185875af1925050503d8060008114610fff576040519150601f19603f3d011682016040523d82523d6000602084013e611004565b606091505b505090508061105a576040805162461bcd60e51b815260206004820152601960248201527f574554483a20455448207472616e73666572206661696c656400000000000000604482015290519081900360640190fd5b505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601281565b6000467f000000000000000000000000000000000000000000000000000000000000000181146110c0576110bb81612555565b6110e2565b7f9d6861d4de8c156e6b3155e3283174a7c6c86fd27c1ff43e1f05cc2d417fbb655b91505090565b600073ffffffffffffffffffffffffffffffffffffffff8516156111c95733600090815260208190526040902054848110156111555760405162461bcd60e51b81526004018080602001828103825260258152602001806126586025913960400191505060405180910390fd5b33600081815260208181526040808320898603905573ffffffffffffffffffffffffffffffffffffffff8a168084529281902080548a019055805189815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a350611302565b33600090815260208190526040902054848110156112185760405162461bcd60e51b81526004018080602001828103825260218152602001806126a16021913960400191505060405180910390fd5b336000818152602081815260408083208986039055805189815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3604051600090339087908381818185875af1925050503d80600081146112a4576040519150601f19603f3d011682016040523d82523d6000602084013e6112a9565b606091505b50509050806112ff576040805162461bcd60e51b815260206004820152601960248201527f574554483a20455448207472616e73666572206661696c656400000000000000604482015290519081900360640190fd5b50505b8473ffffffffffffffffffffffffffffffffffffffff1663a4c0ed36338686866040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050602060405180830381600087803b1580156113a757600080fd5b505af11580156113bb573d6000803e3d6000fd5b505050506040513d60208110156113d157600080fd5b505195945050505050565b600073ffffffffffffffffffffffffffffffffffffffff85163014611448576040805162461bcd60e51b815260206004820152601c60248201527f574554483a20666c617368206d696e74206f6e6c792057455448313000000000604482015290519081900360640190fd5b6dffffffffffffffffffffffffffff8411156114955760405162461bcd60e51b815260040180806020018281038252602481526020018061267d6024913960400191505060405180910390fd5b600380548501908190556dffffffffffffffffffffffffffff1015611501576040805162461bcd60e51b815260206004820152601f60248201527f574554483a20746f74616c206c6f616e206c696d697420657863656564656400604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8616600081815260208181526040808320805489019055805188815290517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a37f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd98673ffffffffffffffffffffffffffffffffffffffff166323e30c8b333088600089896040518763ffffffff1660e01b8152600401808773ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff168152602001858152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050975050505050505050602060405180830381600087803b15801561164c57600080fd5b505af1158015611660573d6000803e3d6000fd5b505050506040513d602081101561167657600080fd5b5051146116ca576040805162461bcd60e51b815260206004820152601760248201527f574554483a20666c617368206c6f616e206661696c6564000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff861660009081526002602090815260408083203084529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146117e55784811015611777576040805162461bcd60e51b815260206004820152601f60248201527f574554483a2072657175657374206578636565647320616c6c6f77616e636500604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff87166000818152600260209081526040808320308085529083529281902089860390819055815181815291519094927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a3505b73ffffffffffffffffffffffffffffffffffffffff87166000908152602081905260409020548581101561184a5760405162461bcd60e51b81526004018080602001828103825260218152602001806126a16021913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff88166000818152602081815260408083208a8603905580518a815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3505060038054859003905550600195945050505050565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208054349081019091558151908152905192939284927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef928290030190a36040517fa4c0ed36000000000000000000000000000000000000000000000000000000008152336004820181815234602484018190526060604485019081526064850187905273ffffffffffffffffffffffffffffffffffffffff89169463a4c0ed36949389928992608401848480828437600081840152601f19601f82011690508083019250505095505050505050602060405180830381600087803b1580156119ce57600080fd5b505af11580156119e2573d6000803e3d6000fd5b505050506040513d60208110156119f857600080fd5b5051949350505050565b600073ffffffffffffffffffffffffffffffffffffffff82163014611a28576000611a3c565b6003546dffffffffffffffffffffffffffff035b92915050565b60006020819052908152604090205481565b60016020526000908152604090205481565b7f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd981565b60035481565b73ffffffffffffffffffffffffffffffffffffffff83163314611bca5773ffffffffffffffffffffffffffffffffffffffff831660009081526002602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611bc85781811015611b5a576040805162461bcd60e51b815260206004820152601f60248201527f574554483a2072657175657374206578636565647320616c6c6f77616e636500604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff84166000818152600260209081526040808320338085529083529281902086860390819055815181815291519094927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a3505b505b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015611c2f5760405162461bcd60e51b81526004018080602001828103825260218152602001806126a16021913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff84166000818152602081815260408083208686039055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a360405160009073ffffffffffffffffffffffffffffffffffffffff85169084908381818185875af1925050503d8060008114611ce7576040519150601f19603f3d011682016040523d82523d6000602084013e611cec565b606091505b5050905080611d42576040805162461bcd60e51b815260206004820152601b60248201527f574554483a204574686572207472616e73666572206661696c65640000000000604482015290519081900360640190fd5b5050505050565b6040518060400160405280600681526020017f574554483130000000000000000000000000000000000000000000000000000081525081565b600073ffffffffffffffffffffffffffffffffffffffff831615611e63573360009081526020819052604090205482811015611def5760405162461bcd60e51b81526004018080602001828103825260258152602001806126586025913960400191505060405180910390fd5b33600081815260208181526040808320878603905573ffffffffffffffffffffffffffffffffffffffff881680845292819020805488019055805187815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a350611f9c565b3360009081526020819052604090205482811015611eb25760405162461bcd60e51b81526004018080602001828103825260218152602001806126a16021913960400191505060405180910390fd5b336000818152602081815260408083208786039055805187815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3604051600090339085908381818185875af1925050503d8060008114611f3e576040519150601f19603f3d011682016040523d82523d6000602084013e611f43565b606091505b5050905080611f99576040805162461bcd60e51b815260206004820152601960248201527f574554483a20455448207472616e73666572206661696c656400000000000000604482015290519081900360640190fd5b50505b50600192915050565b73ffffffffffffffffffffffffffffffffffffffff8116600081815260208181526040808320805434908101909155815190815290517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a350565b33600081815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8916808552908352818420889055815188815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a38473ffffffffffffffffffffffffffffffffffffffff1662ba451f338686866040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050602060405180830381600087803b1580156113a757600080fd5b7f000000000000000000000000000000000000000000000000000000000000000181565b33600081815260208181526040808320805434908101909155815190815290517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3565b834211156121dd576040805162461bcd60e51b815260206004820152601460248201527f574554483a2045787069726564207065726d6974000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff80881660008181526001602081815260408084208054938401905580517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280820195909552948b166060850152608084018a905260a084019190915260c08084018990528451808503909101815260e09093019093528151919092012046917f000000000000000000000000000000000000000000000000000000000000000183146122aa576122a583612555565b6122cc565b7f9d6861d4de8c156e6b3155e3283174a7c6c86fd27c1ff43e1f05cc2d417fbb655b8260405160200180807f190100000000000000000000000000000000000000000000000000000000000081525060020183815260200182815260200192505050604051602081830303815290604052805190602001209050600060018288888860405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015612380573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116158015906123fb57508a73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b61244c576040805162461bcd60e51b815260206004820152601460248201527f574554483a20696e76616c6964207065726d6974000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff808c166000818152600260209081526040808320948f16808452948252918290208d905581518d815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a35050505050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff8316301461252f576040805162461bcd60e51b815260206004820152601c60248201527f574554483a20666c617368206d696e74206f6e6c792057455448313000000000604482015290519081900360640190fd5b50600092915050565b600260209081526000928352604080842090915290825290205481565b604080518082018252601181527f577261707065642045746865722076313000000000000000000000000000000060209182015281518083018352600181527f31000000000000000000000000000000000000000000000000000000000000009082015281517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818301527f5afefa023603a382ac22bd36644e004cefabbfaf61d4180000d8dc2b10c168b8818401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6606082015260808101939093523060a0808501919091528251808503909101815260c090930190915281519101209056fe574554483a207472616e7366657220616d6f756e7420657863656564732062616c616e6365574554483a20696e646976696475616c206c6f616e206c696d6974206578636565646564574554483a206275726e20616d6f756e7420657863656564732062616c616e6365a264697066735822122010a2e85d28f3cbb1bab01194294eeaad30a52826e3d85bf4b42223cb2b05e6a164736f6c63430007060033" + "code": "0x6080806040526004361015610025575b50361561001b57600080fd5b6100236108bd565b005b60003560e01c90816306fdde03146107c557508063095ea7b31461074c57806318160ddd1461073057806323b872dd146107015780632e1a7d4d14610668578063313ce5671461064c5780635cffe9de146102c4578063613255ab1461028757806370a082311461024d57806375d9ad1b1461021257806395d89b41146101d15780639d649e66146101b5578063a9059cbb14610183578063d0e30db01461016f578063d9d98ce4146101385763dd62ed3e146100e2573861000f565b34610133576040366003190112610133576100fb61086e565b610103610884565b9060018060a01b038091166000526001602052604060002091166000526020526020604060002054604051908152f35b600080fd5b346101335760403660031901126101335761016461015461086e565b6001600160a01b03163014610aa0565b602060405160008152f35b6000366003190112610133576100236108bd565b346101335760403660031901126101335760206101ab6101a161086e565b602435903361095f565b6040519015158152f35b3461013357600036600319011261013357602060405160008152f35b346101335760003660031901126101335761020e6040516101f181610809565b60048152630ae8aa8960e31b602082015260405191829182610825565b0390f35b346101335760003660031901126101335760206040517f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd98152f35b34610133576020366003190112610133576001600160a01b0361026e61086e565b1660005260006020526020604060002054604051908152f35b34610133576020366003190112610133576102a061086e565b6001600160a01b031630036102bb576020475b604051908152f35b602060006102b3565b34610133576080366003190112610133576001600160a01b036004358181168103610133576102f1610884565b67ffffffffffffffff60643511610133573660236064350112156101335767ffffffffffffffff60643560040135116101335736602460643560040135606435010111610133576103453084831614610aa0565b6044351561060e5760443547106105c95782821660005260006020526040600020610373604435825461089a565b905560405160443581526000600080516020610aed833981519152602086861693a382604051916323e30c8b60e01b835233600484015216602482015260443560448201526000606482015260a060848201526064356004013560a48201526064356004013560246064350160c4830137600060c46064356004013583010152601f1960208260c48184601f606435600401350116810103018160008888165af19081156105bd57600091610540575b507f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd99150036104f0578181166000526000602052604435604060002054106104ab57600080516020610aed83398151915260208360009484168552848252604085206104926044358254610952565b90556040519360443585521692a3602060405160018152f35b60405162461bcd60e51b815260206004820152601e60248201527f5745544831303a20696e73756666696369656e742072657061796d656e7400006044820152606490fd5b60405162461bcd60e51b815260206004820152602260248201527f5745544831303a20666c617368206c6f616e2063616c6c6261636b206661696c604482015261195960f21b6064820152608490fd5b602091503d82116105b5575b601f820116820182811067ffffffffffffffff82111761059f57602091839160405281010312610133577f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd9905184610423565b634e487b7160e01b600052604160045260246000fd5b3d915061054c565b6040513d6000823e3d90fd5b60405162461bcd60e51b815260206004820152601e60248201527f5745544831303a20696e73756666696369656e74206c697175696469747900006044820152606490fd5b60405162461bcd60e51b815260206004820152601660248201527515d155120c4c0e881a5b9d985b1a5908185b5bdd5b9d60521b6044820152606490fd5b3461013357600036600319011261013357602060405160128152f35b3461013357602036600319011261013357600435336000526000602052610696816040600020541015610906565b33600052600060205260406000206106af828254610952565b905580600081156106f8575b600080809381933390f1156105bd576040519081527f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b6560203392a2005b506108fc6106bb565b346101335760603660031901126101335760206101ab61071f61086e565b610727610884565b6044359161095f565b3461013357600036600319011261013357602047604051908152f35b346101335760403660031901126101335761076561086e565b60243533600052600160205260406000209160018060a01b03169182600052602052806040600020556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3602060405160018152f35b3461013357600036600319011261013357806107e361020e92610809565b600d81526c2bb930b83832b21022ba3432b960991b602082015260405191829182610825565b6040810190811067ffffffffffffffff82111761059f57604052565b6020808252825181830181905290939260005b82811061085a57505060409293506000838284010152601f8019910116010190565b818101860151848201604001528501610838565b600435906001600160a01b038216820361013357565b602435906001600160a01b038216820361013357565b919082018092116108a757565b634e487b7160e01b600052601160045260246000fd5b33600052600060205260406000206108d634825461089a565b90556040513481527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c60203392a2565b1561090d57565b60405162461bcd60e51b815260206004820152601c60248201527f5745544831303a20696e73756666696369656e742062616c616e6365000000006044820152606490fd5b919082039182116108a757565b91909160018060a01b038091169160009383855260209285845260409161098b84848920541015610906565b3386141580610a82575b6109e5575b918091600080516020610aed8339815191529594938789528886528289206109c3868254610952565b90551696878152808552206109d983825461089a565b905551908152a3600190565b858752600185528287203388528552838388205410610a3e57918091600080516020610aed83398151915295949387895260018652828920338a528652828920610a30868254610952565b90559150919293945061099a565b825162461bcd60e51b815260048101869052601e60248201527f5745544831303a20696e73756666696369656e7420616c6c6f77616e636500006044820152606490fd5b50858752600185528287203388528552828720546000191415610995565b15610aa757565b60405162461bcd60e51b815260206004820152601960248201527f5745544831303a20756e737570706f7274656420746f6b656e000000000000006044820152606490fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212207c34c26feecd05ff838fc85995144621f090e1740fb2223f2f4e272503c4754564736f6c63430008140033", + "storage": {} }, "0xe76e1436e855d808db6c2fa80976d0a8feb15e50": { "balance": "0x130ee8e7179044000000" @@ -157,4 +158,4 @@ "count": 5 } } -} \ No newline at end of file +} diff --git a/config/genesis.json b/config/genesis.json index 7588071..868918a 100644 --- a/config/genesis.json +++ b/config/genesis.json @@ -40,7 +40,8 @@ }, "0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f": { "balance": "0x0", - "code": "0x6080604052600436106101b05760003560e01c806370a08231116100ec578063b760faf91161008a578063d0e30db011610064578063d0e30db01461087b578063d505accf14610883578063d9d98ce4146108ee578063dd62ed3e1461093457610202565b8063b760faf914610794578063cae9ca51146107c7578063cd0d00961461086657610202565b80638b28d32f116100c65780638b28d32f146106d45780639555a942146106e957806395d89b4114610739578063a9059cbb1461074e57610202565b806370a082311461063f5780637ecebe001461067f5780638237e538146106bf57610202565b806330adf81f116101595780634000aea0116101335780634000aea0146104295780635cffe9de146104c85780635ddb7d7e14610572578063613255ab146105ff57610202565b806330adf81f146103d4578063313ce567146103e95780633644e5151461041457610202565b8063205c28781161018a578063205c28781461031257806323b872dd1461035a5780632e1a7d4d146103aa57610202565b806306fdde0314610207578063095ea7b31461029157806318160ddd146102eb57610202565b366102025733600081815260208181526040808320805434908101909155815190815290517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3005b600080fd5b34801561021357600080fd5b5061021c61097c565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561025657818101518382015260200161023e565b50505050905090810190601f1680156102835780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561029d57600080fd5b506102d7600480360360408110156102b457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356109b5565b604080519115158252519081900360200190f35b3480156102f757600080fd5b50610300610a28565b60408051918252519081900360200190f35b34801561031e57600080fd5b506103586004803603604081101561033557600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610a30565b005b34801561036657600080fd5b506102d76004803603606081101561037d57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610b82565b3480156103b657600080fd5b50610358600480360360208110156103cd57600080fd5b5035610f24565b3480156103e057600080fd5b5061030061105f565b3480156103f557600080fd5b506103fe611083565b6040805160ff9092168252519081900360200190f35b34801561042057600080fd5b50610300611088565b34801561043557600080fd5b506102d76004803603606081101561044c57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8235169160208101359181019060608101604082013564010000000081111561048957600080fd5b82018360208201111561049b57600080fd5b803590602001918460018302840111640100000000831117156104bd57600080fd5b5090925090506110e8565b3480156104d457600080fd5b506102d7600480360360808110156104eb57600080fd5b73ffffffffffffffffffffffffffffffffffffffff82358116926020810135909116916040820135919081019060808101606082013564010000000081111561053357600080fd5b82018360208201111561054557600080fd5b8035906020019184600183028401116401000000008311171561056757600080fd5b5090925090506113dc565b6102d76004803603604081101561058857600080fd5b73ffffffffffffffffffffffffffffffffffffffff82351691908101906040810160208201356401000000008111156105c057600080fd5b8201836020820111156105d257600080fd5b803590602001918460018302840111640100000000831117156105f457600080fd5b5090925090506118c1565b34801561060b57600080fd5b506103006004803603602081101561062257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611a02565b34801561064b57600080fd5b506103006004803603602081101561066257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611a42565b34801561068b57600080fd5b50610300600480360360208110156106a257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611a54565b3480156106cb57600080fd5b50610300611a66565b3480156106e057600080fd5b50610300611a8a565b3480156106f557600080fd5b506103586004803603606081101561070c57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135611a90565b34801561074557600080fd5b5061021c611d49565b34801561075a57600080fd5b506102d76004803603604081101561077157600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135611d82565b610358600480360360208110156107aa57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611fa5565b3480156107d357600080fd5b506102d7600480360360608110156107ea57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8235169160208101359181019060608101604082013564010000000081111561082757600080fd5b82018360208201111561083957600080fd5b8035906020019184600183028401116401000000008311171561085b57600080fd5b509092509050612009565b34801561087257600080fd5b50610300612117565b61035861213b565b34801561088f57600080fd5b50610358600480360360e08110156108a657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c00135612188565b3480156108fa57600080fd5b506103006004803603604081101561091157600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356124c3565b34801561094057600080fd5b506103006004803603604081101561095757600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516612538565b6040518060400160405280601181526020017f577261707065642045746865722076313000000000000000000000000000000081525081565b33600081815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b600354470190565b3360009081526020819052604090205481811015610a7f5760405162461bcd60e51b81526004018080602001828103825260218152602001806126a16021913960400191505060405180910390fd5b336000818152602081815260408083208686039055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a360405160009073ffffffffffffffffffffffffffffffffffffffff85169084908381818185875af1925050503d8060008114610b21576040519150601f19603f3d011682016040523d82523d6000602084013e610b26565b606091505b5050905080610b7c576040805162461bcd60e51b815260206004820152601960248201527f574554483a20455448207472616e73666572206661696c656400000000000000604482015290519081900360640190fd5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff84163314610cbe5773ffffffffffffffffffffffffffffffffffffffff841660009081526002602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610cbc5782811015610c4e576040805162461bcd60e51b815260206004820152601f60248201527f574554483a2072657175657374206578636565647320616c6c6f77616e636500604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff85166000818152600260209081526040808320338085529083529281902087860390819055815181815291519094927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a3505b505b73ffffffffffffffffffffffffffffffffffffffff831615610db55773ffffffffffffffffffffffffffffffffffffffff841660009081526020819052604090205482811015610d3f5760405162461bcd60e51b81526004018080602001828103825260258152602001806126586025913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8086166000818152602081815260408083208887039055938816808352918490208054880190558351878152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a350610f1a565b73ffffffffffffffffffffffffffffffffffffffff841660009081526020819052604090205482811015610e1a5760405162461bcd60e51b81526004018080602001828103825260218152602001806126a16021913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff85166000818152602081815260408083208786039055805187815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3604051600090339085908381818185875af1925050503d8060008114610ebc576040519150601f19603f3d011682016040523d82523d6000602084013e610ec1565b606091505b5050905080610f17576040805162461bcd60e51b815260206004820152601960248201527f574554483a20455448207472616e73666572206661696c656400000000000000604482015290519081900360640190fd5b50505b5060019392505050565b3360009081526020819052604090205481811015610f735760405162461bcd60e51b81526004018080602001828103825260218152602001806126a16021913960400191505060405180910390fd5b336000818152602081815260408083208686039055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3604051600090339084908381818185875af1925050503d8060008114610fff576040519150601f19603f3d011682016040523d82523d6000602084013e611004565b606091505b505090508061105a576040805162461bcd60e51b815260206004820152601960248201527f574554483a20455448207472616e73666572206661696c656400000000000000604482015290519081900360640190fd5b505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601281565b6000467f000000000000000000000000000000000000000000000000000000000000000181146110c0576110bb81612555565b6110e2565b7f9d6861d4de8c156e6b3155e3283174a7c6c86fd27c1ff43e1f05cc2d417fbb655b91505090565b600073ffffffffffffffffffffffffffffffffffffffff8516156111c95733600090815260208190526040902054848110156111555760405162461bcd60e51b81526004018080602001828103825260258152602001806126586025913960400191505060405180910390fd5b33600081815260208181526040808320898603905573ffffffffffffffffffffffffffffffffffffffff8a168084529281902080548a019055805189815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a350611302565b33600090815260208190526040902054848110156112185760405162461bcd60e51b81526004018080602001828103825260218152602001806126a16021913960400191505060405180910390fd5b336000818152602081815260408083208986039055805189815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3604051600090339087908381818185875af1925050503d80600081146112a4576040519150601f19603f3d011682016040523d82523d6000602084013e6112a9565b606091505b50509050806112ff576040805162461bcd60e51b815260206004820152601960248201527f574554483a20455448207472616e73666572206661696c656400000000000000604482015290519081900360640190fd5b50505b8473ffffffffffffffffffffffffffffffffffffffff1663a4c0ed36338686866040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050602060405180830381600087803b1580156113a757600080fd5b505af11580156113bb573d6000803e3d6000fd5b505050506040513d60208110156113d157600080fd5b505195945050505050565b600073ffffffffffffffffffffffffffffffffffffffff85163014611448576040805162461bcd60e51b815260206004820152601c60248201527f574554483a20666c617368206d696e74206f6e6c792057455448313000000000604482015290519081900360640190fd5b6dffffffffffffffffffffffffffff8411156114955760405162461bcd60e51b815260040180806020018281038252602481526020018061267d6024913960400191505060405180910390fd5b600380548501908190556dffffffffffffffffffffffffffff1015611501576040805162461bcd60e51b815260206004820152601f60248201527f574554483a20746f74616c206c6f616e206c696d697420657863656564656400604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8616600081815260208181526040808320805489019055805188815290517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a37f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd98673ffffffffffffffffffffffffffffffffffffffff166323e30c8b333088600089896040518763ffffffff1660e01b8152600401808773ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff168152602001858152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050975050505050505050602060405180830381600087803b15801561164c57600080fd5b505af1158015611660573d6000803e3d6000fd5b505050506040513d602081101561167657600080fd5b5051146116ca576040805162461bcd60e51b815260206004820152601760248201527f574554483a20666c617368206c6f616e206661696c6564000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff861660009081526002602090815260408083203084529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146117e55784811015611777576040805162461bcd60e51b815260206004820152601f60248201527f574554483a2072657175657374206578636565647320616c6c6f77616e636500604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff87166000818152600260209081526040808320308085529083529281902089860390819055815181815291519094927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a3505b73ffffffffffffffffffffffffffffffffffffffff87166000908152602081905260409020548581101561184a5760405162461bcd60e51b81526004018080602001828103825260218152602001806126a16021913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff88166000818152602081815260408083208a8603905580518a815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3505060038054859003905550600195945050505050565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208054349081019091558151908152905192939284927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef928290030190a36040517fa4c0ed36000000000000000000000000000000000000000000000000000000008152336004820181815234602484018190526060604485019081526064850187905273ffffffffffffffffffffffffffffffffffffffff89169463a4c0ed36949389928992608401848480828437600081840152601f19601f82011690508083019250505095505050505050602060405180830381600087803b1580156119ce57600080fd5b505af11580156119e2573d6000803e3d6000fd5b505050506040513d60208110156119f857600080fd5b5051949350505050565b600073ffffffffffffffffffffffffffffffffffffffff82163014611a28576000611a3c565b6003546dffffffffffffffffffffffffffff035b92915050565b60006020819052908152604090205481565b60016020526000908152604090205481565b7f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd981565b60035481565b73ffffffffffffffffffffffffffffffffffffffff83163314611bca5773ffffffffffffffffffffffffffffffffffffffff831660009081526002602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611bc85781811015611b5a576040805162461bcd60e51b815260206004820152601f60248201527f574554483a2072657175657374206578636565647320616c6c6f77616e636500604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff84166000818152600260209081526040808320338085529083529281902086860390819055815181815291519094927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a3505b505b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015611c2f5760405162461bcd60e51b81526004018080602001828103825260218152602001806126a16021913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff84166000818152602081815260408083208686039055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a360405160009073ffffffffffffffffffffffffffffffffffffffff85169084908381818185875af1925050503d8060008114611ce7576040519150601f19603f3d011682016040523d82523d6000602084013e611cec565b606091505b5050905080611d42576040805162461bcd60e51b815260206004820152601b60248201527f574554483a204574686572207472616e73666572206661696c65640000000000604482015290519081900360640190fd5b5050505050565b6040518060400160405280600681526020017f574554483130000000000000000000000000000000000000000000000000000081525081565b600073ffffffffffffffffffffffffffffffffffffffff831615611e63573360009081526020819052604090205482811015611def5760405162461bcd60e51b81526004018080602001828103825260258152602001806126586025913960400191505060405180910390fd5b33600081815260208181526040808320878603905573ffffffffffffffffffffffffffffffffffffffff881680845292819020805488019055805187815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a350611f9c565b3360009081526020819052604090205482811015611eb25760405162461bcd60e51b81526004018080602001828103825260218152602001806126a16021913960400191505060405180910390fd5b336000818152602081815260408083208786039055805187815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3604051600090339085908381818185875af1925050503d8060008114611f3e576040519150601f19603f3d011682016040523d82523d6000602084013e611f43565b606091505b5050905080611f99576040805162461bcd60e51b815260206004820152601960248201527f574554483a20455448207472616e73666572206661696c656400000000000000604482015290519081900360640190fd5b50505b50600192915050565b73ffffffffffffffffffffffffffffffffffffffff8116600081815260208181526040808320805434908101909155815190815290517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a350565b33600081815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8916808552908352818420889055815188815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a38473ffffffffffffffffffffffffffffffffffffffff1662ba451f338686866040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050602060405180830381600087803b1580156113a757600080fd5b7f000000000000000000000000000000000000000000000000000000000000000181565b33600081815260208181526040808320805434908101909155815190815290517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3565b834211156121dd576040805162461bcd60e51b815260206004820152601460248201527f574554483a2045787069726564207065726d6974000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff80881660008181526001602081815260408084208054938401905580517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280820195909552948b166060850152608084018a905260a084019190915260c08084018990528451808503909101815260e09093019093528151919092012046917f000000000000000000000000000000000000000000000000000000000000000183146122aa576122a583612555565b6122cc565b7f9d6861d4de8c156e6b3155e3283174a7c6c86fd27c1ff43e1f05cc2d417fbb655b8260405160200180807f190100000000000000000000000000000000000000000000000000000000000081525060020183815260200182815260200192505050604051602081830303815290604052805190602001209050600060018288888860405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015612380573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116158015906123fb57508a73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b61244c576040805162461bcd60e51b815260206004820152601460248201527f574554483a20696e76616c6964207065726d6974000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff808c166000818152600260209081526040808320948f16808452948252918290208d905581518d815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a35050505050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff8316301461252f576040805162461bcd60e51b815260206004820152601c60248201527f574554483a20666c617368206d696e74206f6e6c792057455448313000000000604482015290519081900360640190fd5b50600092915050565b600260209081526000928352604080842090915290825290205481565b604080518082018252601181527f577261707065642045746865722076313000000000000000000000000000000060209182015281518083018352600181527f31000000000000000000000000000000000000000000000000000000000000009082015281517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818301527f5afefa023603a382ac22bd36644e004cefabbfaf61d4180000d8dc2b10c168b8818401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6606082015260808101939093523060a0808501919091528251808503909101815260c090930190915281519101209056fe574554483a207472616e7366657220616d6f756e7420657863656564732062616c616e6365574554483a20696e646976696475616c206c6f616e206c696d6974206578636565646564574554483a206275726e20616d6f756e7420657863656564732062616c616e6365a264697066735822122010a2e85d28f3cbb1bab01194294eeaad30a52826e3d85bf4b42223cb2b05e6a164736f6c63430007060033" + "code": "0x6080806040526004361015610025575b50361561001b57600080fd5b6100236108bd565b005b60003560e01c90816306fdde03146107c557508063095ea7b31461074c57806318160ddd1461073057806323b872dd146107015780632e1a7d4d14610668578063313ce5671461064c5780635cffe9de146102c4578063613255ab1461028757806370a082311461024d57806375d9ad1b1461021257806395d89b41146101d15780639d649e66146101b5578063a9059cbb14610183578063d0e30db01461016f578063d9d98ce4146101385763dd62ed3e146100e2573861000f565b34610133576040366003190112610133576100fb61086e565b610103610884565b9060018060a01b038091166000526001602052604060002091166000526020526020604060002054604051908152f35b600080fd5b346101335760403660031901126101335761016461015461086e565b6001600160a01b03163014610aa0565b602060405160008152f35b6000366003190112610133576100236108bd565b346101335760403660031901126101335760206101ab6101a161086e565b602435903361095f565b6040519015158152f35b3461013357600036600319011261013357602060405160008152f35b346101335760003660031901126101335761020e6040516101f181610809565b60048152630ae8aa8960e31b602082015260405191829182610825565b0390f35b346101335760003660031901126101335760206040517f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd98152f35b34610133576020366003190112610133576001600160a01b0361026e61086e565b1660005260006020526020604060002054604051908152f35b34610133576020366003190112610133576102a061086e565b6001600160a01b031630036102bb576020475b604051908152f35b602060006102b3565b34610133576080366003190112610133576001600160a01b036004358181168103610133576102f1610884565b67ffffffffffffffff60643511610133573660236064350112156101335767ffffffffffffffff60643560040135116101335736602460643560040135606435010111610133576103453084831614610aa0565b6044351561060e5760443547106105c95782821660005260006020526040600020610373604435825461089a565b905560405160443581526000600080516020610aed833981519152602086861693a382604051916323e30c8b60e01b835233600484015216602482015260443560448201526000606482015260a060848201526064356004013560a48201526064356004013560246064350160c4830137600060c46064356004013583010152601f1960208260c48184601f606435600401350116810103018160008888165af19081156105bd57600091610540575b507f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd99150036104f0578181166000526000602052604435604060002054106104ab57600080516020610aed83398151915260208360009484168552848252604085206104926044358254610952565b90556040519360443585521692a3602060405160018152f35b60405162461bcd60e51b815260206004820152601e60248201527f5745544831303a20696e73756666696369656e742072657061796d656e7400006044820152606490fd5b60405162461bcd60e51b815260206004820152602260248201527f5745544831303a20666c617368206c6f616e2063616c6c6261636b206661696c604482015261195960f21b6064820152608490fd5b602091503d82116105b5575b601f820116820182811067ffffffffffffffff82111761059f57602091839160405281010312610133577f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd9905184610423565b634e487b7160e01b600052604160045260246000fd5b3d915061054c565b6040513d6000823e3d90fd5b60405162461bcd60e51b815260206004820152601e60248201527f5745544831303a20696e73756666696369656e74206c697175696469747900006044820152606490fd5b60405162461bcd60e51b815260206004820152601660248201527515d155120c4c0e881a5b9d985b1a5908185b5bdd5b9d60521b6044820152606490fd5b3461013357600036600319011261013357602060405160128152f35b3461013357602036600319011261013357600435336000526000602052610696816040600020541015610906565b33600052600060205260406000206106af828254610952565b905580600081156106f8575b600080809381933390f1156105bd576040519081527f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b6560203392a2005b506108fc6106bb565b346101335760603660031901126101335760206101ab61071f61086e565b610727610884565b6044359161095f565b3461013357600036600319011261013357602047604051908152f35b346101335760403660031901126101335761076561086e565b60243533600052600160205260406000209160018060a01b03169182600052602052806040600020556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3602060405160018152f35b3461013357600036600319011261013357806107e361020e92610809565b600d81526c2bb930b83832b21022ba3432b960991b602082015260405191829182610825565b6040810190811067ffffffffffffffff82111761059f57604052565b6020808252825181830181905290939260005b82811061085a57505060409293506000838284010152601f8019910116010190565b818101860151848201604001528501610838565b600435906001600160a01b038216820361013357565b602435906001600160a01b038216820361013357565b919082018092116108a757565b634e487b7160e01b600052601160045260246000fd5b33600052600060205260406000206108d634825461089a565b90556040513481527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c60203392a2565b1561090d57565b60405162461bcd60e51b815260206004820152601c60248201527f5745544831303a20696e73756666696369656e742062616c616e6365000000006044820152606490fd5b919082039182116108a757565b91909160018060a01b038091169160009383855260209285845260409161098b84848920541015610906565b3386141580610a82575b6109e5575b918091600080516020610aed8339815191529594938789528886528289206109c3868254610952565b90551696878152808552206109d983825461089a565b905551908152a3600190565b858752600185528287203388528552838388205410610a3e57918091600080516020610aed83398151915295949387895260018652828920338a528652828920610a30868254610952565b90559150919293945061099a565b825162461bcd60e51b815260048101869052601e60248201527f5745544831303a20696e73756666696369656e7420616c6c6f77616e636500006044820152606490fd5b50858752600185528287203388528552828720546000191415610995565b15610aa757565b60405162461bcd60e51b815260206004820152601960248201527f5745544831303a20756e737570706f7274656420746f6b656e000000000000006044820152606490fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212207c34c26feecd05ff838fc85995144621f090e1740fb2223f2f4e272503c4754564736f6c63430008140033", + "storage": {} }, "0xe76e1436e855d808db6c2fa80976d0a8feb15e50": { "balance": "0x130ee8e7179044000000" @@ -155,4 +156,4 @@ "number": "0x0", "gasUsed": "0x0", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" -} \ No newline at end of file +} diff --git a/contracts/bridge/trustless/EnhancedSwapRouter.sol b/contracts/bridge/trustless/EnhancedSwapRouter.sol index 4d0aa54..d187576 100644 --- a/contracts/bridge/trustless/EnhancedSwapRouter.sol +++ b/contracts/bridge/trustless/EnhancedSwapRouter.sol @@ -12,6 +12,7 @@ import "./interfaces/IAggregationRouter.sol"; import "./interfaces/IDodoexRouter.sol"; import "./interfaces/IBalancerVault.sol"; import "./interfaces/IWETH.sol"; +import "../../liquidity/interfaces/ILiquidityProvider.sol"; /** * @title EnhancedSwapRouter @@ -67,6 +68,7 @@ contract EnhancedSwapRouter is AccessControl, ReentrancyGuard { // Dodoex PMM pool addresses (tokenIn => tokenOut => PMM pool address) mapping(address => mapping(address => address)) public dodoPoolAddresses; + address public dodoLiquidityProvider; /// @dev Uniswap V3 Quoter for on-chain quotes; set via setUniswapQuoter when deployed on 138/651940 address public uniswapQuoter; @@ -91,6 +93,7 @@ contract EnhancedSwapRouter is AccessControl, ReentrancyGuard { error ProviderDisabled(); error InsufficientOutput(); error InvalidRoutingConfig(); + error DodoRouteNotConfigured(); /** * @notice Constructor @@ -324,6 +327,15 @@ contract EnhancedSwapRouter is AccessControl, ReentrancyGuard { dodoPoolAddresses[tokenIn][tokenOut] = poolAddress; } + /** + * @notice Set DODO liquidity provider implementation for environments that execute + * swaps via a local provider/integration instead of an external Dodoex router. + * @param provider Address of ILiquidityProvider-compatible contract + */ + function setDodoLiquidityProvider(address provider) external onlyRole(ROUTING_MANAGER_ROLE) { + dodoLiquidityProvider = provider; + } + /** * @notice Set Uniswap V3 Quoter address for on-chain quotes * @param _quoter Quoter contract address (address(0) to use 0.5% slippage estimate) @@ -349,9 +361,23 @@ contract EnhancedSwapRouter is AccessControl, ReentrancyGuard { if (amountIn == 0) revert ZeroAmount(); if (tokenIn == address(0) || tokenOut == address(0)) revert ZeroAddress(); address pool = dodoPoolAddresses[tokenIn][tokenOut]; - require(pool != address(0), "EnhancedSwapRouter: Dodoex pool not configured"); + if (!_hasDodoRoute(tokenIn, tokenOut, pool)) revert DodoRouteNotConfigured(); IERC20(tokenIn).safeTransferFrom(msg.sender, address(this), amountIn); + + if (dodoLiquidityProvider != address(0)) { + IERC20(tokenIn).approve(dodoLiquidityProvider, amountIn); + amountOut = ILiquidityProvider(dodoLiquidityProvider).executeSwap( + tokenIn, + tokenOut, + amountIn, + amountOutMin + ); + require(amountOut >= amountOutMin, "EnhancedSwapRouter: insufficient output"); + IERC20(tokenOut).safeTransfer(msg.sender, amountOut); + return amountOut; + } + IERC20(tokenIn).approve(dodoexRouter, amountIn); address[] memory dodoPairs = new address[](1); @@ -476,7 +502,18 @@ contract EnhancedSwapRouter is AccessControl, ReentrancyGuard { uint256 amountOutMin ) internal returns (uint256) { address pool = dodoPoolAddresses[weth][stablecoinToken]; - require(pool != address(0), "EnhancedSwapRouter: Dodoex pool not configured"); + if (!_hasDodoRoute(weth, stablecoinToken, pool)) revert DodoRouteNotConfigured(); + + if (dodoLiquidityProvider != address(0)) { + IERC20 wethTokenViaProvider = IERC20(weth); + wethTokenViaProvider.approve(dodoLiquidityProvider, amountIn); + return ILiquidityProvider(dodoLiquidityProvider).executeSwap( + weth, + stablecoinToken, + amountIn, + amountOutMin + ); + } IERC20 wethToken = IERC20(weth); wethToken.approve(dodoexRouter, amountIn); @@ -605,9 +642,30 @@ contract EnhancedSwapRouter is AccessControl, ReentrancyGuard { address stablecoinToken, uint256 amountIn ) external view returns (uint256) { + if (dodoLiquidityProvider != address(0)) { + if (!ILiquidityProvider(dodoLiquidityProvider).supportsTokenPair(weth, stablecoinToken)) { + return 0; + } + (uint256 amountOut,) = ILiquidityProvider(dodoLiquidityProvider).getQuote(weth, stablecoinToken, amountIn); + return amountOut; + } + if (dodoPoolAddresses[weth][stablecoinToken] == address(0)) { + return 0; + } return IDodoexRouter(dodoexRouter).getDodoSwapQuote(weth, stablecoinToken, amountIn); } + function _hasDodoRoute( + address tokenIn, + address tokenOut, + address configuredPool + ) internal view returns (bool) { + if (dodoLiquidityProvider != address(0)) { + return ILiquidityProvider(dodoLiquidityProvider).supportsTokenPair(tokenIn, tokenOut); + } + return configuredPool != address(0); + } + /** * @notice Get Balancer quote (view) * When poolId configured, would query Balancer. Otherwise estimate for stablecoins. @@ -686,4 +744,3 @@ contract EnhancedSwapRouter is AccessControl, ReentrancyGuard { // Allow contract to receive ETH receive() external payable {} } - diff --git a/contracts/dex/DODOPMMIntegration.sol b/contracts/dex/DODOPMMIntegration.sol index 90a4b4d..8ee82f2 100644 --- a/contracts/dex/DODOPMMIntegration.sol +++ b/contracts/dex/DODOPMMIntegration.sol @@ -110,6 +110,12 @@ contract DODOPMMIntegration is AccessControl, ReentrancyGuard { ); event PoolRemoved(address indexed pool); event ReserveSystemSet(address indexed reserveSystem); + event PoolImported( + address indexed pool, + address indexed baseToken, + address indexed quoteToken, + address importer + ); constructor( address admin, @@ -164,22 +170,7 @@ contract DODOPMMIntegration is AccessControl, ReentrancyGuard { isOpenTWAP // Enable TWAP ); - // Register pool - pools[compliantUSDT][officialUSDT] = pool; - pools[officialUSDT][compliantUSDT] = pool; - isRegisteredPool[pool] = true; - allPools.push(pool); - - poolConfigs[pool] = PoolConfig({ - pool: pool, - baseToken: compliantUSDT, - quoteToken: officialUSDT, - lpFeeRate: lpFeeRate, - i: initialPrice, - k: k, - isOpenTWAP: isOpenTWAP, - createdAt: block.timestamp - }); + _recordPool(pool, compliantUSDT, officialUSDT, lpFeeRate, initialPrice, k, isOpenTWAP); emit PoolCreated(pool, compliantUSDT, officialUSDT, msg.sender); } @@ -208,21 +199,7 @@ contract DODOPMMIntegration is AccessControl, ReentrancyGuard { isOpenTWAP ); - pools[compliantUSDC][officialUSDC] = pool; - pools[officialUSDC][compliantUSDC] = pool; - isRegisteredPool[pool] = true; - allPools.push(pool); - - poolConfigs[pool] = PoolConfig({ - pool: pool, - baseToken: compliantUSDC, - quoteToken: officialUSDC, - lpFeeRate: lpFeeRate, - i: initialPrice, - k: k, - isOpenTWAP: isOpenTWAP, - createdAt: block.timestamp - }); + _recordPool(pool, compliantUSDC, officialUSDC, lpFeeRate, initialPrice, k, isOpenTWAP); emit PoolCreated(pool, compliantUSDC, officialUSDC, msg.sender); } @@ -251,21 +228,7 @@ contract DODOPMMIntegration is AccessControl, ReentrancyGuard { isOpenTWAP ); - pools[compliantUSDT][compliantUSDC] = pool; - pools[compliantUSDC][compliantUSDT] = pool; - isRegisteredPool[pool] = true; - allPools.push(pool); - - poolConfigs[pool] = PoolConfig({ - pool: pool, - baseToken: compliantUSDT, - quoteToken: compliantUSDC, - lpFeeRate: lpFeeRate, - i: initialPrice, - k: k, - isOpenTWAP: isOpenTWAP, - createdAt: block.timestamp - }); + _recordPool(pool, compliantUSDT, compliantUSDC, lpFeeRate, initialPrice, k, isOpenTWAP); emit PoolCreated(pool, compliantUSDT, compliantUSDC, msg.sender); } @@ -301,25 +264,46 @@ contract DODOPMMIntegration is AccessControl, ReentrancyGuard { isOpenTWAP ); - pools[baseToken][quoteToken] = pool; - pools[quoteToken][baseToken] = pool; - isRegisteredPool[pool] = true; - allPools.push(pool); - - poolConfigs[pool] = PoolConfig({ - pool: pool, - baseToken: baseToken, - quoteToken: quoteToken, - lpFeeRate: lpFeeRate, - i: initialPrice, - k: k, - isOpenTWAP: isOpenTWAP, - createdAt: block.timestamp - }); + _recordPool(pool, baseToken, quoteToken, lpFeeRate, initialPrice, k, isOpenTWAP); emit PoolCreated(pool, baseToken, quoteToken, msg.sender); } + /** + * @notice Import an already-deployed DODO PMM pool into integration state. + * @dev Use this when the pool exists at the DODO/provider layer but was not + * recorded in the integration mappings or allPools inventory. + */ + function importExistingPool( + address pool, + address baseToken, + address quoteToken, + uint256 lpFeeRate, + uint256 initialPrice, + uint256 k, + bool isOpenTWAP + ) external onlyRole(POOL_MANAGER_ROLE) { + require(pool != address(0), "DODOPMMIntegration: zero pool"); + require(baseToken != address(0), "DODOPMMIntegration: zero base"); + require(quoteToken != address(0), "DODOPMMIntegration: zero quote"); + require(baseToken != quoteToken, "DODOPMMIntegration: same token"); + require(pools[baseToken][quoteToken] == address(0), "DODOPMMIntegration: pair already recorded"); + require(!isRegisteredPool[pool], "DODOPMMIntegration: pool already registered"); + + address actualBase = IDODOPMMPool(pool)._BASE_TOKEN_(); + address actualQuote = IDODOPMMPool(pool)._QUOTE_TOKEN_(); + bool matchesForward = actualBase == baseToken && actualQuote == quoteToken; + bool matchesReverse = actualBase == quoteToken && actualQuote == baseToken; + require(matchesForward || matchesReverse, "DODOPMMIntegration: pool token mismatch"); + + if (matchesReverse) { + (baseToken, quoteToken) = (quoteToken, baseToken); + } + + _recordPool(pool, baseToken, quoteToken, lpFeeRate, initialPrice, k, isOpenTWAP); + emit PoolImported(pool, baseToken, quoteToken, msg.sender); + } + /** * @notice Add liquidity to a DODO PMM pool * @param pool Pool address @@ -595,5 +579,30 @@ contract DODOPMMIntegration is AccessControl, ReentrancyGuard { emit PoolRemoved(pool); } -} + function _recordPool( + address pool, + address baseToken, + address quoteToken, + uint256 lpFeeRate, + uint256 initialPrice, + uint256 k, + bool isOpenTWAP + ) internal { + pools[baseToken][quoteToken] = pool; + pools[quoteToken][baseToken] = pool; + isRegisteredPool[pool] = true; + allPools.push(pool); + + poolConfigs[pool] = PoolConfig({ + pool: pool, + baseToken: baseToken, + quoteToken: quoteToken, + lpFeeRate: lpFeeRate, + i: initialPrice, + k: k, + isOpenTWAP: isOpenTWAP, + createdAt: block.timestamp + }); + } +} diff --git a/contracts/reserve/PriceFeedKeeper.sol b/contracts/reserve/PriceFeedKeeper.sol index 72a71ad..bf00df2 100644 --- a/contracts/reserve/PriceFeedKeeper.sol +++ b/contracts/reserve/PriceFeedKeeper.sol @@ -20,8 +20,8 @@ contract PriceFeedKeeper is AccessControl, ReentrancyGuard { address[] public trackedAssets; mapping(address => bool) public isTracked; - // Update configuration - uint256 public updateInterval = 30; // seconds + // Update configuration (default 6s aligns with PMM mesh automation; admin may set via setUpdateInterval) + uint256 public updateInterval = 6; // seconds mapping(address => uint256) public lastUpdateTime; // Keeper configuration diff --git a/contracts/tokens/CompliantFiatToken.sol b/contracts/tokens/CompliantFiatToken.sol index 9e26573..d96496e 100644 --- a/contracts/tokens/CompliantFiatToken.sol +++ b/contracts/tokens/CompliantFiatToken.sol @@ -11,6 +11,12 @@ import "../compliance/LegallyCompliantBase.sol"; * @notice Generic ISO-4217 compliant fiat/commodity token (ERC-20, DEX-ready) * @dev Use for cEURC, cGBPC, cAUDC, cJPYC, cCHFC, cCADC, cXAUC, cXAUT, etc. * Full ERC-20 for DEX liquidity pools; inherits LegallyCompliantBase. + * + * XAU (gold) invariant — enforced by policy and integrators, not by ERC-20 math: + * When `currencyCode()` is `"XAU"` (e.g. cXAUC, cXAUT), **one full token** means + * **exactly one troy ounce** of fine gold: balances and `mint`/`transfer` amounts use + * `10 ** decimals()` base units per troy ounce (with 6 decimals, `1_000_000` base = 1 oz). + * Fiat codes (USD, EUR, …) use one full token as one unit of that currency at `decimals`. */ contract CompliantFiatToken is ERC20, Pausable, Ownable, LegallyCompliantBase { bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); diff --git a/contracts/tokens/OfficialStableMirrorToken.sol b/contracts/tokens/OfficialStableMirrorToken.sol new file mode 100644 index 0000000..24c80b1 --- /dev/null +++ b/contracts/tokens/OfficialStableMirrorToken.sol @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; + +/** + * @title OfficialStableMirrorToken + * @notice Lightweight ERC-20 used as the local Chain 138 "official" stable mirror. + * @dev This token exists only to provide a live ERC-20 quote-side asset for local PMM pools. + * It is intentionally separate from the compliant token contracts. + */ +contract OfficialStableMirrorToken is ERC20, Ownable { + uint8 private immutable _decimalsStorage; + + constructor( + string memory name_, + string memory symbol_, + uint8 decimals_, + address initialOwner, + uint256 initialSupply + ) ERC20(name_, symbol_) Ownable(initialOwner) { + _decimalsStorage = decimals_; + if (initialSupply > 0) { + _mint(msg.sender, initialSupply); + } + } + + function decimals() public view override returns (uint8) { + return _decimalsStorage; + } + + function mint(address to, uint256 amount) external onlyOwner { + _mint(to, amount); + } + + function burn(address from, uint256 amount) external onlyOwner { + _burn(from, amount); + } +} diff --git a/docs/deployment/ALL_MAINNETS_DEPLOYMENT_RUNBOOK.md b/docs/deployment/ALL_MAINNETS_DEPLOYMENT_RUNBOOK.md index adc7f60..6ca4841 100644 --- a/docs/deployment/ALL_MAINNETS_DEPLOYMENT_RUNBOOK.md +++ b/docs/deployment/ALL_MAINNETS_DEPLOYMENT_RUNBOOK.md @@ -157,7 +157,9 @@ forge script script/dex/DeployPrivatePoolRegistryAndPools.s.sol:DeployPrivatePoo ### PMM (Chain 138) completion checklist 1. Set **DODO_VENDING_MACHINE_ADDRESS** in `.env` to the DODO DVM factory address on Chain 138. **Chain 138 is not in DODO’s official list** — see [DVM_DEPLOYMENT_CHECK.md](DVM_DEPLOYMENT_CHECK.md). Deploy the factory yourself from [DODOEX](https://github.com/DODOEX) or use an existing deployment if available. -2. Set **OFFICIAL_USDT_ADDRESS** and **OFFICIAL_USDC_ADDRESS** to the official or wrapped USDT/USDC token addresses on Chain 138 (already in .env as reference; replace with Chain 138 addresses if different). +2. Set **OFFICIAL_USDT_ADDRESS** and **OFFICIAL_USDC_ADDRESS** to the live Chain 138 quote-side mirror stables: + - `OFFICIAL_USDT_ADDRESS=0x004b63A7B5b0E06f6bB6adb4a5F9f590BF3182D1` + - `OFFICIAL_USDC_ADDRESS=0x71D6687F38b93CCad569Fa6352c876eea967201b` 3. Run: `bash scripts/deployment/deploy-all-mainnets-with-mapper-oracle-pmm.sh pmm` to deploy DODOPMMIntegration. 4. Set **DODOPMM_INTEGRATION_ADDRESS** (or DODO_PMM_INTEGRATION) in .env from the deploy output, then create pools: - cUSDT/USDT and cUSDC/USDC: call `createCUSDTUSDTPool` and `createCUSDCUSDCPool` on the integration (see `docs/integration/DODO_PMM_INTEGRATION.md`). diff --git a/docs/deployment/DEPLOYED_CONTRACTS_OVERVIEW.md b/docs/deployment/DEPLOYED_CONTRACTS_OVERVIEW.md index 85cbe95..bc5d3d7 100644 --- a/docs/deployment/DEPLOYED_CONTRACTS_OVERVIEW.md +++ b/docs/deployment/DEPLOYED_CONTRACTS_OVERVIEW.md @@ -1,5 +1,7 @@ # Deployed Smart Contracts — Cross-Network Overview +> Historical note (2026-03-26): this overview includes superseded PMM stack references from earlier deployment phases. The current canonical Chain 138 PMM stack is `DODOPMMIntegration=0x5BDc62f1ae7D630c37A8B363a1d49845356Ee72d` and `DODOPMMProvider=0x5CAe6Ce155b7f08D3a956F5Dc82fC9945f29B381`. + **Last updated:** 2026-02-20 **Source:** `smom-dbis-138/.env` and deployment runbooks. @@ -63,7 +65,7 @@ flowchart TB | | CCIP Router | `0x42DAb7b888Dd382bD5Adcf9E038dBF1fD03b4817` | CCIP router (on 138) | | | CCIPTxReporter | `0x3F88b662F04d9B1413BA8d65bFC229e830D7d077` | Report txs to mainnet logger | | **PMM** | Mock DVM Factory | `0xB16c3D48A111714B1795E58341FeFDd643Ab01ab` | Create mock pools | -| | DODOPMMIntegration | `0x79cdbaFBaA0FdF9F55D26F360F54cddE5c743F7D` | cUSDT/cUSDC pools | +| | DODOPMMIntegration | `0x5BDc62f1ae7D630c37A8B363a1d49845356Ee72d` | Canonical corrected PMM integration | | **Core eMoney** | Compliance Registry, Token Factory, Bridge Vault, Debt Registry, Policy Manager, Token Impl | (see .env) | Core system | | **Channels** | Payment Channel Manager, Address Mapper, Mirror Manager | (see .env) | State channels | | **Oracle** | Oracle Aggregator, Oracle Proxy | (see .env) | Price feeds | diff --git a/docs/deployment/NEXT_STEPS_COMPLETION.md b/docs/deployment/NEXT_STEPS_COMPLETION.md index 200c89d..44955b6 100644 --- a/docs/deployment/NEXT_STEPS_COMPLETION.md +++ b/docs/deployment/NEXT_STEPS_COMPLETION.md @@ -1,5 +1,7 @@ # Next Steps Completion Summary +> Historical note (2026-03-26): this completion summary preserves an earlier PMM deployment phase. The current canonical Chain 138 PMM stack is `DODOPMMIntegration=0x5BDc62f1ae7D630c37A8B363a1d49845356Ee72d` and `DODOPMMProvider=0x5CAe6Ce155b7f08D3a956F5Dc82fC9945f29B381`. + **Date:** 2026-02-20 This document summarizes what was completed in the "next steps" pass and what remains for the operator. @@ -19,7 +21,7 @@ This document summarizes what was completed in the "next steps" pass and what re | **Verify script** | Optional checks (CCIPTxReporter, genesis) are warnings; log_* fallbacks; safe unset-var handling. | | **Hardhat / Forge** | @emoney/interfaces replaced with relative imports; Hardhat viaIR for 0.8.22; Forge build available. | | **Docs** | WARNINGS_AND_OPTIONAL_TASKS.md, DVM_DEPLOYMENT_CHECK.md, ALL_MAINNETS_DEPLOYMENT_RUNBOOK (PMM step → DVM doc), TODO_TASK_LIST_MASTER §10b updated. | -| **PMM (Chain 138)** | Mock DVM: deployed `MockDVMFactory` at `0xB16c3D48A111714B1795E58341FeFDd643Ab01ab` and `DODOPMMIntegration` at `0x79cdbaFBaA0FdF9F55D26F360F54cddE5c743F7D`. `DODO_VENDING_MACHINE_ADDRESS` and `DODO_PMM_INTEGRATION` set in .env. `run-pmm-and-pools.sh` fixed (no longer rejects valid 0x… addresses). Pools are mock (see DVM_DEPLOYMENT_CHECK.md option 0). | +| **PMM (Chain 138)** | Earlier Mock DVM phase completed; current canonical PMM integration is `0x5BDc62f1ae7D630c37A8B363a1d49845356Ee72d` and supersedes the initial stack. `DODO_VENDING_MACHINE_ADDRESS` and `DODO_PMM_INTEGRATION` were set in .env during the first deployment phase. | --- diff --git a/docs/deployment/PREREQUISITES.md b/docs/deployment/PREREQUISITES.md index 8f67906..2030ab3 100644 --- a/docs/deployment/PREREQUISITES.md +++ b/docs/deployment/PREREQUISITES.md @@ -43,7 +43,7 @@ Complete these **before** running the three operator task scripts. - DODO does not list Chain 138; use your own deployment or an existing DVM if available. - **.env:** Set: - `DODO_VENDING_MACHINE_ADDRESS` — DVM factory on Chain 138. - - `OFFICIAL_USDT_ADDRESS`, `OFFICIAL_USDC_ADDRESS` — official or wrapped USDT/USDC on Chain 138 (already have placeholders). + - `OFFICIAL_USDT_ADDRESS=0x004b63A7B5b0E06f6bB6adb4a5F9f590BF3182D1`, `OFFICIAL_USDC_ADDRESS=0x71D6687F38b93CCad569Fa6352c876eea967201b` — live Chain 138 quote-side mirror stables for PMM pools. - `COMPLIANT_USDT_ADDRESS`, `COMPLIANT_USDC_ADDRESS` — already set. - **Script:** `scripts/deployment/run-pmm-and-pools.sh`. diff --git a/docs/integration/COMPLETE_INTEGRATION_GUIDE.md b/docs/integration/COMPLETE_INTEGRATION_GUIDE.md index 8643811..7543425 100644 --- a/docs/integration/COMPLETE_INTEGRATION_GUIDE.md +++ b/docs/integration/COMPLETE_INTEGRATION_GUIDE.md @@ -122,8 +122,9 @@ This guide provides a complete implementation path for making CompliantUSDT (cUS export DODO_VENDING_MACHINE_ADDRESS=0x... export COMPLIANT_USDT_ADDRESS=0x... export COMPLIANT_USDC_ADDRESS=0x... - export OFFICIAL_USDT_ADDRESS=0x... - export OFFICIAL_USDC_ADDRESS=0x... + # On Chain 138, use the live local quote-side mirror stables + export OFFICIAL_USDT_ADDRESS=0x004b63A7B5b0E06f6bB6adb4a5F9f590BF3182D1 + export OFFICIAL_USDC_ADDRESS=0x71D6687F38b93CCad569Fa6352c876eea967201b # Deploy forge script script/dex/DeployDODOPMMIntegration.s.sol:DeployDODOPMMIntegration \ @@ -383,4 +384,3 @@ For issues or questions: 2. Check troubleshooting section 3. Review contract code comments 4. Contact development team - diff --git a/docs/integration/DODO_PMM_INTEGRATION.md b/docs/integration/DODO_PMM_INTEGRATION.md index 1629df4..5c2cbe3 100644 --- a/docs/integration/DODO_PMM_INTEGRATION.md +++ b/docs/integration/DODO_PMM_INTEGRATION.md @@ -41,11 +41,11 @@ The Master Plan specifies four **public** liquidity pool types for user routing | Pair | Creation method | Notes | |------|-----------------|--------| | **cUSDT / cUSDC** | `createCUSDTCUSDCPool(lpFeeRate, initialPrice, k, isOpenTWAP)` | Dedicated function; swap via `swapCUSDTForUSDC` / `swapUSDCForCUSDT`. Register in DODOPMMProvider for getQuote/executeSwap. | -| **cUSDT / XAU** | `createPool(cUSDT, xauTokenAddress, ...)` | Requires XAU token address on Chain 138. Use generic `createPool`. | +| **cUSDT / XAU** | `createPool(cUSDT, xauTokenAddress, ...)` | Use the Chain 138 XAU anchor token address (`cXAUC` or `cXAUT`) and the generic `createPool`. | | **cUSDC / XAU** | `createPool(cUSDC, xauTokenAddress, ...)` | Same as above. | -| **cEURT / XAU** | `createPool(cEURTAddress, xauTokenAddress, ...)` | Requires cEURT and XAU token addresses on Chain 138. | +| **cEURT / XAU** | `createPool(cEURTAddress, xauTokenAddress, ...)` | Requires `cEURT` and a Chain 138 XAU anchor token (`cXAUC` or `cXAUT`). | -For cUSDT/XAU, cUSDC/XAU, and cEURT/XAU: deploy or obtain token addresses on Chain 138, then call `createPool(baseToken, quoteToken, lpFeeRate, initialPrice, k, isOpenTWAP)` with `POOL_MANAGER_ROLE`. Public pools serve user routing, price discovery, and flash loan access; they do not serve as the primary stabilization engine (see Master Plan private mesh). +For cUSDT/XAU, cUSDC/XAU, and cEURT/XAU: use the deployed Chain 138 XAU anchor token (`cXAUC` at `0x290E52a8819A4fbD0714E517225429aA2B70EC6b` or `cXAUT` at `0x94e408E26c6FD8F4ee00b54dF19082FDA07dC96E`), then call `createPool(baseToken, quoteToken, lpFeeRate, initialPrice, k, isOpenTWAP)` with `POOL_MANAGER_ROLE`. **Unit:** 1 full XAU token = **1 troy ounce** of gold (`10^6` base units with 6 decimals). Public pools serve user routing, price discovery, and flash loan access; they do not serve as the primary stabilization engine (see Master Plan private mesh). --- @@ -101,9 +101,9 @@ RPC_URL=https://... DODO_VENDING_MACHINE_ADDRESS=0x... # DODO Vending Machine Factory DODO_APPROVE_ADDRESS=0x... # Optional -# Official tokens -OFFICIAL_USDT_ADDRESS=0xdAC17F958D2ee523a2206206994597C13D831ec7 -OFFICIAL_USDC_ADDRESS=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 +# Official tokens on Chain 138 (local quote-side mirror stables) +OFFICIAL_USDT_ADDRESS=0x004b63A7B5b0E06f6bB6adb4a5F9f590BF3182D1 +OFFICIAL_USDC_ADDRESS=0x71D6687F38b93CCad569Fa6352c876eea967201b # Compliant tokens COMPLIANT_USDT_ADDRESS=0x93E66202A11B1772E55407B32B44e5Cd8eda7f22 @@ -468,4 +468,3 @@ See `scripts/setup-dodo-pools.sh` for automated pool creation and configuration. 3. Seed initial liquidity 4. Enable trading 5. Monitor and optimize - diff --git a/docs/integration/ORACLE_AND_KEEPER_CHAIN138.md b/docs/integration/ORACLE_AND_KEEPER_CHAIN138.md index e23732a..3f710c4 100644 --- a/docs/integration/ORACLE_AND_KEEPER_CHAIN138.md +++ b/docs/integration/ORACLE_AND_KEEPER_CHAIN138.md @@ -12,6 +12,8 @@ Set in project `.env` (and in token-aggregation or relay when they consume oracl |----------|-------------| | `ORACLE_AGGREGATOR_ADDRESS` | Oracle aggregator contract on Chain 138 (e.g. from deployment). Used by CCIP and other consumers. | | `ORACLE_PROXY_ADDRESS` | Oracle proxy contract on Chain 138 when applicable. | +| `ORACLE_PRICE_FEED` | **OraclePriceFeed** wired to **PriceFeedKeeper** and **ReserveSystem** — not the same as `ORACLE_PROXY_ADDRESS`. | +| `CHAIN138_WETH_MOCK_PRICE_FEED` | Optional **MockPriceFeed** for WETH on the keeper path when Besu block time lags the public aggregator `updatedAt`. Sync: `scripts/reserve/sync-weth-mock-price.sh`. | | `RESERVE_SYSTEM` | ReserveSystem address (Chain 138). Required for DODOPMMIntegration oracle-backed mid price. | | `RPC_URL_138` / `RPC_URL` | RPC endpoint for Chain 138 (keeper and scripts). | @@ -38,10 +40,37 @@ References: [DEPLOYMENT_COMPLETE_GUIDE.md](../deployment/DEPLOYMENT_COMPLETE_GUI 4. **Update oracle price script** One-off or cron-driven update of oracle/oracle proxy with current price: - `scripts/update-oracle-price.sh` — usage: `[rpc-url] [oracle-address] [private-key]`; uses `AGGREGATOR_ADDRESS` and fetches ETH/USD from CoinGecko. + **CoinGecko Demo keys** (`CG-…`): use `https://api.coingecko.com` with header `x-cg-demo-api-key` (not `pro-api.coingecko.com` with `x-cg-pro-api-key`). Paid Pro uses the pro host and pro header; the script tries demo first, then pro, then unauthenticated public. Schedule this (or the keeper service) so PMM oracle-backed prices and reporting stay fresh. --- +## PMM mesh automation (6-second tick) + +**Policy:** Run off-chain ticks every **6 seconds** so oracle pushes, `PriceFeedKeeper` upkeep, and PMM/WETH read paths stay warm—supporting peg alignment with `DODOPMMIntegration` / optional `ReserveSystem`. + +| Component | Role | +|-----------|------| +| `scripts/reserve/pmm-mesh-6s-automation.sh` | Loop: `getPoolPriceOrOracle` on `PMM_MESH_POLL_POOLS`, WETH9/WETH10 `totalSupply` reads, conditional `performUpkeep`, `update-oracle-price.sh`. | +| `PMM_MESH_INTERVAL_SEC` | Default **6**. | +| `PriceFeedKeeper.updateInterval` | Default on **new** deployments is **6s** (`PriceFeedKeeper.sol`). **Existing** keepers: run `scripts/reserve/set-price-feed-keeper-interval.sh 6` as admin. | +| `KEEPER_PRIVATE_KEY` | Wallet with **KEEPER_ROLE** on `PriceFeedKeeper` for `performUpkeep` txs. | +| `MESH_WETH_WRAP_WEI` | Optional tiny `WETH.deposit{value}` on a throttled cadence (`MESH_WETH_WRAP_EVERY_N`); costs gas—default **0** (off). | + +**systemd:** `config/systemd/chain138-pmm-mesh-automation.service.example` in the Proxmox repo—copy, fix paths, `enable --now`. + +**Bring-up checklist (operator):** +1. `PRICE_FEED_KEEPER_ADDRESS` in `smom-dbis-138/.env` (Chain 138: `0xD3AD6831aacB5386B8A25BB8D8176a6C8a026f04` per explorer docs—verify live). +2. `KEEPER_PRIVATE_KEY` optional if same as `PRIVATE_KEY` (must have `KEEPER_ROLE` on the keeper). +3. `./scripts/reserve/set-price-feed-keeper-interval.sh 6` once if the keeper still used a 30s interval. +4. Oracle: `scripts/update-oracle-price.sh` needs Besu-safe paths (eth_call + explicit `--gas-limit`); set `AGGREGATOR_ADDRESS` / transmitter as deployed. +5. If the keeper uses a **WETH MockPriceFeed** (`CHAIN138_WETH_MOCK_PRICE_FEED`), run `scripts/reserve/sync-weth-mock-price.sh` on a schedule (or from the same cron as the mesh) so ReserveSystem WETH tracks the market. +6. Start: `nohup ./scripts/reserve/pmm-mesh-6s-automation.sh >> logs/pmm-mesh-automation.log 2>&1 &` (optional: `MESH_CAST_GAS_PRICE=2gwei` for Besu) + +**Note:** On-chain PMM curves still move on **swaps**; this loop **does not** replace liquidity. It **feeds** oracles/keeper and **observes** PMM/WETH state on a fixed cadence. + +--- + ## PMM and Reporting - **DODOPMMIntegration**: Optional `setReserveSystem(ReserveSystem)`; then `getPoolPriceOrOracle(pool)` uses ReserveSystem when base/quote are registered. diff --git a/docs/integration/QUICK_START.md b/docs/integration/QUICK_START.md index 50fd89f..b43b337 100644 --- a/docs/integration/QUICK_START.md +++ b/docs/integration/QUICK_START.md @@ -37,8 +37,9 @@ export RPC_URL=http://192.168.11.250:8545 # Chain 138 export DODO_VENDING_MACHINE_ADDRESS=0x... # Check DODO docs export COMPLIANT_USDT_ADDRESS=0x93E66202A11B1772E55407B32B44e5Cd8eda7f22 export COMPLIANT_USDC_ADDRESS=0xf22258f57794CC8E06237084b353Ab30fFfa640b -export OFFICIAL_USDT_ADDRESS=0xdAC17F958D2ee523a2206206994597C13D831ec7 -export OFFICIAL_USDC_ADDRESS=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 +# Chain 138 local quote-side mirror stables +export OFFICIAL_USDT_ADDRESS=0x004b63A7B5b0E06f6bB6adb4a5F9f590BF3182D1 +export OFFICIAL_USDC_ADDRESS=0x71D6687F38b93CCad569Fa6352c876eea967201b # Deploy forge script script/dex/DeployDODOPMMIntegration.s.sol:DeployDODOPMMIntegration \ @@ -147,4 +148,3 @@ cast call $DODO_PMM_INTEGRATION_ADDRESS \ 5. Enable trading See `COMPLETE_INTEGRATION_GUIDE.md` for detailed instructions. - diff --git a/docs/tokenization/TOKEN_SCOPE_GRU.md b/docs/tokenization/TOKEN_SCOPE_GRU.md index e31e5d3..6ff8f5b 100644 --- a/docs/tokenization/TOKEN_SCOPE_GRU.md +++ b/docs/tokenization/TOKEN_SCOPE_GRU.md @@ -18,8 +18,8 @@ This document lists GRU-M1 base money, ISO-4217 W tokens, Aave-style asset/debt | cJPYC | CompliantFiatToken.sol | Specified| 6 | JPY (often 0 or 2 decimals; 6 for uniformity). | | cCHFC | CompliantFiatToken.sol | Specified| 6 | CHF. | | cCADC | CompliantFiatToken.sol | Specified| 6 | CAD. | -| cXAUC | CompliantFiatToken.sol | Specified| 6 | XAU-backed. | -| cXAUT | CompliantFiatToken.sol | Specified| 6 | Tether XAU. | +| cXAUC | CompliantFiatToken.sol | Specified| 6 | XAU; **1 token = 1 troy oz Au** (canonical). | +| cXAUT | CompliantFiatToken.sol | Specified| 6 | XAU; **1 token = 1 troy oz Au** (canonical). | | LiXAU | — | Specified| 6 | XAU-liquidity-adjusted; map or add. | Properties for all: ISO-4217 aligned naming and decimals, non-interest-bearing, fully redeemable, E-Money safeguards, reserve attestation hooks. Full ERC-20 (transfer, approve, balanceOf) for DEX pools. diff --git a/env.additions.example b/env.additions.example index eadd3b0..d87c19b 100644 --- a/env.additions.example +++ b/env.additions.example @@ -10,9 +10,13 @@ DODO_PMM_PROVIDER_ADDRESS=0x5CAe6Ce155b7f08D3a956F5Dc82fC9945f29B381 # DODO PMM Integration (Chain 138) DODO_PMM_INTEGRATION_ADDRESS=0x5BDc62f1ae7D630c37A8B363a1d49845356Ee72d +# Local quote-side mirror stables (Chain 138); optional — see deploy runbooks +OFFICIAL_USDT_ADDRESS=0x004b63A7B5b0E06f6bB6adb4a5F9f590BF3182D1 +OFFICIAL_USDC_ADDRESS=0x71D6687F38b93CCad569Fa6352c876eea967201b + # PMM pool addresses (optional; RegisterDODOPools reads from integration if unset) POOL_CUSDTCUSDC=0x9fcB06Aa1FD5215DC0E91Fd098aeff4B62fEa5C8 -POOL_CUSDTUSDT=0x6fc60DEDc92a2047062294488539992710b99D71 +POOL_CUSDTUSDT=0xa3Ee6091696B28e5497b6F491fA1e99047250c59 POOL_CUSDCUSDC=0x90bd9Bf18Daa26Af3e814ea224032d015db58Ea5 # Token-aggregation (quote API): same integration address so indexer can index DODO pools diff --git a/foundry.toml b/foundry.toml index 5a3f994..a670802 100644 --- a/foundry.toml +++ b/foundry.toml @@ -10,6 +10,9 @@ optimizer = true optimizer_runs = 200 via_ir = true evm_version = "london" +fs_permissions = [ + { access = "read", path = "./config" } +] remappings = [ "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", @@ -55,4 +58,3 @@ arbitrum = { key = "${ARBISCAN_API_KEY:-${ETHERSCAN_API_KEY}}", url = "https://a # Cronos mainnet (chain 25). Etherscan-style API; chainid required for v2. # API key from explorer.cronos.org/register (CRONOSCAN_API_KEY) cronos = { key = "${CRONOSCAN_API_KEY:-${ETHERSCAN_API_KEY}}", url = "https://explorer-api.cronos.org/mainnet/api?chainid=25" } - diff --git a/script/DeployOfficialUSDC138.s.sol b/script/DeployOfficialUSDC138.s.sol new file mode 100644 index 0000000..3c21a54 --- /dev/null +++ b/script/DeployOfficialUSDC138.s.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {Script, console} from "forge-std/Script.sol"; +import {OfficialStableMirrorToken} from "../contracts/tokens/OfficialStableMirrorToken.sol"; + +/** + * @title DeployOfficialUSDC138 + * @notice Deploy the local Chain 138 quote-side USDC mirror used by DODO PMM pools. + */ +contract DeployOfficialUSDC138 is Script { + function run() external { + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + address deployer = vm.addr(deployerPrivateKey); + address owner = vm.envOr("OFFICIAL_USDC_138_OWNER", deployer); + uint256 initialSupply = vm.envOr("OFFICIAL_USDC_138_INITIAL_SUPPLY", uint256(0)); + + console.log("Deploying Official USDC (Chain 138) with deployer:", vm.toString(deployer)); + console.log("Owner:", vm.toString(owner)); + console.log("Initial supply:", initialSupply); + + vm.startBroadcast(deployerPrivateKey); + + OfficialStableMirrorToken token = new OfficialStableMirrorToken( + "USD Coin (Chain 138)", + "USDC", + 6, + owner, + initialSupply + ); + + console.log("Official USDC (Chain 138) deployed at:", vm.toString(address(token))); + + vm.stopBroadcast(); + } +} diff --git a/script/DeployOfficialUSDT138.s.sol b/script/DeployOfficialUSDT138.s.sol new file mode 100644 index 0000000..6438f9f --- /dev/null +++ b/script/DeployOfficialUSDT138.s.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {Script, console} from "forge-std/Script.sol"; +import {OfficialStableMirrorToken} from "../contracts/tokens/OfficialStableMirrorToken.sol"; + +/** + * @title DeployOfficialUSDT138 + * @notice Deploy the local Chain 138 quote-side USDT mirror used by DODO PMM pools. + */ +contract DeployOfficialUSDT138 is Script { + function run() external { + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + address deployer = vm.addr(deployerPrivateKey); + address owner = vm.envOr("OFFICIAL_USDT_138_OWNER", deployer); + uint256 initialSupply = vm.envOr("OFFICIAL_USDT_138_INITIAL_SUPPLY", uint256(0)); + + console.log("Deploying Official USDT (Chain 138) with deployer:", vm.toString(deployer)); + console.log("Owner:", vm.toString(owner)); + console.log("Initial supply:", initialSupply); + + vm.startBroadcast(deployerPrivateKey); + + OfficialStableMirrorToken token = new OfficialStableMirrorToken( + "Tether USD (Chain 138)", + "USDT", + 6, + owner, + initialSupply + ); + + console.log("Official USDT (Chain 138) deployed at:", vm.toString(address(token))); + + vm.stopBroadcast(); + } +} diff --git a/script/bridge/trustless/DeployEnhancedSwapRouter.s.sol b/script/bridge/trustless/DeployEnhancedSwapRouter.s.sol index f1a27d8..2425065 100644 --- a/script/bridge/trustless/DeployEnhancedSwapRouter.s.sol +++ b/script/bridge/trustless/DeployEnhancedSwapRouter.s.sol @@ -10,6 +10,8 @@ import "../../../contracts/bridge/trustless/EnhancedSwapRouter.sol"; * @dev Deploys EnhancedSwapRouter with Uniswap V3, Curve, Dodoex, Balancer, and 1inch */ contract DeployEnhancedSwapRouter is Script { + address constant PLACEHOLDER = 0x000000000000000000000000000000000000dEaD; + // Ethereum Mainnet addresses address constant UNISWAP_V3_ROUTER = 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45; address constant CURVE_3POOL = 0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7; @@ -21,39 +23,77 @@ contract DeployEnhancedSwapRouter is Script { address constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; address constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F; + // Chain 138 canonical token addresses + address constant CHAIN138_WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; + address constant CHAIN138_USDT = 0x004b63A7B5b0E06f6bB6adb4a5F9f590BF3182D1; + address constant CHAIN138_USDC = 0x71D6687F38b93CCad569Fa6352c876eea967201b; + address constant CHAIN138_DAI_PLACEHOLDER = 0x6B175474E89094C44Da98b954EedeAC495271d0F; + + // Chain 138 live DODO pool map (2026-03-26) + address constant CHAIN138_cUSDT = 0x93E66202A11B1772E55407B32B44e5Cd8eda7f22; + address constant CHAIN138_cUSDC = 0xf22258f57794CC8E06237084b353Ab30fFfa640b; + address constant CHAIN138_cEURT = 0xdf4b71c61E5912712C1Bdd451416B9aC26949d72; + address constant CHAIN138_cXAUC = 0x290E52a8819A4fbD0714E517225429aA2B70EC6b; + address constant CHAIN138_POOL_CUSDTCUSDC = 0xff8d3b8fDF7B112759F076B69f4271D4209C0849; + address constant CHAIN138_POOL_CUSDTUSDT = 0x6fc60DEDc92a2047062294488539992710b99D71; + address constant CHAIN138_POOL_CUSDCUSDC = 0x0309178Ae30302D83C76d6DD402a684ef3160eeC; + address constant CHAIN138_POOL_CUSDT_XAU_PUBLIC = 0x1AA55E2001E5651349aFf5a63FD7a7ae44f0f1b0; + address constant CHAIN138_POOL_CUSDC_XAU_PUBLIC = 0xEa9AC6357CaCB42a83b9082B870610363b177CbA; + address constant CHAIN138_POOL_CEURT_XAU_PUBLIC = 0xba99bc1eAac164569d5aca96c806934dDaf970CF; + function run() external { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); address deployer = vm.addr(deployerPrivateKey); + uint256 chainId = block.chainid; + bool isMainnet = chainId == 1; + bool isChain138 = chainId == 138; + + require(isMainnet || isChain138, "DeployEnhancedSwapRouter: supported chains are Ethereum Mainnet and Chain 138"); + + ( + address uniswapV3Router, + address curve3Pool, + address dodoexRouter, + address balancerVault, + address oneInchRouter, + address weth, + address usdt, + address usdc, + address dai + ) = _resolveAddresses(chainId); console.log("=== EnhancedSwapRouter Deployment ==="); console.log("Deployer:", deployer); - console.log("Chain ID:", block.chainid); - - require(block.chainid == 1, "DeployEnhancedSwapRouter: Ethereum Mainnet only"); + console.log("Chain ID:", chainId); + if (isChain138) { + console.log("Mode: Chain 138 env-driven deployment"); + console.log("Note: live DODO pools are stable/stable and stable/XAU."); + console.log("Note: WETH->stable routing remains optional until real WETH routes are configured."); + } vm.startBroadcast(deployerPrivateKey); console.log("\n--- Deploying EnhancedSwapRouter ---"); - console.log("Uniswap V3 Router:", UNISWAP_V3_ROUTER); - console.log("Curve 3Pool:", CURVE_3POOL); - console.log("Dodoex Router:", DODOEX_ROUTER); - console.log("Balancer Vault:", BALANCER_VAULT); - console.log("1inch Router:", ONEINCH_ROUTER); - console.log("WETH:", WETH); - console.log("USDT:", USDT); - console.log("USDC:", USDC); - console.log("DAI:", DAI); + console.log("Uniswap V3 Router:", uniswapV3Router); + console.log("Curve 3Pool:", curve3Pool); + console.log("Dodoex Router:", dodoexRouter); + console.log("Balancer Vault:", balancerVault); + console.log("1inch Router:", oneInchRouter); + console.log("WETH:", weth); + console.log("USDT:", usdt); + console.log("USDC:", usdc); + console.log("DAI:", dai); EnhancedSwapRouter router = new EnhancedSwapRouter( - UNISWAP_V3_ROUTER, - CURVE_3POOL, - DODOEX_ROUTER, - BALANCER_VAULT, - ONEINCH_ROUTER, - WETH, - USDT, - USDC, - DAI + uniswapV3Router, + curve3Pool, + dodoexRouter, + balancerVault, + oneInchRouter, + weth, + usdt, + usdc, + dai ); console.log("\nEnhancedSwapRouter deployed at:", address(router)); @@ -62,7 +102,11 @@ contract DeployEnhancedSwapRouter is Script { router.grantRole(router.ROUTING_MANAGER_ROLE(), deployer); // Configure default routing - _configureDefaultRouting(router, deployer); + _configureDefaultRouting(router); + + if (isChain138) { + _configureChain138InitialState(router, uniswapV3Router, curve3Pool, dodoexRouter, balancerVault, oneInchRouter); + } vm.stopBroadcast(); @@ -70,9 +114,13 @@ contract DeployEnhancedSwapRouter is Script { console.log("EnhancedSwapRouter:", address(router)); console.log("\n=== Export to .env ==="); console.log("export ENHANCED_SWAP_ROUTER=", vm.toString(address(router))); + if (isChain138) { + console.log("export ENHANCED_SWAP_ROUTER_CHAIN138=", vm.toString(address(router))); + console.log("export ENHANCED_SWAP_ROUTER_ADDRESS=", vm.toString(address(router))); + } } - function _configureDefaultRouting(EnhancedSwapRouter router, address deployer) internal { + function _configureDefaultRouting(EnhancedSwapRouter router) internal { console.log("\n--- Configuring Default Routing ---"); // Small swaps (< $10k): Uniswap V3, Dodoex @@ -102,5 +150,110 @@ contract DeployEnhancedSwapRouter is Script { // after identifying the actual pool addresses console.log("\nWARNING: Remember to configure Balancer pool IDs after deployment"); } -} + function _configureChain138InitialState( + EnhancedSwapRouter router, + address uniswapV3Router, + address curve3Pool, + address dodoexRouter, + address balancerVault, + address oneInchRouter + ) internal { + console.log("\n--- Chain 138 Initial Configuration ---"); + address dodoPmmProvider = vm.envOr("DODO_PMM_PROVIDER_ADDRESS", address(0)); + if (dodoPmmProvider == address(0)) { + dodoPmmProvider = vm.envOr("DODO_PMM_PROVIDER", address(0)); + } + + _registerPair(router, CHAIN138_cUSDT, CHAIN138_cUSDC, CHAIN138_POOL_CUSDTCUSDC); + _registerPair(router, CHAIN138_cUSDT, CHAIN138_USDT, CHAIN138_POOL_CUSDTUSDT); + _registerPair(router, CHAIN138_cUSDC, CHAIN138_USDC, CHAIN138_POOL_CUSDCUSDC); + _registerPair(router, CHAIN138_cUSDT, CHAIN138_cXAUC, CHAIN138_POOL_CUSDT_XAU_PUBLIC); + _registerPair(router, CHAIN138_cUSDC, CHAIN138_cXAUC, CHAIN138_POOL_CUSDC_XAU_PUBLIC); + _registerPair(router, CHAIN138_cEURT, CHAIN138_cXAUC, CHAIN138_POOL_CEURT_XAU_PUBLIC); + + if (dodoPmmProvider != address(0)) { + router.setDodoLiquidityProvider(dodoPmmProvider); + console.log("Configured DODO PMM provider:", dodoPmmProvider); + } + + // Disable providers that are definitely not usable until explicitly configured on Chain 138. + if (curve3Pool == PLACEHOLDER) { + router.setProviderEnabled(EnhancedSwapRouter.SwapProvider.Curve, false); + console.log("Disabled Curve provider (placeholder address)"); + } + if (balancerVault == PLACEHOLDER) { + router.setProviderEnabled(EnhancedSwapRouter.SwapProvider.Balancer, false); + console.log("Disabled Balancer provider (placeholder address)"); + } + if (oneInchRouter == PLACEHOLDER) { + router.setProviderEnabled(EnhancedSwapRouter.SwapProvider.OneInch, false); + console.log("Disabled 1inch provider (placeholder address)"); + } + if (uniswapV3Router == PLACEHOLDER) { + router.setProviderEnabled(EnhancedSwapRouter.SwapProvider.UniswapV3, false); + console.log("Disabled Uniswap V3 provider (placeholder address)"); + } + if (dodoexRouter == PLACEHOLDER && dodoPmmProvider == address(0)) { + router.setProviderEnabled(EnhancedSwapRouter.SwapProvider.Dodoex, false); + console.log("Disabled Dodoex provider (no router and no PMM provider configured)"); + } else { + console.log("Dodo pool mappings registered for current live Chain 138 pairs."); + } + + console.log("WARNING: swapToStablecoin() still needs real WETH->stable routes to be useful on Chain 138."); + console.log("WARNING: current Chain 138 DODO initialization is primarily for token-to-token pair mappings via swapTokenToToken()."); + } + + function _registerPair( + EnhancedSwapRouter router, + address tokenA, + address tokenB, + address pool + ) internal { + router.setDodoPoolAddress(tokenA, tokenB, pool); + router.setDodoPoolAddress(tokenB, tokenA, pool); + console.log("Registered DODO pool:", pool); + } + + function _resolveAddresses( + uint256 chainId + ) + internal + returns ( + address uniswapV3Router, + address curve3Pool, + address dodoexRouter, + address balancerVault, + address oneInchRouter, + address weth, + address usdt, + address usdc, + address dai + ) + { + if (chainId == 1) { + uniswapV3Router = vm.envOr("UNISWAP_V3_ROUTER", UNISWAP_V3_ROUTER); + curve3Pool = vm.envOr("CURVE_3POOL", CURVE_3POOL); + dodoexRouter = vm.envOr("DODOEX_ROUTER", DODOEX_ROUTER); + balancerVault = vm.envOr("BALANCER_VAULT", BALANCER_VAULT); + oneInchRouter = vm.envOr("ONEINCH_ROUTER", ONEINCH_ROUTER); + weth = vm.envOr("WETH", WETH); + usdt = vm.envOr("USDT", USDT); + usdc = vm.envOr("USDC", USDC); + dai = vm.envOr("DAI", DAI); + return (uniswapV3Router, curve3Pool, dodoexRouter, balancerVault, oneInchRouter, weth, usdt, usdc, dai); + } + + // Chain 138: use canonical token defaults and env-driven protocol addresses. + uniswapV3Router = vm.envOr("UNISWAP_V3_ROUTER", PLACEHOLDER); + curve3Pool = vm.envOr("CURVE_3POOL", PLACEHOLDER); + dodoexRouter = vm.envOr("DODOEX_ROUTER", PLACEHOLDER); + balancerVault = vm.envOr("BALANCER_VAULT", PLACEHOLDER); + oneInchRouter = vm.envOr("ONEINCH_ROUTER", PLACEHOLDER); + weth = vm.envOr("WETH", CHAIN138_WETH); + usdt = vm.envOr("OFFICIAL_USDT_ADDRESS", CHAIN138_USDT); + usdc = vm.envOr("OFFICIAL_USDC_ADDRESS", CHAIN138_USDC); + dai = vm.envOr("DAI", CHAIN138_DAI_PLACEHOLDER); + } +} diff --git a/script/deploy/DeployCompliantFiatTokens.s.sol b/script/deploy/DeployCompliantFiatTokens.s.sol index 5f79153..7a33705 100644 --- a/script/deploy/DeployCompliantFiatTokens.s.sol +++ b/script/deploy/DeployCompliantFiatTokens.s.sol @@ -9,10 +9,11 @@ import {CompliantFiatToken} from "../../contracts/tokens/CompliantFiatToken.sol" * @title DeployCompliantFiatTokens * @notice Deterministic deployment of CompliantFiatToken (cEURC, cEURT, cGBPC, cGBPT, cAUDC, cJPYC, cCHFC, cCADC, cXAUC, cXAUT; optional cCADT) via CREATE2. * @dev Use same ADMIN/OWNER and salts per chain for identical addresses. See docs/runbooks and TOKEN_SCOPE_GRU.md. + * cXAUC/cXAUT use currency code XAU: **1 full token = 1 troy oz Au** (see CompliantFiatToken NatSpec). */ contract DeployCompliantFiatTokens is Script { uint256 constant DECIMALS = 6; - uint256 constant INITIAL_SUPPLY = 1_000_000 * 10**6; // 1M tokens + uint256 constant INITIAL_SUPPLY = 1_000_000 * 10**6; // 1M units: fiat = currency units; XAU = troy ounces function run() external { uint256 pk = vm.envUint("PRIVATE_KEY"); diff --git a/script/deploy/DeployCompliantFiatTokensForChain.s.sol b/script/deploy/DeployCompliantFiatTokensForChain.s.sol index 6cc5850..d349416 100644 --- a/script/deploy/DeployCompliantFiatTokensForChain.s.sol +++ b/script/deploy/DeployCompliantFiatTokensForChain.s.sol @@ -17,10 +17,12 @@ import {CompliantFiatToken} from "../../contracts/tokens/CompliantFiatToken.sol" * OWNER, ADMIN (optional; default deployer) * DEPLOY_CUSDT=1, DEPLOY_CUSDC=1 (default both 1) * DEPLOY_CEURC=1, DEPLOY_CEURT=1, ... (optional; deploy extra CompliantFiatToken) + * + * XAU: cXAUC/cXAUT — 1 full token = 1 troy ounce Au (see CompliantFiatToken). */ contract DeployCompliantFiatTokensForChain is Script { uint256 constant DECIMALS = 6; - uint256 constant INITIAL_SUPPLY = 1_000_000 * 10**6; // 1M + uint256 constant INITIAL_SUPPLY = 1_000_000 * 10**6; // 1M units (fiat: currency; XAU: troy oz) function run() external { uint256 pk = vm.envUint("PRIVATE_KEY"); diff --git a/script/dex/AddLiquidityPMMPoolsChain138.s.sol b/script/dex/AddLiquidityPMMPoolsChain138.s.sol index a38e83d..3f93a90 100644 --- a/script/dex/AddLiquidityPMMPoolsChain138.s.sol +++ b/script/dex/AddLiquidityPMMPoolsChain138.s.sol @@ -41,9 +41,8 @@ contract AddLiquidityPMMPoolsChain138 is Script { address usdt = integration.officialUSDT(); address usdc = integration.officialUSDC(); - // On Chain 138, DODOPMMIntegration may have been deployed with mainnet official USDT/USDC - // (0xdAC17F958D2ee523a2206206994597C13D831ec7, 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48). - // Those addresses have no code on 138, so skip cUSDT/USDT and cUSDC/USDC to avoid "call to non-contract". + // On Chain 138, cUSDT/USDT and cUSDC/USDC should point at live local mirror quote tokens. + // If the configured quote-side addresses have no code on 138, skip those pools to avoid "call to non-contract". bool skipOfficialPools = block.chainid == 138 && ( !_isContract(usdt) || !_isContract(usdc) ); diff --git a/script/dex/CreatePublicXAUPoolsChain138.s.sol b/script/dex/CreatePublicXAUPoolsChain138.s.sol new file mode 100644 index 0000000..f1ea761 --- /dev/null +++ b/script/dex/CreatePublicXAUPoolsChain138.s.sol @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {Script, console} from "forge-std/Script.sol"; +import {DODOPMMIntegration} from "../../contracts/dex/DODOPMMIntegration.sol"; + +/** + * @title CreatePublicXAUPoolsChain138 + * @notice Create the public XAU-anchored pools on Chain 138 using the configured cXAU anchor token. + * @dev Env: + * - PRIVATE_KEY + * - DODOPMM_INTEGRATION or DODOPMM_INTEGRATION_ADDRESS + * - XAU_ADDRESS_138 or CXAUC_ADDRESS_138 or CXAUT_ADDRESS_138 + * Optional: + * - COMPLIANT_USDT_ADDRESS, COMPLIANT_USDC_ADDRESS, cEURT_ADDRESS_138 + * - CREATE_CUSDT_XAU=1, CREATE_CUSDC_XAU=1, CREATE_CEURT_XAU=1 + */ +contract CreatePublicXAUPoolsChain138 is Script { + address internal constant CHAIN138_CUSDT = 0x93E66202A11B1772E55407B32B44e5Cd8eda7f22; + address internal constant CHAIN138_CUSDC = 0xf22258f57794CC8E06237084b353Ab30fFfa640b; + address internal constant CHAIN138_CEURT = 0xdf4b71c61E5912712C1Bdd451416B9aC26949d72; + address internal constant CHAIN138_CXAUC = 0x290E52a8819A4fbD0714E517225429aA2B70EC6b; + address internal constant CHAIN138_CXAUT = 0x94e408E26c6FD8F4ee00b54dF19082FDA07dC96E; + + uint256 internal constant LP_FEE_BPS = 3; + uint256 internal constant INITIAL_PRICE_1E18 = 1e18; + uint256 internal constant K_50PCT = 0.5e18; + bool internal constant USE_TWAP = true; + + function run() external { + uint256 pk = vm.envUint("PRIVATE_KEY"); + address integrationAddr = vm.envOr("DODOPMM_INTEGRATION", address(0)); + if (integrationAddr == address(0)) integrationAddr = vm.envOr("DODOPMM_INTEGRATION_ADDRESS", address(0)); + require(integrationAddr != address(0), "DODOPMM_INTEGRATION not set"); + + address xau = vm.envOr("XAU_ADDRESS_138", address(0)); + if (xau == address(0)) xau = vm.envOr("CXAUC_ADDRESS_138", address(0)); + if (xau == address(0)) xau = vm.envOr("CXAUT_ADDRESS_138", address(0)); + if (xau == address(0) && block.chainid == 138) xau = CHAIN138_CXAUC; + require(xau != address(0), "XAU anchor not set"); + + address cUSDT = vm.envOr("COMPLIANT_USDT_ADDRESS", address(0)); + address cUSDC = vm.envOr("COMPLIANT_USDC_ADDRESS", address(0)); + address cEURT = vm.envOr("cEURT_ADDRESS_138", address(0)); + + if (cUSDT == address(0) && block.chainid == 138) cUSDT = CHAIN138_CUSDT; + if (cUSDC == address(0) && block.chainid == 138) cUSDC = CHAIN138_CUSDC; + if (cEURT == address(0) && block.chainid == 138) cEURT = CHAIN138_CEURT; + + bool createCUSDT = vm.envOr("CREATE_CUSDT_XAU", true); + bool createCUSDC = vm.envOr("CREATE_CUSDC_XAU", true); + bool createCEURT = vm.envOr("CREATE_CEURT_XAU", true); + + DODOPMMIntegration integration = DODOPMMIntegration(integrationAddr); + + vm.startBroadcast(pk); + + if (createCUSDT && cUSDT != address(0)) { + _createIfMissing(integration, cUSDT, xau, "cUSDT/XAU"); + } + if (createCUSDC && cUSDC != address(0)) { + _createIfMissing(integration, cUSDC, xau, "cUSDC/XAU"); + } + if (createCEURT && cEURT != address(0)) { + _createIfMissing(integration, cEURT, xau, "cEURT/XAU"); + } + + vm.stopBroadcast(); + + console.log("Public XAU pools checked against anchor:", xau == CHAIN138_CXAUC ? "cXAUC" : (xau == CHAIN138_CXAUT ? "cXAUT" : "custom")); + console.log("Default Chain 138 XAU anchors:", vm.toString(CHAIN138_CXAUC), vm.toString(CHAIN138_CXAUT)); + } + + function _createIfMissing( + DODOPMMIntegration integration, + address base, + address quote, + string memory label + ) internal { + address existing = integration.pools(base, quote); + if (existing != address(0)) { + console.log(label, "already exists at", existing); + return; + } + + address pool = integration.createPool(base, quote, LP_FEE_BPS, INITIAL_PRICE_1E18, K_50PCT, USE_TWAP); + console.log(label, "created at", pool); + } +} diff --git a/script/dex/DeployDODOPMMIntegration.s.sol b/script/dex/DeployDODOPMMIntegration.s.sol index 8740557..40666ec 100644 --- a/script/dex/DeployDODOPMMIntegration.s.sol +++ b/script/dex/DeployDODOPMMIntegration.s.sol @@ -24,8 +24,16 @@ contract DeployDODOPMMIntegration is Script { address compliantUSDT = vm.envOr("COMPLIANT_USDT_ADDRESS", address(0)); address compliantUSDC = vm.envOr("COMPLIANT_USDC_ADDRESS", address(0)); - if (dodoVendingMachine == address(0) || compliantUSDT == address(0) || compliantUSDC == address(0)) { - console.log("Skipping DODO PMM deploy: set DODO_VENDING_MACHINE_ADDRESS, COMPLIANT_USDT_ADDRESS, COMPLIANT_USDC_ADDRESS in .env"); + if ( + dodoVendingMachine == address(0) || + officialUSDT == address(0) || + officialUSDC == address(0) || + compliantUSDT == address(0) || + compliantUSDC == address(0) + ) { + console.log( + "Skipping DODO PMM deploy: set DODO_VENDING_MACHINE_ADDRESS, OFFICIAL_USDT_ADDRESS, OFFICIAL_USDC_ADDRESS, COMPLIANT_USDT_ADDRESS, COMPLIANT_USDC_ADDRESS in .env" + ); return; } @@ -64,4 +72,3 @@ contract DeployDODOPMMIntegration is Script { console.log("3. Configure pool parameters (lpFeeRate, k, initialPrice)"); } } - diff --git a/script/dex/DeployPrivatePoolRegistryAndPools.s.sol b/script/dex/DeployPrivatePoolRegistryAndPools.s.sol index f2efddc..7bd9a4f 100644 --- a/script/dex/DeployPrivatePoolRegistryAndPools.s.sol +++ b/script/dex/DeployPrivatePoolRegistryAndPools.s.sol @@ -13,6 +13,8 @@ import {DODOPMMIntegration} from "../../contracts/dex/DODOPMMIntegration.sol"; * Deployer must have POOL_MANAGER_ROLE on DODOPMMIntegration to create pools. */ contract DeployPrivatePoolRegistryAndPools is Script { + address internal constant CHAIN138_CXAUC = 0x290E52a8819A4fbD0714E517225429aA2B70EC6b; + address internal constant CHAIN138_CXAUT = 0x94e408E26c6FD8F4ee00b54dF19082FDA07dC96E; uint256 constant LP_FEE_BPS = 3; uint256 constant INITIAL_PRICE_1E18 = 1e18; uint256 constant K_50PCT = 0.5e18; @@ -29,35 +31,37 @@ contract DeployPrivatePoolRegistryAndPools is Script { console.log("PrivatePoolRegistry deployed at:", vm.toString(address(registry))); address integrationAddr = vm.envOr("DODOPMM_INTEGRATION_ADDRESS", address(0)); + if (integrationAddr == address(0)) integrationAddr = vm.envOr("DODO_PMM_INTEGRATION_ADDRESS", address(0)); + if (integrationAddr == address(0)) integrationAddr = vm.envOr("DODOPMM_INTEGRATION", address(0)); + if (integrationAddr == address(0)) integrationAddr = vm.envOr("DODO_PMM_INTEGRATION", address(0)); address xau = vm.envOr("XAU_ADDRESS_138", address(0)); + if (xau == address(0)) xau = vm.envOr("CXAUC_ADDRESS_138", address(0)); + if (xau == address(0)) xau = vm.envOr("CXAUT_ADDRESS_138", address(0)); + if (xau == address(0) && block.chainid == 138) xau = CHAIN138_CXAUC; if (integrationAddr != address(0) && xau != address(0)) { address cUSDT = vm.envOr("COMPLIANT_USDT_ADDRESS", address(0)); address cUSDC = vm.envOr("COMPLIANT_USDC_ADDRESS", address(0)); address cEURT = vm.envOr("cEURT_ADDRESS_138", address(0)); + if (cUSDT == address(0) && block.chainid == 138) cUSDT = 0x93E66202A11B1772E55407B32B44e5Cd8eda7f22; + if (cUSDC == address(0) && block.chainid == 138) cUSDC = 0xf22258f57794CC8E06237084b353Ab30fFfa640b; + if (cEURT == address(0) && block.chainid == 138) cEURT = 0xdf4b71c61E5912712C1Bdd451416B9aC26949d72; DODOPMMIntegration integration = DODOPMMIntegration(integrationAddr); if (cUSDT != address(0)) { - try integration.createPool(cUSDT, xau, LP_FEE_BPS, INITIAL_PRICE_1E18, K_50PCT, USE_TWAP) returns (address pool) { - registry.register(cUSDT, xau, pool); - console.log("Created and registered cUSDT/XAU pool:", vm.toString(pool)); - } catch {} + _ensureRegistered(registry, integration, cUSDT, xau, "cUSDT/XAU"); } if (cUSDC != address(0)) { - try integration.createPool(cUSDC, xau, LP_FEE_BPS, INITIAL_PRICE_1E18, K_50PCT, USE_TWAP) returns (address pool) { - registry.register(cUSDC, xau, pool); - console.log("Created and registered cUSDC/XAU pool:", vm.toString(pool)); - } catch {} + _ensureRegistered(registry, integration, cUSDC, xau, "cUSDC/XAU"); } if (cEURT != address(0)) { - try integration.createPool(cEURT, xau, LP_FEE_BPS, INITIAL_PRICE_1E18, K_50PCT, USE_TWAP) returns (address pool) { - registry.register(cEURT, xau, pool); - console.log("Created and registered cEURT/XAU pool:", vm.toString(pool)); - } catch {} + _ensureRegistered(registry, integration, cEURT, xau, "cEURT/XAU"); } } else { - console.log("Skipping pool creation (set DODOPMM_INTEGRATION_ADDRESS and XAU_ADDRESS_138 to create XAU-anchored pools)"); + console.log( + "Skipping pool creation (set DODOPMM_INTEGRATION_ADDRESS and XAU_ADDRESS_138/CXAUC_ADDRESS_138/CXAUT_ADDRESS_138 to create XAU-anchored pools)" + ); } vm.stopBroadcast(); @@ -65,5 +69,30 @@ contract DeployPrivatePoolRegistryAndPools is Script { console.log("\n=== Deployment Summary ==="); console.log("PrivatePoolRegistry:", vm.toString(address(registry))); console.log("Admin:", vm.toString(admin)); + console.log("Default XAU anchor on Chain 138:", vm.toString(CHAIN138_CXAUC)); + console.log("Alternate XAU anchor on Chain 138:", vm.toString(CHAIN138_CXAUT)); + } + + function _ensureRegistered( + PrivatePoolRegistry registry, + DODOPMMIntegration integration, + address base, + address quote, + string memory label + ) internal { + address pool = integration.pools(base, quote); + if (pool == address(0)) { + pool = integration.createPool(base, quote, LP_FEE_BPS, INITIAL_PRICE_1E18, K_50PCT, USE_TWAP); + console.log("Created", label, "pool:", vm.toString(pool)); + } else { + console.log(label, "pool already exists:", vm.toString(pool)); + } + + if (registry.getPrivatePool(base, quote) == address(0)) { + registry.register(base, quote, pool); + console.log("Registered", label, "pool:", vm.toString(pool)); + } else { + console.log(label, "already registered:", vm.toString(registry.getPrivatePool(base, quote))); + } } } diff --git a/script/liquidity/ImportProviderPoolsToIntegration.s.sol b/script/liquidity/ImportProviderPoolsToIntegration.s.sol new file mode 100644 index 0000000..64581cc --- /dev/null +++ b/script/liquidity/ImportProviderPoolsToIntegration.s.sol @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {Script, stdJson, console} from "forge-std/Script.sol"; +import {DODOPMMIntegration} from "../../contracts/dex/DODOPMMIntegration.sol"; +import {DODOPMMProvider} from "../../contracts/liquidity/providers/DODOPMMProvider.sol"; + +/** + * @title ImportProviderPoolsToIntegration + * @notice Import provider-known pools into DODOPMMIntegration using the desired-state JSON. + * @dev This is the migration path for stale provider-only pools that already exist as DODO pool + * contracts but are missing from integration.pools / allPools / poolConfigs. + * + * Required env: + * - PRIVATE_KEY + * - DODO_PMM_INTEGRATION_ADDRESS (or DODO_PMM_INTEGRATION) + * - DODO_PMM_PROVIDER_ADDRESS (or DODO_PMM_PROVIDER) for target provider compatibility + * + * Optional env: + * - DODO_PMM_PROVIDER_SOURCE_ADDRESS (or DODO_PMM_PROVIDER_SOURCE) to read from an existing provider + * - POOL_CONFIG_JSON (defaults to smom-dbis-138/config/chain138-pmm-pools.json) + * - LP_FEE_RATE / INITIAL_PRICE / K_FACTOR / ENABLE_TWAP to override JSON defaults + */ +contract ImportProviderPoolsToIntegration is Script { + using stdJson for string; + + string internal constant DEFAULT_CONFIG_PATH = "config/chain138-pmm-pools.json"; + + function run() external { + uint256 pk = vm.envUint("PRIVATE_KEY"); + address integrationAddr = vm.envAddress("DODO_PMM_INTEGRATION_ADDRESS"); + if (integrationAddr == address(0)) integrationAddr = vm.envAddress("DODO_PMM_INTEGRATION"); + address providerAddr = vm.envAddress("DODO_PMM_PROVIDER_ADDRESS"); + if (providerAddr == address(0)) providerAddr = vm.envAddress("DODO_PMM_PROVIDER"); + address providerSourceAddr = vm.envOr("DODO_PMM_PROVIDER_SOURCE_ADDRESS", address(0)); + if (providerSourceAddr == address(0)) providerSourceAddr = vm.envOr("DODO_PMM_PROVIDER_SOURCE", address(0)); + if (providerSourceAddr == address(0)) providerSourceAddr = providerAddr; + require(integrationAddr != address(0), "DODO_PMM_INTEGRATION_ADDRESS not set"); + require(providerAddr != address(0), "DODO_PMM_PROVIDER_ADDRESS not set"); + + string memory path = vm.envOr("POOL_CONFIG_JSON", string(DEFAULT_CONFIG_PATH)); + string memory json = vm.readFile(path); + + DODOPMMIntegration integration = DODOPMMIntegration(integrationAddr); + DODOPMMProvider providerSource = DODOPMMProvider(providerSourceAddr); + + uint256 lpFeeRate = vm.envOr("LP_FEE_RATE", json.readUint(".defaults.lpFeeRate")); + uint256 initialPrice = vm.envOr("INITIAL_PRICE", json.readUint(".defaults.initialPrice")); + uint256 kFactor = vm.envOr("K_FACTOR", json.readUint(".defaults.kFactor")); + bool enableTwap = vm.envOr("ENABLE_TWAP", json.readBool(".defaults.enableTwap")); + + string[] memory cStars = json.readStringArray(".groups.cStarSymbols"); + string[] memory officials = json.readStringArray(".groups.officialStableSymbols"); + string memory wethSymbol = json.readString(".groups.wethSymbol"); + bool deployCStarVsCStar = json.readBool(".groups.deploy.cStarVsCStar"); + bool deployCStarVsOfficial = json.readBool(".groups.deploy.cStarVsOfficial"); + bool deployCStarVsWeth = json.readBool(".groups.deploy.cStarVsWeth"); + bool deployOfficialVsWeth = json.readBool(".groups.deploy.officialVsWeth"); + + vm.startBroadcast(pk); + + if (deployCStarVsCStar) { + for (uint256 i = 0; i < cStars.length; i++) { + for (uint256 j = i + 1; j < cStars.length; j++) { + _importIfNeeded(json, providerSource, integration, cStars[i], cStars[j], lpFeeRate, initialPrice, kFactor, enableTwap); + } + } + } + + if (deployCStarVsOfficial) { + for (uint256 i = 0; i < cStars.length; i++) { + for (uint256 j = 0; j < officials.length; j++) { + _importIfNeeded(json, providerSource, integration, cStars[i], officials[j], lpFeeRate, initialPrice, kFactor, enableTwap); + } + } + } + + if (deployCStarVsWeth) { + for (uint256 i = 0; i < cStars.length; i++) { + _importIfNeeded(json, providerSource, integration, cStars[i], wethSymbol, lpFeeRate, initialPrice, kFactor, enableTwap); + } + } + + if (deployOfficialVsWeth) { + for (uint256 i = 0; i < officials.length; i++) { + _importIfNeeded(json, providerSource, integration, officials[i], wethSymbol, lpFeeRate, initialPrice, kFactor, enableTwap); + } + } + + for (uint256 i = 0; json.keyExists(string.concat(".explicitPairs[", vm.toString(i), "]")); i++) { + string memory baseKey = string.concat(".explicitPairs[", vm.toString(i), "].baseSymbol"); + string memory quoteKey = string.concat(".explicitPairs[", vm.toString(i), "].quoteSymbol"); + string memory explicitBase = json.readString(baseKey); + string memory explicitQuote = json.readString(quoteKey); + _importIfNeeded(json, providerSource, integration, explicitBase, explicitQuote, lpFeeRate, initialPrice, kFactor, enableTwap); + } + + vm.stopBroadcast(); + } + + function _importIfNeeded( + string memory json, + DODOPMMProvider provider, + DODOPMMIntegration integration, + string memory baseSymbol, + string memory quoteSymbol, + uint256 lpFeeRate, + uint256 initialPrice, + uint256 kFactor, + bool enableTwap + ) internal { + address base = json.readAddress(string.concat(".tokens.", baseSymbol)); + address quote = json.readAddress(string.concat(".tokens.", quoteSymbol)); + if (base == address(0) || quote == address(0) || base == quote) return; + + address integrationPool = integration.pools(base, quote); + if (integrationPool != address(0)) return; + + address providerPool = provider.pools(base, quote); + if (providerPool == address(0)) return; + + integration.importExistingPool( + providerPool, + base, + quote, + lpFeeRate, + initialPrice, + kFactor, + enableTwap + ); + + console.log("Imported:", baseSymbol, "/", quoteSymbol); + console.log("Pool:", providerPool); + } +} diff --git a/script/liquidity/RegisterDODOPools.s.sol b/script/liquidity/RegisterDODOPools.s.sol index 7148a9a..71b8d8c 100644 --- a/script/liquidity/RegisterDODOPools.s.sol +++ b/script/liquidity/RegisterDODOPools.s.sol @@ -7,10 +7,11 @@ import {DODOPMMIntegration} from "../../contracts/dex/DODOPMMIntegration.sol"; /** * @title RegisterDODOPools - * @notice Register existing DODO PMM pools with DODOPMMProvider. + * @notice Register all existing DODO PMM pools from DODOPMMIntegration with DODOPMMProvider. * @dev Set DODO_PMM_PROVIDER_ADDRESS, DODO_PMM_INTEGRATION (or DODO_PMM_INTEGRATION_ADDRESS). - * Pool addresses: POOL_CUSDTCUSDC, POOL_CUSDTUSDT, POOL_CUSDCUSDC (optional). - * Token addresses read from integration if not in env. + * Reads integration.getAllPools() and poolConfigs(pool), then registers both directions + * for every discovered pool so provider.supportsTokenPair() and executeSwap() work + * symmetrically across the current live set and any future c* full-mesh expansion. */ contract RegisterDODOPools is Script { function run() external { @@ -18,34 +19,35 @@ contract RegisterDODOPools is Script { address providerAddr = vm.envAddress("DODO_PMM_PROVIDER_ADDRESS"); address integrationAddr = vm.envAddress("DODO_PMM_INTEGRATION"); if (integrationAddr == address(0)) integrationAddr = vm.envAddress("DODO_PMM_INTEGRATION_ADDRESS"); + require(providerAddr != address(0), "DODO_PMM_PROVIDER_ADDRESS not set"); require(integrationAddr != address(0), "DODO_PMM_INTEGRATION not set"); DODOPMMIntegration integration = DODOPMMIntegration(integrationAddr); - address cusdt = integration.compliantUSDT(); - address cusdc = integration.compliantUSDC(); - address usdt = integration.officialUSDT(); - address usdc = integration.officialUSDC(); - - address poolCusdtCusdc = vm.envOr("POOL_CUSDTCUSDC", address(0)); - address poolCusdtUsdt = vm.envOr("POOL_CUSDTUSDT", address(0)); - address poolCusdcUsdc = vm.envOr("POOL_CUSDCUSDC", address(0)); - DODOPMMProvider provider = DODOPMMProvider(providerAddr); + address[] memory pools = integration.getAllPools(); + require(pools.length > 0, "No pools found in DODOPMMIntegration"); + vm.startBroadcast(pk); - - if (poolCusdtCusdc != address(0)) { - provider.registerPool(cusdt, cusdc, poolCusdtCusdc); - console.log("Registered cUSDT/cUSDC pool:", poolCusdtCusdc); + for (uint256 i = 0; i < pools.length; i++) { + try integration.getPoolConfig(pools[i]) returns (DODOPMMIntegration.PoolConfig memory config) { + _registerPair(provider, config.baseToken, config.quoteToken, pools[i]); + } catch { + console.log("Skipping removed or unreadable pool:", pools[i]); + } } - if (poolCusdtUsdt != address(0)) { - provider.registerPool(cusdt, usdt, poolCusdtUsdt); - console.log("Registered cUSDT/USDT pool:", poolCusdtUsdt); - } - if (poolCusdcUsdc != address(0)) { - provider.registerPool(cusdc, usdc, poolCusdcUsdc); - console.log("Registered cUSDC/USDC pool:", poolCusdcUsdc); - } - vm.stopBroadcast(); } + + function _registerPair( + DODOPMMProvider provider, + address tokenA, + address tokenB, + address pool + ) internal { + provider.registerPool(tokenA, tokenB, pool); + provider.registerPool(tokenB, tokenA, pool); + console.log("Registered base:", tokenA); + console.log("Registered quote:", tokenB); + console.log("Pool:", pool); + } } diff --git a/scripts/bridge/fund-bsc-relay-bridge.sh b/scripts/bridge/fund-bsc-relay-bridge.sh new file mode 100755 index 0000000..1cde5e9 --- /dev/null +++ b/scripts/bridge/fund-bsc-relay-bridge.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +cd "$PROJECT_ROOT" + +source "$PROJECT_ROOT/scripts/lib/deployment/dotenv.sh" +load_deployment_env + +if [[ -f "$PROJECT_ROOT/services/relay/.env.bsc" ]]; then + set -a + # shellcheck disable=SC1091 + source "$PROJECT_ROOT/services/relay/.env.bsc" + set +a +fi + +DRY_RUN=0 +AMOUNT_WEI="" + +while [[ $# -gt 0 ]]; do + case "$1" in + --dry-run) + DRY_RUN=1 + shift + ;; + *) + if [[ -z "$AMOUNT_WEI" ]]; then + AMOUNT_WEI="$1" + fi + shift + ;; + esac +done + +RPC_URL="${DEST_RPC_URL:-${BSC_RPC_URL:-${BSC_MAINNET_RPC:-}}}" +BRIDGE_ADDRESS="${DEST_RELAY_BRIDGE:-}" +WETH_ADDRESS="${DEST_WETH9_ADDRESS:-0x2170Ed0880ac9A755fd29B2688956BD959F933F8}" + +if [[ -z "${PRIVATE_KEY:-}" ]]; then + echo "Set PRIVATE_KEY in .env" >&2 + exit 1 +fi +if [[ -z "$RPC_URL" ]]; then + echo "Set BSC_RPC_URL (or BSC_MAINNET_RPC / DEST_RPC_URL) in .env" >&2 + exit 1 +fi +if [[ -z "$BRIDGE_ADDRESS" ]]; then + echo "Set DEST_RELAY_BRIDGE in services/relay/.env.bsc" >&2 + exit 1 +fi + +DEPLOYER="$(cast wallet address --private-key "$PRIVATE_KEY")" + +if [[ -z "$AMOUNT_WEI" ]]; then + AMOUNT_WEI="$(cast call "$WETH_ADDRESS" "balanceOf(address)(uint256)" "$DEPLOYER" --rpc-url "$RPC_URL")" +fi + +if [[ -z "$AMOUNT_WEI" || "$AMOUNT_WEI" == "0" ]]; then + if [[ "$DRY_RUN" == "1" ]]; then + AMOUNT_WEI="1000000000000000" + echo "No BSC WETH available; using placeholder amount for dry-run: $AMOUNT_WEI wei" + else + echo "No BSC WETH available to fund the BSC relay bridge." >&2 + exit 1 + fi +fi + +CMD=(cast send "$WETH_ADDRESS" "transfer(address,uint256)" "$BRIDGE_ADDRESS" "$AMOUNT_WEI" --rpc-url "$RPC_URL" --private-key "$PRIVATE_KEY" --legacy) +DRY_CMD=(cast send "$WETH_ADDRESS" "transfer(address,uint256)" "$BRIDGE_ADDRESS" "$AMOUNT_WEI" --rpc-url "$RPC_URL" --private-key "" --legacy) + +echo "BSC relay funding" +echo " Deployer: $DEPLOYER" +echo " WETH: $WETH_ADDRESS" +echo " Bridge: $BRIDGE_ADDRESS" +echo " Amount: $AMOUNT_WEI wei" + +if [[ "$DRY_RUN" == "1" ]]; then + printf ' [DRY RUN] ' + printf '%q ' "${DRY_CMD[@]}" + printf '\n' + exit 0 +fi + +"${CMD[@]}" diff --git a/scripts/bridge/fund-mainnet-relay-bridge.sh b/scripts/bridge/fund-mainnet-relay-bridge.sh new file mode 100755 index 0000000..8a2e4bf --- /dev/null +++ b/scripts/bridge/fund-mainnet-relay-bridge.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +cd "$PROJECT_ROOT" + +source "$PROJECT_ROOT/scripts/lib/deployment/dotenv.sh" +load_deployment_env + +DRY_RUN=0 +AMOUNT_WEI="" + +while [[ $# -gt 0 ]]; do + case "$1" in + --dry-run) + DRY_RUN=1 + shift + ;; + *) + if [[ -z "$AMOUNT_WEI" ]]; then + AMOUNT_WEI="$1" + fi + shift + ;; + esac +done + +RPC_URL="${RPC_URL_MAINNET:-${ETHEREUM_MAINNET_RPC:-}}" +BRIDGE_ADDRESS="${CCIP_RELAY_BRIDGE_MAINNET:-${RELAY_BRIDGE_MAINNET:-${CW_BRIDGE_MAINNET:-}}}" +WETH_ADDRESS="${WETH9_MAINNET:-0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2}" + +if [[ -z "${PRIVATE_KEY:-}" ]]; then + echo "Set PRIVATE_KEY in .env" >&2 + exit 1 +fi +if [[ -z "$RPC_URL" ]]; then + echo "Set ETHEREUM_MAINNET_RPC (or RPC_URL_MAINNET) in .env" >&2 + exit 1 +fi +if [[ -z "$BRIDGE_ADDRESS" ]]; then + echo "Set CCIP_RELAY_BRIDGE_MAINNET (or RELAY_BRIDGE_MAINNET / CW_BRIDGE_MAINNET) in .env" >&2 + exit 1 +fi + +DEPLOYER="$(cast wallet address --private-key "$PRIVATE_KEY")" + +if [[ -z "$AMOUNT_WEI" ]]; then + AMOUNT_WEI="$(cast call "$WETH_ADDRESS" "balanceOf(address)(uint256)" "$DEPLOYER" --rpc-url "$RPC_URL")" +fi + +if [[ -z "$AMOUNT_WEI" || "$AMOUNT_WEI" == "0" ]]; then + if [[ "$DRY_RUN" == "1" ]]; then + AMOUNT_WEI="1000000000000000" + echo "No WETH available; using placeholder amount for dry-run: $AMOUNT_WEI wei" + else + echo "No WETH available to fund the Mainnet relay bridge." >&2 + exit 1 + fi +fi + +CMD=(cast send "$WETH_ADDRESS" "transfer(address,uint256)" "$BRIDGE_ADDRESS" "$AMOUNT_WEI" --rpc-url "$RPC_URL" --private-key "$PRIVATE_KEY" --legacy) +DRY_CMD=(cast send "$WETH_ADDRESS" "transfer(address,uint256)" "$BRIDGE_ADDRESS" "$AMOUNT_WEI" --rpc-url "$RPC_URL" --private-key "" --legacy) + +echo "Mainnet relay funding" +echo " Deployer: $DEPLOYER" +echo " WETH: $WETH_ADDRESS" +echo " Bridge: $BRIDGE_ADDRESS" +echo " Amount: $AMOUNT_WEI wei" + +if [[ "$DRY_RUN" == "1" ]]; then + printf ' [DRY RUN] ' + printf '%q ' "${DRY_CMD[@]}" + printf '\n' + exit 0 +fi + +"${CMD[@]}" diff --git a/scripts/configuration/check-link-balance-at-address.sh b/scripts/configuration/check-link-balance-at-address.sh index 15af5fa..594dafb 100755 --- a/scripts/configuration/check-link-balance-at-address.sh +++ b/scripts/configuration/check-link-balance-at-address.sh @@ -20,12 +20,15 @@ log_success() { echo -e "${GREEN}[✓]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } -# Load environment -if [ -f "$PROJECT_ROOT/.env" ]; then +if [[ -f "$PROJECT_ROOT/scripts/lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/scripts/lib/deployment/dotenv.sh" + load_deployment_env --repo-root "$PROJECT_ROOT" +elif [ -f "$PROJECT_ROOT/.env" ]; then source "$PROJECT_ROOT/.env" 2>/dev/null || true fi -if [ -z "$PRIVATE_KEY" ]; then +if [ -z "${PRIVATE_KEY:-}" ]; then log_error "PRIVATE_KEY not set in .env" exit 1 fi diff --git a/scripts/configuration/check-link-balance.sh b/scripts/configuration/check-link-balance.sh index 76b4270..d90d074 100755 --- a/scripts/configuration/check-link-balance.sh +++ b/scripts/configuration/check-link-balance.sh @@ -7,6 +7,7 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +cd "$PROJECT_ROOT" 2>/dev/null || true # Colors RED='\033[0;31m' @@ -21,12 +22,15 @@ log_success() { echo -e "${GREEN}[✓]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } -# Load environment -if [ -f "$PROJECT_ROOT/.env" ]; then +if [[ -f "$PROJECT_ROOT/scripts/lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/scripts/lib/deployment/dotenv.sh" + load_deployment_env --repo-root "$PROJECT_ROOT" +elif [ -f "$PROJECT_ROOT/.env" ]; then source "$PROJECT_ROOT/.env" 2>/dev/null || true fi -if [ -z "$PRIVATE_KEY" ]; then +if [ -z "${PRIVATE_KEY:-}" ]; then log_error "PRIVATE_KEY not set in .env" exit 1 fi diff --git a/scripts/configuration/execute-full-bidirectional-config.sh b/scripts/configuration/execute-full-bidirectional-config.sh index 217edb9..1a8b3dd 100755 --- a/scripts/configuration/execute-full-bidirectional-config.sh +++ b/scripts/configuration/execute-full-bidirectional-config.sh @@ -1,14 +1,24 @@ #!/usr/bin/env bash +# Full bidirectional bridge configuration (Ethereum mainnet ↔ Chain 138). +# Legacy scripts under scripts/configuration/configure-chain138-* were removed; this delegates to deployment helpers. -# Execute Full Bidirectional Bridge Configuration -# This script attempts to configure both directions using available selector information - -set -e +set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +cd "$PROJECT_ROOT" + +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "$PROJECT_ROOT" +elif [[ -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +fi -# Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' @@ -16,54 +26,21 @@ BLUE='\033[0;34m' NC='\033[0m' log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } +log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_success() { echo -e "${GREEN}[✓]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } -log_error() { echo -e "${RED}[ERROR]${NC} $1"; } -log_info "=== Full Bidirectional Bridge Configuration ===" -log_info "" +log_info "=== Mainnet ↔ Chain 138 (WETH9/WETH10 bridges) ===" +bash "$PROJECT_ROOT/scripts/deployment/execute-bridge-config.sh" || log_warn "execute-bridge-config.sh exited non-zero (review output)." -# Load environment if available -if [ -f "$PROJECT_ROOT/.env" ]; then - source "$PROJECT_ROOT/.env" 2>/dev/null || true -fi +log_info "=== Config-ready chains (Gnosis/Cronos/Celo/Wemix) ===" +log_info "When bridge addresses are in .env, run: scripts/deployment/complete-config-ready-chains.sh" -# Step 1: Configure ChainID 138 → Mainnet (always possible) -log_info "Step 1: Configuring ChainID 138 → Mainnet..." -./scripts/configuration/configure-chain138-to-mainnet.sh - -log_info "" -log_info "---" - -# Step 2: Try to configure Mainnet → ChainID 138 (if selector available) -log_info "Step 2: Attempting Mainnet → ChainID 138 configuration..." - -# Get selector from networks.json if not in env -if [ -z "$CHAIN138_SELECTOR" ] && [ -f "$PROJECT_ROOT/networks.json" ]; then - CHAIN138_SELECTOR=$(python3 -c "import json; data=json.load(open('$PROJECT_ROOT/networks.json')); print(data['networks']['138']['chainSelector'])" 2>/dev/null || echo "") - if [ -n "$CHAIN138_SELECTOR" ]; then - log_info "Using ChainID 138 selector from networks.json: $CHAIN138_SELECTOR" - export CHAIN138_SELECTOR - fi -fi - -if [ -n "$CHAIN138_SELECTOR" ]; then - ./scripts/configuration/configure-mainnet-to-chain138.sh - log_success "✓ Bidirectional configuration complete!" +log_info "=== Optional verification ===" +if [[ -x "$PROJECT_ROOT/scripts/verify-bridge-setup-checklist.sh" ]]; then + bash "$PROJECT_ROOT/scripts/verify-bridge-setup-checklist.sh" || log_warn "Checklist reported issues (non-fatal)." else - log_warn "⚠ ChainID 138 selector not available - only ChainID 138 → Mainnet configured" - log_info "To complete bidirectional setup:" - log_info "1. Determine ChainID 138 selector" - log_info "2. Set in .env: CHAIN138_SELECTOR=" - log_info "3. Run: ./scripts/configuration/configure-mainnet-to-chain138.sh" + log_warn "verify-bridge-setup-checklist.sh not found or not executable." fi -log_info "" -log_info "---" - -# Step 3: Verify configuration -log_info "Step 3: Verifying configuration..." -./scripts/configuration/verify-bridge-configuration.sh - -log_info "" -log_success "=== Configuration Process Complete ===" +log_success "=== Done ===" diff --git a/scripts/configuration/find-chain-selector.sh b/scripts/configuration/find-chain-selector.sh index 9106857..72fabb4 100755 --- a/scripts/configuration/find-chain-selector.sh +++ b/scripts/configuration/find-chain-selector.sh @@ -19,7 +19,10 @@ log_success() { echo -e "${GREEN}[✓]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } # Load environment variables +# Default matches operator LAN Core RPC (see project AGENTS.md / rules). CHAIN138_RPC="${RPC_URL_138:-http://192.168.11.211:8545}" +CHAIN138_RPC="${CHAIN138_RPC%$'\r'}" +CHAIN138_RPC="${CHAIN138_RPC%$'\n'}" CCIP_ROUTER_138="${CCIP_ROUTER_138:-0x42DAb7b888Dd382bD5Adcf9E038dBF1fD03b4817}" log_info "=== Finding ChainID 138 CCIP Selector ===" diff --git a/scripts/create-all-dodo-pools-from-token-api.sh b/scripts/create-all-dodo-pools-from-token-api.sh index 2db5d70..3e1b6a4 100755 --- a/scripts/create-all-dodo-pools-from-token-api.sh +++ b/scripts/create-all-dodo-pools-from-token-api.sh @@ -5,6 +5,12 @@ set -euo pipefail +hex_to_addr() { + local value="${1#0x}" + [[ ${#value} -ge 40 ]] || return 1 + printf '0x%s\n' "${value: -40}" +} + SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" @@ -19,7 +25,11 @@ log_success() { echo -e "${GREEN}[✓]${NC} $1"; } log_warn() { echo -e "${YELLOW}[⚠]${NC} $1"; } log_error() { echo -e "${RED}[✗]${NC} $1"; } -if [ -f "$PROJECT_ROOT/.env" ]; then +if [[ -f "$SCRIPT_DIR/lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/lib/deployment/dotenv.sh" + load_deployment_env --repo-root "$PROJECT_ROOT" +elif [ -f "$PROJECT_ROOT/.env" ]; then set -a source "$PROJECT_ROOT/.env" set +a @@ -131,7 +141,7 @@ while true; do continue fi - if ! pool_addr=$(cast call "$DODO_PMM_INTEGRATION" "pools(address,address)(address)" "$token_addr" "$QUOTE_TOKEN" --rpc-url "$RPC_URL" 2>/dev/null | cast --to-addr 2>/dev/null); then + if ! pool_addr=$(cast call "$DODO_PMM_INTEGRATION" "pools(address,address)(address)" "$token_addr" "$QUOTE_TOKEN" --rpc-url "$RPC_URL" 2>/dev/null | while read -r raw; do hex_to_addr "$raw" 2>/dev/null || true; done); then pool_addr="" fi if [ -n "$pool_addr" ] && [ "$pool_addr" != "0x0000000000000000000000000000000000000000" ]; then @@ -153,7 +163,7 @@ while true; do --private-key "$PRIVATE_KEY" \ --legacy \ -q 2>/dev/null; then - pool_addr=$(cast call "$DODO_PMM_INTEGRATION" "pools(address,address)(address)" "$token_addr" "$QUOTE_TOKEN" --rpc-url "$RPC_URL" | cast --to-addr) + pool_addr=$(cast call "$DODO_PMM_INTEGRATION" "pools(address,address)(address)" "$token_addr" "$QUOTE_TOKEN" --rpc-url "$RPC_URL" | while read -r raw; do hex_to_addr "$raw"; done) log_success "Pool created: $pool_addr" if [ -n "$ENHANCED_SWAP_ROUTER" ] && [ "$ENHANCED_SWAP_ROUTER" != "0x0000000000000000000000000000000000000000" ]; then diff --git a/scripts/create-pmm-full-mesh-chain138.sh b/scripts/create-pmm-full-mesh-chain138.sh index cb4cdd5..cd17a45 100755 --- a/scripts/create-pmm-full-mesh-chain138.sh +++ b/scripts/create-pmm-full-mesh-chain138.sh @@ -1,128 +1,10 @@ #!/usr/bin/env bash -# Create the full PMM pool mesh on Chain 138: all c* vs c* pairs plus c* vs official USDT/USDC. -# Uses DODOPMMIntegration.createPool() and registers each pool with DODOPMMProvider. -# Skip pairs that already have a pool. Requires POOL_MANAGER_ROLE on integration and provider. -# -# Usage: -# ./scripts/create-pmm-full-mesh-chain138.sh # all c* mesh + optional official pairs -# MESH_ONLY_C_STAR=1 ./scripts/create-pmm-full-mesh-chain138.sh # only c* vs c* (no official) -# DRY_RUN=1 ./scripts/create-pmm-full-mesh-chain138.sh # print only, no txs -# -# Requires: PRIVATE_KEY, RPC_URL_138, DODO_PMM_INTEGRATION_ADDRESS, DODO_PMM_PROVIDER_ADDRESS in .env +# Backward-compatible entrypoint for Chain 138 PMM desired-state sync. +# Delegates to JSON-driven sync (config/chain138-pmm-pools.json). set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" -cd "$PROJECT_ROOT" -[[ -f .env ]] && set -a && source .env && set +a -RPC="${RPC_URL_138:-${RPC_URL:-http://192.168.11.211:8545}}" -INT="${DODO_PMM_INTEGRATION_ADDRESS:-${DODO_PMM_INTEGRATION:-}}" -PROV="${DODO_PMM_PROVIDER_ADDRESS:-}" -LP_FEE="${LP_FEE_RATE:-3}" -I="${INITIAL_PRICE:-1000000000000000000}" -K="${K_FACTOR:-500000000000000000}" -TWAP="${ENABLE_TWAP:-false}" -DRY_RUN="${DRY_RUN:-0}" -MESH_ONLY_C_STAR="${MESH_ONLY_C_STAR:-0}" - -# 12 c* tokens on Chain 138 (symbol:address) -declare -a C_STAR_SYMS=(cUSDT cUSDC cEURC cEURT cGBPC cGBPT cAUDC cJPYC cCHFC cCADC cXAUC cXAUT) -declare -a C_STAR_ADDRS=( - 0x93E66202A11B1772E55407B32B44e5Cd8eda7f22 - 0xf22258f57794CC8E06237084b353Ab30fFfa640b - 0x8085961F9cF02b4d800A3c6d386D31da4B34266a - 0xdf4b71c61E5912712C1Bdd451416B9aC26949d72 - 0x003960f16D9d34F2e98d62723B6721Fb92074aD2 - 0x350f54e4D23795f86A9c03988c7135357CCaD97c - 0xD51482e567c03899eecE3CAe8a058161FD56069D - 0xEe269e1226a334182aace90056EE4ee5Cc8A6770 - 0x873990849DDa5117d7C644f0aF24370797C03885 - 0x54dBd40cF05e15906A2C21f600937e96787f5679 - 0x290E52a8819A4fbD0714E517225429aA2B70EC6b - 0x94e408E26c6FD8F4ee00b54dF19082FDA07dC96E -) - -[[ -n "${PRIVATE_KEY:-}" ]] || { echo "PRIVATE_KEY not set"; exit 1; } -[[ -n "$INT" ]] || { echo "DODO_PMM_INTEGRATION_ADDRESS (or DODO_PMM_INTEGRATION) not set"; exit 1; } -[[ -n "$PROV" ]] || { echo "DODO_PMM_PROVIDER_ADDRESS not set"; exit 1; } - -# Official USDT/USDC on 138 (from integration if available) -OFFICIAL_USDT="${OFFICIAL_USDT_ADDRESS:-0x004b63A7B5b0E06f6bB6adb4a5F9f590BF3182D1}" -OFFICIAL_USDC="${OFFICIAL_USDC_ADDRESS:-}" -if [[ -z "$OFFICIAL_USDC" ]] && command -v cast &>/dev/null; then - OFFICIAL_USDC=$(cast call "$INT" "officialUSDC()(address)" --rpc-url "$RPC" 2>/dev/null | cast --to-addr 2>/dev/null || true) -fi -[[ -z "$OFFICIAL_USDC" ]] && OFFICIAL_USDC="0x0000000000000000000000000000000000000000" - -created=0 -skipped=0 -failed=0 - -pool_exists() { - local base="$1" quote="$2" - local addr - addr=$(cast call "$INT" "pools(address,address)(address)" "$base" "$quote" --rpc-url "$RPC" 2>/dev/null | cast --to-addr 2>/dev/null || echo "0x0") - [[ -n "$addr" && "$addr" != "0x0000000000000000000000000000000000000000" ]] -} - -create_pool() { - local base="$1" quote="$2" label="$3" - if pool_exists "$base" "$quote"; then - echo " SKIP $label (pool exists)" - ((skipped++)) || true - return 0 - fi - if [[ "$DRY_RUN" == "1" ]]; then - echo " [DRY] would create $label" - ((created++)) || true - return 0 - fi - if cast send "$INT" "createPool(address,address,uint256,uint256,uint256,bool)" \ - "$base" "$quote" "$LP_FEE" "$I" "$K" "$TWAP" \ - --rpc-url "$RPC" --private-key "$PRIVATE_KEY" --legacy --gas-limit 500000 -q 2>/dev/null; then - local pool_addr - pool_addr=$(cast call "$INT" "pools(address,address)(address)" "$base" "$quote" --rpc-url "$RPC" | cast --to-addr) - echo " OK $label -> $pool_addr" - if [[ -n "$PROV" ]]; then - cast send "$PROV" "registerPool(address,address,address)" "$base" "$quote" "$pool_addr" \ - --rpc-url "$RPC" --private-key "$PRIVATE_KEY" --legacy --gas-limit 200000 -q 2>/dev/null && echo " registered with provider" || echo " provider register failed" - fi - ((created++)) || true - else - echo " FAIL $label" - ((failed++)) || true - fi -} - -echo "=== PMM full mesh Chain 138 ===" -echo " Integration: $INT Provider: $PROV RPC: $RPC" -echo " Mesh: c* vs c* (+ c* vs official USDT/USDC if MESH_ONLY_C_STAR != 1)" -echo "" - -# 1) All c* vs c* pairs (base < quote by address to avoid duplicates) -n=${#C_STAR_ADDRS[@]} -for ((i=0; i/dev/null || true TARGET_WETH9="0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" TARGET_WETH10="0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9F" diff --git a/scripts/deployment/canary-region.sh b/scripts/deployment/canary-region.sh index 433e92b..d4fddf6 100755 --- a/scripts/deployment/canary-region.sh +++ b/scripts/deployment/canary-region.sh @@ -12,6 +12,22 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi TERRAFORM_DIR="$PROJECT_ROOT/terraform" REGION="${1:-northeurope}" diff --git a/scripts/deployment/check-balances-gas-and-deploy.sh b/scripts/deployment/check-balances-gas-and-deploy.sh index 7bf57a9..ffa1d14 100755 --- a/scripts/deployment/check-balances-gas-and-deploy.sh +++ b/scripts/deployment/check-balances-gas-and-deploy.sh @@ -33,13 +33,6 @@ load_deployment_env parse_deploy_tag "$@" DO_DEPLOY="${DO_DEPLOY:-0}" -# Load .env (load_deployment_env already did; keep for any vars set after) -if [ -f .env ]; then - set -a - source .env - set +a -fi - # Infura: use Basic Auth URL when INFURA_PROJECT_SECRET is set (fixes "error sending request" from Infura) SCRIPT_LIB="$SCRIPT_DIR/../lib" [ -f "${SCRIPT_LIB}/infura.sh" ] && source "${SCRIPT_LIB}/infura.sh" diff --git a/scripts/deployment/check-cronos-api.sh b/scripts/deployment/check-cronos-api.sh index 5cdfd6b..4fbde5c 100755 --- a/scripts/deployment/check-cronos-api.sh +++ b/scripts/deployment/check-cronos-api.sh @@ -6,7 +6,22 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" -source .env 2>/dev/null || true +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi RPC="${CRONOS_RPC_URL:-https://evm.cronos.org}" CONTRACTS=( diff --git a/scripts/deployment/check-cronos-verification-status.sh b/scripts/deployment/check-cronos-verification-status.sh index 57c5f02..c815c85 100755 --- a/scripts/deployment/check-cronos-verification-status.sh +++ b/scripts/deployment/check-cronos-verification-status.sh @@ -7,6 +7,22 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi RPC="${CRONOS_RPC_URL:-https://evm.cronos.org}" CONTRACTS=( diff --git a/scripts/deployment/check-dapp-env.sh b/scripts/deployment/check-dapp-env.sh index 1750629..38730aa 100755 --- a/scripts/deployment/check-dapp-env.sh +++ b/scripts/deployment/check-dapp-env.sh @@ -5,6 +5,22 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi ENV_FILE="${1:-$REPO_ROOT/.env}" get_var() { diff --git a/scripts/deployment/check-deployment-status.sh b/scripts/deployment/check-deployment-status.sh index 5a9aaea..3731c5d 100755 --- a/scripts/deployment/check-deployment-status.sh +++ b/scripts/deployment/check-deployment-status.sh @@ -11,6 +11,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi log_info "=== Deployment Status Check ===" diff --git a/scripts/deployment/check-env-required.sh b/scripts/deployment/check-env-required.sh index 85edb44..4d77973 100755 --- a/scripts/deployment/check-env-required.sh +++ b/scripts/deployment/check-env-required.sh @@ -6,6 +6,22 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi ENV_FILE="${PROJECT_ROOT}/.env" echo "=== .env check (keys only, no values) ===" diff --git a/scripts/deployment/check-link-balance-config-ready-chains.sh b/scripts/deployment/check-link-balance-config-ready-chains.sh index fab1cc5..bc4aa33 100755 --- a/scripts/deployment/check-link-balance-config-ready-chains.sh +++ b/scripts/deployment/check-link-balance-config-ready-chains.sh @@ -10,7 +10,16 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" -[[ -f "$PROJECT_ROOT/.env" ]] && set -a && source "$PROJECT_ROOT/.env" && set +a +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "$PROJECT_ROOT" +elif [[ -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +fi CHAIN="${1:-all}" REQUIRED_LINK="20" # 10 per WETH9 bridge + 10 per WETH10 bridge @@ -21,10 +30,10 @@ LINK_TOKEN_CRONOS="${LINK_TOKEN_CRONOS:-${CCIP_CRONOS_LINK_TOKEN:-0x8c80A01F461f LINK_TOKEN_CELO="${LINK_TOKEN_CELO:-${CCIP_CELO_LINK_TOKEN:-0xd07294e6E917e07dfDcee882dd1e2565085C2ae0}}" LINK_TOKEN_WEMIX="${LINK_TOKEN_WEMIX:-${CCIP_WEMIX_LINK_TOKEN:-0x80f1FcdC96B55e459BF52b998aBBE2c364935d69}}" -GNOSIS_RPC="${GNOSIS_RPC:-https://rpc.gnosischain.com}" -CRONOS_RPC="${CRONOS_RPC:-https://evm.cronos.org}" -CELO_RPC="${CELO_RPC:-https://forno.celo.org}" -WEMIX_RPC="${WEMIX_RPC:-https://api.wemix.com}" +GNOSIS_RPC="${GNOSIS_RPC:-${GNOSIS_MAINNET_RPC:-https://rpc.gnosischain.com}}" +CRONOS_RPC="${CRONOS_RPC:-${CRONOS_RPC_URL:-https://evm.cronos.org}}" +CELO_RPC="${CELO_RPC:-${CELO_MAINNET_RPC:-https://forno.celo.org}}" +WEMIX_RPC="${WEMIX_RPC:-${WEMIX_MAINNET_RPC:-https://api.wemix.com}}" if [[ -z "${PRIVATE_KEY:-}" ]]; then echo "Error: Set PRIVATE_KEY in .env" >&2 @@ -42,7 +51,7 @@ check_link() { local name="$1" rpc="$2" link_token="$3" [[ -z "$rpc" || -z "$link_token" ]] && return 1 local raw - raw=$(cast call "$link_token" "balanceOf(address)(uint256)" "$DEPLOYER" --rpc-url "$rpc" 2>/dev/null || echo "0") + raw=$(cast call "${link_token,,}" "balanceOf(address)(uint256)" "${DEPLOYER,,}" --rpc-url "$rpc" 2>/dev/null || echo "0") local link_val link_val=$(echo "scale=4; $raw / 1000000000000000000" | bc 2>/dev/null || echo "0") if [[ -z "$link_val" || "$link_val" == "0" ]]; then diff --git a/scripts/deployment/check-mainnet-balances.sh b/scripts/deployment/check-mainnet-balances.sh index 0c1c284..d3ef23a 100755 --- a/scripts/deployment/check-mainnet-balances.sh +++ b/scripts/deployment/check-mainnet-balances.sh @@ -7,6 +7,22 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi # Load environment variables diff --git a/scripts/deployment/check-mainnet-deployment-status.sh b/scripts/deployment/check-mainnet-deployment-status.sh index de56fd5..523ce36 100755 --- a/scripts/deployment/check-mainnet-deployment-status.sh +++ b/scripts/deployment/check-mainnet-deployment-status.sh @@ -7,6 +7,22 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi # Colors diff --git a/scripts/deployment/check-rpc-status.sh b/scripts/deployment/check-rpc-status.sh index 910cbef..5208052 100755 --- a/scripts/deployment/check-rpc-status.sh +++ b/scripts/deployment/check-rpc-status.sh @@ -11,6 +11,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi log_info "=== RPC Endpoint Status Check for Chain ID 138 ===" diff --git a/scripts/deployment/check-syntax.sh b/scripts/deployment/check-syntax.sh index 8d7010d..fac9b3b 100755 --- a/scripts/deployment/check-syntax.sh +++ b/scripts/deployment/check-syntax.sh @@ -5,6 +5,22 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$REPO_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi FAIL=0 diff --git a/scripts/deployment/check-wallet-balances.sh b/scripts/deployment/check-wallet-balances.sh index ba43e31..a1a78a7 100755 --- a/scripts/deployment/check-wallet-balances.sh +++ b/scripts/deployment/check-wallet-balances.sh @@ -8,6 +8,22 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi # Colors diff --git a/scripts/deployment/complete-all-deployment.sh b/scripts/deployment/complete-all-deployment.sh index 7f17019..58ae3a4 100755 --- a/scripts/deployment/complete-all-deployment.sh +++ b/scripts/deployment/complete-all-deployment.sh @@ -55,6 +55,22 @@ echo "PHASE 2: STORE NODE SECRETS" echo "======================================================================" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi bash scripts/key-management/store-nodes-in-keyvault.sh 2>&1 | tee /tmp/store-secrets.log diff --git a/scripts/deployment/complete-config-ready-chains.sh b/scripts/deployment/complete-config-ready-chains.sh index 843c88f..2bff125 100755 --- a/scripts/deployment/complete-config-ready-chains.sh +++ b/scripts/deployment/complete-config-ready-chains.sh @@ -11,9 +11,13 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" [[ -f "$SCRIPT_DIR/../lib/init.sh" ]] && source "$SCRIPT_DIR/../lib/init.sh" 2>/dev/null || true PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" - -if [[ -f "$PROJECT_ROOT/.env" ]]; then +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "$PROJECT_ROOT" +elif [[ -f "$PROJECT_ROOT/.env" ]]; then set -a + # shellcheck disable=SC1090 source "$PROJECT_ROOT/.env" set +a fi @@ -26,11 +30,15 @@ CELO_SELECTOR="${CELO_SELECTOR:-1346049177634351622}" WEMIX_SELECTOR="${WEMIX_SELECTOR:-5142893604156789321}" CHAIN138_SELECTOR="${CHAIN138_SELECTOR:-}" -CHAIN138_RPC="${CHAIN138_RPC:-${RPC_URL:-https://rpc-core.d-bis.org}}" -GNOSIS_RPC="${GNOSIS_RPC:-https://rpc.gnosischain.com}" -CRONOS_RPC="${CRONOS_RPC:-https://evm.cronos.org}" -CELO_RPC="${CELO_RPC:-https://forno.celo.org}" -WEMIX_RPC="${WEMIX_RPC:-https://api.wemix.com}" +# Prefer LAN/core RPC for 138 when set (matches fund / deploy scripts). +CHAIN138_RPC="${RPC_URL_138:-${CHAIN138_RPC:-${RPC_URL:-https://rpc-core.d-bis.org}}}" +CHAIN138_RPC="${CHAIN138_RPC//$'\r'/}" +CHAIN138_RPC="${CHAIN138_RPC//$'\n'/}" +# Align with fund-ccip-bridges-with-link.sh / .env.example (MAINNET_RPC aliases). +GNOSIS_RPC="${GNOSIS_RPC:-${GNOSIS_MAINNET_RPC:-https://rpc.gnosischain.com}}" +CRONOS_RPC="${CRONOS_RPC:-${CRONOS_RPC_URL:-https://evm.cronos.org}}" +CELO_RPC="${CELO_RPC:-${CELO_MAINNET_RPC:-https://forno.celo.org}}" +WEMIX_RPC="${WEMIX_RPC:-${WEMIX_MAINNET_RPC:-https://api.wemix.com}}" PRIVATE_KEY="${PRIVATE_KEY:-}" if [[ -n "$PRIVATE_KEY" && ! "$PRIVATE_KEY" =~ ^0x ]]; then @@ -38,18 +46,22 @@ if [[ -n "$PRIVATE_KEY" && ! "$PRIVATE_KEY" =~ ^0x ]]; then fi # Chain 138 bridge addresses (required) -WETH9_138=$(grep "CCIPWETH9_BRIDGE_CHAIN138=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "${CCIPWETH9_BRIDGE_CHAIN138:-}") -WETH10_138=$(grep "CCIPWETH10_BRIDGE_CHAIN138=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "${CCIPWETH10_BRIDGE_CHAIN138:-}") +WETH9_138=$(grep "CCIPWETH9_BRIDGE_CHAIN138=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH9_BRIDGE_CHAIN138:-}") +WETH10_138=$(grep "CCIPWETH10_BRIDGE_CHAIN138=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH10_BRIDGE_CHAIN138:-}") # Config-ready chain bridge addresses (optional; if set, we configure them) -WETH9_GNOSIS=$(grep "CCIPWETH9_BRIDGE_GNOSIS=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "${CCIPWETH9_BRIDGE_GNOSIS:-}") -WETH10_GNOSIS=$(grep "CCIPWETH10_BRIDGE_GNOSIS=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "${CCIPWETH10_BRIDGE_GNOSIS:-}") -WETH9_CRONOS=$(grep "CCIPWETH9_BRIDGE_CRONOS=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "${CCIPWETH9_BRIDGE_CRONOS:-}") -WETH10_CRONOS=$(grep "CCIPWETH10_BRIDGE_CRONOS=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "${CCIPWETH10_BRIDGE_CRONOS:-}") -WETH9_CELO=$(grep "CCIPWETH9_BRIDGE_CELO=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "${CCIPWETH9_BRIDGE_CELO:-}") -WETH10_CELO=$(grep "CCIPWETH10_BRIDGE_CELO=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "${CCIPWETH10_BRIDGE_CELO:-}") -WETH9_WEMIX=$(grep "CCIPWETH9_BRIDGE_WEMIX=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "${CCIPWETH9_BRIDGE_WEMIX:-}") -WETH10_WEMIX=$(grep "CCIPWETH10_BRIDGE_WEMIX=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "${CCIPWETH10_BRIDGE_WEMIX:-}") +WETH9_GNOSIS=$(grep "CCIPWETH9_BRIDGE_GNOSIS=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH9_BRIDGE_GNOSIS:-}") +WETH10_GNOSIS=$(grep "CCIPWETH10_BRIDGE_GNOSIS=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH10_BRIDGE_GNOSIS:-}") +WETH9_CRONOS=$(grep "CCIPWETH9_BRIDGE_CRONOS=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH9_BRIDGE_CRONOS:-}") +WETH10_CRONOS=$(grep "CCIPWETH10_BRIDGE_CRONOS=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH10_BRIDGE_CRONOS:-}") +WETH9_CELO=$(grep "CCIPWETH9_BRIDGE_CELO=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH9_BRIDGE_CELO:-}") +WETH10_CELO=$(grep "CCIPWETH10_BRIDGE_CELO=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH10_BRIDGE_CELO:-}") +WETH9_WEMIX=$(grep "CCIPWETH9_BRIDGE_WEMIX=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH9_BRIDGE_WEMIX:-}") +WETH10_WEMIX=$(grep "CCIPWETH10_BRIDGE_WEMIX=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH10_BRIDGE_WEMIX:-}") + +# Besu eth_call via `cast call` can return -32602; lowercase 20-byte addresses avoids some failures on sends. +WETH9_138="${WETH9_138,,}" +WETH10_138="${WETH10_138,,}" DRY_RUN="${DRY_RUN:-0}" @@ -69,10 +81,14 @@ run_or_echo() { if [[ "$DRY_RUN" = "1" ]]; then echo " [DRY RUN] $*" else - if eval "$*" >/dev/null 2>&1; then + # With set -e, _out=$(eval ...) would exit the whole script on failure; use if to absorb it. + local _out + if _out=$(eval "$*" 2>&1); then log_success " OK" + [[ -n "$_out" ]] && echo " $_out" else - log_warn " Failed (non-fatal) - run manually to see error" + log_warn " Failed (non-fatal)" + echo " $_out" >&2 fi fi } @@ -90,10 +106,10 @@ configure_chain_138_destination() { echo " Configuring Chain 138 → $label..." if [[ -n "$addr9" ]]; then - run_or_echo "cast send $WETH9_138 \"addDestination(uint64,address)\" $selector $addr9 --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY --legacy --gas-limit 200000" + run_or_echo "cast send $WETH9_138 \"addDestination(uint64,address)\" $selector ${addr9,,} --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY --legacy --gas-limit 250000 --gas-price 2000000000" fi if [[ -n "$addr10" ]]; then - run_or_echo "cast send $WETH10_138 \"addDestination(uint64,address)\" $selector $addr10 --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY --legacy --gas-limit 200000" + run_or_echo "cast send $WETH10_138 \"addDestination(uint64,address)\" $selector ${addr10,,} --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY --legacy --gas-limit 250000 --gas-price 2000000000" fi } @@ -110,10 +126,10 @@ configure_remote_chain_destination() { echo " Configuring $label → Chain 138..." if [[ -n "$addr9" ]]; then - run_or_echo "cast send $addr9 \"addDestination(uint64,address)\" $CHAIN138_SELECTOR $WETH9_138 --rpc-url $rpc --private-key \$PRIVATE_KEY --legacy" + run_or_echo "cast send ${addr9,,} \"addDestination(uint64,address)\" $CHAIN138_SELECTOR $WETH9_138 --rpc-url $rpc --private-key \$PRIVATE_KEY --legacy --gas-limit 400000" fi if [[ -n "$addr10" ]]; then - run_or_echo "cast send $addr10 \"addDestination(uint64,address)\" $CHAIN138_SELECTOR $WETH10_138 --rpc-url $rpc --private-key \$PRIVATE_KEY --legacy" + run_or_echo "cast send ${addr10,,} \"addDestination(uint64,address)\" $CHAIN138_SELECTOR $WETH10_138 --rpc-url $rpc --private-key \$PRIVATE_KEY --legacy --gas-limit 400000" fi } diff --git a/scripts/deployment/complete-phase2.sh b/scripts/deployment/complete-phase2.sh index 4ff0893..6e7d37a 100755 --- a/scripts/deployment/complete-phase2.sh +++ b/scripts/deployment/complete-phase2.sh @@ -8,6 +8,22 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi log() { log_success "[✓] $1" diff --git a/scripts/deployment/configure-avalanche-arbitrum-cronos-bridges.sh b/scripts/deployment/configure-avalanche-arbitrum-cronos-bridges.sh index 6146979..43ffaa2 100755 --- a/scripts/deployment/configure-avalanche-arbitrum-cronos-bridges.sh +++ b/scripts/deployment/configure-avalanche-arbitrum-cronos-bridges.sh @@ -9,10 +9,20 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" - -if [[ -f .env ]]; then +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then set -a - source .env + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" set +a fi @@ -25,6 +35,8 @@ CRONOS_SELECTOR="${CRONOS_SELECTOR:-1456215246176062136}" CHAIN138_SELECTOR="${CHAIN138_SELECTOR:-138}" CHAIN138_RPC="${RPC_URL_138:-${CHAIN138_RPC:-http://192.168.11.211:8545}}" +CHAIN138_RPC="${CHAIN138_RPC%$'\r'}" +CHAIN138_RPC="${CHAIN138_RPC%$'\n'}" # Prefer explicit RPC; else Infura (INFURA_PROJECT_ID + optional INFURA_PROJECT_SECRET); else public _avalanche_infura=$(build_infura_rpc "avalanche-mainnet" 2>/dev/null || true) _arbitrum_infura=$(build_infura_rpc "arbitrum-mainnet" 2>/dev/null || true) @@ -41,6 +53,11 @@ WETH10_ARBITRUM="${CCIPWETH10_BRIDGE_ARBITRUM:-}" WETH9_CRONOS="${CCIPWETH9_BRIDGE_CRONOS:-}" WETH10_CRONOS="${CCIPWETH10_BRIDGE_CRONOS:-}" +[[ -n "$WETH9_138" ]] && WETH9_138="${WETH9_138,,}" +[[ -n "$WETH10_138" ]] && WETH10_138="${WETH10_138,,}" +_gas138="--legacy --gas-limit 250000 --gas-price 2000000000" +_gas_remote="--legacy --gas-limit 400000" + PRIVATE_KEY="${PRIVATE_KEY:-}" [[ -n "$PRIVATE_KEY" && ! "$PRIVATE_KEY" =~ ^0x ]] && PRIVATE_KEY="0x$PRIVATE_KEY" @@ -54,10 +71,13 @@ run_or_echo() { if [[ "$DRY_RUN" = "1" ]]; then echo " [DRY RUN] $*" else - if eval "$*"; then + local _out + if _out=$(eval "$*" 2>&1); then echo -e " ${GREEN}OK${NC}" + [[ -n "$_out" ]] && echo " $_out" else - echo -e " ${RED}Failed${NC}" + echo -e " ${RED}Failed${NC}" >&2 + echo " $_out" >&2 return 1 fi fi @@ -86,20 +106,20 @@ echo "" # Step A: Chain 138 → Avalanche if [[ -n "$WETH9_AVALANCHE" || -n "$WETH10_AVALANCHE" ]]; then echo " Chain 138 → Avalanche:" - [[ -n "$WETH9_AVALANCHE" ]] && run_or_echo "cast send $WETH9_138 'addDestination(uint64,address)' $AVALANCHE_SELECTOR $WETH9_AVALANCHE --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY --legacy" || true - [[ -n "$WETH10_AVALANCHE" ]] && run_or_echo "cast send $WETH10_138 'addDestination(uint64,address)' $AVALANCHE_SELECTOR $WETH10_AVALANCHE --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY --legacy" || true + [[ -n "$WETH9_AVALANCHE" ]] && run_or_echo "cast send $WETH9_138 \"addDestination(uint64,address)\" $AVALANCHE_SELECTOR ${WETH9_AVALANCHE,,} --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY $_gas138" || true + [[ -n "$WETH10_AVALANCHE" && -n "$WETH10_138" ]] && run_or_echo "cast send $WETH10_138 \"addDestination(uint64,address)\" $AVALANCHE_SELECTOR ${WETH10_AVALANCHE,,} --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY $_gas138" || true fi # Step A: Chain 138 → Arbitrum if [[ -n "$WETH9_ARBITRUM" || -n "$WETH10_ARBITRUM" ]]; then echo " Chain 138 → Arbitrum:" - [[ -n "$WETH9_ARBITRUM" ]] && run_or_echo "cast send $WETH9_138 'addDestination(uint64,address)' $ARBITRUM_SELECTOR $WETH9_ARBITRUM --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY --legacy" || true - [[ -n "$WETH10_ARBITRUM" ]] && run_or_echo "cast send $WETH10_138 'addDestination(uint64,address)' $ARBITRUM_SELECTOR $WETH10_ARBITRUM --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY --legacy" || true + [[ -n "$WETH9_ARBITRUM" ]] && run_or_echo "cast send $WETH9_138 \"addDestination(uint64,address)\" $ARBITRUM_SELECTOR ${WETH9_ARBITRUM,,} --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY $_gas138" || true + [[ -n "$WETH10_ARBITRUM" && -n "$WETH10_138" ]] && run_or_echo "cast send $WETH10_138 \"addDestination(uint64,address)\" $ARBITRUM_SELECTOR ${WETH10_ARBITRUM,,} --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY $_gas138" || true fi # Step A: Chain 138 → Cronos if [[ -n "$WETH9_CRONOS" || -n "$WETH10_CRONOS" ]]; then echo " Chain 138 → Cronos:" - [[ -n "$WETH9_CRONOS" ]] && run_or_echo "cast send $WETH9_138 'addDestination(uint64,address)' $CRONOS_SELECTOR $WETH9_CRONOS --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY --legacy" || true - [[ -n "$WETH10_CRONOS" ]] && run_or_echo "cast send $WETH10_138 'addDestination(uint64,address)' $CRONOS_SELECTOR $WETH10_CRONOS --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY --legacy" || true + [[ -n "$WETH9_CRONOS" ]] && run_or_echo "cast send $WETH9_138 \"addDestination(uint64,address)\" $CRONOS_SELECTOR ${WETH9_CRONOS,,} --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY $_gas138" || true + [[ -n "$WETH10_CRONOS" && -n "$WETH10_138" ]] && run_or_echo "cast send $WETH10_138 \"addDestination(uint64,address)\" $CRONOS_SELECTOR ${WETH10_CRONOS,,} --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY $_gas138" || true fi echo "" @@ -109,20 +129,20 @@ echo "" # Step B: Avalanche → Chain 138 if [[ -n "$WETH9_AVALANCHE" || -n "$WETH10_AVALANCHE" ]]; then echo " Avalanche → Chain 138:" - [[ -n "$WETH9_AVALANCHE" ]] && run_or_echo "cast send $WETH9_AVALANCHE 'addDestination(uint64,address)' $CHAIN138_SELECTOR $WETH9_138 --rpc-url $AVALANCHE_RPC --private-key \$PRIVATE_KEY --legacy" || true - [[ -n "$WETH10_AVALANCHE" ]] && run_or_echo "cast send $WETH10_AVALANCHE 'addDestination(uint64,address)' $CHAIN138_SELECTOR $WETH10_138 --rpc-url $AVALANCHE_RPC --private-key \$PRIVATE_KEY --legacy" || true + [[ -n "$WETH9_AVALANCHE" ]] && run_or_echo "cast send ${WETH9_AVALANCHE,,} \"addDestination(uint64,address)\" $CHAIN138_SELECTOR $WETH9_138 --rpc-url $AVALANCHE_RPC --private-key \$PRIVATE_KEY $_gas_remote" || true + [[ -n "$WETH10_AVALANCHE" && -n "$WETH10_138" ]] && run_or_echo "cast send ${WETH10_AVALANCHE,,} \"addDestination(uint64,address)\" $CHAIN138_SELECTOR $WETH10_138 --rpc-url $AVALANCHE_RPC --private-key \$PRIVATE_KEY $_gas_remote" || true fi # Step B: Arbitrum → Chain 138 if [[ -n "$WETH9_ARBITRUM" || -n "$WETH10_ARBITRUM" ]]; then echo " Arbitrum → Chain 138:" - [[ -n "$WETH9_ARBITRUM" ]] && run_or_echo "cast send $WETH9_ARBITRUM 'addDestination(uint64,address)' $CHAIN138_SELECTOR $WETH9_138 --rpc-url $ARBITRUM_RPC --private-key \$PRIVATE_KEY --legacy" || true - [[ -n "$WETH10_ARBITRUM" ]] && run_or_echo "cast send $WETH10_ARBITRUM 'addDestination(uint64,address)' $CHAIN138_SELECTOR $WETH10_138 --rpc-url $ARBITRUM_RPC --private-key \$PRIVATE_KEY --legacy" || true + [[ -n "$WETH9_ARBITRUM" ]] && run_or_echo "cast send ${WETH9_ARBITRUM,,} \"addDestination(uint64,address)\" $CHAIN138_SELECTOR $WETH9_138 --rpc-url $ARBITRUM_RPC --private-key \$PRIVATE_KEY $_gas_remote" || true + [[ -n "$WETH10_ARBITRUM" && -n "$WETH10_138" ]] && run_or_echo "cast send ${WETH10_ARBITRUM,,} \"addDestination(uint64,address)\" $CHAIN138_SELECTOR $WETH10_138 --rpc-url $ARBITRUM_RPC --private-key \$PRIVATE_KEY $_gas_remote" || true fi # Step B: Cronos → Chain 138 if [[ -n "$WETH9_CRONOS" || -n "$WETH10_CRONOS" ]]; then echo " Cronos → Chain 138:" - [[ -n "$WETH9_CRONOS" ]] && run_or_echo "cast send $WETH9_CRONOS 'addDestination(uint64,address)' $CHAIN138_SELECTOR $WETH9_138 --rpc-url $CRONOS_RPC --private-key \$PRIVATE_KEY --legacy" || true - [[ -n "$WETH10_CRONOS" ]] && run_or_echo "cast send $WETH10_CRONOS 'addDestination(uint64,address)' $CHAIN138_SELECTOR $WETH10_138 --rpc-url $CRONOS_RPC --private-key \$PRIVATE_KEY --legacy" || true + [[ -n "$WETH9_CRONOS" ]] && run_or_echo "cast send ${WETH9_CRONOS,,} \"addDestination(uint64,address)\" $CHAIN138_SELECTOR $WETH9_138 --rpc-url $CRONOS_RPC --private-key \$PRIVATE_KEY $_gas_remote" || true + [[ -n "$WETH10_CRONOS" && -n "$WETH10_138" ]] && run_or_echo "cast send ${WETH10_CRONOS,,} \"addDestination(uint64,address)\" $CHAIN138_SELECTOR $WETH10_138 --rpc-url $CRONOS_RPC --private-key \$PRIVATE_KEY $_gas_remote" || true fi echo "" diff --git a/scripts/deployment/configure-bridge-destinations.sh b/scripts/deployment/configure-bridge-destinations.sh index f7da49c..2567a46 100755 --- a/scripts/deployment/configure-bridge-destinations.sh +++ b/scripts/deployment/configure-bridge-destinations.sh @@ -1,107 +1,123 @@ -#!/bin/bash +#!/usr/bin/env bash +# Configure Chain 138 ↔ Ethereum mainnet CCIP WETH bridge destinations. +# Uses CCIPWETH9Bridge / CCIPWETH10Bridge addDestination(uint64,address) (receiver = peer bridge on the other chain). +# For Gnosis/Cronos/Celo/Wemix, use complete-config-ready-chains.sh instead. +# +# Env: PRIVATE_KEY; bridge addresses (see below); RPC_URL_138; ETHEREUM_MAINNET_RPC or RPC_URL_MAINNET. +# +# shellcheck disable=SC1090 -# Configure Bridge Destinations Script -# Configures ChainID 138 ↔ Mainnet bidirectional bridge destinations +set -euo pipefail -set -e +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "$PROJECT_ROOT" +fi -# Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' -NC='\033[0m' # No Color +NC='\033[0m' -# Configuration PRIVATE_KEY="${PRIVATE_KEY:-}" -RPC_URL_138="${RPC_URL_138:-http://192.168.11.175:8545}" -RPC_URL_MAINNET="${RPC_URL_MAINNET:-https://eth.llamarpc.com}" - -# Chain Selectors -MAINNET_CHAIN_SELECTOR="5009297550715157269" -CHAIN138_CHAIN_SELECTOR="${CHAIN138_CHAIN_SELECTOR:-}" # To be determined - -# Contract Addresses (set these after deployment) -WETH9_BRIDGE_138="${WETH9_BRIDGE_138:-}" -WETH10_BRIDGE_138="${WETH10_BRIDGE_138:-}" -WETH9_MAINNET="${WETH9_MAINNET:-0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2}" -WETH10_MAINNET="${WETH10_MAINNET:-0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f}" - -echo -e "${GREEN}=== Bridge Destination Configuration ===${NC}\n" - -# Check prerequisites -if [ -z "$PRIVATE_KEY" ]; then - echo -e "${RED}ERROR: PRIVATE_KEY environment variable not set${NC}" - exit 1 +if [[ -n "$PRIVATE_KEY" && ! "$PRIVATE_KEY" =~ ^0x ]]; then + PRIVATE_KEY="0x$PRIVATE_KEY" fi -if [ -z "$WETH9_BRIDGE_138" ] || [ -z "$WETH10_BRIDGE_138" ]; then - echo -e "${YELLOW}WARNING: Bridge addresses not set. Please set WETH9_BRIDGE_138 and WETH10_BRIDGE_138${NC}" - exit 1 +RPC_URL_138="${RPC_URL_138:-http://192.168.11.211:8545}" +RPC_URL_138="${RPC_URL_138%$'\r'}" +RPC_URL_138="${RPC_URL_138%$'\n'}" +RPC_URL_MAINNET="${RPC_URL_MAINNET:-${ETHEREUM_MAINNET_RPC:-https://eth.llamarpc.com}}" +RPC_URL_MAINNET="${RPC_URL_MAINNET%$'\r'}" +RPC_URL_MAINNET="${RPC_URL_MAINNET%$'\n'}" + +MAINNET_CHAIN_SELECTOR="${MAINNET_CHAIN_SELECTOR:-5009297550715157269}" +CHAIN138_CHAIN_SELECTOR="${CHAIN138_CHAIN_SELECTOR:-${CHAIN138_SELECTOR:-}}" + +# 138-side bridges (aliases match .env CCIP* names) +WETH9_BRIDGE_138="${WETH9_BRIDGE_138:-${CCIPWETH9_BRIDGE_CHAIN138:-}}" +WETH10_BRIDGE_138="${WETH10_BRIDGE_138:-${CCIPWETH10_BRIDGE_CHAIN138:-}}" +# Mainnet peer *bridge* contracts (not WETH token addresses) +WETH9_MAINNET="${WETH9_MAINNET:-${MAINNET_CCIP_WETH9_BRIDGE:-}}" +WETH10_MAINNET="${WETH10_MAINNET:-${MAINNET_CCIP_WETH10_BRIDGE:-}}" + +echo -e "${GREEN}=== Bridge destination configuration (138 ↔ Mainnet) ===${NC}\n" + +if [[ -z "$PRIVATE_KEY" ]]; then + echo -e "${RED}ERROR: PRIVATE_KEY not set (env or .env)${NC}" >&2 + exit 1 +fi + +if [[ -z "$WETH9_BRIDGE_138" || -z "$WETH10_BRIDGE_138" ]]; then + echo -e "${RED}ERROR: Set WETH9_BRIDGE_138 / WETH10_BRIDGE_138 or CCIPWETH9_BRIDGE_CHAIN138 / CCIPWETH10_BRIDGE_CHAIN138${NC}" >&2 + exit 1 +fi + +if [[ -z "$WETH9_MAINNET" || -z "$WETH10_MAINNET" ]]; then + echo -e "${RED}ERROR: Set mainnet peer bridge addresses: WETH9_MAINNET / WETH10_MAINNET${NC}" >&2 + echo -e " (or MAINNET_CCIP_WETH9_BRIDGE / MAINNET_CCIP_WETH10_BRIDGE). These must be the CCIP bridge contracts on Ethereum, not WETH token addresses.${NC}" >&2 + exit 1 fi -# Function to add destination add_destination() { - local bridge_address=$1 - local chain_selector=$2 - local destination_token=$3 - local rpc_url=$4 - local network_name=$5 + local bridge_address=$1 + local chain_selector=$2 + local receiver_bridge=$3 + local rpc_url=$4 + local network_name=$5 - echo -e "${GREEN}Adding destination to $network_name bridge...${NC}" - - cast send "$bridge_address" \ - "addDestination(uint64,address,address)" \ - "$chain_selector" \ - "$destination_token" \ - "0x0000000000000000000000000000000000000000" \ - --rpc-url "$rpc_url" \ - --private-key "$PRIVATE_KEY" \ - --legacy + echo -e "${GREEN}Adding destination on $network_name bridge...${NC}" + cast send "${bridge_address,,}" \ + "addDestination(uint64,address)" \ + "$chain_selector" \ + "${receiver_bridge,,}" \ + --rpc-url "$rpc_url" \ + --private-key "$PRIVATE_KEY" \ + --legacy \ + --gas-limit 250000 \ + --gas-price 2000000000 - echo -e "${GREEN}✓ Destination added${NC}\n" + echo -e "${GREEN}✓ Destination added${NC}\n" } -# Function to verify destinations verify_destinations() { - local bridge_address=$1 - local rpc_url=$2 - local network_name=$3 + local bridge_address=$1 + local rpc_url=$2 + local network_name=$3 - echo -e "${GREEN}Verifying destinations on $network_name...${NC}" - - local chains=$(cast call "$bridge_address" \ - "getDestinationChains()(uint64[])" \ - --rpc-url "$rpc_url") - + echo -e "${GREEN}Verifying destinations on $network_name...${NC}" + local chains + if chains=$(cast call "${bridge_address,,}" \ + "getDestinationChains()(uint64[])" \ + --rpc-url "$rpc_url" 2>/dev/null); then echo -e "${GREEN}Destination chains: $chains${NC}\n" + else + echo -e "${YELLOW}Could not read getDestinationChains (cast/RPC). Try cast rpc eth_call or another RPC.${NC}\n" + fi } -# Configure ChainID 138 → Mainnet -echo -e "${YELLOW}=== Configuring ChainID 138 → Mainnet ===${NC}\n" +echo -e "${YELLOW}=== Chain 138 → Mainnet ===${NC}\n" -echo -e "${GREEN}1. Configuring WETH9 Bridge (ChainID 138 → Mainnet)${NC}" -add_destination "$WETH9_BRIDGE_138" "$MAINNET_CHAIN_SELECTOR" "$WETH9_MAINNET" "$RPC_URL_138" "ChainID 138" +echo -e "${GREEN}1. WETH9 bridge on 138 → Mainnet peer${NC}" +add_destination "$WETH9_BRIDGE_138" "$MAINNET_CHAIN_SELECTOR" "$WETH9_MAINNET" "$RPC_URL_138" "Chain 138 WETH9" -echo -e "${GREEN}2. Configuring WETH10 Bridge (ChainID 138 → Mainnet)${NC}" -add_destination "$WETH10_BRIDGE_138" "$MAINNET_CHAIN_SELECTOR" "$WETH10_MAINNET" "$RPC_URL_138" "ChainID 138" +echo -e "${GREEN}2. WETH10 bridge on 138 → Mainnet peer${NC}" +add_destination "$WETH10_BRIDGE_138" "$MAINNET_CHAIN_SELECTOR" "$WETH10_MAINNET" "$RPC_URL_138" "Chain 138 WETH10" -# Verify ChainID 138 bridges -echo -e "${YELLOW}=== Verifying ChainID 138 Bridges ===${NC}\n" +echo -e "${YELLOW}=== Verify 138 bridges ===${NC}\n" verify_destinations "$WETH9_BRIDGE_138" "$RPC_URL_138" "WETH9 Bridge" verify_destinations "$WETH10_BRIDGE_138" "$RPC_URL_138" "WETH10 Bridge" -# Note: Mainnet → ChainID 138 requires ChainID 138 selector -if [ -z "$CHAIN138_CHAIN_SELECTOR" ]; then - echo -e "${YELLOW}NOTE: ChainID 138 chain selector not set.${NC}" - echo -e "${YELLOW}To configure Mainnet → ChainID 138, first determine the ChainID 138 selector.${NC}" - echo -e "${YELLOW}You can find it using: cast call 'getChainSelector()(uint64)' --rpc-url $RPC_URL_138${NC}\n" +if [[ -z "$CHAIN138_CHAIN_SELECTOR" ]]; then + echo -e "${YELLOW}NOTE: CHAIN138_CHAIN_SELECTOR / CHAIN138_SELECTOR not set.${NC}" + echo -e "${YELLOW}To add Chain 138 as a destination on Mainnet bridges, set the selector then run addDestination on mainnet (see complete-config-ready-chains.sh pattern).${NC}" + echo -e "${YELLOW}Router getChainSelector() may revert on custom routers; see docs/deployment/CHAIN138_SELECTOR_NOTES.md${NC}\n" else - echo -e "${YELLOW}=== Configuring Mainnet → ChainID 138 ===${NC}\n" - echo -e "${YELLOW}NOTE: This requires deploying bridges on Mainnet first.${NC}\n" + echo -e "${YELLOW}=== Mainnet → Chain 138 ===${NC}" + echo -e "${YELLOW}CHAIN138_CHAIN_SELECTOR=$CHAIN138_CHAIN_SELECTOR — run addDestination on each Mainnet bridge with this selector and the 138 peer bridge address (not automated here).${NC}\n" fi -echo -e "${GREEN}=== Configuration Complete ===${NC}\n" -echo -e "Next Steps:" -echo -e " 1. Test bidirectional transfers" -echo -e " 2. Monitor bridge activity" -echo -e " 3. Verify LINK token balances for CCIP fees" +echo -e "${GREEN}=== Done ===${NC}\n" +echo -e "Next: fund bridges with LINK; test transfers; monitor fees." diff --git a/scripts/deployment/configure-weth10-bridge.sh b/scripts/deployment/configure-weth10-bridge.sh index e505ebe..6583894 100755 --- a/scripts/deployment/configure-weth10-bridge.sh +++ b/scripts/deployment/configure-weth10-bridge.sh @@ -1,38 +1,56 @@ #!/usr/bin/env bash -# Configure CCIPWETH10Bridge destinations +# Print cast commands to configure CCIPWETH10Bridge (Mainnet ↔ Chain 138). +# For hands-off execution use execute-bridge-config.sh (WETH9 + WETH10). + +set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "$SCRIPT_DIR/../lib/init.sh" +[[ -f "$SCRIPT_DIR/../lib/init.sh" ]] && source "$SCRIPT_DIR/../lib/init.sh" 2>/dev/null || true PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" -# Load environment -if [ -f "$PROJECT_ROOT/.env" ]; then - source "$PROJECT_ROOT/.env" +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a fi MAINNET_RPC="${ETHEREUM_MAINNET_RPC:-https://eth.llamarpc.com}" -CHAIN138_RPC="${RPC_URL:-https://rpc.d-bis.org}" -PRIVATE_KEY="${PRIVATE_KEY}" -if [[ ! "$PRIVATE_KEY" =~ ^0x ]]; then - PRIVATE_KEY="0x$PRIVATE_KEY" +MAINNET_RPC="${MAINNET_RPC%$'\r'}" +MAINNET_RPC="${MAINNET_RPC%$'\n'}" +CHAIN138_RPC="${RPC_URL_138:-${CHAIN138_RPC:-http://192.168.11.211:8545}}" +CHAIN138_RPC="${CHAIN138_RPC%$'\r'}" +CHAIN138_RPC="${CHAIN138_RPC%$'\n'}" + +PRIVATE_KEY="${PRIVATE_KEY:-}" +[[ -n "$PRIVATE_KEY" && ! "$PRIVATE_KEY" =~ ^0x ]] && PRIVATE_KEY="0x$PRIVATE_KEY" + +WETH10_BRIDGE_MAINNET=$(grep "CCIPWETH10_BRIDGE_MAINNET=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH10_BRIDGE_MAINNET:-}") +WETH10_BRIDGE_CHAIN138=$(grep "CCIPWETH10_BRIDGE_CHAIN138=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH10_BRIDGE_CHAIN138:-}") + +CHAIN138_SELECTOR="${CHAIN138_SELECTOR:-138}" +ETH_SELECTOR="${ETH_MAINNET_SELECTOR:-5009297550715157269}" + +WETH10_BRIDGE_MAINNET="${WETH10_BRIDGE_MAINNET,,}" +WETH10_BRIDGE_CHAIN138="${WETH10_BRIDGE_CHAIN138,,}" + +if [[ -z "$WETH10_BRIDGE_MAINNET" || -z "$WETH10_BRIDGE_CHAIN138" ]]; then + echo "Error: Set CCIPWETH10_BRIDGE_MAINNET and CCIPWETH10_BRIDGE_CHAIN138 in .env" >&2 + exit 1 fi -WETH10_BRIDGE_MAINNET=$(grep "CCIPWETH10_BRIDGE_MAINNET=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "") -WETH10_BRIDGE_CHAIN138=$(grep "CCIPWETH10_BRIDGE_CHAIN138=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "") - -CHAIN138_SELECTOR="${CHAIN138_SELECTOR:-0x000000000000008a}" -ETH_SELECTOR="${ETH_MAINNET_SELECTOR:-0x500147}" - -if [ -z "$WETH10_BRIDGE_MAINNET" ] || [ -z "$WETH10_BRIDGE_CHAIN138" ]; then - echo "Error: Bridge addresses not found in .env" - exit 1 -fi - -echo "Configuring CCIPWETH10Bridge..." -echo " Mainnet Bridge: $WETH10_BRIDGE_MAINNET" -echo " Chain-138 Bridge: $WETH10_BRIDGE_CHAIN138" -echo "To configure, run:" -echo " # On Mainnet:" -echo " cast send $WETH10_BRIDGE_MAINNET \"addDestination(uint64,address)\" $CHAIN138_SELECTOR $WETH10_BRIDGE_CHAIN138 --rpc-url $MAINNET_RPC --private-key $PRIVATE_KEY" -echo " # On Chain-138:" -echo " cast send $WETH10_BRIDGE_CHAIN138 \"addDestination(uint64,address)\" $ETH_SELECTOR $WETH10_BRIDGE_MAINNET --rpc-url $CHAIN138_RPC --private-key $PRIVATE_KEY" +echo "=== CCIPWETH10Bridge — run these cast commands (decimal selectors) ===" +echo "" +echo "# On Ethereum mainnet (add Chain 138 as destination):" +echo "cast send ${WETH10_BRIDGE_MAINNET} \"addDestination(uint64,address)\" ${CHAIN138_SELECTOR} ${WETH10_BRIDGE_CHAIN138} \\" +echo " --rpc-url ${MAINNET_RPC} --private-key \"\$PRIVATE_KEY\" --legacy --gas-limit 400000" +echo "" +echo "# On Chain 138 (add Mainnet as destination):" +echo "cast send ${WETH10_BRIDGE_CHAIN138} \"addDestination(uint64,address)\" ${ETH_SELECTOR} ${WETH10_BRIDGE_MAINNET} \\" +echo " --rpc-url ${CHAIN138_RPC} --private-key \"\$PRIVATE_KEY\" --legacy --gas-limit 250000 --gas-price 2000000000" +echo "" +echo "Or run: ./scripts/deployment/execute-bridge-config.sh" diff --git a/scripts/deployment/configure-weth9-bridge.sh b/scripts/deployment/configure-weth9-bridge.sh index c5d891e..e3fdd35 100755 --- a/scripts/deployment/configure-weth9-bridge.sh +++ b/scripts/deployment/configure-weth9-bridge.sh @@ -1,38 +1,56 @@ #!/usr/bin/env bash -# Configure CCIPWETH9Bridge destinations +# Print cast commands to configure CCIPWETH9Bridge (Mainnet ↔ Chain 138). +# For hands-off execution use execute-bridge-config.sh (WETH9 + WETH10). + +set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "$SCRIPT_DIR/../lib/init.sh" +[[ -f "$SCRIPT_DIR/../lib/init.sh" ]] && source "$SCRIPT_DIR/../lib/init.sh" 2>/dev/null || true PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" -# Load environment -if [ -f "$PROJECT_ROOT/.env" ]; then - source "$PROJECT_ROOT/.env" +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a fi MAINNET_RPC="${ETHEREUM_MAINNET_RPC:-https://eth.llamarpc.com}" -CHAIN138_RPC="${RPC_URL:-https://rpc.d-bis.org}" -PRIVATE_KEY="${PRIVATE_KEY}" -if [[ ! "$PRIVATE_KEY" =~ ^0x ]]; then - PRIVATE_KEY="0x$PRIVATE_KEY" +MAINNET_RPC="${MAINNET_RPC%$'\r'}" +MAINNET_RPC="${MAINNET_RPC%$'\n'}" +CHAIN138_RPC="${RPC_URL_138:-${CHAIN138_RPC:-http://192.168.11.211:8545}}" +CHAIN138_RPC="${CHAIN138_RPC%$'\r'}" +CHAIN138_RPC="${CHAIN138_RPC%$'\n'}" + +PRIVATE_KEY="${PRIVATE_KEY:-}" +[[ -n "$PRIVATE_KEY" && ! "$PRIVATE_KEY" =~ ^0x ]] && PRIVATE_KEY="0x$PRIVATE_KEY" + +WETH9_BRIDGE_MAINNET=$(grep "CCIPWETH9_BRIDGE_MAINNET=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH9_BRIDGE_MAINNET:-}") +WETH9_BRIDGE_CHAIN138=$(grep "CCIPWETH9_BRIDGE_CHAIN138=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH9_BRIDGE_CHAIN138:-}") + +CHAIN138_SELECTOR="${CHAIN138_SELECTOR:-138}" +ETH_SELECTOR="${ETH_MAINNET_SELECTOR:-5009297550715157269}" + +WETH9_BRIDGE_MAINNET="${WETH9_BRIDGE_MAINNET,,}" +WETH9_BRIDGE_CHAIN138="${WETH9_BRIDGE_CHAIN138,,}" + +if [[ -z "$WETH9_BRIDGE_MAINNET" || -z "$WETH9_BRIDGE_CHAIN138" ]]; then + echo "Error: Set CCIPWETH9_BRIDGE_MAINNET and CCIPWETH9_BRIDGE_CHAIN138 in .env" >&2 + exit 1 fi -WETH9_BRIDGE_MAINNET=$(grep "CCIPWETH9_BRIDGE_MAINNET=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "") -WETH9_BRIDGE_CHAIN138=$(grep "CCIPWETH9_BRIDGE_CHAIN138=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "") - -CHAIN138_SELECTOR="${CHAIN138_SELECTOR:-0x000000000000008a}" -ETH_SELECTOR="${ETH_MAINNET_SELECTOR:-0x500147}" - -if [ -z "$WETH9_BRIDGE_MAINNET" ] || [ -z "$WETH9_BRIDGE_CHAIN138" ]; then - echo "Error: Bridge addresses not found in .env" - exit 1 -fi - -echo "Configuring CCIPWETH9Bridge..." -echo " Mainnet Bridge: $WETH9_BRIDGE_MAINNET" -echo " Chain-138 Bridge: $WETH9_BRIDGE_CHAIN138" -echo "To configure, run:" -echo " # On Mainnet:" -echo " cast send $WETH9_BRIDGE_MAINNET \"addDestination(uint64,address)\" $CHAIN138_SELECTOR $WETH9_BRIDGE_CHAIN138 --rpc-url $MAINNET_RPC --private-key $PRIVATE_KEY" -echo " # On Chain-138:" -echo " cast send $WETH9_BRIDGE_CHAIN138 \"addDestination(uint64,address)\" $ETH_SELECTOR $WETH9_BRIDGE_MAINNET --rpc-url $CHAIN138_RPC --private-key $PRIVATE_KEY" +echo "=== CCIPWETH9Bridge — run these cast commands (decimal selectors) ===" +echo "" +echo "# On Ethereum mainnet (add Chain 138 as destination):" +echo "cast send ${WETH9_BRIDGE_MAINNET} \"addDestination(uint64,address)\" ${CHAIN138_SELECTOR} ${WETH9_BRIDGE_CHAIN138} \\" +echo " --rpc-url ${MAINNET_RPC} --private-key \"\$PRIVATE_KEY\" --legacy --gas-limit 400000" +echo "" +echo "# On Chain 138 (add Mainnet as destination):" +echo "cast send ${WETH9_BRIDGE_CHAIN138} \"addDestination(uint64,address)\" ${ETH_SELECTOR} ${WETH9_BRIDGE_MAINNET} \\" +echo " --rpc-url ${CHAIN138_RPC} --private-key \"\$PRIVATE_KEY\" --legacy --gas-limit 250000 --gas-price 2000000000" +echo "" +echo "Or run: ./scripts/deployment/execute-bridge-config.sh" diff --git a/scripts/deployment/create-terraform-backend.sh b/scripts/deployment/create-terraform-backend.sh index 8b2b852..843715d 100755 --- a/scripts/deployment/create-terraform-backend.sh +++ b/scripts/deployment/create-terraform-backend.sh @@ -8,6 +8,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi log_info "=== Creating Terraform Backend Storage Account ===" diff --git a/scripts/deployment/create-uniswap-v3-pool-cusdt-cusdc.sh b/scripts/deployment/create-uniswap-v3-pool-cusdt-cusdc.sh index 398b553..f321cc8 100755 --- a/scripts/deployment/create-uniswap-v3-pool-cusdt-cusdc.sh +++ b/scripts/deployment/create-uniswap-v3-pool-cusdt-cusdc.sh @@ -10,8 +10,23 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi DOTENV="$REPO_ROOT/.env" -if [[ -f "$DOTENV" ]]; then set -a; source "$DOTENV"; set +a; fi UNISWAP_V3_FACTORY="${UNISWAP_V3_FACTORY:-0x1F98431c8aD98523631AE4a59f267346ea31F984}" FEE="${FEE:-500}" diff --git a/scripts/deployment/deploy-36-region-infrastructure.sh b/scripts/deployment/deploy-36-region-infrastructure.sh index 62c7944..2046c44 100755 --- a/scripts/deployment/deploy-36-region-infrastructure.sh +++ b/scripts/deployment/deploy-36-region-infrastructure.sh @@ -7,6 +7,22 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi TF_DIR="$PROJECT_ROOT/terraform/well-architected/cloud-sovereignty" cd "$TF_DIR" diff --git a/scripts/deployment/deploy-all-contracts.sh b/scripts/deployment/deploy-all-contracts.sh index 9f44c1e..256ad13 100755 --- a/scripts/deployment/deploy-all-contracts.sh +++ b/scripts/deployment/deploy-all-contracts.sh @@ -5,8 +5,23 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi -source .env 2>/dev/null || true RPC_URL="${RPC_URL_138:-http://localhost:8545}" GAS_PRICE="${GAS_PRICE:-1000000000}" diff --git a/scripts/deployment/deploy-all-from-proxy.sh b/scripts/deployment/deploy-all-from-proxy.sh index 20626fa..e250fa7 100755 --- a/scripts/deployment/deploy-all-from-proxy.sh +++ b/scripts/deployment/deploy-all-from-proxy.sh @@ -7,6 +7,22 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "Phase 2 Complete Deployment from Proxy Host" diff --git a/scripts/deployment/deploy-all-mainnet.sh b/scripts/deployment/deploy-all-mainnet.sh index 50fbfb2..d3c7e98 100755 --- a/scripts/deployment/deploy-all-mainnet.sh +++ b/scripts/deployment/deploy-all-mainnet.sh @@ -8,6 +8,22 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi # Load environment variables diff --git a/scripts/deployment/deploy-all-mainnets-with-mapper-oracle-pmm.sh b/scripts/deployment/deploy-all-mainnets-with-mapper-oracle-pmm.sh index c6c0630..9a8e6fc 100755 --- a/scripts/deployment/deploy-all-mainnets-with-mapper-oracle-pmm.sh +++ b/scripts/deployment/deploy-all-mainnets-with-mapper-oracle-pmm.sh @@ -8,11 +8,24 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi # Load .env without strict unset (avoid init.sh pipefail on .env) -set +u -[ -f .env ] && source .env -set -u [ -f "$SCRIPT_DIR/../lib/infura.sh" ] && source "$SCRIPT_DIR/../lib/infura.sh" PHASE="${1:-all}" diff --git a/scripts/deployment/deploy-all-ordered.sh b/scripts/deployment/deploy-all-ordered.sh index 1c5a548..efa2b0b 100755 --- a/scripts/deployment/deploy-all-ordered.sh +++ b/scripts/deployment/deploy-all-ordered.sh @@ -11,6 +11,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi log_info "=== Deploy All Contracts in Proper Order ===" diff --git a/scripts/deployment/deploy-all-phases.sh b/scripts/deployment/deploy-all-phases.sh index f4ba677..57324fa 100755 --- a/scripts/deployment/deploy-all-phases.sh +++ b/scripts/deployment/deploy-all-phases.sh @@ -15,6 +15,22 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi if [ -f .env ]; then set -a diff --git a/scripts/deployment/deploy-all-ready-chains.sh b/scripts/deployment/deploy-all-ready-chains.sh index 18eb600..cbc9287 100755 --- a/scripts/deployment/deploy-all-ready-chains.sh +++ b/scripts/deployment/deploy-all-ready-chains.sh @@ -8,6 +8,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi # Source environment if [ -f .env ]; then diff --git a/scripts/deployment/deploy-all.sh b/scripts/deployment/deploy-all.sh index ca1eec0..f902785 100755 --- a/scripts/deployment/deploy-all.sh +++ b/scripts/deployment/deploy-all.sh @@ -9,6 +9,22 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi DEPLOYMENT_LOG="${PROJECT_ROOT}/deployment.log" CONTRACT_ADDRESSES_FILE="${PROJECT_ROOT}/contracts-deployed.json" diff --git a/scripts/deployment/deploy-bridges-chain138.sh b/scripts/deployment/deploy-bridges-chain138.sh index 24157bd..5317205 100755 --- a/scripts/deployment/deploy-bridges-chain138.sh +++ b/scripts/deployment/deploy-bridges-chain138.sh @@ -4,6 +4,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi log_info "=== Deploying Bridges on Chain-138 ===" diff --git a/scripts/deployment/deploy-bridges-config-ready-chains.sh b/scripts/deployment/deploy-bridges-config-ready-chains.sh index cccd0c0..9908ed4 100755 --- a/scripts/deployment/deploy-bridges-config-ready-chains.sh +++ b/scripts/deployment/deploy-bridges-config-ready-chains.sh @@ -14,8 +14,27 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi -[[ -f "$PROJECT_ROOT/.env" ]] && set -a && source "$PROJECT_ROOT/.env" && set +a +GNOSIS_RPC="${GNOSIS_RPC:-${GNOSIS_MAINNET_RPC:-}}" +CRONOS_RPC="${CRONOS_RPC:-${CRONOS_RPC_URL:-}}" +CELO_RPC="${CELO_RPC:-${CELO_MAINNET_RPC:-}}" +WEMIX_RPC="${WEMIX_RPC:-${WEMIX_MAINNET_RPC:-}}" DRY_RUN="${DRY_RUN:-0}" SIMULATE="${SIMULATE:-0}" diff --git a/scripts/deployment/deploy-bridges-mainnet.sh b/scripts/deployment/deploy-bridges-mainnet.sh index 7344113..9cb9345 100755 --- a/scripts/deployment/deploy-bridges-mainnet.sh +++ b/scripts/deployment/deploy-bridges-mainnet.sh @@ -7,6 +7,22 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi # Load environment variables diff --git a/scripts/deployment/deploy-cacti.sh b/scripts/deployment/deploy-cacti.sh index 1364897..63cb346 100755 --- a/scripts/deployment/deploy-cacti.sh +++ b/scripts/deployment/deploy-cacti.sh @@ -8,6 +8,22 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi # Configuration NAMESPACE="${NAMESPACE:-cacti}" diff --git a/scripts/deployment/deploy-ccip-logger-all-chains.sh b/scripts/deployment/deploy-ccip-logger-all-chains.sh index c5c4fec..7b2eacf 100755 --- a/scripts/deployment/deploy-ccip-logger-all-chains.sh +++ b/scripts/deployment/deploy-ccip-logger-all-chains.sh @@ -9,10 +9,20 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" - -if [[ -f .env ]]; then +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then set -a - source .env + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" set +a fi diff --git a/scripts/deployment/deploy-ccip-router.sh b/scripts/deployment/deploy-ccip-router.sh index bb6d9ab..a6e659d 100755 --- a/scripts/deployment/deploy-ccip-router.sh +++ b/scripts/deployment/deploy-ccip-router.sh @@ -39,6 +39,22 @@ echo "Data Fee Per Byte: $DATA_FEE_PER_BYTE" # Deploy using Foundry cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi forge script script/DeployCCIPRouter.s.sol \ --rpc-url "$RPC_URL" \ diff --git a/scripts/deployment/deploy-ccip-weth10-bridge.sh b/scripts/deployment/deploy-ccip-weth10-bridge.sh index c4ef4c1..ed2a718 100755 --- a/scripts/deployment/deploy-ccip-weth10-bridge.sh +++ b/scripts/deployment/deploy-ccip-weth10-bridge.sh @@ -45,6 +45,22 @@ echo "WETH10 Address: $WETH10_ADDRESS" echo "Fee Token (LINK): $CCIP_FEE_TOKEN" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi # Export environment variables for Foundry export PRIVATE_KEY diff --git a/scripts/deployment/deploy-ccip-weth9-bridge.sh b/scripts/deployment/deploy-ccip-weth9-bridge.sh index 91b2481..a43044f 100755 --- a/scripts/deployment/deploy-ccip-weth9-bridge.sh +++ b/scripts/deployment/deploy-ccip-weth9-bridge.sh @@ -45,6 +45,22 @@ echo "WETH9 Address: $WETH9_ADDRESS" echo "Fee Token (LINK): $CCIP_FEE_TOKEN" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi # Export environment variables for Foundry export PRIVATE_KEY diff --git a/scripts/deployment/deploy-contracts-once-ready.sh b/scripts/deployment/deploy-contracts-once-ready.sh index 904637b..b2c8816 100755 --- a/scripts/deployment/deploy-contracts-once-ready.sh +++ b/scripts/deployment/deploy-contracts-once-ready.sh @@ -7,8 +7,23 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi -source .env 2>/dev/null || true RPC_URL="${RPC_URL:-http://localhost:8545}" PRIVATE_KEY="${PRIVATE_KEY:-}" diff --git a/scripts/deployment/deploy-contracts-ordered.sh b/scripts/deployment/deploy-contracts-ordered.sh index 4c961cf..ec110a2 100755 --- a/scripts/deployment/deploy-contracts-ordered.sh +++ b/scripts/deployment/deploy-contracts-ordered.sh @@ -11,6 +11,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi # Load environment variables if [ ! -f .env ]; then diff --git a/scripts/deployment/deploy-contracts-parallel.sh b/scripts/deployment/deploy-contracts-parallel.sh index 6ef85a0..e02a610 100755 --- a/scripts/deployment/deploy-contracts-parallel.sh +++ b/scripts/deployment/deploy-contracts-parallel.sh @@ -8,6 +8,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi # Load environment variables if [ ! -f .env ]; then diff --git a/scripts/deployment/deploy-contracts-unified.sh b/scripts/deployment/deploy-contracts-unified.sh index dcfe70a..f000931 100755 --- a/scripts/deployment/deploy-contracts-unified.sh +++ b/scripts/deployment/deploy-contracts-unified.sh @@ -8,6 +8,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi # Default values MODE="${MODE:-ordered}" # ordered or parallel diff --git a/scripts/deployment/deploy-cusdt-cusdc-all-chains.sh b/scripts/deployment/deploy-cusdt-cusdc-all-chains.sh index 905b52b..0438b4e 100755 --- a/scripts/deployment/deploy-cusdt-cusdc-all-chains.sh +++ b/scripts/deployment/deploy-cusdt-cusdc-all-chains.sh @@ -8,7 +8,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" DOTENV="$REPO_ROOT/.env" cd "$REPO_ROOT" -if [[ -f "$DOTENV" ]]; then set -a; source "$DOTENV"; set +a; fi +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "$REPO_ROOT" +elif [[ -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi + +GNOSIS_MAINNET_RPC="${GNOSIS_MAINNET_RPC:-${GNOSIS_RPC:-}}" +CRONOS_RPC_URL="${CRONOS_RPC_URL:-${CRONOS_RPC:-}}" +CELO_MAINNET_RPC="${CELO_MAINNET_RPC:-${CELO_RPC:-}}" +WEMIX_MAINNET_RPC="${WEMIX_MAINNET_RPC:-${WEMIX_RPC:-}}" # Chain name : chain_id : RPC env var name CHAINS=( diff --git a/scripts/deployment/deploy-firefly.sh b/scripts/deployment/deploy-firefly.sh index ab557d5..d99b71a 100755 --- a/scripts/deployment/deploy-firefly.sh +++ b/scripts/deployment/deploy-firefly.sh @@ -8,6 +8,22 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi # Configuration NAMESPACE="${NAMESPACE:-firefly}" diff --git a/scripts/deployment/deploy-full-parity-all-chains.sh b/scripts/deployment/deploy-full-parity-all-chains.sh index 403010f..401dc6b 100644 --- a/scripts/deployment/deploy-full-parity-all-chains.sh +++ b/scripts/deployment/deploy-full-parity-all-chains.sh @@ -11,10 +11,23 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi -set +u -[ -f .env ] && source .env -set -u [ -f "$SCRIPT_DIR/../lib/infura.sh" ] && source "$SCRIPT_DIR/../lib/infura.sh" PHASE="${1:-all}" diff --git a/scripts/deployment/deploy-keyvaults-only.sh b/scripts/deployment/deploy-keyvaults-only.sh index 58783f3..9079fe6 100755 --- a/scripts/deployment/deploy-keyvaults-only.sh +++ b/scripts/deployment/deploy-keyvaults-only.sh @@ -5,6 +5,22 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi TERRAFORM_DIR="$PROJECT_ROOT/terraform/well-architected/cloud-sovereignty" echo "╔════════════════════════════════════════════════════════════════╗" diff --git a/scripts/deployment/deploy-mainnet-tether-mirror.sh b/scripts/deployment/deploy-mainnet-tether-mirror.sh index 14c34d3..1aa1c67 100755 --- a/scripts/deployment/deploy-mainnet-tether-mirror.sh +++ b/scripts/deployment/deploy-mainnet-tether-mirror.sh @@ -8,6 +8,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../../" && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi # Source environment variables if [ -f .env ]; then diff --git a/scripts/deployment/deploy-multicall.sh b/scripts/deployment/deploy-multicall.sh index 987bcf7..1db6674 100755 --- a/scripts/deployment/deploy-multicall.sh +++ b/scripts/deployment/deploy-multicall.sh @@ -20,6 +20,22 @@ echo "Deploying Multicall to ChainID 138..." echo "RPC URL: $RPC_URL" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi forge script script/DeployMulticall.s.sol \ --rpc-url "$RPC_URL" \ diff --git a/scripts/deployment/deploy-multisig.sh b/scripts/deployment/deploy-multisig.sh index a8faf61..505be45 100755 --- a/scripts/deployment/deploy-multisig.sh +++ b/scripts/deployment/deploy-multisig.sh @@ -8,6 +8,22 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi RPC_URL="${RPC_URL:-http://localhost:8545}" PRIVATE_KEY="${PRIVATE_KEY:-}" diff --git a/scripts/deployment/deploy-off-chain-services.sh b/scripts/deployment/deploy-off-chain-services.sh index b01ab90..451c82f 100755 --- a/scripts/deployment/deploy-off-chain-services.sh +++ b/scripts/deployment/deploy-off-chain-services.sh @@ -96,6 +96,22 @@ deploy_service() { fi cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi } # Main deployment diff --git a/scripts/deployment/deploy-official-dvm-chain138.sh b/scripts/deployment/deploy-official-dvm-chain138.sh index 79126ca..b1d6698 100644 --- a/scripts/deployment/deploy-official-dvm-chain138.sh +++ b/scripts/deployment/deploy-official-dvm-chain138.sh @@ -7,6 +7,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" DODO_DIR="$PROJECT_ROOT/lib/dodo-contractV2" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi if [[ ! -f .env ]]; then echo "ERROR: .env not found" >&2 diff --git a/scripts/deployment/deploy-optional-future-all.sh b/scripts/deployment/deploy-optional-future-all.sh index ad1645a..8f54d17 100755 --- a/scripts/deployment/deploy-optional-future-all.sh +++ b/scripts/deployment/deploy-optional-future-all.sh @@ -12,6 +12,22 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi if [ -f .env ]; then set -a diff --git a/scripts/deployment/deploy-phase1.sh b/scripts/deployment/deploy-phase1.sh index 3129668..8157f81 100755 --- a/scripts/deployment/deploy-phase1.sh +++ b/scripts/deployment/deploy-phase1.sh @@ -8,6 +8,22 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi log() { log_success "[✓] $1" diff --git a/scripts/deployment/deploy-phase2-and-contracts-parallel.sh b/scripts/deployment/deploy-phase2-and-contracts-parallel.sh index 70de17f..8a93394 100755 --- a/scripts/deployment/deploy-phase2-and-contracts-parallel.sh +++ b/scripts/deployment/deploy-phase2-and-contracts-parallel.sh @@ -8,6 +8,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi # Load environment variables if [ ! -f .env ]; then diff --git a/scripts/deployment/deploy-phase2-from-proxy.sh b/scripts/deployment/deploy-phase2-from-proxy.sh index 456b1d6..dc26a0c 100755 --- a/scripts/deployment/deploy-phase2-from-proxy.sh +++ b/scripts/deployment/deploy-phase2-from-proxy.sh @@ -9,6 +9,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "Phase 2 Deployment from Proxy Host" diff --git a/scripts/deployment/deploy-phase2.sh b/scripts/deployment/deploy-phase2.sh index 4569839..b5a1590 100755 --- a/scripts/deployment/deploy-phase2.sh +++ b/scripts/deployment/deploy-phase2.sh @@ -8,6 +8,22 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi TERRAFORM_DIR="$PROJECT_ROOT/terraform" log() { diff --git a/scripts/deployment/deploy-sufficient-balance-chains.sh b/scripts/deployment/deploy-sufficient-balance-chains.sh index 477f85e..9ccdc1a 100755 --- a/scripts/deployment/deploy-sufficient-balance-chains.sh +++ b/scripts/deployment/deploy-sufficient-balance-chains.sh @@ -10,6 +10,22 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi # Load .env if [ -f .env ]; then diff --git a/scripts/deployment/deploy-tokenization-service.sh b/scripts/deployment/deploy-tokenization-service.sh index 80dfd40..51eb448 100755 --- a/scripts/deployment/deploy-tokenization-service.sh +++ b/scripts/deployment/deploy-tokenization-service.sh @@ -8,6 +8,22 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi # Configuration NAMESPACE="${NAMESPACE:-besu-network}" diff --git a/scripts/deployment/deploy-tokens-and-weth-all-chains-skip-canonical.sh b/scripts/deployment/deploy-tokens-and-weth-all-chains-skip-canonical.sh index e6f912f..034ba86 100755 --- a/scripts/deployment/deploy-tokens-and-weth-all-chains-skip-canonical.sh +++ b/scripts/deployment/deploy-tokens-and-weth-all-chains-skip-canonical.sh @@ -34,8 +34,23 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi -[ -f .env ] && set -a && source .env && set +a DRY_RUN=false CHAINS_FILTER="" diff --git a/scripts/deployment/deploy-vault-system-and-ac-vdc-sdc.sh b/scripts/deployment/deploy-vault-system-and-ac-vdc-sdc.sh index c41abd2..bacf3a5 100755 --- a/scripts/deployment/deploy-vault-system-and-ac-vdc-sdc.sh +++ b/scripts/deployment/deploy-vault-system-and-ac-vdc-sdc.sh @@ -6,8 +6,23 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi -source .env 2>/dev/null || true RPC_URL="${RPC_URL_138:-http://192.168.11.211:8545}" GAS_PRICE="${GAS_PRICE:-1000000000}" diff --git a/scripts/deployment/deploy-weth-create.sh b/scripts/deployment/deploy-weth-create.sh index db5092d..b7787dc 100755 --- a/scripts/deployment/deploy-weth-create.sh +++ b/scripts/deployment/deploy-weth-create.sh @@ -8,9 +8,24 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi # Load environment -source .env 2>/dev/null || true RPC_URL="${RPC_URL:-http://localhost:8545}" PRIVATE_KEY="${PRIVATE_KEY:-}" diff --git a/scripts/deployment/deploy-weth-create2.sh b/scripts/deployment/deploy-weth-create2.sh index f9fe7b3..8200754 100755 --- a/scripts/deployment/deploy-weth-create2.sh +++ b/scripts/deployment/deploy-weth-create2.sh @@ -7,9 +7,24 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi # Load environment -source .env 2>/dev/null || true RPC_URL="${RPC_URL:-http://localhost:8545}" PRIVATE_KEY="${PRIVATE_KEY:-}" diff --git a/scripts/deployment/deploy-weth-unified.sh b/scripts/deployment/deploy-weth-unified.sh index ab5f695..47698df 100755 --- a/scripts/deployment/deploy-weth-unified.sh +++ b/scripts/deployment/deploy-weth-unified.sh @@ -81,6 +81,22 @@ if [ -z "$PRIVATE_KEY" ]; then fi cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "🚀 Unified WETH Deployment" diff --git a/scripts/deployment/deploy-weth-with-ccip.sh b/scripts/deployment/deploy-weth-with-ccip.sh index 6e54333..a9fda6e 100755 --- a/scripts/deployment/deploy-weth-with-ccip.sh +++ b/scripts/deployment/deploy-weth-with-ccip.sh @@ -69,6 +69,22 @@ fi echo "=========================================" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi # Export environment variables for Foundry export PRIVATE_KEY diff --git a/scripts/deployment/deploy-weth.sh b/scripts/deployment/deploy-weth.sh index 983a754..6379ff1 100755 --- a/scripts/deployment/deploy-weth.sh +++ b/scripts/deployment/deploy-weth.sh @@ -20,6 +20,22 @@ echo "Deploying WETH to ChainID 138..." echo "RPC URL: $RPC_URL" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi forge script script/DeployWETH.s.sol \ --rpc-url "$RPC_URL" \ diff --git a/scripts/deployment/deploy-weth10.sh b/scripts/deployment/deploy-weth10.sh index 5597416..ab939a9 100755 --- a/scripts/deployment/deploy-weth10.sh +++ b/scripts/deployment/deploy-weth10.sh @@ -20,6 +20,22 @@ echo "Deploying WETH10 to ChainID 138..." echo "RPC URL: $RPC_URL" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi forge script script/DeployWETH10.s.sol \ --rpc-url "$RPC_URL" \ diff --git a/scripts/deployment/deployment-readiness-report.sh b/scripts/deployment/deployment-readiness-report.sh index ecf4471..047b3b4 100755 --- a/scripts/deployment/deployment-readiness-report.sh +++ b/scripts/deployment/deployment-readiness-report.sh @@ -4,6 +4,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi log_info "=== Ethereum Mainnet Deployment Readiness Report ===" diff --git a/scripts/deployment/dry-run-enhanced-swap-router-chain138.sh b/scripts/deployment/dry-run-enhanced-swap-router-chain138.sh new file mode 100644 index 0000000..010af9f --- /dev/null +++ b/scripts/deployment/dry-run-enhanced-swap-router-chain138.sh @@ -0,0 +1,247 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SMOM_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +ENV_FILE="$SMOM_ROOT/.env" +RUN_FORGE_DRY_RUN=0 +RUN_TIMEOUT_SECONDS="${RUN_TIMEOUT_SECONDS:-90}" +VERBOSITY="${VERBOSITY:--vv}" + +while [[ $# -gt 0 ]]; do + case "$1" in + --run) + RUN_FORGE_DRY_RUN=1 + shift + ;; + --timeout-seconds) + RUN_TIMEOUT_SECONDS="${2:?missing value for --timeout-seconds}" + shift 2 + ;; + --verbosity) + VERBOSITY="${2:?missing value for --verbosity}" + shift 2 + ;; + *) + echo "Unknown argument: $1" >&2 + echo "Usage: $0 [--run] [--timeout-seconds ] [--verbosity <-v|-vv|-vvv|...>]" >&2 + exit 1 + ;; + esac +done + +CHAIN138_WETH_DEFAULT="0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" +CHAIN138_USDT_DEFAULT="0x004b63A7B5b0E06f6bB6adb4a5F9f590BF3182D1" +CHAIN138_USDC_DEFAULT="0x71D6687F38b93CCad569Fa6352c876eea967201b" +DAI_PLACEHOLDER_DEFAULT="0x6B175474E89094C44Da98b954EedeAC495271d0F" + +if [[ -f "$ENV_FILE" ]]; then + set -a + # shellcheck disable=SC1090 + source "$ENV_FILE" + set +a +fi + +RPC_URL_138="${RPC_URL_138:-http://192.168.11.211:8545}" +WETH="${WETH:-$CHAIN138_WETH_DEFAULT}" +OFFICIAL_USDT_ADDRESS="${OFFICIAL_USDT_ADDRESS:-$CHAIN138_USDT_DEFAULT}" +OFFICIAL_USDC_ADDRESS="${OFFICIAL_USDC_ADDRESS:-$CHAIN138_USDC_DEFAULT}" +DAI="${DAI:-$DAI_PLACEHOLDER_DEFAULT}" + +missing=() +[[ -n "${PRIVATE_KEY:-}" ]] || missing+=("PRIVATE_KEY") +[[ -n "${RPC_URL_138:-}" ]] || missing+=("RPC_URL_138") + +show_var() { + local name="$1" value="$2" note="${3:-}" + printf ' %-28s %s' "$name" "$value" + [[ -n "$note" ]] && printf ' (%s)' "$note" + printf '\n' +} + +probe_bool() { + local label="$1" token_in="$2" token_out="$3" provider="$4" + local calldata payload response result + calldata="$(cast calldata "supportsTokenPair(address,address)" "$token_in" "$token_out" 2>/dev/null || true)" + [[ -n "$calldata" ]] || { + echo " UNKNOWN: $label (failed to encode calldata)" + return 2 + } + payload=$(printf '{"jsonrpc":"2.0","method":"eth_call","params":[{"to":"%s","data":"%s"},"latest"],"id":1}' "$provider" "$calldata") + response="$(curl -s -X POST "$RPC_URL_138" -H 'Content-Type: application/json' --data "$payload" 2>/dev/null || true)" + result="$(printf '%s' "$response" | sed -n 's/.*"result":"\([^"]*\)".*/\1/p')" + case "$result" in + "true"|"0x0000000000000000000000000000000000000000000000000000000000000001") + echo " OK: $label" + return 0 + ;; + "false"|"0x0000000000000000000000000000000000000000000000000000000000000000") + echo " MISSING: $label" + return 1 + ;; + *) + echo " UNKNOWN: $label (provider call failed)" + return 2 + ;; + esac +} + +run_forge_dry_run() { + local forge_cmd=( + forge script script/bridge/trustless/DeployEnhancedSwapRouter.s.sol:DeployEnhancedSwapRouter + --skip test + --non-interactive + --rpc-url "$RPC_URL_138" + --private-key "$PRIVATE_KEY" + "$VERBOSITY" + ) + local exit_code=0 + + echo "Running targeted build warm-up" + forge build contracts/bridge/trustless/EnhancedSwapRouter.sol script/bridge/trustless/DeployEnhancedSwapRouter.s.sol + echo "" + echo "Running sourced non-broadcast forge script" + echo "Timeout: ${RUN_TIMEOUT_SECONDS}s" + echo "Verbosity: $VERBOSITY" + echo "" + + set +e + if command -v timeout >/dev/null 2>&1; then + timeout "${RUN_TIMEOUT_SECONDS}s" "${forge_cmd[@]}" + exit_code=$? + else + "${forge_cmd[@]}" + exit_code=$? + fi + set -e + + if (( exit_code == 124 )); then + echo "" + echo "Forge dry-run timed out after ${RUN_TIMEOUT_SECONDS}s." + echo "Likely causes:" + echo " - large project compilation still dominates the preflight" + echo " - RPC simulation is slow on the current Chain 138 endpoint" + echo " - the script needs more visibility to pinpoint the slow phase" + echo "Next diagnostic step:" + echo " bash scripts/deployment/dry-run-enhanced-swap-router-chain138.sh --run --timeout-seconds 180 --verbosity -vvv" + return 124 + fi + + if (( exit_code != 0 )); then + echo "" + echo "Forge dry-run failed with exit code ${exit_code}." + return "$exit_code" + fi +} + +echo "=== EnhancedSwapRouter Chain 138 Dry Run ===" +echo "Project root: $SMOM_ROOT" +echo "Env file: $ENV_FILE" +echo "" + +if (( ${#missing[@]} > 0 )); then + echo "Missing required env:" + for item in "${missing[@]}"; do + echo " - $item" + done + echo "" + echo "Set them in $ENV_FILE or export them in your shell, then rerun." + exit 1 +fi + +echo "Required env" +show_var "RPC_URL_138" "$RPC_URL_138" "Core RPC only" +show_var "PRIVATE_KEY" "" "value loaded; not printed" +echo "" + +echo "Chain 138 token env used by the deploy script" +show_var "WETH" "$WETH" "defaults to Chain 138 canonical WETH" +show_var "OFFICIAL_USDT_ADDRESS" "$OFFICIAL_USDT_ADDRESS" "defaults to Chain 138 mirror USDT" +show_var "OFFICIAL_USDC_ADDRESS" "$OFFICIAL_USDC_ADDRESS" "defaults to Chain 138 mirror USDC" +show_var "DAI" "$DAI" "placeholder unless a real Chain 138 DAI exists" +echo "" + +echo "Optional provider env" +show_var "DODOEX_ROUTER" "${DODOEX_ROUTER:-}" "unset => Dodoex provider disabled after deploy" +show_var "DODO_PMM_PROVIDER_ADDRESS" "${DODO_PMM_PROVIDER_ADDRESS:-${DODO_PMM_PROVIDER:-}}" "set => Chain 138 uses deployed PMM provider backend" +show_var "UNISWAP_V3_ROUTER" "${UNISWAP_V3_ROUTER:-}" "unset => Uniswap provider disabled after deploy" +show_var "CURVE_3POOL" "${CURVE_3POOL:-}" "unset => Curve provider disabled after deploy" +show_var "BALANCER_VAULT" "${BALANCER_VAULT:-}" "unset => Balancer provider disabled after deploy" +show_var "ONEINCH_ROUTER" "${ONEINCH_ROUTER:-}" "unset => 1inch provider disabled after deploy" +echo "" + +echo "Live execution readiness" +if [[ -n "${DODO_PMM_PROVIDER_ADDRESS:-${DODO_PMM_PROVIDER:-}}" ]]; then + echo " OK: DODO PMM provider is set, so Chain 138 can use the deployed PMM integration/provider backend." +elif [[ -z "${DODOEX_ROUTER:-}" ]]; then + echo " BLOCKER: neither DODOEX_ROUTER nor DODO_PMM_PROVIDER_ADDRESS is set." + echo " BLOCKER: live Chain 138 DODO pool mappings would be registered, but no DODO execution path would remain enabled." +else + echo " OK: DODOEX_ROUTER is set, so external Dodoex token-to-token execution can stay enabled." +fi +if [[ -z "${UNISWAP_V3_ROUTER:-}" && -z "${BALANCER_VAULT:-}" && -z "${CURVE_3POOL:-}" && -z "${ONEINCH_ROUTER:-}" ]]; then + echo " NOTE: no secondary providers are configured yet; that is acceptable for DODO-only bring-up." +fi +echo " GAP: swapToStablecoin() still needs real WETH -> stable routes before it is operational on Chain 138." +echo "" + +if [[ -n "${DODO_PMM_PROVIDER_ADDRESS:-${DODO_PMM_PROVIDER:-}}" ]] && command -v cast >/dev/null 2>&1; then + DODO_PROVIDER_TO_PROBE="${DODO_PMM_PROVIDER_ADDRESS:-${DODO_PMM_PROVIDER}}" + live_pair_missing=0 + echo "Live PMM provider route probe" + probe_bool "WETH -> OFFICIAL_USDT_ADDRESS" "$WETH" "$OFFICIAL_USDT_ADDRESS" "$DODO_PROVIDER_TO_PROBE" || true + probe_bool "WETH -> OFFICIAL_USDC_ADDRESS" "$WETH" "$OFFICIAL_USDC_ADDRESS" "$DODO_PROVIDER_TO_PROBE" || true + probe_bool "WETH -> DAI" "$WETH" "$DAI" "$DODO_PROVIDER_TO_PROBE" || true + echo "Registered live-pair probe" + probe_bool "cUSDT -> cUSDC" "0x93E66202A11B1772E55407B32B44e5Cd8eda7f22" "0xf22258f57794CC8E06237084b353Ab30fFfa640b" "$DODO_PROVIDER_TO_PROBE" || true + if ! probe_bool "cUSDT -> OFFICIAL_USDT_ADDRESS" "0x93E66202A11B1772E55407B32B44e5Cd8eda7f22" "$OFFICIAL_USDT_ADDRESS" "$DODO_PROVIDER_TO_PROBE"; then + live_pair_missing=1 + fi + if (( live_pair_missing == 1 )); then + echo " BLOCKER: the deployed DODOPMMProvider is missing at least one documented live pair registration." + echo " FIX: rerun RegisterDODOPools.s.sol with the corrected 2026-03-26 public pool map." + fi + echo " NOTE: current bridge-and-swap via swapToStablecoin() needs at least one WETH -> stable route above." + echo "" +fi + +echo "Live DODO pairs preloaded by the deploy script" +echo " - cUSDT <-> cUSDC" +echo " - cUSDT <-> USDT" +echo " - cUSDC <-> USDC" +echo " - cUSDT <-> cXAUC" +echo " - cUSDC <-> cXAUC" +echo " - cEURT <-> cXAUC" +echo "" + +echo "Exact dry-run command" +echo "cd \"$SMOM_ROOT\" && source .env && forge script script/bridge/trustless/DeployEnhancedSwapRouter.s.sol:DeployEnhancedSwapRouter --rpc-url \"$RPC_URL_138\" --private-key \"\$PRIVATE_KEY\"" +echo "" +echo "Example minimal exports before dry-run" +cat <stable routes to be useful on Chain 138." + +if (( RUN_FORGE_DRY_RUN == 1 )); then + echo "" + run_forge_dry_run +fi diff --git a/scripts/deployment/dry-run-mainnet-deployment.sh b/scripts/deployment/dry-run-mainnet-deployment.sh index 398a04b..ae742ff 100755 --- a/scripts/deployment/dry-run-mainnet-deployment.sh +++ b/scripts/deployment/dry-run-mainnet-deployment.sh @@ -108,6 +108,22 @@ validate_address "$WETH10_ADDRESS" "WETH10" # Step 4: Compile contracts log_info "Step 4: Compiling contracts..." cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi echo "Compiling CCIPWETH9Bridge..." if forge build --contracts contracts/ccip/CCIPWETH9Bridge.sol 2>&1 | grep -q "Compiler run successful\|No files changed"; then diff --git a/scripts/deployment/ensure-prerequisites.sh b/scripts/deployment/ensure-prerequisites.sh index db0ae4b..61d0541 100755 --- a/scripts/deployment/ensure-prerequisites.sh +++ b/scripts/deployment/ensure-prerequisites.sh @@ -9,6 +9,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # PROJECT_ROOT = smom-dbis-138 PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi RED='\033[0;31m' GREEN='\033[0;32m' diff --git a/scripts/deployment/execute-all-phases.sh b/scripts/deployment/execute-all-phases.sh index 66f45a9..901f1c2 100755 --- a/scripts/deployment/execute-all-phases.sh +++ b/scripts/deployment/execute-all-phases.sh @@ -5,6 +5,22 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi echo "╔════════════════════════════════════════════════════════════════╗" echo "║ EXECUTING ALL DEPLOYMENT PHASES ║" diff --git a/scripts/deployment/execute-bridge-config.sh b/scripts/deployment/execute-bridge-config.sh index 3a9889e..42625c4 100755 --- a/scripts/deployment/execute-bridge-config.sh +++ b/scripts/deployment/execute-bridge-config.sh @@ -1,66 +1,83 @@ #!/usr/bin/env bash -# Execute bridge destination configuration +# Execute WETH9/WETH10 bridge addDestination both directions: Ethereum mainnet ↔ Chain 138. +# Requires .env with bridge addresses and PRIVATE_KEY. + +set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +cd "$PROJECT_ROOT" - -log_info "=== Executing Bridge Configuration ===" - -# Load environment -if [ -f "$PROJECT_ROOT/.env" ]; then - source "$PROJECT_ROOT/.env" +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a fi +log_info "=== Executing bridge configuration (Mainnet ↔ Chain 138) ===" + MAINNET_RPC="${ETHEREUM_MAINNET_RPC:-https://eth.llamarpc.com}" -CHAIN138_RPC="${RPC_URL:-https://rpc.d-bis.org}" -PRIVATE_KEY="${PRIVATE_KEY}" -if [[ ! "$PRIVATE_KEY" =~ ^0x ]]; then - PRIVATE_KEY="0x$PRIVATE_KEY" +MAINNET_RPC="${MAINNET_RPC%$'\r'}" +MAINNET_RPC="${MAINNET_RPC%$'\n'}" +CHAIN138_RPC="${RPC_URL_138:-${CHAIN138_RPC:-http://192.168.11.211:8545}}" +CHAIN138_RPC="${CHAIN138_RPC%$'\r'}" +CHAIN138_RPC="${CHAIN138_RPC%$'\n'}" + +PRIVATE_KEY="${PRIVATE_KEY:-}" +[[ -n "$PRIVATE_KEY" && ! "$PRIVATE_KEY" =~ ^0x ]] && PRIVATE_KEY="0x$PRIVATE_KEY" + +WETH9_MAINNET=$(grep "CCIPWETH9_BRIDGE_MAINNET=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH9_BRIDGE_MAINNET:-}") +WETH10_MAINNET=$(grep "CCIPWETH10_BRIDGE_MAINNET=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH10_BRIDGE_MAINNET:-}") +WETH9_CHAIN138=$(grep "CCIPWETH9_BRIDGE_CHAIN138=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH9_BRIDGE_CHAIN138:-}") +WETH10_CHAIN138=$(grep "CCIPWETH10_BRIDGE_CHAIN138=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH10_BRIDGE_CHAIN138:-}") + +CHAIN138_SELECTOR="${CHAIN138_SELECTOR:-138}" +ETH_SELECTOR="${ETH_MAINNET_SELECTOR:-5009297550715157269}" + +WETH9_MAINNET="${WETH9_MAINNET,,}" +WETH10_MAINNET="${WETH10_MAINNET,,}" +WETH9_CHAIN138="${WETH9_CHAIN138,,}" +WETH10_CHAIN138="${WETH10_CHAIN138,,}" + +if [[ -z "$WETH9_MAINNET" || -z "$WETH9_CHAIN138" || -z "$WETH10_MAINNET" || -z "$WETH10_CHAIN138" ]]; then + log_error "Bridge addresses not found in .env (CCIPWETH9/10_BRIDGE_MAINNET and CCIPWETH9/10_BRIDGE_CHAIN138)" + exit 1 fi -WETH9_MAINNET=$(grep "CCIPWETH9_BRIDGE_MAINNET=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "") -WETH10_MAINNET=$(grep "CCIPWETH10_BRIDGE_MAINNET=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "") -WETH9_CHAIN138=$(grep "CCIPWETH9_BRIDGE_CHAIN138=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "") -WETH10_CHAIN138=$(grep "CCIPWETH10_BRIDGE_CHAIN138=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "") +_gas138=(--legacy --gas-limit 250000 --gas-price 2000000000) +_gas_main=(--legacy --gas-limit 400000) -CHAIN138_SELECTOR="${CHAIN138_SELECTOR:-0x000000000000008a}" -ETH_SELECTOR="${ETH_MAINNET_SELECTOR:-0x500147}" - -if [ -z "$WETH9_MAINNET" ] || [ -z "$WETH9_CHAIN138" ] || [ -z "$WETH10_MAINNET" ] || [ -z "$WETH10_CHAIN138" ]; then - log_error "Error: Bridge addresses not found in .env" - exit 1 -fi +_try() { + local _o + if _o=$("$@" 2>&1); then + log_success "OK" + [[ -n "$_o" ]] && echo "$_o" + else + log_warn "Command failed (non-fatal for batch)" + echo "$_o" >&2 + fi +} echo "Configuring WETH9 Bridge..." -echo " Adding Chain-138 destination to Mainnet bridge..." -if cast send "$WETH9_MAINNET" "addDestination(uint64,address)" "$CHAIN138_SELECTOR" "$WETH9_CHAIN138" --rpc-url "$MAINNET_RPC" --private-key "$PRIVATE_KEY" --legacy 2>&1 | grep -q "Success\|success"; then - log_success "✅ WETH9 Mainnet → Chain-138 configured" -else - log_warn "⚠️ Configuration may have failed - check transaction" -fi - -echo " Adding Mainnet destination to Chain-138 bridge..." -if cast send "$WETH9_CHAIN138" "addDestination(uint64,address)" "$ETH_SELECTOR" "$WETH9_MAINNET" --rpc-url "$CHAIN138_RPC" --private-key "$PRIVATE_KEY" --legacy 2>&1 | grep -q "Success\|success"; then - log_success "✅ WETH9 Chain-138 → Mainnet configured" -else - log_warn "⚠️ Configuration may have failed - check transaction" -fi +echo " Mainnet → Chain 138..." +_try cast send "$WETH9_MAINNET" "addDestination(uint64,address)" "$CHAIN138_SELECTOR" "$WETH9_CHAIN138" \ + --rpc-url "$MAINNET_RPC" --private-key "$PRIVATE_KEY" "${_gas_main[@]}" +echo " Chain 138 → Mainnet..." +_try cast send "$WETH9_CHAIN138" "addDestination(uint64,address)" "$ETH_SELECTOR" "$WETH9_MAINNET" \ + --rpc-url "$CHAIN138_RPC" --private-key "$PRIVATE_KEY" "${_gas138[@]}" echo "Configuring WETH10 Bridge..." -echo " Adding Chain-138 destination to Mainnet bridge..." -if cast send "$WETH10_MAINNET" "addDestination(uint64,address)" "$CHAIN138_SELECTOR" "$WETH10_CHAIN138" --rpc-url "$MAINNET_RPC" --private-key "$PRIVATE_KEY" --legacy 2>&1 | grep -q "Success\|success"; then - log_success "✅ WETH10 Mainnet → Chain-138 configured" -else - log_warn "⚠️ Configuration may have failed - check transaction" -fi +echo " Mainnet → Chain 138..." +_try cast send "$WETH10_MAINNET" "addDestination(uint64,address)" "$CHAIN138_SELECTOR" "$WETH10_CHAIN138" \ + --rpc-url "$MAINNET_RPC" --private-key "$PRIVATE_KEY" "${_gas_main[@]}" +echo " Chain 138 → Mainnet..." +_try cast send "$WETH10_CHAIN138" "addDestination(uint64,address)" "$ETH_SELECTOR" "$WETH10_MAINNET" \ + --rpc-url "$CHAIN138_RPC" --private-key "$PRIVATE_KEY" "${_gas138[@]}" -echo " Adding Mainnet destination to Chain-138 bridge..." -if cast send "$WETH10_CHAIN138" "addDestination(uint64,address)" "$ETH_SELECTOR" "$WETH10_MAINNET" --rpc-url "$CHAIN138_RPC" --private-key "$PRIVATE_KEY" --legacy 2>&1 | grep -q "Success\|success"; then - log_success "✅ WETH10 Chain-138 → Mainnet configured" -else - log_warn "⚠️ Configuration may have failed - check transaction" -fi - -log_success "✅ Bridge configuration complete!" +log_success "Bridge configuration attempts finished (review output above)." diff --git a/scripts/deployment/execute-cross-chain-test.sh b/scripts/deployment/execute-cross-chain-test.sh index 0e24aa6..5f571ef 100755 --- a/scripts/deployment/execute-cross-chain-test.sh +++ b/scripts/deployment/execute-cross-chain-test.sh @@ -4,6 +4,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi log_info "=== Cross-Chain Transfer Test ===" diff --git a/scripts/deployment/export-cronos-verification-sources.sh b/scripts/deployment/export-cronos-verification-sources.sh index bf30963..50a7ebd 100755 --- a/scripts/deployment/export-cronos-verification-sources.sh +++ b/scripts/deployment/export-cronos-verification-sources.sh @@ -7,6 +7,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" OUT_DIR="$PROJECT_ROOT/.cronos-verify" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi mkdir -p "$OUT_DIR" diff --git a/scripts/deployment/find-all-deployed-contracts.sh b/scripts/deployment/find-all-deployed-contracts.sh index 5390f7f..4d2bd77 100755 --- a/scripts/deployment/find-all-deployed-contracts.sh +++ b/scripts/deployment/find-all-deployed-contracts.sh @@ -7,8 +7,23 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi -source .env 2>/dev/null || true echo "==========================================" echo "Finding All Deployed Mainnet Contracts" diff --git a/scripts/deployment/fix-configuration-issues.sh b/scripts/deployment/fix-configuration-issues.sh index 6cb3891..17fcf03 100755 --- a/scripts/deployment/fix-configuration-issues.sh +++ b/scripts/deployment/fix-configuration-issues.sh @@ -11,6 +11,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi log_info "=== Fixing Configuration Issues ===" diff --git a/scripts/deployment/fund-ccip-bridges-with-link.sh b/scripts/deployment/fund-ccip-bridges-with-link.sh index e7df320..a6106ce 100755 --- a/scripts/deployment/fund-ccip-bridges-with-link.sh +++ b/scripts/deployment/fund-ccip-bridges-with-link.sh @@ -20,10 +20,13 @@ run_or_echo() { if [[ "${DRY_RUN:-0}" = "1" ]]; then echo " [DRY RUN] $*" else - if eval "$*"; then + local _out + if _out=$(eval "$*" 2>&1); then echo " OK" + [[ -n "$_out" ]] && echo " $_out" else - echo " Failed (non-fatal)" + echo " Failed (non-fatal)" >&2 + echo " $_out" >&2 fi fi } @@ -38,13 +41,15 @@ fi echo "Funding CCIP bridges with LINK (amount per bridge: $LINK_AMOUNT_WEI wei)" echo "" -# Chain 138 +# Chain 138 (Besu: gas estimation often fails; use explicit legacy gas like manual cast) if [[ -n "${RPC_URL_138:-}" && -n "${LINK_TOKEN_CHAIN138:-${LINK_TOKEN:-}}" ]]; then link="${LINK_TOKEN_CHAIN138:-$LINK_TOKEN}" + link="${link,,}" rpc=$(ensure_rpc "$RPC_URL_138") echo "Chain 138 (RPC: ${rpc%%\?*}...)" - [[ -n "${CCIPWETH9_BRIDGE_CHAIN138:-}" ]] && run_or_echo "cast send $link \"transfer(address,uint256)\" $CCIPWETH9_BRIDGE_CHAIN138 $LINK_AMOUNT_WEI --rpc-url \"$rpc\" --private-key \"\$PRIVATE_KEY\" --legacy" - [[ -n "${CCIPWETH10_BRIDGE_CHAIN138:-}" ]] && run_or_echo "cast send $link \"transfer(address,uint256)\" $CCIPWETH10_BRIDGE_CHAIN138 $LINK_AMOUNT_WEI --rpc-url \"$rpc\" --private-key \"\$PRIVATE_KEY\" --legacy" + _gas138="--legacy --gas-limit 250000 --gas-price 2000000000" + [[ -n "${CCIPWETH9_BRIDGE_CHAIN138:-}" ]] && run_or_echo "cast send $link \"transfer(address,uint256)\" ${CCIPWETH9_BRIDGE_CHAIN138,,} $LINK_AMOUNT_WEI --rpc-url \"$rpc\" --private-key \"\$PRIVATE_KEY\" $_gas138" + [[ -n "${CCIPWETH10_BRIDGE_CHAIN138:-}" ]] && run_or_echo "cast send $link \"transfer(address,uint256)\" ${CCIPWETH10_BRIDGE_CHAIN138,,} $LINK_AMOUNT_WEI --rpc-url \"$rpc\" --private-key \"\$PRIVATE_KEY\" $_gas138" echo "" fi @@ -58,8 +63,8 @@ if [[ -n "${ETHEREUM_MAINNET_RPC:-}" && -n "${MAINNET_LINK_TOKEN:-${CCIP_ETH_LIN echo "" fi -# BSC, Polygon, Base, Optimism, Arbitrum, Avalanche, Cronos, Gnosis, Celo -for label in BSC POLYGON BASE OPTIMISM ARBITRUM AVALANCHE CRONOS GNOSIS CELO; do +# BSC, Polygon, Base, Optimism, Arbitrum, Avalanche, Cronos, Gnosis, Celo, Wemix (matches check-link-balance-config-ready-chains.sh) +for label in BSC POLYGON BASE OPTIMISM ARBITRUM AVALANCHE CRONOS GNOSIS CELO WEMIX; do case "$label" in BSC) rpc_var="BSC_RPC_URL"; link_var="CCIP_BSC_LINK_TOKEN"; ;; POLYGON) rpc_var="POLYGON_MAINNET_RPC"; link_var="CCIP_POLYGON_LINK_TOKEN"; ;; @@ -70,6 +75,7 @@ for label in BSC POLYGON BASE OPTIMISM ARBITRUM AVALANCHE CRONOS GNOSIS CELO; do CRONOS) rpc_var="CRONOS_RPC_URL"; link_var="CCIP_CRONOS_LINK_TOKEN"; rpc_fb="CRONOS_RPC"; link_fb="LINK_TOKEN_CRONOS"; ;; GNOSIS) rpc_var="GNOSIS_MAINNET_RPC"; link_var="CCIP_GNOSIS_LINK_TOKEN"; rpc_fb="GNOSIS_RPC"; link_fb="LINK_TOKEN_GNOSIS"; ;; CELO) rpc_var="CELO_MAINNET_RPC"; link_var="CCIP_CELO_LINK_TOKEN"; rpc_fb="CELO_RPC"; link_fb="LINK_TOKEN_CELO"; ;; + WEMIX) rpc_var="WEMIX_RPC"; link_var="CCIP_WEMIX_LINK_TOKEN"; rpc_fb="WEMIX_MAINNET_RPC"; link_fb="LINK_TOKEN_WEMIX"; ;; esac rpc="${!rpc_var:-${!rpc_fb:-}}" link="${!link_var:-${!link_fb:-}}" @@ -83,8 +89,8 @@ for label in BSC POLYGON BASE OPTIMISM ARBITRUM AVALANCHE CRONOS GNOSIS CELO; do [[ -z "$addr9" && -z "$addr10" ]] && continue echo "$label" - [[ -n "$addr9" ]] && run_or_echo "cast send $link \"transfer(address,uint256)\" $addr9 $LINK_AMOUNT_WEI --rpc-url \"$rpc\" --private-key \"\$PRIVATE_KEY\" --legacy" - [[ -n "$addr10" ]] && run_or_echo "cast send $link \"transfer(address,uint256)\" $addr10 $LINK_AMOUNT_WEI --rpc-url \"$rpc\" --private-key \"\$PRIVATE_KEY\" --legacy" + [[ -n "$addr9" ]] && run_or_echo "cast send ${link,,} \"transfer(address,uint256)\" ${addr9,,} $LINK_AMOUNT_WEI --rpc-url \"$rpc\" --private-key \"\$PRIVATE_KEY\" --legacy" + [[ -n "$addr10" ]] && run_or_echo "cast send ${link,,} \"transfer(address,uint256)\" ${addr10,,} $LINK_AMOUNT_WEI --rpc-url \"$rpc\" --private-key \"\$PRIVATE_KEY\" --legacy" echo "" done diff --git a/scripts/deployment/generate-all-adapters.sh b/scripts/deployment/generate-all-adapters.sh index 02966ab..2373272 100755 --- a/scripts/deployment/generate-all-adapters.sh +++ b/scripts/deployment/generate-all-adapters.sh @@ -6,6 +6,22 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi CONTRACTS_DIR="$PROJECT_ROOT/contracts/bridge/adapters" SCRIPTS_DIR="$PROJECT_ROOT/script/deploy/chains" CONFIG_DIR="$PROJECT_ROOT/config/chains" diff --git a/scripts/deployment/generate-genesis-with-validators.sh b/scripts/deployment/generate-genesis-with-validators.sh index 65c4e90..f117683 100755 --- a/scripts/deployment/generate-genesis-with-validators.sh +++ b/scripts/deployment/generate-genesis-with-validators.sh @@ -9,6 +9,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi CONFIG_DIR="$PROJECT_ROOT/config" KEYS_DIR="$PROJECT_ROOT/keys" diff --git a/scripts/deployment/generate-phase2-tfvars.sh b/scripts/deployment/generate-phase2-tfvars.sh index fe720e8..e3212be 100755 --- a/scripts/deployment/generate-phase2-tfvars.sh +++ b/scripts/deployment/generate-phase2-tfvars.sh @@ -6,6 +6,22 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi OUTPUT_FILE="${1:-${PROJECT_ROOT}/terraform/phases/phase2/terraform.tfvars}" # Load .env if it exists diff --git a/scripts/deployment/generate-static-nodes.sh b/scripts/deployment/generate-static-nodes.sh index 97f7b0d..eff8a38 100755 --- a/scripts/deployment/generate-static-nodes.sh +++ b/scripts/deployment/generate-static-nodes.sh @@ -8,6 +8,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi CONFIG_DIR="$PROJECT_ROOT/config" diff --git a/scripts/deployment/get-app-gateway-ip.sh b/scripts/deployment/get-app-gateway-ip.sh index 2e2619a..c8cd93c 100755 --- a/scripts/deployment/get-app-gateway-ip.sh +++ b/scripts/deployment/get-app-gateway-ip.sh @@ -9,6 +9,22 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi # Load environment variables if [ -f "${PROJECT_ROOT}/.env" ]; then diff --git a/scripts/deployment/get-wallet-address.sh b/scripts/deployment/get-wallet-address.sh index 1fe028d..de0a7a3 100755 --- a/scripts/deployment/get-wallet-address.sh +++ b/scripts/deployment/get-wallet-address.sh @@ -7,6 +7,22 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi # Colors diff --git a/scripts/deployment/import-all-resources.sh b/scripts/deployment/import-all-resources.sh index cf5616e..13b0e37 100755 --- a/scripts/deployment/import-all-resources.sh +++ b/scripts/deployment/import-all-resources.sh @@ -22,6 +22,22 @@ run() { } PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi TERRAFORM_DIR="$PROJECT_ROOT/terraform/well-architected/cloud-sovereignty" cd "$TERRAFORM_DIR" diff --git a/scripts/deployment/import-existing-clusters.sh b/scripts/deployment/import-existing-clusters.sh index d6f124f..cabd1ef 100755 --- a/scripts/deployment/import-existing-clusters.sh +++ b/scripts/deployment/import-existing-clusters.sh @@ -7,6 +7,22 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi TERRAFORM_DIR="$PROJECT_ROOT/terraform/well-architected/cloud-sovereignty" cd "$TERRAFORM_DIR" diff --git a/scripts/deployment/init-terraform.sh b/scripts/deployment/init-terraform.sh index 08ac592..63d644d 100755 --- a/scripts/deployment/init-terraform.sh +++ b/scripts/deployment/init-terraform.sh @@ -8,6 +8,22 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi TERRAFORM_DIR="$PROJECT_ROOT/terraform" log() { diff --git a/scripts/deployment/inventory-chain138-pmm-desired-state.sh b/scripts/deployment/inventory-chain138-pmm-desired-state.sh new file mode 100755 index 0000000..f37deb1 --- /dev/null +++ b/scripts/deployment/inventory-chain138-pmm-desired-state.sh @@ -0,0 +1,183 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SMOM_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +ENV_FILE="$SMOM_ROOT/.env" +CONFIG_JSON="${POOL_CONFIG_JSON:-$SMOM_ROOT/config/chain138-pmm-pools.json}" +ORIG_RPC_URL_138="${RPC_URL_138-}" +ORIG_RPC_URL="${RPC_URL-}" +ORIG_DODO_PMM_INTEGRATION_ADDRESS="${DODO_PMM_INTEGRATION_ADDRESS-}" +ORIG_DODO_PMM_INTEGRATION="${DODO_PMM_INTEGRATION-}" +ORIG_DODO_PMM_PROVIDER_ADDRESS="${DODO_PMM_PROVIDER_ADDRESS-}" +ORIG_DODO_PMM_PROVIDER="${DODO_PMM_PROVIDER-}" + +if [[ -f "$ENV_FILE" ]]; then + set -a + # shellcheck disable=SC1090 + source "$ENV_FILE" + set +a +fi + +[[ -n "$ORIG_RPC_URL_138" ]] && RPC_URL_138="$ORIG_RPC_URL_138" +[[ -n "$ORIG_RPC_URL" ]] && RPC_URL="$ORIG_RPC_URL" +[[ -n "$ORIG_DODO_PMM_INTEGRATION_ADDRESS" ]] && DODO_PMM_INTEGRATION_ADDRESS="$ORIG_DODO_PMM_INTEGRATION_ADDRESS" +[[ -n "$ORIG_DODO_PMM_INTEGRATION" ]] && DODO_PMM_INTEGRATION="$ORIG_DODO_PMM_INTEGRATION" +[[ -n "$ORIG_DODO_PMM_PROVIDER_ADDRESS" ]] && DODO_PMM_PROVIDER_ADDRESS="$ORIG_DODO_PMM_PROVIDER_ADDRESS" +[[ -n "$ORIG_DODO_PMM_PROVIDER" ]] && DODO_PMM_PROVIDER="$ORIG_DODO_PMM_PROVIDER" + +RPC_URL_138="${RPC_URL_138:-${RPC_URL:-http://192.168.11.211:8545}}" +DODO_PMM_INTEGRATION_ADDRESS="${DODO_PMM_INTEGRATION_ADDRESS:-${DODO_PMM_INTEGRATION:-}}" +DODO_PMM_PROVIDER_ADDRESS="${DODO_PMM_PROVIDER_ADDRESS:-${DODO_PMM_PROVIDER:-}}" + +[[ -f "$CONFIG_JSON" ]] || { echo "POOL_CONFIG_JSON not found: $CONFIG_JSON" >&2; exit 1; } +command -v jq >/dev/null 2>&1 || { echo "jq is required" >&2; exit 1; } +command -v cast >/dev/null 2>&1 || { echo "cast is required" >&2; exit 1; } +[[ -n "$DODO_PMM_INTEGRATION_ADDRESS" ]] || { echo "DODO_PMM_INTEGRATION_ADDRESS not set" >&2; exit 1; } +[[ -n "$DODO_PMM_PROVIDER_ADDRESS" ]] || { echo "DODO_PMM_PROVIDER_ADDRESS not set" >&2; exit 1; } + +declare -A TOKENS=() +while IFS=$'\t' read -r sym addr; do + TOKENS["$sym"]="$addr" +done < <(jq -r '.tokens | to_entries[] | [.key, .value] | @tsv' "$CONFIG_JSON") + +mapfile -t C_STARS < <(jq -r '.groups.cStarSymbols[]' "$CONFIG_JSON") +mapfile -t OFFICIALS < <(jq -r '.groups.officialStableSymbols[]' "$CONFIG_JSON") +WETH_SYMBOL="$(jq -r '.groups.wethSymbol' "$CONFIG_JSON")" + +rpc_call() { + local to="$1" data="$2" + local payload + payload=$(printf '{"jsonrpc":"2.0","method":"eth_call","params":[{"to":"%s","data":"%s"},"latest"],"id":1}' "$to" "$data") + curl -s -X POST "$RPC_URL_138" -H 'Content-Type: application/json' --data "$payload" +} + +json_result() { + sed -n 's/.*"result":"\([^"]*\)".*/\1/p' +} + +hex_to_addr() { + local value="${1#0x}" + if [[ ${#value} -lt 40 ]]; then + echo "0x0000000000000000000000000000000000000000" + return 0 + fi + printf '0x%s\n' "${value: -40}" +} + +pool_for() { + local calldata result + calldata="$(cast calldata "pools(address,address)" "$1" "$2" 2>/dev/null || true)" + [[ -n "$calldata" ]] || { echo "0x0000000000000000000000000000000000000000"; return 0; } + result="$(rpc_call "$DODO_PMM_INTEGRATION_ADDRESS" "$calldata" | json_result)" + [[ -n "$result" ]] || { echo "0x0000000000000000000000000000000000000000"; return 0; } + hex_to_addr "$result" +} + +provider_pool_for() { + local calldata result + calldata="$(cast calldata "pools(address,address)" "$1" "$2" 2>/dev/null || true)" + [[ -n "$calldata" ]] || { echo "0x0000000000000000000000000000000000000000"; return 0; } + result="$(rpc_call "$DODO_PMM_PROVIDER_ADDRESS" "$calldata" | json_result)" + [[ -n "$result" ]] || { echo "0x0000000000000000000000000000000000000000"; return 0; } + hex_to_addr "$result" +} + +declare -A SEEN=() +DESIRED_PAIRS=() + +add_pair() { + local base_sym="$1" quote_sym="$2" + local base="${TOKENS[$base_sym]:-}" + local quote="${TOKENS[$quote_sym]:-}" + local key="${base_sym}|${quote_sym}" + + [[ -n "$base" && -n "$quote" ]] || return 0 + [[ -z "${SEEN[$key]:-}" ]] || return 0 + SEEN["$key"]=1 + DESIRED_PAIRS+=("${base_sym}|${base}|${quote_sym}|${quote}") +} + +if [[ "$(jq -r '.groups.deploy.cStarVsCStar' "$CONFIG_JSON")" == "true" ]]; then + for ((i=0; i<${#C_STARS[@]}; i++)); do + for ((j=i+1; j<${#C_STARS[@]}; j++)); do + add_pair "${C_STARS[$i]}" "${C_STARS[$j]}" + done + done +fi +if [[ "$(jq -r '.groups.deploy.cStarVsOfficial' "$CONFIG_JSON")" == "true" ]]; then + for cstar in "${C_STARS[@]}"; do + for official in "${OFFICIALS[@]}"; do + add_pair "$cstar" "$official" + done + done +fi +if [[ "$(jq -r '.groups.deploy.cStarVsWeth' "$CONFIG_JSON")" == "true" ]]; then + for cstar in "${C_STARS[@]}"; do + add_pair "$cstar" "$WETH_SYMBOL" + done +fi +if [[ "$(jq -r '.groups.deploy.officialVsWeth' "$CONFIG_JSON")" == "true" ]]; then + for official in "${OFFICIALS[@]}"; do + add_pair "$official" "$WETH_SYMBOL" + done +fi +while IFS=$'\t' read -r base_sym quote_sym; do + add_pair "$base_sym" "$quote_sym" +done < <(jq -r '.explicitPairs[]? | [.baseSymbol, .quoteSymbol] | @tsv' "$CONFIG_JSON") + +echo "=== Chain 138 PMM Desired-State Inventory ===" +echo "Config: $CONFIG_JSON" +echo "Integration: $DODO_PMM_INTEGRATION_ADDRESS" +echo "Provider: $DODO_PMM_PROVIDER_ADDRESS" +echo "RPC: $RPC_URL_138" +echo "Desired pairs:${#DESIRED_PAIRS[@]}" +echo "" + +existing=0 +missing=0 +aligned=0 +needs_registration=0 +stale_provider_only=0 +provider_mismatch=0 + +for pair in "${DESIRED_PAIRS[@]}"; do + IFS='|' read -r base_sym base quote_sym quote <<< "$pair" + label="${base_sym}/${quote_sym}" + pool="$(pool_for "$base" "$quote")" + provider_pool_ab="$(provider_pool_for "$base" "$quote")" + provider_pool_ba="$(provider_pool_for "$quote" "$base")" + + if [[ "$pool" != "0x0000000000000000000000000000000000000000" ]]; then + ((existing++)) || true + status="EXISTS" + else + ((missing++)) || true + status="MISSING" + fi + + if [[ "$pool" != "0x0000000000000000000000000000000000000000" && "$provider_pool_ab" == "$pool" && "$provider_pool_ba" == "$pool" ]]; then + ((aligned++)) || true + route_status="ALIGNED" + elif [[ "$pool" != "0x0000000000000000000000000000000000000000" && "$provider_pool_ab" == "0x0000000000000000000000000000000000000000" && "$provider_pool_ba" == "0x0000000000000000000000000000000000000000" ]]; then + ((needs_registration++)) || true + route_status="NEEDS_REGISTRATION" + elif [[ "$pool" == "0x0000000000000000000000000000000000000000" && ( "$provider_pool_ab" != "0x0000000000000000000000000000000000000000" || "$provider_pool_ba" != "0x0000000000000000000000000000000000000000" ) ]]; then + ((stale_provider_only++)) || true + route_status="STALE_PROVIDER_ONLY" + else + ((provider_mismatch++)) || true + route_status="PROVIDER_MISMATCH" + fi + + echo "$status $route_status $label integrationPool=$pool providerAB=$provider_pool_ab providerBA=$provider_pool_ba" +done + +echo "" +echo "Summary:" +echo " Existing pools: $existing" +echo " Missing pools: $missing" +echo " Aligned routes: $aligned" +echo " Needs registration: $needs_registration" +echo " Stale provider only: $stale_provider_only" +echo " Provider mismatch: $provider_mismatch" diff --git a/scripts/deployment/inventory-register-dodo-pools-chain138.sh b/scripts/deployment/inventory-register-dodo-pools-chain138.sh new file mode 100644 index 0000000..4b2c06c --- /dev/null +++ b/scripts/deployment/inventory-register-dodo-pools-chain138.sh @@ -0,0 +1,120 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SMOM_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +ENV_FILE="$SMOM_ROOT/.env" + +if [[ -f "$ENV_FILE" ]]; then + set -a + # shellcheck disable=SC1090 + source "$ENV_FILE" + set +a +fi + +RPC_URL_138="${RPC_URL_138:-http://192.168.11.211:8545}" +DODO_PMM_INTEGRATION_ADDRESS="${DODO_PMM_INTEGRATION_ADDRESS:-${DODO_PMM_INTEGRATION:-}}" +DODO_PMM_PROVIDER_ADDRESS="${DODO_PMM_PROVIDER_ADDRESS:-${DODO_PMM_PROVIDER:-}}" + +[[ -n "$DODO_PMM_INTEGRATION_ADDRESS" ]] || { echo "DODO_PMM_INTEGRATION_ADDRESS not set"; exit 1; } +[[ -n "$DODO_PMM_PROVIDER_ADDRESS" ]] || { echo "DODO_PMM_PROVIDER_ADDRESS not set"; exit 1; } + +declare -A SYMBOLS=( + ["0x93e66202a11b1772e55407b32b44e5cd8eda7f22"]="cUSDT" + ["0xf22258f57794cc8e06237084b353ab30fffa640b"]="cUSDC" + ["0x8085961f9cf02b4d800a3c6d386d31da4b34266a"]="cEURC" + ["0xdf4b71c61e5912712c1bdd451416b9ac26949d72"]="cEURT" + ["0x003960f16d9d34f2e98d62723b6721fb92074ad2"]="cGBPC" + ["0x350f54e4d23795f86a9c03988c7135357ccad97c"]="cGBPT" + ["0xd51482e567c03899eece3cae8a058161fd56069d"]="cAUDC" + ["0xee269e1226a334182aace90056ee4ee5cc8a6770"]="cJPYC" + ["0x873990849dda5117d7c644f0af24370797c03885"]="cCHFC" + ["0x54dbd40cf05e15906a2c21f600937e96787f5679"]="cCADC" + ["0x290e52a8819a4fbd0714e517225429aa2b70ec6b"]="cXAUC" + ["0x94e408e26c6fd8f4ee00b54df19082fda07dc96e"]="cXAUT" + ["0x004b63a7b5b0e06f6bb6adb4a5f9f590bf3182d1"]="USDT" + ["0x71d6687f38b93ccad569fa6352c876eea967201b"]="USDC" + ["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]="WETH" +) + +rpc_call() { + local to="$1" data="$2" + local payload + payload=$(printf '{"jsonrpc":"2.0","method":"eth_call","params":[{"to":"%s","data":"%s"},"latest"],"id":1}' "$to" "$data") + curl -s -X POST "$RPC_URL_138" -H 'Content-Type: application/json' --data "$payload" +} + +json_result() { + sed -n 's/.*"result":"\([^"]*\)".*/\1/p' +} + +word_at() { + local hex="$1" index="$2" + local start=$(( index * 64 )) + printf '%s' "${hex:$start:64}" +} + +addr_from_word() { + local word="$1" + printf '0x%s' "${word:24:40}" +} + +symbol_for() { + local lower + lower="$(printf '%s' "$1" | tr '[:upper:]' '[:lower:]')" + if [[ -n "${SYMBOLS[$lower]:-}" ]]; then + printf '%s' "${SYMBOLS[$lower]}" + else + printf '%s' "$1" + fi +} + +decode_address_array() { + local result="${1#0x}" + local count_hex count i + count_hex="$(word_at "$result" 1)" + count=$((16#$count_hex)) + for ((i=0; i/dev/null || true CHAIN="${1:-chain138}" case "$CHAIN" in diff --git a/scripts/deployment/run-all-next-steps.sh b/scripts/deployment/run-all-next-steps.sh index f2930d6..93c39ba 100755 --- a/scripts/deployment/run-all-next-steps.sh +++ b/scripts/deployment/run-all-next-steps.sh @@ -7,6 +7,22 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi echo "╔════════════════════════════════════════════════════════════════╗" echo "║ CHAIN-138 DEPLOYMENT - ALL NEXT STEPS ║" diff --git a/scripts/deployment/run-all-tests.sh b/scripts/deployment/run-all-tests.sh index 7231fe3..bfe51cd 100755 --- a/scripts/deployment/run-all-tests.sh +++ b/scripts/deployment/run-all-tests.sh @@ -4,6 +4,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi log_info "=== Running All Deployment Tests ===" diff --git a/scripts/deployment/run-e2e-trustless-live-test.sh b/scripts/deployment/run-e2e-trustless-live-test.sh index 95e3e9f..6b9040c 100755 --- a/scripts/deployment/run-e2e-trustless-live-test.sh +++ b/scripts/deployment/run-e2e-trustless-live-test.sh @@ -14,12 +14,27 @@ SCRIPT_PATH="${BASH_SOURCE[0]}" [[ -z "$SCRIPT_PATH" ]] && SCRIPT_PATH="$0" SCRIPT_DIR="$(cd "$(dirname "$SCRIPT_PATH")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi if [[ ! -d "$REPO_ROOT" ]]; then echo "Error: REPO_ROOT not found: $REPO_ROOT. Run from smom-dbis-138 repo, e.g. cd /path/to/smom-dbis-138 && ./scripts/deployment/run-e2e-trustless-live-test.sh" exit 1 fi cd "$REPO_ROOT" || { echo "Error: cannot cd to $REPO_ROOT"; exit 1; } -[[ -f .env ]] && set -a && source .env && set +a # Use _MAINNET variants if unsuffixed not set (for .env that only has _MAINNET) export BOND_MANAGER="${BOND_MANAGER:-${BOND_MANAGER_MAINNET:-}}" diff --git a/scripts/deployment/run-final-unblock-checklist.sh b/scripts/deployment/run-final-unblock-checklist.sh new file mode 100755 index 0000000..83b7b70 --- /dev/null +++ b/scripts/deployment/run-final-unblock-checklist.sh @@ -0,0 +1,562 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +cd "$PROJECT_ROOT" + +source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" +source "$SCRIPT_DIR/../lib/deployment/prompts.sh" +load_deployment_env + +DRY_RUN=0 +STATUS_ONLY=0 +JSON_OUTPUT=0 +RUN_STATUS=1 +RUN_MAINNET_LINK=1 +RUN_MAINNET_LP=1 +RUN_MAINNET_RELAY=1 +RUN_BSC_LINK=1 +RUN_BSC_RELAY=1 +RUN_FINAL_CHECK=1 + +MAINNET_GAS_TARGET_WEI="$(eth_to_wei "0.05")" +BSC_GAS_TARGET_WEI="$(eth_to_wei "0.06")" +MAINNET_LINK_WEI="10000000000000000000" +BSC_LINK_WEI="10000000000000000000" +MAINNET_LP_ETH_TARGET_WEI="$(eth_to_wei "1")" +MAINNET_LP_WETH_TARGET_WEI="$(eth_to_wei "0.5")" +MAINNET_RELAY_WETH_TARGET_WEI="$(eth_to_wei "0.01")" +BSC_RELAY_WETH_TARGET_WEI="$(eth_to_wei "0.01")" +MAINNET_ETH_WEI="$(eth_to_wei "0.985")" +MAINNET_WETH_WEI="$(eth_to_wei "0.499")" +MAINNET_RELAY_WETH_WEI="$(eth_to_wei "0.007365719417988711")" +BSC_RELAY_WETH_WEI="$(eth_to_wei "0.01")" + +usage() { + cat <<'EOF' +Run the final Mainnet/BSC unblock funding sequence from one place. + +Usage: + ./scripts/deployment/run-final-unblock-checklist.sh + ./scripts/deployment/run-final-unblock-checklist.sh --dry-run + ./scripts/deployment/run-final-unblock-checklist.sh --only mainnet-link mainnet-lp check + ./scripts/deployment/run-final-unblock-checklist.sh --skip bsc-link bsc-relay + ./scripts/deployment/run-final-unblock-checklist.sh --mainnet-link 5 --bsc-link 5 + ./scripts/deployment/run-final-unblock-checklist.sh --mainnet-eth 1 --mainnet-weth 0.5 + ./scripts/deployment/run-final-unblock-checklist.sh --status-only + ./scripts/deployment/run-final-unblock-checklist.sh --status-only --json + +Steps: + status Print the exact checklist path and current target amounts + mainnet-link Fund both Mainnet CCIP bridges with LINK + mainnet-lp Fund LiquidityPoolETH on Mainnet + mainnet-relay Fund the Mainnet relay bridge with WETH + bsc-link Fund both BSC CCIP bridges with LINK + bsc-relay Fund the BSC relay bridge with WETH + check Run the trustless bridge readiness check + +Amount tags: + --mainnet-link LINK per Mainnet bridge (default 10) + --bsc-link LINK per BSC bridge (default 10) + --mainnet-eth ETH to add to LiquidityPoolETH (default 0.985) + --mainnet-weth WETH to add to LiquidityPoolETH (default 0.499) + --mainnet-relay-weth WETH for Mainnet relay bridge (default 0.007365719417988711) + --bsc-relay-weth WETH for BSC relay bridge (default 0.01) + --status-only Print live balances and deficits, then exit + --json Emit the status block as JSON + --dry-run Print commands without broadcasting +EOF +} + +normalize_step_name() { + case "${1,,}" in + status) echo "status" ;; + mainnet-link|mainnet_link) echo "mainnet-link" ;; + mainnet-lp|mainnet_lp) echo "mainnet-lp" ;; + mainnet-relay|mainnet_relay) echo "mainnet-relay" ;; + bsc-link|bsc_link) echo "bsc-link" ;; + bsc-relay|bsc_relay) echo "bsc-relay" ;; + check|final-check|final_check) echo "check" ;; + *) echo "" ;; + esac +} + +enable_only_steps() { + RUN_STATUS=0 + RUN_MAINNET_LINK=0 + RUN_MAINNET_LP=0 + RUN_MAINNET_RELAY=0 + RUN_BSC_LINK=0 + RUN_BSC_RELAY=0 + RUN_FINAL_CHECK=0 + while [[ $# -gt 0 ]]; do + local step + step="$(normalize_step_name "$1")" + [[ -z "$step" ]] && break + case "$step" in + status) RUN_STATUS=1 ;; + mainnet-link) RUN_MAINNET_LINK=1 ;; + mainnet-lp) RUN_MAINNET_LP=1 ;; + mainnet-relay) RUN_MAINNET_RELAY=1 ;; + bsc-link) RUN_BSC_LINK=1 ;; + bsc-relay) RUN_BSC_RELAY=1 ;; + check) RUN_FINAL_CHECK=1 ;; + esac + shift + done + ONLY_REMAINING=("$@") +} + +skip_steps() { + while [[ $# -gt 0 ]]; do + local step + step="$(normalize_step_name "$1")" + [[ -z "$step" ]] && break + case "$step" in + status) RUN_STATUS=0 ;; + mainnet-link) RUN_MAINNET_LINK=0 ;; + mainnet-lp) RUN_MAINNET_LP=0 ;; + mainnet-relay) RUN_MAINNET_RELAY=0 ;; + bsc-link) RUN_BSC_LINK=0 ;; + bsc-relay) RUN_BSC_RELAY=0 ;; + check) RUN_FINAL_CHECK=0 ;; + esac + shift + done + SKIP_REMAINING=("$@") +} + +fmt_eth() { + cast from-wei "${1:-0}" ether 2>/dev/null || echo "${1:-0}" +} + +wei_max_zero_sub() { + python3 - "$1" "$2" <<'PY' +import sys +target = int(sys.argv[1] or "0") +current = int(sys.argv[2] or "0") +print(max(target - current, 0)) +PY +} + +fetch_native_balance() { + local rpc="$1" + local addr="$2" + [[ -z "$rpc" || -z "$addr" ]] && { echo "0"; return 0; } + cast balance "$addr" --rpc-url "$rpc" 2>/dev/null || echo "0" +} + +sanitize_uint_output() { + local raw="${1:-0}" + raw="${raw%% *}" + if [[ "$raw" =~ ^0x[0-9a-fA-F]+$ ]]; then + cast --to-dec "$raw" 2>/dev/null || echo "0" + elif [[ "$raw" =~ ^[0-9]+$ ]]; then + echo "$raw" + else + echo "0" + fi +} + +fetch_token_balance() { + local token="$1" + local holder="$2" + local rpc="$3" + [[ -z "$token" || -z "$holder" || -z "$rpc" ]] && { echo "0"; return 0; } + sanitize_uint_output "$(cast call "$token" "balanceOf(address)(uint256)" "$holder" --rpc-url "$rpc" 2>/dev/null || echo "0")" +} + +fetch_lp_available() { + local pool="$1" + local index="$2" + local rpc="$3" + [[ -z "$pool" || -z "$rpc" ]] && { echo "0"; return 0; } + sanitize_uint_output "$(cast call "$pool" "getAvailableLiquidity(uint8)(uint256)" "$index" --rpc-url "$rpc" 2>/dev/null || echo "0")" +} + +print_balance_line() { + local label="$1" + local current="$2" + local target="$3" + local unit="${4:-ETH}" + local deficit + deficit="$(wei_max_zero_sub "$target" "$current")" + printf ' %-30s current=%s %s | target=%s %s | deficit=%s %s\n' \ + "$label" "$(fmt_eth "$current")" "$unit" "$(fmt_eth "$target")" "$unit" "$(fmt_eth "$deficit")" "$unit" +} + +status_from_deficit() { + local deficit="${1:-0}" + if [[ "$deficit" == "0" ]]; then + echo "ok" + else + echo "needs_topup" + fi +} + +ensure_private_key() { + if [[ -z "${PRIVATE_KEY:-}" ]]; then + echo "Set PRIVATE_KEY in .env before running the final unblock wrapper." >&2 + exit 1 + fi +} + +run_or_echo_array() { + local -n cmd_ref=$1 + local -n dry_ref=$2 + if [[ "$DRY_RUN" == "1" ]]; then + printf ' [DRY RUN] ' + printf '%q ' "${dry_ref[@]}" + printf '\n' + else + "${cmd_ref[@]}" + fi +} + +fund_ccip_bridge_link() { + local label="$1" + local rpc="$2" + local link_token="$3" + local bridge9="$4" + local bridge10="$5" + local amount_wei="$6" + + if [[ -z "$rpc" || -z "$link_token" ]]; then + echo "Skipping $label LINK funding: missing RPC or LINK token address." + return 0 + fi + + echo "" + echo "--- $label CCIP bridge LINK funding ---" + echo " LINK token: $link_token" + echo " Amount per bridge: $(fmt_eth "$amount_wei") LINK" + + if [[ -n "$bridge9" ]]; then + local cmd=(cast send "$link_token" "transfer(address,uint256)" "$bridge9" "$amount_wei" --rpc-url "$rpc" --private-key "$PRIVATE_KEY" --legacy) + local dry=(cast send "$link_token" "transfer(address,uint256)" "$bridge9" "$amount_wei" --rpc-url "$rpc" --private-key "" --legacy) + run_or_echo_array cmd dry + fi + if [[ -n "$bridge10" ]]; then + local cmd=(cast send "$link_token" "transfer(address,uint256)" "$bridge10" "$amount_wei" --rpc-url "$rpc" --private-key "$PRIVATE_KEY" --legacy) + local dry=(cast send "$link_token" "transfer(address,uint256)" "$bridge10" "$amount_wei" --rpc-url "$rpc" --private-key "" --legacy) + run_or_echo_array cmd dry + fi +} + +echo_status() { + local deployer mainnet_eth bsc_bnb + local mainnet_bridge9_link mainnet_bridge10_link bsc_bridge9_link bsc_bridge10_link + local lp_eth_available lp_weth_available + local mainnet_relay_weth bsc_relay_weth + + deployer="$(cast wallet address --private-key "$PRIVATE_KEY")" + mainnet_eth="$(fetch_native_balance "$MAINNET_RPC" "$deployer")" + bsc_bnb="$(fetch_native_balance "$BSC_RPC" "$deployer")" + mainnet_bridge9_link="$(fetch_token_balance "$MAINNET_LINK_TOKEN" "$MAINNET_BRIDGE9" "$MAINNET_RPC")" + mainnet_bridge10_link="$(fetch_token_balance "$MAINNET_LINK_TOKEN" "$MAINNET_BRIDGE10" "$MAINNET_RPC")" + bsc_bridge9_link="$(fetch_token_balance "$BSC_LINK_TOKEN" "$BSC_BRIDGE9" "$BSC_RPC")" + bsc_bridge10_link="$(fetch_token_balance "$BSC_LINK_TOKEN" "$BSC_BRIDGE10" "$BSC_RPC")" + lp_eth_available="$(fetch_lp_available "${LIQUIDITY_POOL_ETH_MAINNET:-${LIQUIDITY_POOL:-}}" 0 "$MAINNET_RPC")" + lp_weth_available="$(fetch_lp_available "${LIQUIDITY_POOL_ETH_MAINNET:-${LIQUIDITY_POOL:-}}" 1 "$MAINNET_RPC")" + mainnet_relay_weth="$(fetch_token_balance "${WETH9_MAINNET:-0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2}" "${CCIP_RELAY_BRIDGE_MAINNET:-${RELAY_BRIDGE_MAINNET:-${CW_BRIDGE_MAINNET:-}}}" "$MAINNET_RPC")" + bsc_relay_weth="$(fetch_token_balance "${DEST_WETH9_ADDRESS:-0x2170Ed0880ac9A755fd29B2688956BD959F933F8}" "${DEST_RELAY_BRIDGE:-}" "$BSC_RPC")" + + mainnet_gas_deficit="$(wei_max_zero_sub "$MAINNET_GAS_TARGET_WEI" "$mainnet_eth")" + mainnet_bridge9_link_deficit="$(wei_max_zero_sub "$MAINNET_LINK_WEI" "$mainnet_bridge9_link")" + mainnet_bridge10_link_deficit="$(wei_max_zero_sub "$MAINNET_LINK_WEI" "$mainnet_bridge10_link")" + mainnet_lp_eth_deficit="$(wei_max_zero_sub "$MAINNET_LP_ETH_TARGET_WEI" "$lp_eth_available")" + mainnet_lp_weth_deficit="$(wei_max_zero_sub "$MAINNET_LP_WETH_TARGET_WEI" "$lp_weth_available")" + mainnet_relay_weth_deficit="$(wei_max_zero_sub "$MAINNET_RELAY_WETH_TARGET_WEI" "$mainnet_relay_weth")" + mainnet_gas_status="$(status_from_deficit "$mainnet_gas_deficit")" + mainnet_bridge9_link_status="$(status_from_deficit "$mainnet_bridge9_link_deficit")" + mainnet_bridge10_link_status="$(status_from_deficit "$mainnet_bridge10_link_deficit")" + mainnet_lp_eth_status="$(status_from_deficit "$mainnet_lp_eth_deficit")" + mainnet_lp_weth_status="$(status_from_deficit "$mainnet_lp_weth_deficit")" + mainnet_relay_weth_status="$(status_from_deficit "$mainnet_relay_weth_deficit")" + bsc_gas_deficit="$(wei_max_zero_sub "$BSC_GAS_TARGET_WEI" "$bsc_bnb")" + bsc_bridge9_link_deficit="$(wei_max_zero_sub "$BSC_LINK_WEI" "$bsc_bridge9_link")" + bsc_bridge10_link_deficit="$(wei_max_zero_sub "$BSC_LINK_WEI" "$bsc_bridge10_link")" + bsc_relay_weth_deficit="$(wei_max_zero_sub "$BSC_RELAY_WETH_TARGET_WEI" "$bsc_relay_weth")" + bsc_gas_status="$(status_from_deficit "$bsc_gas_deficit")" + bsc_bridge9_link_status="$(status_from_deficit "$bsc_bridge9_link_deficit")" + bsc_bridge10_link_status="$(status_from_deficit "$bsc_bridge10_link_deficit")" + bsc_relay_weth_status="$(status_from_deficit "$bsc_relay_weth_deficit")" + + if [[ "$JSON_OUTPUT" == "1" ]]; then + python3 - <&2 + usage >&2 + exit 1 + ;; + esac +done + +ensure_private_key + +MAINNET_RPC="${ETHEREUM_MAINNET_RPC:-${RPC_URL_MAINNET:-}}" +BSC_RPC="${BSC_RPC_URL:-${BSC_MAINNET_RPC:-${DEST_RPC_URL:-}}}" +MAINNET_LINK_TOKEN="${MAINNET_LINK_TOKEN:-${CCIP_ETH_LINK_TOKEN:-}}" +BSC_LINK_TOKEN="${CCIP_BSC_LINK_TOKEN:-${LINK_TOKEN_BSC:-}}" +MAINNET_BRIDGE9="${MAINNET_CCIP_WETH9_BRIDGE:-}" +MAINNET_BRIDGE10="${MAINNET_CCIP_WETH10_BRIDGE:-}" +BSC_BRIDGE9="${CCIPWETH9_BRIDGE_BSC:-}" +BSC_BRIDGE10="${CCIPWETH10_BRIDGE_BSC:-}" + +mainnet_gas_deficit="" +mainnet_bridge9_link_deficit="" +mainnet_bridge10_link_deficit="" +mainnet_lp_eth_deficit="" +mainnet_lp_weth_deficit="" +mainnet_relay_weth_deficit="" +mainnet_gas_status="" +mainnet_bridge9_link_status="" +mainnet_bridge10_link_status="" +mainnet_lp_eth_status="" +mainnet_lp_weth_status="" +mainnet_relay_weth_status="" +bsc_gas_deficit="" +bsc_bridge9_link_deficit="" +bsc_bridge10_link_deficit="" +bsc_relay_weth_deficit="" +bsc_gas_status="" +bsc_bridge9_link_status="" +bsc_bridge10_link_status="" +bsc_relay_weth_status="" + +if [[ "$JSON_OUTPUT" != "1" ]]; then + echo "==============================================" + echo "Running final unblock checklist" + echo "==============================================" +fi + +if [[ "$RUN_STATUS" == "1" ]]; then + echo_status +fi + +if [[ "$STATUS_ONLY" == "1" ]]; then + exit 0 +fi + +if [[ "$RUN_MAINNET_LINK" == "1" ]]; then + fund_ccip_bridge_link "Mainnet" "$MAINNET_RPC" "$MAINNET_LINK_TOKEN" "$MAINNET_BRIDGE9" "$MAINNET_BRIDGE10" "$MAINNET_LINK_WEI" +fi + +if [[ "$RUN_MAINNET_LP" == "1" ]]; then + echo "" + echo "--- Mainnet LP funding ---" + LP_ARGS=(--eth-wei "$MAINNET_ETH_WEI" --weth-wei "$MAINNET_WETH_WEI") + [[ "$DRY_RUN" == "1" ]] && LP_ARGS+=(--dry-run) + ./scripts/deployment/fund-mainnet-lp.sh "${LP_ARGS[@]}" +fi + +if [[ "$RUN_MAINNET_RELAY" == "1" ]]; then + echo "" + echo "--- Mainnet relay bridge funding ---" + RELAY_ARGS=("$MAINNET_RELAY_WETH_WEI") + [[ "$DRY_RUN" == "1" ]] && RELAY_ARGS+=(--dry-run) + ./scripts/bridge/fund-mainnet-relay-bridge.sh "${RELAY_ARGS[@]}" +fi + +if [[ "$RUN_BSC_LINK" == "1" ]]; then + fund_ccip_bridge_link "BSC" "$BSC_RPC" "$BSC_LINK_TOKEN" "$BSC_BRIDGE9" "$BSC_BRIDGE10" "$BSC_LINK_WEI" +fi + +if [[ "$RUN_BSC_RELAY" == "1" ]]; then + echo "" + echo "--- BSC relay bridge funding ---" + RELAY_ARGS=("$BSC_RELAY_WETH_WEI") + [[ "$DRY_RUN" == "1" ]] && RELAY_ARGS+=(--dry-run) + ./scripts/bridge/fund-bsc-relay-bridge.sh "${RELAY_ARGS[@]}" +fi + +if [[ "$RUN_FINAL_CHECK" == "1" ]]; then + echo "" + echo "--- Final readiness check ---" + ./scripts/deployment/live-test-trustless-bridge.sh --check +fi + +echo "" +echo "Done. Reconcile any remaining top-up gaps against:" +echo " /home/intlc/projects/proxmox/docs/03-deployment/FINAL_UNBLOCK_CHECKLIST_MAINNET_BSC.md" diff --git a/scripts/deployment/run-pmm-full-parity-all-phases.sh b/scripts/deployment/run-pmm-full-parity-all-phases.sh index 617d6f9..0c04a5e 100755 --- a/scripts/deployment/run-pmm-full-parity-all-phases.sh +++ b/scripts/deployment/run-pmm-full-parity-all-phases.sh @@ -13,8 +13,6 @@ cd "$REPO_ROOT" source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" load_deployment_env -# Ensure .env is loaded (for PRIVATE_KEY, RPCs, etc.) -[[ -f ".env" ]] && set -a && source ".env" && set +a RUN_PHASE1="${RUN_PHASE1:-1}" RUN_PHASE2="${RUN_PHASE2:-1}" @@ -23,7 +21,7 @@ RPC_138="${RPC_URL_138:-${RPC_URL:-http://192.168.11.211:8545}}" GAS_PRICE="${GAS_PRICE_138:-${GAS_PRICE:-1000000000}}" INTEGRATION="${DODO_PMM_INTEGRATION_ADDRESS:-${DODO_PMM_INTEGRATION:-0x5BDc62f1ae7D630c37A8B363a1d49845356Ee72d}}" POOL_CUSDTCUSDC="${POOL_CUSDTCUSDC:-0x9fcB06Aa1FD5215DC0E91Fd098aeff4B62fEa5C8}" -POOL_CUSDTUSDT="${POOL_CUSDTUSDT:-0x6fc60DEDc92a2047062294488539992710b99D71}" +POOL_CUSDTUSDT="${POOL_CUSDTUSDT:-0xa3Ee6091696B28e5497b6F491fA1e99047250c59}" POOL_CUSDCUSDC="${POOL_CUSDCUSDC:-0x90bd9Bf18Daa26Af3e814ea224032d015db58Ea5}" export RPC_URL_138="$RPC_138" diff --git a/scripts/deployment/setup-monitoring-complete.sh b/scripts/deployment/setup-monitoring-complete.sh index f8a5b65..f7c1db5 100755 --- a/scripts/deployment/setup-monitoring-complete.sh +++ b/scripts/deployment/setup-monitoring-complete.sh @@ -4,6 +4,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi log_info "=== Complete Monitoring Setup ===" diff --git a/scripts/deployment/setup-monitoring.sh b/scripts/deployment/setup-monitoring.sh index f1e3ff5..398255d 100755 --- a/scripts/deployment/setup-monitoring.sh +++ b/scripts/deployment/setup-monitoring.sh @@ -4,6 +4,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi log_info "=== Monitoring Setup Guide ===" diff --git a/scripts/deployment/setup-terraform-backend.sh b/scripts/deployment/setup-terraform-backend.sh index 0c8de51..fd1a266 100755 --- a/scripts/deployment/setup-terraform-backend.sh +++ b/scripts/deployment/setup-terraform-backend.sh @@ -8,6 +8,22 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi log() { log_success "[✓] $1" diff --git a/scripts/deployment/start-local-testnet.sh b/scripts/deployment/start-local-testnet.sh index e086949..4d40d0d 100755 --- a/scripts/deployment/start-local-testnet.sh +++ b/scripts/deployment/start-local-testnet.sh @@ -11,6 +11,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi log_info "=== Starting Local Anvil Testnet ===" diff --git a/scripts/deployment/submit-ethereum-lists-pr.sh b/scripts/deployment/submit-ethereum-lists-pr.sh index 6ee6ada..d19b17d 100755 --- a/scripts/deployment/submit-ethereum-lists-pr.sh +++ b/scripts/deployment/submit-ethereum-lists-pr.sh @@ -9,6 +9,22 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi CHAIN_DATA_FILE="${PROJECT_ROOT}/metamask/ethereum-lists-chain.json" PR_TEMPLATE="${PROJECT_ROOT}/metamask/ethereum-lists-pr.md" TEMP_DIR=$(mktemp -d) diff --git a/scripts/deployment/submit-token-list.sh b/scripts/deployment/submit-token-list.sh index 83cf992..1b38cbe 100755 --- a/scripts/deployment/submit-token-list.sh +++ b/scripts/deployment/submit-token-list.sh @@ -9,6 +9,22 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi TOKEN_LIST_FILE="${PROJECT_ROOT}/metamask/token-list.json" TOKEN_LIST_URL="https://raw.githubusercontent.com/Defi-Oracle-Tooling/smom-dbis-138/main/metamask/token-list.json" diff --git a/scripts/deployment/sync-chain138-pmm-pools-from-json.sh b/scripts/deployment/sync-chain138-pmm-pools-from-json.sh new file mode 100755 index 0000000..d295a9c --- /dev/null +++ b/scripts/deployment/sync-chain138-pmm-pools-from-json.sh @@ -0,0 +1,307 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SMOM_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +ENV_FILE="$SMOM_ROOT/.env" +CONFIG_JSON="${POOL_CONFIG_JSON:-$SMOM_ROOT/config/chain138-pmm-pools.json}" +ORIG_RPC_URL_138="${RPC_URL_138-}" +ORIG_RPC_URL="${RPC_URL-}" +ORIG_DODO_PMM_INTEGRATION_ADDRESS="${DODO_PMM_INTEGRATION_ADDRESS-}" +ORIG_DODO_PMM_INTEGRATION="${DODO_PMM_INTEGRATION-}" +ORIG_DODO_PMM_PROVIDER_ADDRESS="${DODO_PMM_PROVIDER_ADDRESS-}" +ORIG_DODO_PMM_PROVIDER="${DODO_PMM_PROVIDER-}" +ORIG_PRIVATE_KEY="${PRIVATE_KEY-}" +ORIG_DRY_RUN="${DRY_RUN-}" +ORIG_CHAIN_GAS_PRICE="${CHAIN_GAS_PRICE-}" +ORIG_TX_TIMEOUT_SECONDS="${TX_TIMEOUT_SECONDS-}" +ORIG_POST_CREATE_POLL_SECONDS="${POST_CREATE_POLL_SECONDS-}" +ORIG_POST_CREATE_POLL_INTERVAL="${POST_CREATE_POLL_INTERVAL-}" + +if [[ -f "$ENV_FILE" ]]; then + set -a + # shellcheck disable=SC1090 + source "$ENV_FILE" + set +a +fi + +[[ -n "$ORIG_RPC_URL_138" ]] && RPC_URL_138="$ORIG_RPC_URL_138" +[[ -n "$ORIG_RPC_URL" ]] && RPC_URL="$ORIG_RPC_URL" +[[ -n "$ORIG_DODO_PMM_INTEGRATION_ADDRESS" ]] && DODO_PMM_INTEGRATION_ADDRESS="$ORIG_DODO_PMM_INTEGRATION_ADDRESS" +[[ -n "$ORIG_DODO_PMM_INTEGRATION" ]] && DODO_PMM_INTEGRATION="$ORIG_DODO_PMM_INTEGRATION" +[[ -n "$ORIG_DODO_PMM_PROVIDER_ADDRESS" ]] && DODO_PMM_PROVIDER_ADDRESS="$ORIG_DODO_PMM_PROVIDER_ADDRESS" +[[ -n "$ORIG_DODO_PMM_PROVIDER" ]] && DODO_PMM_PROVIDER="$ORIG_DODO_PMM_PROVIDER" +[[ -n "$ORIG_PRIVATE_KEY" ]] && PRIVATE_KEY="$ORIG_PRIVATE_KEY" +[[ -n "$ORIG_DRY_RUN" ]] && DRY_RUN="$ORIG_DRY_RUN" +[[ -n "$ORIG_CHAIN_GAS_PRICE" ]] && CHAIN_GAS_PRICE="$ORIG_CHAIN_GAS_PRICE" +[[ -n "$ORIG_TX_TIMEOUT_SECONDS" ]] && TX_TIMEOUT_SECONDS="$ORIG_TX_TIMEOUT_SECONDS" +[[ -n "$ORIG_POST_CREATE_POLL_SECONDS" ]] && POST_CREATE_POLL_SECONDS="$ORIG_POST_CREATE_POLL_SECONDS" +[[ -n "$ORIG_POST_CREATE_POLL_INTERVAL" ]] && POST_CREATE_POLL_INTERVAL="$ORIG_POST_CREATE_POLL_INTERVAL" + +RPC_URL_138="${RPC_URL_138:-${RPC_URL:-http://192.168.11.211:8545}}" +DODO_PMM_INTEGRATION_ADDRESS="${DODO_PMM_INTEGRATION_ADDRESS:-${DODO_PMM_INTEGRATION:-}}" +DODO_PMM_PROVIDER_ADDRESS="${DODO_PMM_PROVIDER_ADDRESS:-${DODO_PMM_PROVIDER:-}}" +DRY_RUN="${DRY_RUN:-0}" + +[[ -f "$CONFIG_JSON" ]] || { echo "POOL_CONFIG_JSON not found: $CONFIG_JSON" >&2; exit 1; } +command -v jq >/dev/null 2>&1 || { echo "jq is required" >&2; exit 1; } +command -v cast >/dev/null 2>&1 || { echo "cast is required" >&2; exit 1; } +[[ -n "$DODO_PMM_INTEGRATION_ADDRESS" ]] || { echo "DODO_PMM_INTEGRATION_ADDRESS not set" >&2; exit 1; } +[[ -n "$DODO_PMM_PROVIDER_ADDRESS" ]] || { echo "DODO_PMM_PROVIDER_ADDRESS not set" >&2; exit 1; } +[[ "$DRY_RUN" == "1" || -n "${PRIVATE_KEY:-}" ]] || { echo "PRIVATE_KEY not set (required unless DRY_RUN=1)" >&2; exit 1; } +CHAIN_GAS_PRICE="${CHAIN_GAS_PRICE:-1000000000}" +TX_TIMEOUT_SECONDS="${TX_TIMEOUT_SECONDS:-120}" +POST_CREATE_POLL_SECONDS="${POST_CREATE_POLL_SECONDS:-20}" +POST_CREATE_POLL_INTERVAL="${POST_CREATE_POLL_INTERVAL:-1}" + +LP_FEE="${LP_FEE_RATE:-$(jq -r '.defaults.lpFeeRate' "$CONFIG_JSON")}" +INITIAL_PRICE="${INITIAL_PRICE:-$(jq -r '.defaults.initialPrice' "$CONFIG_JSON")}" +K_FACTOR="${K_FACTOR:-$(jq -r '.defaults.kFactor' "$CONFIG_JSON")}" +ENABLE_TWAP="${ENABLE_TWAP:-$(jq -r '.defaults.enableTwap' "$CONFIG_JSON")}" + +declare -A TOKENS=() +while IFS=$'\t' read -r sym addr; do + TOKENS["$sym"]="$addr" +done < <(jq -r '.tokens | to_entries[] | [.key, .value] | @tsv' "$CONFIG_JSON") + +mapfile -t C_STARS < <(jq -r '.groups.cStarSymbols[]' "$CONFIG_JSON") +mapfile -t OFFICIALS < <(jq -r '.groups.officialStableSymbols[]' "$CONFIG_JSON") +WETH_SYMBOL="$(jq -r '.groups.wethSymbol' "$CONFIG_JSON")" +DEPLOY_CSTAR_CSTAR="$(jq -r '.groups.deploy.cStarVsCStar' "$CONFIG_JSON")" +DEPLOY_CSTAR_OFFICIAL="$(jq -r '.groups.deploy.cStarVsOfficial' "$CONFIG_JSON")" +DEPLOY_CSTAR_WETH="$(jq -r '.groups.deploy.cStarVsWeth' "$CONFIG_JSON")" +DEPLOY_OFFICIAL_WETH="$(jq -r '.groups.deploy.officialVsWeth' "$CONFIG_JSON")" + +declare -A SEEN=() +DESIRED_PAIRS=() + +add_pair() { + local base_sym="$1" quote_sym="$2" + local base="${TOKENS[$base_sym]:-}" + local quote="${TOKENS[$quote_sym]:-}" + local key="${base_sym}|${quote_sym}" + + [[ -n "$base" && -n "$quote" ]] || return 0 + [[ "$base" != "0x0000000000000000000000000000000000000000" ]] || return 0 + [[ "$quote" != "0x0000000000000000000000000000000000000000" ]] || return 0 + [[ -z "${SEEN[$key]:-}" ]] || return 0 + + SEEN["$key"]=1 + DESIRED_PAIRS+=("${base_sym}|${base}|${quote_sym}|${quote}") +} + +if [[ "$DEPLOY_CSTAR_CSTAR" == "true" ]]; then + for ((i=0; i<${#C_STARS[@]}; i++)); do + for ((j=i+1; j<${#C_STARS[@]}; j++)); do + add_pair "${C_STARS[$i]}" "${C_STARS[$j]}" + done + done +fi + +if [[ "$DEPLOY_CSTAR_OFFICIAL" == "true" ]]; then + for cstar in "${C_STARS[@]}"; do + for official in "${OFFICIALS[@]}"; do + add_pair "$cstar" "$official" + done + done +fi + +if [[ "$DEPLOY_CSTAR_WETH" == "true" ]]; then + for cstar in "${C_STARS[@]}"; do + add_pair "$cstar" "$WETH_SYMBOL" + done +fi + +if [[ "$DEPLOY_OFFICIAL_WETH" == "true" ]]; then + for official in "${OFFICIALS[@]}"; do + add_pair "$official" "$WETH_SYMBOL" + done +fi + +while IFS=$'\t' read -r base_sym quote_sym; do + add_pair "$base_sym" "$quote_sym" +done < <(jq -r '.explicitPairs[]? | [.baseSymbol, .quoteSymbol] | @tsv' "$CONFIG_JSON") + +zero_addr='0x0000000000000000000000000000000000000000' +created=0 +registered=0 +skipped_existing=0 +failed=0 +CURRENT_NONCE="" + +if [[ "$DRY_RUN" != "1" ]]; then + DEPLOYER_ADDRESS="$(cast wallet address --private-key "$PRIVATE_KEY" 2>/dev/null || true)" + [[ -n "$DEPLOYER_ADDRESS" ]] || { echo "Failed to derive deployer address from PRIVATE_KEY" >&2; exit 1; } +fi + +rpc_call() { + local to="$1" data="$2" + local payload + payload=$(printf '{"jsonrpc":"2.0","method":"eth_call","params":[{"to":"%s","data":"%s"},"latest"],"id":1}' "$to" "$data") + curl -s -X POST "$RPC_URL_138" -H 'Content-Type: application/json' --data "$payload" +} + +json_result() { + sed -n 's/.*"result":"\([^"]*\)".*/\1/p' +} + +hex_to_addr() { + local value="${1#0x}" + if [[ ${#value} -lt 40 ]]; then + echo "$zero_addr" + return 0 + fi + printf '0x%s\n' "${value: -40}" +} + +pool_for() { + local calldata result + calldata="$(cast calldata "pools(address,address)" "$1" "$2" 2>/dev/null || true)" + [[ -n "$calldata" ]] || { echo "$zero_addr"; return 0; } + result="$(rpc_call "$DODO_PMM_INTEGRATION_ADDRESS" "$calldata" | json_result)" + [[ -n "$result" ]] || { echo "$zero_addr"; return 0; } + hex_to_addr "$result" +} + +provider_pool_for() { + local calldata result + calldata="$(cast calldata "pools(address,address)" "$1" "$2" 2>/dev/null || true)" + [[ -n "$calldata" ]] || { echo "$zero_addr"; return 0; } + result="$(rpc_call "$DODO_PMM_PROVIDER_ADDRESS" "$calldata" | json_result)" + [[ -n "$result" ]] || { echo "$zero_addr"; return 0; } + hex_to_addr "$result" +} + +send_tx() { + local to="$1" + shift + local attempts nonce output rc + for attempts in 1 2 3; do + nonce="$(cast nonce "$DEPLOYER_ADDRESS" --block pending --rpc-url "$RPC_URL_138" 2>/dev/null || true)" + [[ -n "$nonce" ]] || { + echo "Failed to fetch pending nonce for deployer" >&2 + return 1 + } + set +e + output="$(cast send "$to" "$@" \ + --rpc-url "$RPC_URL_138" \ + --private-key "$PRIVATE_KEY" \ + --legacy \ + --gas-price "$CHAIN_GAS_PRICE" \ + --nonce "$nonce" \ + --confirmations 1 \ + --timeout "$TX_TIMEOUT_SECONDS" \ + -q 2>&1)" + rc=$? + set -e + if (( rc == 0 )); then + return 0 + fi + if [[ "$output" == *"Nonce too low"* || "$output" == *"Replacement transaction underpriced"* ]]; then + sleep 1 + continue + fi + printf '%s\n' "$output" >&2 + return "$rc" + done + printf '%s\n' "$output" >&2 + return 1 +} + +wait_for_pool() { + local base="$1" quote="$2" + local max_polls poll current + max_polls=$((POST_CREATE_POLL_SECONDS / POST_CREATE_POLL_INTERVAL)) + (( max_polls < 1 )) && max_polls=1 + for ((poll=0; poll zero pool address" + ((failed++)) || true + return 1 + fi + if [[ "$DRY_RUN" == "1" ]]; then + echo " [DRY] would ensure provider registration for $label -> $pool (both directions)" + ((registered++)) || true + return 0 + fi + if send_tx "$DODO_PMM_PROVIDER_ADDRESS" "registerPool(address,address,address)" "$base" "$quote" "$pool" --gas-limit 200000 \ + && send_tx "$DODO_PMM_PROVIDER_ADDRESS" "registerPool(address,address,address)" "$quote" "$base" "$pool" --gas-limit 200000; then + echo " OK register $label -> $pool" + ((registered++)) || true + return 0 + fi + echo " FAIL register $label -> $pool" + ((failed++)) || true + return 1 +} + +echo "=== Chain 138 PMM Desired-State Sync ===" +echo "Config: $CONFIG_JSON" +echo "Integration: $DODO_PMM_INTEGRATION_ADDRESS" +echo "Provider: $DODO_PMM_PROVIDER_ADDRESS" +echo "RPC: $RPC_URL_138" +echo "Dry run: $DRY_RUN" +echo "Desired pairs:${#DESIRED_PAIRS[@]}" +echo "" + +for pair in "${DESIRED_PAIRS[@]}"; do + IFS='|' read -r base_sym base quote_sym quote <<< "$pair" + label="${base_sym}/${quote_sym}" + existing_pool="$(pool_for "$base" "$quote")" + provider_pool="$(provider_pool_for "$base" "$quote")" + if [[ -n "$existing_pool" && "$existing_pool" != "$zero_addr" ]]; then + echo "SKIP create $label (exists: $existing_pool)" + ((skipped_existing++)) || true + register_pair "$base" "$quote" "$existing_pool" "$label" + continue + fi + + if [[ -n "$provider_pool" && "$provider_pool" != "$zero_addr" ]]; then + echo "BLOCKER create $label (provider already points to existing pool $provider_pool, but integration has no pool record)" + echo " Repair requires importing the existing pool into DODOPMMIntegration with importExistingPool(...)." + ((failed++)) || true + continue + fi + + if [[ "$DRY_RUN" == "1" ]]; then + echo "[DRY] would create $label" + ((created++)) || true + continue + fi + + if send_tx "$DODO_PMM_INTEGRATION_ADDRESS" "createPool(address,address,uint256,uint256,uint256,bool)" \ + "$base" "$quote" "$LP_FEE" "$INITIAL_PRICE" "$K_FACTOR" "$ENABLE_TWAP" --gas-limit 500000; then + new_pool="$(wait_for_pool "$base" "$quote")" + if [[ -z "$new_pool" || "$new_pool" == "$zero_addr" ]]; then + echo "FAIL create $label (tx confirmed but integration still reports zero pool address)" + ((failed++)) || true + continue + fi + echo "OK create $label -> $new_pool" + ((created++)) || true + register_pair "$base" "$quote" "$new_pool" "$label" + else + echo "FAIL create $label" + ((failed++)) || true + fi +done + +echo "" +echo "Summary:" +echo " Created: $created" +echo " Registered: $registered" +echo " Existing: $skipped_existing" +echo " Failed: $failed" diff --git a/scripts/deployment/test-cross-chain.sh b/scripts/deployment/test-cross-chain.sh index f48cbc9..83ec249 100755 --- a/scripts/deployment/test-cross-chain.sh +++ b/scripts/deployment/test-cross-chain.sh @@ -4,6 +4,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi log_info "=== Cross-Chain Transfer Test ===" diff --git a/scripts/deployment/update-rpc-security.sh b/scripts/deployment/update-rpc-security.sh index 7865a54..8bb76b1 100755 --- a/scripts/deployment/update-rpc-security.sh +++ b/scripts/deployment/update-rpc-security.sh @@ -8,6 +8,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi log_info "=== Updating RPC Security Configuration ===" diff --git a/scripts/deployment/update-token-list.sh b/scripts/deployment/update-token-list.sh index c6d68c5..a5f4a63 100755 --- a/scripts/deployment/update-token-list.sh +++ b/scripts/deployment/update-token-list.sh @@ -9,6 +9,22 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi CONTRACT_ADDRESSES_FILE="${PROJECT_ROOT}/contracts-deployed.json" TOKEN_LIST_FILE="${PROJECT_ROOT}/metamask/token-list.json" diff --git a/scripts/deployment/validate-deployment-config.sh b/scripts/deployment/validate-deployment-config.sh index e49bacf..2b6ff63 100755 --- a/scripts/deployment/validate-deployment-config.sh +++ b/scripts/deployment/validate-deployment-config.sh @@ -11,6 +11,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi ERRORS=0 WARNINGS=0 diff --git a/scripts/deployment/verify-36-region-clusters.sh b/scripts/deployment/verify-36-region-clusters.sh index 4c67100..8c1324c 100755 --- a/scripts/deployment/verify-36-region-clusters.sh +++ b/scripts/deployment/verify-36-region-clusters.sh @@ -7,6 +7,22 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi # Load environment variables if [ -f "$PROJECT_ROOT/.env" ]; then diff --git a/scripts/deployment/verify-all-rpcs.sh b/scripts/deployment/verify-all-rpcs.sh index fde4e7e..b8ded27 100755 --- a/scripts/deployment/verify-all-rpcs.sh +++ b/scripts/deployment/verify-all-rpcs.sh @@ -6,6 +6,22 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi echo "=== RPC Endpoint Verification ===" echo "" diff --git a/scripts/deployment/verify-ccip-logger-other-chains.sh b/scripts/deployment/verify-ccip-logger-other-chains.sh index 6a46476..a7e2e17 100755 --- a/scripts/deployment/verify-ccip-logger-other-chains.sh +++ b/scripts/deployment/verify-ccip-logger-other-chains.sh @@ -11,10 +11,20 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" - -if [[ -f .env ]]; then +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then set -a - source .env + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" set +a fi diff --git a/scripts/deployment/verify-contract-etherscan.sh b/scripts/deployment/verify-contract-etherscan.sh index 4d2b9ae..25ac21c 100755 --- a/scripts/deployment/verify-contract-etherscan.sh +++ b/scripts/deployment/verify-contract-etherscan.sh @@ -7,6 +7,22 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi # Load environment variables diff --git a/scripts/deployment/verify-contract-ownership.sh b/scripts/deployment/verify-contract-ownership.sh index aeef12d..cd23c06 100755 --- a/scripts/deployment/verify-contract-ownership.sh +++ b/scripts/deployment/verify-contract-ownership.sh @@ -7,8 +7,23 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi -source .env 2>/dev/null || true # Get deployer address if [ -z "${PRIVATE_KEY:-}" ]; then diff --git a/scripts/deployment/verify-contracts-parallel.sh b/scripts/deployment/verify-contracts-parallel.sh index 8653afd..ec073e6 100755 --- a/scripts/deployment/verify-contracts-parallel.sh +++ b/scripts/deployment/verify-contracts-parallel.sh @@ -8,6 +8,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi # Load environment variables if [ ! -f .env ]; then diff --git a/scripts/deployment/verify-cronos-contracts.sh b/scripts/deployment/verify-cronos-contracts.sh index 6e81fa0..d72dc0b 100755 --- a/scripts/deployment/verify-cronos-contracts.sh +++ b/scripts/deployment/verify-cronos-contracts.sh @@ -8,8 +8,23 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi -source .env 2>/dev/null || true if [ -z "${CRONOSCAN_API_KEY:-}" ]; then echo "ERROR: CRONOSCAN_API_KEY not set. Set in .env (from explorer.cronos.org/register)." diff --git a/scripts/deployment/verify-deployed-contracts.sh b/scripts/deployment/verify-deployed-contracts.sh index a6a42e4..c17269e 100755 --- a/scripts/deployment/verify-deployed-contracts.sh +++ b/scripts/deployment/verify-deployed-contracts.sh @@ -7,8 +7,23 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi -source .env 2>/dev/null || true if [ -z "${ETHERSCAN_API_KEY:-}" ]; then echo "ERROR: ETHERSCAN_API_KEY not set. Set in .env or export." diff --git a/scripts/deployment/verify-deployment.sh b/scripts/deployment/verify-deployment.sh index b76bcba..d84d251 100755 --- a/scripts/deployment/verify-deployment.sh +++ b/scripts/deployment/verify-deployment.sh @@ -15,6 +15,22 @@ SCRIPT_OPTIONS="--fast Skip long-running checks\n--verbose SCRIPT_REQUIREMENTS="Azure CLI, jq, access to cluster contexts" handle_help "${1:-}" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi CONTRACT_ADDRESSES_FILE="${PROJECT_ROOT}/contracts-deployed.json" # Load environment variables diff --git a/scripts/deployment/verify-env.sh b/scripts/deployment/verify-env.sh index df3807b..c2dd5d7 100755 --- a/scripts/deployment/verify-env.sh +++ b/scripts/deployment/verify-env.sh @@ -8,6 +8,22 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi ENV_FILE="${PROJECT_ROOT}/.env" # Load .env file if it exists diff --git a/scripts/deployment/verify-mainnet-contracts.sh b/scripts/deployment/verify-mainnet-contracts.sh index a691176..b75fb52 100755 --- a/scripts/deployment/verify-mainnet-contracts.sh +++ b/scripts/deployment/verify-mainnet-contracts.sh @@ -7,8 +7,23 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi -source .env 2>/dev/null || true echo "==========================================" echo "Ethereum Mainnet Contract Verification" diff --git a/scripts/deployment/verify-mainnet-deployments.sh b/scripts/deployment/verify-mainnet-deployments.sh index 4974717..8302b09 100755 --- a/scripts/deployment/verify-mainnet-deployments.sh +++ b/scripts/deployment/verify-mainnet-deployments.sh @@ -4,6 +4,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi log_info "=== Verifying Mainnet Deployments ===" diff --git a/scripts/deployment/verify-mainnet-etherscan.sh b/scripts/deployment/verify-mainnet-etherscan.sh index 49933ce..24059ed 100755 --- a/scripts/deployment/verify-mainnet-etherscan.sh +++ b/scripts/deployment/verify-mainnet-etherscan.sh @@ -7,8 +7,23 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi -source .env 2>/dev/null || true echo "==========================================" echo "Ethereum Mainnet Contract Verification" diff --git a/scripts/deployment/verify-trustless-deployments.sh b/scripts/deployment/verify-trustless-deployments.sh index 5ba0f5a..85cd31c 100755 --- a/scripts/deployment/verify-trustless-deployments.sh +++ b/scripts/deployment/verify-trustless-deployments.sh @@ -7,6 +7,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" DOTENV="$REPO_ROOT/.env" cd "$REPO_ROOT" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi [[ -f "$DOTENV" ]] && set -a && source "$DOTENV" && set +a PASS=0 diff --git a/scripts/deployment/wait-and-run-all-next-steps.sh b/scripts/deployment/wait-and-run-all-next-steps.sh index 2680e5e..3cb6fd0 100755 --- a/scripts/deployment/wait-and-run-all-next-steps.sh +++ b/scripts/deployment/wait-and-run-all-next-steps.sh @@ -6,6 +6,22 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi echo "╔════════════════════════════════════════════════════════════════╗" echo "║ WAIT FOR INFRASTRUCTURE & RUN ALL NEXT STEPS ║" diff --git a/scripts/deployment/wait-and-run-next-steps.sh b/scripts/deployment/wait-and-run-next-steps.sh index c5be097..107170b 100755 --- a/scripts/deployment/wait-and-run-next-steps.sh +++ b/scripts/deployment/wait-and-run-next-steps.sh @@ -6,6 +6,22 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi REGIONS=( "northeurope" "uksouth" "ukwest" "francecentral" "germanywestcentral" diff --git a/scripts/get-usdt-usdc-supply.sh b/scripts/get-usdt-usdc-supply.sh index 494887e..9fb0308 100755 --- a/scripts/get-usdt-usdc-supply.sh +++ b/scripts/get-usdt-usdc-supply.sh @@ -5,7 +5,7 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" # Colors RED='\033[0;31m' @@ -19,15 +19,18 @@ log_success() { echo -e "${GREEN}[✓]${NC} $1"; } log_error() { echo -e "${RED}[✗]${NC} $1"; } log_warn() { echo -e "${YELLOW}[⚠]${NC} $1"; } -# Load environment variables if .env exists -if [ -f "$PROJECT_ROOT/.env" ]; then - source "$PROJECT_ROOT/.env" -elif [ -f "$PROJECT_ROOT/smom-dbis-138/.env" ]; then - source "$PROJECT_ROOT/smom-dbis-138/.env" +if [[ -f "$SCRIPT_DIR/lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/lib/deployment/dotenv.sh" + load_deployment_env --repo-root "$PROJECT_ROOT" +elif [ -f "$PROJECT_ROOT/.env" ]; then + set -a && source "$PROJECT_ROOT/.env" && set +a fi # Configuration -RPC_URL="${RPC_URL:-${RPC_URL_138:-http://192.168.11.250:8545}}" +RPC_URL="${RPC_URL:-${RPC_URL_138:-http://192.168.11.211:8545}}" +RPC_URL="${RPC_URL%$'\r'}" +RPC_URL="${RPC_URL%$'\n'}" COMPLIANT_USDT_ADDRESS="${COMPLIANT_USDT_ADDRESS:-0x93E66202A11B1772E55407B32B44e5Cd8eda7f22}" COMPLIANT_USDC_ADDRESS="${COMPLIANT_USDC_ADDRESS:-0xf22258f57794CC8E06237084b353Ab30fFfa640b}" diff --git a/scripts/lib/deployment/README.md b/scripts/lib/deployment/README.md index 0aab92f..627dc67 100644 --- a/scripts/lib/deployment/README.md +++ b/scripts/lib/deployment/README.md @@ -57,6 +57,7 @@ No `FUND_ETH_AMOUNT_WEI` / `FUND_WETH_AMOUNT_WEI` in .env. | live-test-trustless-bridge.sh | --check (optional: print LP stats and BondManager totalEthHeld); prints cast commands for lock → claim → finalize → release | | deploy-trustless-l2s.sh | --chain, --lockbox / --no-lockbox | | fund-ccip-bridges-with-link.sh | --link amount, --dry-run | +| run-final-unblock-checklist.sh | --dry-run, --status-only, --json, --only / --skip, --mainnet-link, --bsc-link, --mainnet-eth, --mainnet-weth, --mainnet-relay-weth, --bsc-relay-weth | | fix-nonce-and-retry.sh | --chain, --script (positional still supported) | | run-remaining-g2g3-with-nonce-fix.sh | --delay, --lockbox / --no-lockbox | | check-balances-gas-and-deploy.sh | --deploy | diff --git a/scripts/lib/deployment/dotenv.sh b/scripts/lib/deployment/dotenv.sh index a67d75c..9f1ab2d 100644 --- a/scripts/lib/deployment/dotenv.sh +++ b/scripts/lib/deployment/dotenv.sh @@ -39,6 +39,17 @@ load_deployment_env() { if [[ -z "${PRIVATE_KEY:-}" && -n "${DEPLOYER_PRIVATE_KEY:-}" ]]; then export PRIVATE_KEY="$DEPLOYER_PRIVATE_KEY" fi + # Trailing CR/LF on RPC URL lines breaks cast/curl; strip common RPC vars after load. + local _k _v + for _k in RPC_URL_138 RPC_URL CHAIN138_RPC ETHEREUM_MAINNET_RPC GNOSIS_MAINNET_RPC GNOSIS_RPC \ + CRONOS_RPC_URL CRONOS_RPC CELO_MAINNET_RPC CELO_RPC BSC_RPC_URL POLYGON_MAINNET_RPC \ + BASE_MAINNET_RPC OPTIMISM_MAINNET_RPC ARBITRUM_MAINNET_RPC AVALANCHE_RPC_URL WEMIX_RPC WEMIX_MAINNET_RPC; do + _v="${!_k:-}" + [[ -z "$_v" ]] && continue + _v="${_v%$'\r'}" + _v="${_v%$'\n'}" + export "$_k=$_v" + done } # Require vars for mainnet LP funding (G4). Fails with message if missing. diff --git a/scripts/lib/deployment/patch-all-deployment-dotenv.py b/scripts/lib/deployment/patch-all-deployment-dotenv.py new file mode 100644 index 0000000..3984678 --- /dev/null +++ b/scripts/lib/deployment/patch-all-deployment-dotenv.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python3 +""" +One-shot helper: add load_deployment_env to deployment/*.sh that still raw-source .env. +Run from repo: python3 scripts/lib/deployment/patch-all-deployment-dotenv.py +Idempotent: skips files that already call load_deployment_env. +""" +from __future__ import annotations + +import re +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[3] # smom-dbis-138 +DEP = ROOT / "scripts" / "deployment" + +SNIPPET = """ +# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. +if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" + load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" +elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$PROJECT_ROOT/.env" + set +a +elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then + set -a + # shellcheck disable=SC1090 + source "$REPO_ROOT/.env" + set +a +fi +""".lstrip("\n") + +REMOVE_SUBSTRINGS = [ + "\nsource .env 2>/dev/null || true\n", + "\nsource .env 2>/dev/null || true", + "\n[[ -f \"$PROJECT_ROOT/.env\" ]] && set -a && source \"$PROJECT_ROOT/.env\" && set +a\n", + "\n[[ -f .env ]] && set -a && source .env && set +a\n", + "\n[ -f .env ] && set -a && source .env && set +a\n", +] + +SET_U_BLOCK = re.compile( + r"\nset \+u\n\[ -f \.env \] && source \.env\nset -u\n", re.MULTILINE +) +DOTENV_IF = re.compile( + r"\nif \[\[ -f \"\$DOTENV\" \]\]; then set -a; source \"\$DOTENV\"; set \+a; fi\n", + re.MULTILINE, +) + + +def find_insert_line(lines: list[str]) -> int | None: + for i, line in enumerate(lines): + s = line.strip() + if re.match(r'^cd "\$(PROJECT_ROOT|REPO_ROOT)"\s*$', s): + return i + 1 + for i, line in enumerate(lines[:30]): + if "PROJECT_ROOT=" in line and "$(cd" in line: + return i + 1 + if "REPO_ROOT=" in line and "$(cd" in line: + return i + 1 + return None + + +def main() -> None: + changed = 0 + for path in sorted(DEP.glob("*.sh")): + text = path.read_text(encoding="utf-8", errors="replace") + if "load_deployment_env" in text: + continue + if "SCRIPT_DIR=" not in text or ( + "PROJECT_ROOT=" not in text and "REPO_ROOT=" not in text + ): + continue + lines = text.splitlines(keepends=True) + ins = find_insert_line(lines) + if ins is None: + continue + window = "".join(lines[max(0, ins - 2) : min(len(lines), ins + 8)]) + if "load_deployment_env" in window: + continue + new_body = "".join(lines) + new_body = SET_U_BLOCK.sub("\n", new_body) + new_body = DOTENV_IF.sub("\n", new_body) + for sub in REMOVE_SUBSTRINGS: + new_body = new_body.replace(sub, "\n", 1) + lines = new_body.splitlines(keepends=True) + ins = find_insert_line(lines) + if ins is None: + continue + lines.insert(ins, SNIPPET + ("\n" if not SNIPPET.endswith("\n") else "")) + out = "".join(lines) + if out != text: + path.write_text(out, encoding="utf-8") + changed += 1 + print("patched", path.relative_to(ROOT)) + print("done, changed", changed, "files") + + +if __name__ == "__main__": + main() diff --git a/scripts/load-env.sh b/scripts/load-env.sh index 7748c5f..51c77a3 100644 --- a/scripts/load-env.sh +++ b/scripts/load-env.sh @@ -1,29 +1,25 @@ #!/usr/bin/env bash -# Source the correct dotenv for smom-dbis-138 (single source for deploy, relay, token-aggregation). -# Uses repo-root .env unless ENV_FILE is already set. Export ENV_FILE so scripts using -# scripts/lib/deployment/dotenv.sh (load_deployment_env) use the same file. +# Source smom-dbis-138 dotenv with RPC CR/LF trimming (load_deployment_env). +# Uses repo-root .env unless ENV_FILE is set. Prefer this over raw `source .env` in new scripts. # Usage: source scripts/load-env.sh (from smom-dbis-138) -# source smom-dbis-138/scripts/load-env.sh (from repo root) -# ENV_FILE=/path/to/.env source scripts/load-env.sh (override) -# Do not execute; source it so variables are in the current shell. +# ENV_FILE=/path/to/.env source scripts/load-env.sh +# Do not execute; source so variables apply to the current shell. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)" -[[ -z "${ENV_FILE:-}" ]] && ENV_FILE="${SCRIPT_DIR}/../.env" -export ENV_FILE -if [[ -f "$ENV_FILE" ]]; then - set -a - source "$ENV_FILE" - set +a - SECURE_SECRETS_FILE="${SECURE_SECRETS_FILE:-$HOME/.secure-secrets/private-keys.env}" - if [[ -f "$SECURE_SECRETS_FILE" ]]; then - set -a - source "$SECURE_SECRETS_FILE" - set +a - fi - if [[ -z "${PRIVATE_KEY:-}" && -n "${DEPLOYER_PRIVATE_KEY:-}" ]]; then - export PRIVATE_KEY="$DEPLOYER_PRIVATE_KEY" - fi - echo "Loaded: $ENV_FILE" +export ENV_FILE="${ENV_FILE:-${SCRIPT_DIR}/../.env}" +if [[ -f "$SCRIPT_DIR/lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/lib/deployment/dotenv.sh" + load_deployment_env --repo-root "$(cd "$SCRIPT_DIR/.." && pwd)" + echo "Loaded via load_deployment_env: ${ENV_FILE:-${SCRIPT_DIR}/../.env}" else - echo "WARN: $ENV_FILE not found" >&2 + if [[ -f "$ENV_FILE" ]]; then + set -a + # shellcheck disable=SC1090 + source "$ENV_FILE" + set +a + echo "Loaded: $ENV_FILE (dotenv.sh missing — no RPC trim)" + else + echo "WARN: $ENV_FILE not found" >&2 + fi fi diff --git a/scripts/mint-all-c-star-138.sh b/scripts/mint-all-c-star-138.sh index 095e674..e4a4dee 100755 --- a/scripts/mint-all-c-star-138.sh +++ b/scripts/mint-all-c-star-138.sh @@ -2,6 +2,7 @@ # Mint all 12 c* tokens on Chain 138 to the deployer. # Usage: ./scripts/mint-all-c-star-138.sh [amount_human] # amount_human = 1000000 (default = 1M each). 6 decimals. +# For cXAUC/cXAUT, amount_human is troy ounces (1 token = 1 troy oz Au), not USD. # Requires: PRIVATE_KEY, RPC_URL_138 in .env. set -euo pipefail diff --git a/scripts/mint-to-750m.sh b/scripts/mint-to-750m.sh index 4a9ddbb..36b14fd 100755 --- a/scripts/mint-to-750m.sh +++ b/scripts/mint-to-750m.sh @@ -5,16 +5,19 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" -# Load environment variables -if [ -f "$PROJECT_ROOT/.env" ]; then - source "$PROJECT_ROOT/.env" -elif [ -f "$PROJECT_ROOT/smom-dbis-138/.env" ]; then - source "$PROJECT_ROOT/smom-dbis-138/.env" +if [[ -f "$SCRIPT_DIR/lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/lib/deployment/dotenv.sh" + load_deployment_env --repo-root "$PROJECT_ROOT" +elif [ -f "$PROJECT_ROOT/.env" ]; then + set -a && source "$PROJECT_ROOT/.env" && set +a fi -RPC_URL="${RPC_URL:-${RPC_URL_138:-http://192.168.11.250:8545}}" +RPC_URL="${RPC_URL:-${RPC_URL_138:-http://192.168.11.211:8545}}" +RPC_URL="${RPC_URL%$'\r'}" +RPC_URL="${RPC_URL%$'\n'}" USDT_ADDRESS="0x93E66202A11B1772E55407B32B44e5Cd8eda7f22" USDC_ADDRESS="0xf22258f57794CC8E06237084b353Ab30fFfa640b" diff --git a/scripts/mint-xau-chain138.sh b/scripts/mint-xau-chain138.sh new file mode 100755 index 0000000..4d3c862 --- /dev/null +++ b/scripts/mint-xau-chain138.sh @@ -0,0 +1,81 @@ +#!/usr/bin/env bash +# Mint cXAUC and/or cXAUT on Chain 138 to the minter (owner) address. +# Amounts are always in TROY OUNCES (1 full token = 1 troy oz Au; 6 decimals). +# +# Usage: +# ./scripts/mint-xau-chain138.sh # mint both tokens (default) +# ./scripts/mint-xau-chain138.sh --cxauc-only +# ./scripts/mint-xau-chain138.sh --cxaut-only +# MINT_TO=0x... ./scripts/mint-xau-chain138.sh # recipient (default: deployer from PRIVATE_KEY) +# DRY_RUN=1 ./scripts/mint-xau-chain138.sh 100 +# +# Requires: PRIVATE_KEY, RPC_URL_138 (or RPC_URL) in .env +# +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" +cd "$PROJECT_ROOT" +[ -f .env ] && set -a && source .env && set +a + +CXAUC="0x290E52a8819A4fbD0714E517225429aA2B70EC6b" +CXAUT="0x94e408E26c6FD8F4ee00b54dF19082FDA07dC96E" +RPC="${RPC_URL_138:-${RPC_URL:-http://192.168.11.211:8545}}" +GAS_LIMIT="${GAS_LIMIT:-200000}" + +[ -n "${PRIVATE_KEY:-}" ] || { echo "PRIVATE_KEY not set"; exit 1; } + +OZ="${1:-}" +[ -n "$OZ" ] || { echo "Usage: $0 [--cxauc-only|--cxaut-only]"; exit 1; } +shift || true + +DO_CXAUC=1 +DO_CXAUT=1 +for a in "$@"; do + case "$a" in + --cxauc-only) DO_CXAUC=1; DO_CXAUT=0 ;; + --cxaut-only) DO_CXAUC=0; DO_CXAUT=1 ;; + *) echo "Unknown option: $a"; exit 1 ;; + esac +done + +BASE_UNITS="$(python3 -c " +from decimal import Decimal, ROUND_DOWN +import sys +d = Decimal(sys.argv[1].strip()) +if d <= 0: + sys.exit('troy_ounces must be positive') +# 1 troy oz = 10^6 base units (6 decimals) +b = (d * Decimal(10**6)).to_integral_value(rounding=ROUND_DOWN) +if b <= 0 or b > 2**256 - 1: + sys.exit('amount out of range') +print(int(b)) +" "$OZ")" || exit 1 + +if [ -n "${MINT_TO:-}" ]; then + TO="$MINT_TO" +else + TO="$(cast wallet address "$PRIVATE_KEY")" || exit 1 +fi + +echo "=== Mint XAU-compliant tokens (troy oz) ===" +echo " RPC: $RPC" +echo " Recipient: $TO" +echo " Troy ounces: $OZ -> base units: $BASE_UNITS" +echo " cXAUC: $DO_CXAUC cXAUT: $DO_CXAUT" +echo "" + +run_mint() { + local addr="$1" + local label="$2" + if [ -n "${DRY_RUN:-}" ]; then + echo "[dry-run] cast send $label $addr mint $TO $BASE_UNITS" + return 0 + fi + cast send "$addr" "mint(address,uint256)" "$TO" "$BASE_UNITS" \ + --rpc-url "$RPC" --private-key "$PRIVATE_KEY" --legacy --gas-limit "$GAS_LIMIT" +} + +[ "$DO_CXAUC" = 1 ] && run_mint "$CXAUC" "cXAUC" +[ "$DO_CXAUT" = 1 ] && run_mint "$CXAUT" "cXAUT" +echo "Done." diff --git a/scripts/reconcile-xau-deployer-chain138.sh b/scripts/reconcile-xau-deployer-chain138.sh new file mode 100755 index 0000000..79f081c --- /dev/null +++ b/scripts/reconcile-xau-deployer-chain138.sh @@ -0,0 +1,126 @@ +#!/usr/bin/env bash +# Burn deployer's full cXAUC + cXAUT balances, then remint using troy-ounce semantics +# (1 full token = 1 troy oz Au). Optional USD target + spot to derive ounces. +# +# Defaults (override with env): +# RETARGET_USD=50000000 Total USD notional (see RETARGET_MODE) +# RETARGET_MODE=split split = half USD to cXAUC, half to cXAUT | each = full USD per token +# XAU_SPOT_USD=4506.30 USD per troy oz (set from your pricing feed) +# +# Or set explicit troy ounces (skips USD math): +# TROY_OZ_CXAUC=1234.5 TROY_OZ_CXAUT=1234.5 +# +# DRY_RUN=1 print actions only +# SKIP_BURN=1 only mint (dangerous if balance nonzero) +# +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" +cd "$PROJECT_ROOT" +[ -f .env ] && set -a && source .env && set +a + +CXAUC="0x290E52a8819A4fbD0714E517225429aA2B70EC6b" +CXAUT="0x94e408E26c6FD8F4ee00b54dF19082FDA07dC96E" +RPC="${RPC_URL_138:-${RPC_URL:-http://192.168.11.211:8545}}" +GAS_LIMIT="${GAS_LIMIT:-200000}" + +RETARGET_USD="${RETARGET_USD:-50000000}" +RETARGET_MODE="${RETARGET_MODE:-split}" +XAU_SPOT_USD="${XAU_SPOT_USD:-4506.30}" + +[ -n "${PRIVATE_KEY:-}" ] || { echo "PRIVATE_KEY not set"; exit 1; } +DEPLOYER="$(cast wallet address "$PRIVATE_KEY")" || exit 1 + +balance_of() { + local token="$1" + local data raw + data="$(cast calldata "balanceOf(address)" "$DEPLOYER")" + raw="$(cast rpc eth_call "{\"to\":\"$token\",\"data\":\"$data\"}" latest --rpc-url "$RPC" | tr -d '\n\"')" + python3 -c "print(int('$raw', 16))" +} + +to_base_units() { + python3 -c " +from decimal import Decimal, ROUND_DOWN +import sys +oz = Decimal(sys.argv[1].strip()) +if oz <= 0: + sys.exit('troy oz must be positive') +b = (oz * Decimal(10**6)).to_integral_value(rounding=ROUND_DOWN) +print(int(b)) +" "$1" +} + +run_burn() { + local token="$1" label="$2" bal="$3" + [ "$bal" != "0" ] || { echo " $label: balance 0, skip burn"; return 0; } + if [ -n "${DRY_RUN:-}" ]; then + echo "[dry-run] burn $label balance=$bal" + return 0 + fi + cast send "$token" "burn(uint256)" "$bal" \ + --rpc-url "$RPC" --private-key "$PRIVATE_KEY" --legacy --gas-limit "$GAS_LIMIT" +} + +run_mint() { + local token="$1" label="$2" oz="$3" + local base + base="$(to_base_units "$oz")" + if [ -n "${DRY_RUN:-}" ]; then + echo "[dry-run] mint $label ${oz} oz -> $base base to $DEPLOYER" + return 0 + fi + cast send "$token" "mint(address,uint256)" "$DEPLOYER" "$base" \ + --rpc-url "$RPC" --private-key "$PRIVATE_KEY" --legacy --gas-limit "$GAS_LIMIT" +} + +if [ -n "${TROY_OZ_CXAUC:-}" ] && [ -n "${TROY_OZ_CXAUT:-}" ]; then + OZ_CXAUC="$TROY_OZ_CXAUC" + OZ_CXAUT="$TROY_OZ_CXAUT" +else + read -r OZ_CXAUC OZ_CXAUT < <(RETARGET_USD="$RETARGET_USD" RETARGET_MODE="$RETARGET_MODE" XAU_SPOT_USD="$XAU_SPOT_USD" python3 <<'PY' +import os +from decimal import Decimal, ROUND_DOWN +spot = Decimal(os.environ["XAU_SPOT_USD"]) +total = Decimal(os.environ["RETARGET_USD"]) +mode = os.environ.get("RETARGET_MODE", "split") +if spot <= 0 or total <= 0: + raise SystemExit("RETARGET_USD and XAU_SPOT_USD must be positive") +if mode == "split": + usd_c = total / Decimal(2) + usd_t = total / Decimal(2) +elif mode == "each": + usd_c = total + usd_t = total +else: + raise SystemExit("RETARGET_MODE must be split or each") +oz_c = (usd_c / spot).quantize(Decimal("0.000001"), rounding=ROUND_DOWN) +oz_t = (usd_t / spot).quantize(Decimal("0.000001"), rounding=ROUND_DOWN) +print(f"{oz_c:f} {oz_t:f}") +PY +) +fi + +echo "=== Reconcile cXAUC / cXAUT (deployer $DEPLOYER) ===" +echo " RPC: $RPC" +echo " Target: cXAUC=${OZ_CXAUC} oz cXAUT=${OZ_CXAUT} oz" +echo " (RETARGET_USD=$RETARGET_USD RETARGET_MODE=$RETARGET_MODE XAU_SPOT_USD=$XAU_SPOT_USD)" +echo "" + +BAL_C="$(balance_of "$CXAUC")" +BAL_T="$(balance_of "$CXAUT")" +echo " Current balances (base units): cXAUC=$BAL_C cXAUT=$BAL_T" + +if [ -z "${SKIP_BURN:-}" ]; then + echo "--- Burn ---" + run_burn "$CXAUC" "cXAUC" "$BAL_C" + run_burn "$CXAUT" "cXAUT" "$BAL_T" +else + echo "--- Skip burn (SKIP_BURN=1) ---" +fi + +echo "--- Mint ---" +run_mint "$CXAUC" "cXAUC" "$OZ_CXAUC" +run_mint "$CXAUT" "cXAUT" "$OZ_CXAUT" +echo "Done." diff --git a/scripts/reserve/keeper-service.js b/scripts/reserve/keeper-service.js index 0c790c0..f6e1689 100755 --- a/scripts/reserve/keeper-service.js +++ b/scripts/reserve/keeper-service.js @@ -25,7 +25,7 @@ const CONFIG = { rpcUrl: process.env.RPC_URL_138 || 'http://localhost:8545', keeperPrivateKey: process.env.KEEPER_PRIVATE_KEY, keeperAddress: process.env.PRICE_FEED_KEEPER_ADDRESS, - updateInterval: parseInt(process.env.UPDATE_INTERVAL || '30') * 1000, // Convert to milliseconds + updateInterval: parseInt(process.env.UPDATE_INTERVAL || '6') * 1000, // PMM mesh default cadence maxRetries: 3, retryDelay: 5000, // 5 seconds }; diff --git a/scripts/reserve/keeper-service.sh b/scripts/reserve/keeper-service.sh index c28819d..9927f80 100755 --- a/scripts/reserve/keeper-service.sh +++ b/scripts/reserve/keeper-service.sh @@ -12,7 +12,7 @@ fi # Configuration RPC_URL="${RPC_URL_138:-http://localhost:8545}" KEEPER_ADDRESS="${PRICE_FEED_KEEPER_ADDRESS}" -UPDATE_INTERVAL="${UPDATE_INTERVAL:-30}" # seconds +UPDATE_INTERVAL="${UPDATE_INTERVAL:-6}" # seconds (PMM mesh / peg tick cadence) MAX_RETRIES=3 # Colors for output diff --git a/scripts/reserve/pmm-mesh-6s-automation.sh b/scripts/reserve/pmm-mesh-6s-automation.sh new file mode 100755 index 0000000..739cc9f --- /dev/null +++ b/scripts/reserve/pmm-mesh-6s-automation.sh @@ -0,0 +1,169 @@ +#!/usr/bin/env bash +# Chain 138 PMM / oracle mesh tick — default every 6 seconds. +# Off-chain automation (systemd recommended). Keeps oracle + PriceFeedKeeper aligned with +# DODOPMMIntegration / ReserveSystem reads; optional WETH/ETH polling for mesh depth signals. +# +# Env (smom-dbis-138/.env or parent load-project-env): +# PMM_MESH_INTERVAL_SEC=6 Sleep between ticks +# RPC_URL_138 / RPC_URL +# PRIVATE_KEY or DEPLOYER_PRIVATE_KEY — ETH/USD oracle push (update-oracle-price.sh) +# KEEPER_PRIVATE_KEY + PRICE_FEED_KEEPER_ADDRESS — on-chain keeper performUpkeep when needed +# DODO_PMM_INTEGRATION_ADDRESS — default 0x5BDc… (current canonical integration) +# PMM_MESH_POLL_POOLS — space-separated pool addresses (default: cUSDT/cUSDC PMM pool) +# ENABLE_MESH_ORACLE_TICK=1 Run scripts/update-oracle-price.sh each tick (skips on-chain if <1% move) +# ENABLE_MESH_KEEPER_TICK=1 Run keeper when checkUpkeep is true +# ENABLE_MESH_PMM_READS=1 eth_call getPoolPriceOrOracle per pool (warm path / observability) +# ENABLE_MESH_WETH_READS=1 eth_call WETH9/WETH10 totalSupply (ETH mesh signal) +# MESH_WETH_WRAP_WEI=0 If >0 and KEEPER_PRIVATE_KEY set: WETH9.deposit{value} (costs gas; rare) +# MESH_WETH_WRAP_EVERY_N=60 Only wrap every N ticks when MESH_WETH_WRAP_WEI>0 +# MAX_TICKS= Exit after N ticks (empty = run forever) +# DRY_RUN=1 Log only, no txs +# +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SMOM_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +cd "$SMOM_ROOT" + +if [ -f "$SMOM_ROOT/.env" ]; then + set -a + # shellcheck source=/dev/null + source "$SMOM_ROOT/.env" + set +a +fi + +# Proxmox repo root .env (parent of smom-dbis-138) if key not in submodule .env +REPO_ROOT="$(cd "$SMOM_ROOT/.." && pwd)" +if [ -z "${PRIVATE_KEY:-}" ] && [ -f "$REPO_ROOT/.env" ]; then + set -a + # shellcheck source=/dev/null + source "$REPO_ROOT/.env" 2>/dev/null || true + set +a +fi + +RPC="${RPC_URL_138:-${RPC_URL:-http://192.168.11.211:8545}}" +INTERVAL="${PMM_MESH_INTERVAL_SEC:-6}" +DODO="${DODO_PMM_INTEGRATION_ADDRESS:-${DODO_PMM_INTEGRATION:-0x5BDc62f1ae7D630c37A8B363a1d49845356Ee72d}}" +# Canonical cUSDT/cUSDC PMM pool on Chain 138 (current integration) +DEFAULT_POOLS="0xff8d3b8fDF7B112759F076B69f4271D4209C0849" +POOLS="${PMM_MESH_POLL_POOLS:-$DEFAULT_POOLS}" +WETH9="${WETH9_ADDRESS:-0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2}" +WETH10="${WETH10_ADDRESS:-0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f}" + +ENABLE_ORACLE="${ENABLE_MESH_ORACLE_TICK:-1}" +ENABLE_KEEPER="${ENABLE_MESH_KEEPER_TICK:-1}" +ENABLE_PMM_READS="${ENABLE_MESH_PMM_READS:-1}" +ENABLE_WETH_READS="${ENABLE_MESH_WETH_READS:-1}" +WRAP_WEI="${MESH_WETH_WRAP_WEI:-0}" +WRAP_EVERY_N="${MESH_WETH_WRAP_EVERY_N:-60}" +# Besu often needs an explicit gas price for replacement / mempool policy. +MESH_CAST_GAS_PRICE="${MESH_CAST_GAS_PRICE:-2gwei}" + +ORACLE_PK="${PRIVATE_KEY:-${DEPLOYER_PRIVATE_KEY:-}}" +KEEPER_PK="${KEEPER_PRIVATE_KEY:-${PRIVATE_KEY:-}}" + +log() { echo "[$(date -Iseconds)] $*"; } + +eth_call_price() { + local to="$1" data="$2" + cast rpc eth_call "{\"to\":\"$to\",\"data\":\"$data\"}" latest --rpc-url "$RPC" 2>/dev/null | tr -d '\n\"' || true +} + +tick_pmm_reads() { + [ "$ENABLE_PMM_READS" = "1" ] || return 0 + [ -n "$DODO" ] || return 0 + for pool in $POOLS; do + [ "$pool" = "0x0000000000000000000000000000000000000000" ] && continue + data=$(cast calldata "getPoolPriceOrOracle(address)" "$pool" 2>/dev/null) || continue + out=$(eth_call_price "$DODO" "$data") + if [ -n "$out" ]; then + log "PMM getPoolPriceOrOracle($pool) -> $out" + fi + done +} + +tick_weth_reads() { + [ "$ENABLE_WETH_READS" = "1" ] || return 0 + for w in "$WETH9" "$WETH10"; do + data=$(cast calldata "totalSupply()" 2>/dev/null) || continue + out=$(eth_call_price "$w" "$data") + if [ -n "$out" ]; then + log "WETH totalSupply($w) raw -> $out" + fi + done +} + +tick_keeper() { + [ "$ENABLE_KEEPER" = "1" ] || return 0 + local k="${PRICE_FEED_KEEPER_ADDRESS:-}" + [ -n "$k" ] && [ -n "$KEEPER_PK" ] || { log "keeper tick skipped (set PRICE_FEED_KEEPER_ADDRESS + KEEPER_PRIVATE_KEY)"; return 0; } + local raw dec first + raw="$(cast rpc eth_call "{\"to\":\"$k\",\"data\":\"$(cast calldata "checkUpkeep()")\"}" latest --rpc-url "$RPC" 2>/dev/null | tr -d '\n\"')" || return 0 + dec="$(cast abi-decode "checkUpkeep()(bool,address[])" "$raw" 2>/dev/null)" || return 0 + first=$(echo "$dec" | head -1) + if [ "$first" = "true" ]; then + log "keeper checkUpkeep=true; performUpkeep" + if [ -n "${DRY_RUN:-}" ]; then + log "[dry-run] cast send performUpkeep" + return 0 + fi + if ! cast send "$k" "performUpkeep()" --rpc-url "$RPC" --private-key "$KEEPER_PK" \ + --legacy --gas-limit 500000 --gas-price "$MESH_CAST_GAS_PRICE"; then + log "WARN: performUpkeep failed (RPC / gas / nonce); next tick in ${INTERVAL}s" + fi + else + log "keeper checkUpkeep=false (no tx)" + fi +} + +tick_oracle() { + [ "$ENABLE_ORACLE" = "1" ] || return 0 + [ -n "$ORACLE_PK" ] || { log "oracle tick skipped (set PRIVATE_KEY)"; return 0; } + if [ -n "${DRY_RUN:-}" ]; then + log "[dry-run] update-oracle-price.sh" + return 0 + fi + # Exits 0 when price unchanged (<1%) or on success; failures must not stop the loop + if ! bash "$SMOM_ROOT/scripts/update-oracle-price.sh" "$RPC"; then + log "WARN: update-oracle-price.sh failed (rate limit / RPC / gas); next tick in ${INTERVAL}s" + fi +} + +tick_weth_wrap() { + (( ${WRAP_WEI:-0} > 0 )) || return 0 + [ -n "$KEEPER_PK" ] || { log "WETH wrap skipped (no KEEPER_PRIVATE_KEY)"; return 0; } + local n="${TICK_COUNT:-0}" + [ "$WRAP_EVERY_N" -gt 0 ] || WRAP_EVERY_N=1 + if (( n % WRAP_EVERY_N != 0 )); then + return 0 + fi + log "WETH9.deposit value=$WRAP_WEI wei (mesh activity)" + if [ -n "${DRY_RUN:-}" ]; then + log "[dry-run] cast send deposit" + return 0 + fi + if ! cast send "$WETH9" "deposit()" --value "$WRAP_WEI" --rpc-url "$RPC" --private-key "$KEEPER_PK" \ + --legacy --gas-limit 150000 --gas-price "$MESH_CAST_GAS_PRICE"; then + log "WARN: WETH9.deposit failed; next tick in ${INTERVAL}s" + fi +} + +TICK_COUNT=0 +log "=== PMM mesh automation === interval=${INTERVAL}s RPC=$RPC" +log "DODO=$DODO pools=$POOLS" + +while true; do + TICK_COUNT=$((TICK_COUNT + 1)) + log "--- tick $TICK_COUNT ---" + tick_pmm_reads + tick_weth_reads + tick_keeper + tick_oracle + tick_weth_wrap + + if [ -n "${MAX_TICKS:-}" ] && [ "$TICK_COUNT" -ge "$MAX_TICKS" ]; then + log "MAX_TICKS=$MAX_TICKS reached, exit" + break + fi + sleep "$INTERVAL" +done diff --git a/scripts/reserve/set-price-feed-keeper-interval.sh b/scripts/reserve/set-price-feed-keeper-interval.sh new file mode 100755 index 0000000..7a1f933 --- /dev/null +++ b/scripts/reserve/set-price-feed-keeper-interval.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# One-shot: set PriceFeedKeeper.updateInterval to match PMM mesh cadence (default 6 seconds). +# Caller must hold DEFAULT_ADMIN_ROLE on the keeper. +# +# Usage: +# ./scripts/reserve/set-price-feed-keeper-interval.sh [seconds] +# Env: PRICE_FEED_KEEPER_ADDRESS, PRIVATE_KEY (admin), RPC_URL_138 +# +set -euo pipefail +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$(cd "$SCRIPT_DIR/../.." && pwd)" +[ -f .env ] && set -a && source .env && set +a + +SEC="${1:-6}" +K="${PRICE_FEED_KEEPER_ADDRESS:-}" +RPC="${RPC_URL_138:-${RPC_URL:-http://192.168.11.211:8545}}" +PK="${PRIVATE_KEY:-}" + +[ -n "$K" ] || { echo "PRICE_FEED_KEEPER_ADDRESS required"; exit 1; } +[ -n "$PK" ] || { echo "PRIVATE_KEY required (admin on keeper)"; exit 1; } + +echo "Setting PriceFeedKeeper $K updateInterval to ${SEC}s" +cast send "$K" "setUpdateInterval(uint256)" "$SEC" \ + --rpc-url "$RPC" --private-key "$PK" --legacy --gas-limit 120000 +echo "Done." diff --git a/scripts/reserve/sync-weth-mock-price.sh b/scripts/reserve/sync-weth-mock-price.sh new file mode 100755 index 0000000..06d04c4 --- /dev/null +++ b/scripts/reserve/sync-weth-mock-price.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +# Push ETH/USD into the on-chain WETH MockPriceFeed used by OraclePriceFeed / PriceFeedKeeper +# (avoids Besu vs aggregator updatedAt skew on the public ETH/USD aggregator). +# +# Env: smom-dbis-138/.env — RPC_URL_138, PRIVATE_KEY, optional CHAIN138_WETH_MOCK_PRICE_FEED, +# COINGECKO_API_KEY (Pro URL + header when set). +# Usage: ./scripts/reserve/sync-weth-mock-price.sh [rpc-url] + +set -euo pipefail +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SMOM_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +cd "$SMOM_ROOT" + +if [ -f "$SMOM_ROOT/.env" ]; then + set -a + # shellcheck source=/dev/null + source "$SMOM_ROOT/.env" + set +a +fi + +RPC="${1:-${RPC_URL_138:-${RPC_URL:-http://192.168.11.211:8545}}}" +MOCK="${CHAIN138_WETH_MOCK_PRICE_FEED:-0x3e8725b8De386feF3eFE5678c92eA6aDB41992B2}" +CG_UA="${COINGECKO_USER_AGENT:-proxmox-chain138-oracle/1.0 (dbis-138)}" + +if [ -z "${PRIVATE_KEY:-}" ]; then + echo "ERROR: PRIVATE_KEY required" >&2 + exit 1 +fi + +fetch_usd() { + local u="0" + if [ -n "${COINGECKO_API_KEY:-}" ]; then + u=$(curl -s --max-time 20 -A "$CG_UA" -H "x-cg-demo-api-key: $COINGECKO_API_KEY" \ + 'https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd' | \ + python3 -c "import sys, json; d=json.load(sys.stdin); print(d.get('ethereum',{}).get('usd',0) or 0)" 2>/dev/null || echo 0) + fi + if { [ "$u" = "0" ] || [ -z "$u" ]; } && [ -n "${COINGECKO_API_KEY:-}" ]; then + u=$(curl -s --max-time 20 -A "$CG_UA" -H "x-cg-pro-api-key: $COINGECKO_API_KEY" \ + 'https://pro-api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd' | \ + python3 -c "import sys, json; d=json.load(sys.stdin); print(d.get('ethereum',{}).get('usd',0) or 0)" 2>/dev/null || echo 0) + fi + if [ "$u" = "0" ] || [ -z "$u" ]; then + u=$(curl -s --max-time 20 -A "$CG_UA" 'https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd' | \ + python3 -c "import sys, json; d=json.load(sys.stdin); print(d.get('ethereum',{}).get('usd',0) or 0)" 2>/dev/null || echo 0) + fi + echo "$u" +} + +USD="$(fetch_usd)" +if [ "$(python3 -c "print(1 if float('$USD')>0 else 0)" 2>/dev/null || echo 0)" != 1 ]; then + echo "WARN: CoinGecko failed, trying Binance..." >&2 + USD=$(curl -s 'https://api.binance.com/api/v3/ticker/price?symbol=ETHUSDT' | \ + python3 -c "import sys, json; print(json.load(sys.stdin).get('price',0) or 0)" 2>/dev/null || echo 0) +fi + +PRICE_I256="$(python3 -c "u=float('$USD'); print(int(round(u*1e8)))")" +if [ "$PRICE_I256" -le 0 ]; then + echo "ERROR: invalid ETH price: $USD" >&2 + exit 1 +fi + +echo "Mock $MOCK updatePrice(int256) = $PRICE_I256 (8 dec; USD ~ $USD)" +cast send "$MOCK" "updatePrice(int256)" "$PRICE_I256" \ + --rpc-url "$RPC" \ + --private-key "$PRIVATE_KEY" \ + --legacy \ + --gas-limit 200000 \ + --gas-price "${MESH_CAST_GAS_PRICE:-2gwei}" diff --git a/scripts/setup-dodo-pools.sh b/scripts/setup-dodo-pools.sh index 70f0b9c..8b67f51 100755 --- a/scripts/setup-dodo-pools.sh +++ b/scripts/setup-dodo-pools.sh @@ -4,8 +4,14 @@ set -euo pipefail +hex_to_addr() { + local value="${1#0x}" + [[ ${#value} -ge 40 ]] || return 1 + printf '0x%s\n' "${value: -40}" +} + SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" # Colors RED='\033[0;31m' @@ -19,19 +25,22 @@ log_success() { echo -e "${GREEN}[✓]${NC} $1"; } log_warn() { echo -e "${YELLOW}[⚠]${NC} $1"; } log_error() { echo -e "${RED}[✗]${NC} $1"; } -# Load environment variables -if [ -f "$PROJECT_ROOT/.env" ]; then - source "$PROJECT_ROOT/.env" -elif [ -f "$PROJECT_ROOT/smom-dbis-138/.env" ]; then - source "$PROJECT_ROOT/smom-dbis-138/.env" +if [[ -f "$SCRIPT_DIR/lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/lib/deployment/dotenv.sh" + load_deployment_env --repo-root "$PROJECT_ROOT" +elif [ -f "$PROJECT_ROOT/.env" ]; then + set -a && source "$PROJECT_ROOT/.env" && set +a fi -RPC_URL="${RPC_URL:-${RPC_URL_138:-http://192.168.11.250:8545}}" +RPC_URL="${RPC_URL:-${RPC_URL_138:-http://192.168.11.211:8545}}" +RPC_URL="${RPC_URL%$'\r'}" +RPC_URL="${RPC_URL%$'\n'}" INTEGRATION_ADDRESS="${DODO_PMM_INTEGRATION_ADDRESS:-}" COMPLIANT_USDT="${COMPLIANT_USDT_ADDRESS:-0x93E66202A11B1772E55407B32B44e5Cd8eda7f22}" COMPLIANT_USDC="${COMPLIANT_USDC_ADDRESS:-0xf22258f57794CC8E06237084b353Ab30fFfa640b}" -OFFICIAL_USDT="${OFFICIAL_USDT_ADDRESS:-}" -OFFICIAL_USDC="${OFFICIAL_USDC_ADDRESS:-}" +OFFICIAL_USDT="${OFFICIAL_USDT_ADDRESS:-0x004b63A7B5b0E06f6bB6adb4a5F9f590BF3182D1}" +OFFICIAL_USDC="${OFFICIAL_USDC_ADDRESS:-0x71D6687F38b93CCad569Fa6352c876eea967201b}" if [ -z "$INTEGRATION_ADDRESS" ]; then log_error "DODO_PMM_INTEGRATION_ADDRESS not set" @@ -68,8 +77,8 @@ log_info " TWAP Enabled: $ENABLE_TWAP" log_info "" # Check if pools already exist -USDT_POOL=$(cast call "$INTEGRATION_ADDRESS" "pools(address,address)" "$COMPLIANT_USDT" "$OFFICIAL_USDT" --rpc-url "$RPC_URL" 2>/dev/null | cast --to-addr 2>/dev/null || echo "") -USDC_POOL=$(cast call "$INTEGRATION_ADDRESS" "pools(address,address)" "$COMPLIANT_USDC" "$OFFICIAL_USDC" --rpc-url "$RPC_URL" 2>/dev/null | cast --to-addr 2>/dev/null || echo "") +USDT_POOL=$(cast call "$INTEGRATION_ADDRESS" "pools(address,address)" "$COMPLIANT_USDT" "$OFFICIAL_USDT" --rpc-url "$RPC_URL" 2>/dev/null | while read -r raw; do hex_to_addr "$raw" 2>/dev/null || true; done) +USDC_POOL=$(cast call "$INTEGRATION_ADDRESS" "pools(address,address)" "$COMPLIANT_USDC" "$OFFICIAL_USDC" --rpc-url "$RPC_URL" 2>/dev/null | while read -r raw; do hex_to_addr "$raw" 2>/dev/null || true; done) if [ "$USDT_POOL" != "0x0000000000000000000000000000000000000000" ] && [ -n "$USDT_POOL" ]; then log_warn "USDT pool already exists: $USDT_POOL" @@ -89,7 +98,7 @@ else --legacy \ -vv - USDT_POOL=$(cast call "$INTEGRATION_ADDRESS" "pools(address,address)" "$COMPLIANT_USDT" "$OFFICIAL_USDT" --rpc-url "$RPC_URL" 2>/dev/null | cast --to-addr 2>/dev/null || echo "") + USDT_POOL=$(cast call "$INTEGRATION_ADDRESS" "pools(address,address)" "$COMPLIANT_USDT" "$OFFICIAL_USDT" --rpc-url "$RPC_URL" 2>/dev/null | while read -r raw; do hex_to_addr "$raw" 2>/dev/null || true; done) log_success "USDT pool created: $USDT_POOL" fi @@ -111,7 +120,7 @@ else --legacy \ -vv - USDC_POOL=$(cast call "$INTEGRATION_ADDRESS" "pools(address,address)" "$COMPLIANT_USDC" "$OFFICIAL_USDC" --rpc-url "$RPC_URL" 2>/dev/null | cast --to-addr 2>/dev/null || echo "") + USDC_POOL=$(cast call "$INTEGRATION_ADDRESS" "pools(address,address)" "$COMPLIANT_USDC" "$OFFICIAL_USDC" --rpc-url "$RPC_URL" 2>/dev/null | while read -r raw; do hex_to_addr "$raw" 2>/dev/null || true; done) log_success "USDC pool created: $USDC_POOL" fi @@ -128,4 +137,3 @@ log_info "" log_info "For PMM coverage of all tokens (chain 138/651940), use:" log_info " scripts/create-all-dodo-pools-from-token-api.sh" log_info " (requires TOKEN_AGGREGATION_API_URL, CHAIN_ID, QUOTE_TOKEN_ADDRESS, DODO_PMM_INTEGRATION_ADDRESS, ENHANCED_SWAP_ROUTER_ADDRESS, UNIVERSAL_ASSET_REGISTRY_ADDRESS)" - diff --git a/scripts/setup-reserve-vault.sh b/scripts/setup-reserve-vault.sh index bf203be..b165833 100755 --- a/scripts/setup-reserve-vault.sh +++ b/scripts/setup-reserve-vault.sh @@ -5,7 +5,7 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" # Colors RED='\033[0;31m' @@ -19,14 +19,17 @@ log_success() { echo -e "${GREEN}[✓]${NC} $1"; } log_warn() { echo -e "${YELLOW}[⚠]${NC} $1"; } log_error() { echo -e "${RED}[✗]${NC} $1"; } -# Load environment variables -if [ -f "$PROJECT_ROOT/.env" ]; then - source "$PROJECT_ROOT/.env" -elif [ -f "$PROJECT_ROOT/smom-dbis-138/.env" ]; then - source "$PROJECT_ROOT/smom-dbis-138/.env" +if [[ -f "$SCRIPT_DIR/lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/lib/deployment/dotenv.sh" + load_deployment_env --repo-root "$PROJECT_ROOT" +elif [ -f "$PROJECT_ROOT/.env" ]; then + set -a && source "$PROJECT_ROOT/.env" && set +a fi -RPC_URL="${RPC_URL:-${ETH_MAINNET_RPC_URL:-}}" +RPC_URL="${RPC_URL:-${ETHEREUM_MAINNET_RPC:-${ETH_MAINNET_RPC_URL:-}}}" +RPC_URL="${RPC_URL%$'\r'}" +RPC_URL="${RPC_URL%$'\n'}" VAULT_ADDRESS="${STABLECOIN_RESERVE_VAULT_ADDRESS:-}" OFFICIAL_USDT="${OFFICIAL_USDT_ADDRESS:-0xdAC17F958D2ee523a2206206994597C13D831ec7}" OFFICIAL_USDC="${OFFICIAL_USDC_ADDRESS:-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48}" diff --git a/scripts/sync-weth10-genesis-bytecode.py b/scripts/sync-weth10-genesis-bytecode.py new file mode 100755 index 0000000..2d40081 --- /dev/null +++ b/scripts/sync-weth10-genesis-bytecode.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python3 +""" +Re-embed WETH10 runtime bytecode in genesis JSON files from the current +contracts/tokens/WETH10.sol build (Foundry solc 0.8.20 + foundry.toml). + +Run from repo: python3 smom-dbis-138/scripts/sync-weth10-genesis-bytecode.py + +Live Chain 138 nodes must NOT replace genesis.json in place (different genesis += fork). Use this for new networks, templates, and Blockscout verification +alignment with the submodule source. +""" +from __future__ import annotations + +import json +import subprocess +import sys +from pathlib import Path + +WETH10 = "0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f" +SMOM = Path(__file__).resolve().parent.parent +ROOT = SMOM.parent + +GENESIS_FILES = [ + SMOM / "config" / "genesis.json", + ROOT / "smom-dbis-138-proxmox" / "config" / "genesis.json", + SMOM / "terraform" / "phases" / "phase1" / "config" / "genesis-138.json", +] +TEMPLATE = SMOM / "config" / "genesis-template-for-operator.json" + + +def forge_deployed_bytecode() -> str: + out = subprocess.check_output( + [ + "forge", + "inspect", + "contracts/tokens/WETH10.sol:WETH10", + "deployedBytecode", + ], + cwd=str(SMOM), + text=True, + ).strip() + if not out.startswith("0x"): + raise SystemExit(f"unexpected forge output: {out[:80]}...") + return out + + +def patch_alloc(alloc: dict, code: str) -> None: + key = next((k for k in alloc if k.lower() == WETH10.lower()), None) + if not key: + raise SystemExit(f"alloc missing WETH10 ({WETH10})") + entry = alloc[key] + entry["code"] = code + if "storage" not in entry: + entry["storage"] = {} + + +def main() -> int: + code = forge_deployed_bytecode() + for path in GENESIS_FILES: + if not path.is_file(): + print(f"skip (missing): {path}", file=sys.stderr) + continue + data = json.loads(path.read_text()) + patch_alloc(data["alloc"], code) + path.write_text(json.dumps(data, indent=2) + "\n") + print(f"updated {path}") + + if TEMPLATE.is_file(): + data = json.loads(TEMPLATE.read_text()) + g = data.get("genesis") or data + alloc = g.get("alloc") + if not alloc: + raise SystemExit("template: no genesis.alloc") + patch_alloc(alloc, code) + TEMPLATE.write_text(json.dumps(data, indent=2) + "\n") + print(f"updated {TEMPLATE}") + + print(f"WETH10 code length: {len(code)} chars (solc tail matches 0.8.x)") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/update-oracle-price.sh b/scripts/update-oracle-price.sh index 0aee081..cd74147 100755 --- a/scripts/update-oracle-price.sh +++ b/scripts/update-oracle-price.sh @@ -76,15 +76,49 @@ if ! curl -s -X POST -H "Content-Type: application/json" \ fi log_success "RPC is accessible" -# Fetch current ETH price from CoinGecko +# Besu / some nodes reject typed `cast call`; use eth_call + calldata. +eth_call_raw() { + local to="$1" + local sig="$2" + shift 2 + local data + data=$(cast calldata "$sig" "$@") || return 1 + cast rpc eth_call "{\"to\":\"$to\",\"data\":\"$data\"}" latest --rpc-url "$RPC_URL" 2>/dev/null | tr -d '\n\"' || true +} + +abi_decode_bool() { + local h="${1:-0x0}" + python3 -c "x=int('${h}',16); print('true' if x else 'false')" +} + +# Fetch ETH/USD: try Pro API when key is set; fall back to public CoinGecko if Pro errors or rate-limits. +# CoinGecko may 429 without a descriptive User-Agent when many requests share an IP. +CG_UA="${COINGECKO_USER_AGENT:-proxmox-chain138-oracle/1.0 (dbis-138)}" log_info "Fetching ETH/USD price from CoinGecko..." -ETH_PRICE=$(curl -s 'https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd' | \ - python3 -c "import sys, json; data = json.load(sys.stdin); print(data.get('ethereum', {}).get('usd', '0'))" 2>/dev/null || echo "0") +ETH_PRICE="0" +# Demo keys: api.coingecko.com + x-cg-demo-api-key. Paid Pro: pro-api.coingecko.com + x-cg-pro-api-key. +if [ -n "${COINGECKO_API_KEY:-}" ]; then + ETH_PRICE=$(curl -s --max-time 20 -A "$CG_UA" -H "x-cg-demo-api-key: $COINGECKO_API_KEY" \ + 'https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd' | \ + python3 -c "import sys, json; data = json.load(sys.stdin); print(data.get('ethereum', {}).get('usd', '0'))" 2>/dev/null || echo "0") +fi +if [ "$ETH_PRICE" = "0" ] || [ -z "$ETH_PRICE" ]; then + if [ -n "${COINGECKO_API_KEY:-}" ]; then + ETH_PRICE=$(curl -s --max-time 20 -A "$CG_UA" -H "x-cg-pro-api-key: $COINGECKO_API_KEY" \ + 'https://pro-api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd' | \ + python3 -c "import sys, json; data = json.load(sys.stdin); print(data.get('ethereum', {}).get('usd', '0'))" 2>/dev/null || echo "0") + fi +fi +if [ "$ETH_PRICE" = "0" ] || [ -z "$ETH_PRICE" ]; then + log_info "Authenticated CoinGecko unset or returned no price; trying public CoinGecko..." + ETH_PRICE=$(curl -s --max-time 20 -A "$CG_UA" 'https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd' | \ + python3 -c "import sys, json; data = json.load(sys.stdin); print(data.get('ethereum', {}).get('usd', '0'))" 2>/dev/null || echo "0") +fi if [ "$ETH_PRICE" = "0" ] || [ -z "$ETH_PRICE" ]; then log_error "Failed to fetch ETH price from CoinGecko" log_info "Trying Binance API as fallback..." - ETH_PRICE=$(curl -s 'https://api.binance.com/api/v3/ticker/price?symbol=ETHUSDT' | \ + ETH_PRICE=$(curl -s --max-time 20 'https://api.binance.com/api/v3/ticker/price?symbol=ETHUSDT' | \ python3 -c "import sys, json; data = json.load(sys.stdin); print(data.get('price', '0'))" 2>/dev/null || echo "0") fi @@ -106,40 +140,35 @@ PYEOF log_info "Price in 8 decimals: $PRICE_DECIMALS" echo "" -# Check current oracle price -log_info "Checking current oracle price..." -CURRENT_ORACLE_DATA=$(cast call "$ORACLE_ADDRESS" \ - "latestRoundData()" \ - --rpc-url "$RPC_URL" 2>/dev/null || echo "") +# Latest round: prefer aggregator (proxy at ORACLE_ADDRESS often returns empty on Besu) +LR_READ_CONTRACT="${ORACLE_LATEST_ROUND_CONTRACT:-$AGGREGATOR_ADDRESS}" -if [ -n "$CURRENT_ORACLE_DATA" ] && [ "$CURRENT_ORACLE_DATA" != "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" ]; then - # Parse current price - CURRENT_ANSWER=$(echo "$CURRENT_ORACLE_DATA" | cut -c 131-194) # Extract answer field - CURRENT_PRICE=$(python3 << PYEOF -answer_hex = "$CURRENT_ANSWER" -answer_int = int(answer_hex, 16) -# Handle negative (if signed) -if answer_int > 2**255: - answer_int = answer_int - 2**256 -price = answer_int / 100000000 -print(price) -PYEOF -) - log_info "Current oracle price: \$$(printf '%.2f' $CURRENT_PRICE)" - - # Check if update is needed (only update if difference > 1%) - PRICE_DIFF=$(python3 << PYEOF -current = float("$CURRENT_PRICE") -new = float("$ETH_PRICE") -diff = abs(new - current) / current * 100 -print(diff) -PYEOF -) - - if (( $(echo "$PRICE_DIFF < 1" | bc -l) )); then - log_warn "Price difference is less than 1% (${PRICE_DIFF}%)" - log_info "Skipping update to save gas" - exit 0 +# Check current oracle price (eth_call — Besu-safe) +log_info "Checking current oracle price (source $LR_READ_CONTRACT)..." +LR_RAW="$(eth_call_raw "$LR_READ_CONTRACT" "latestRoundData()")" +CURRENT_ORACLE_DATA="" +if [ -n "$LR_RAW" ] && [ "$LR_RAW" != "0x" ]; then + read -r LR_ROUND LR_ANS_INT <<< "$(python3 -c " +raw = '$LR_RAW'.lower().replace('0x', '') +if len(raw) < 128: + print('0 0') + raise SystemExit(0) +rid = int(raw[0:64], 16) +ans = int(raw[64:128], 16) +if ans >= 2**255: + ans -= 2**256 +print(rid, ans) +")" + if [ "${LR_ROUND:-0}" != "0" ] || [ "${LR_ANS_INT:-0}" != "0" ]; then + CURRENT_ORACLE_DATA="$LR_RAW" + CURRENT_PRICE=$(python3 -c "print(${LR_ANS_INT:-0} / 100000000.0)") + log_info "Current oracle price: \$$(printf '%.2f' "$CURRENT_PRICE")" + PRICE_DIFF=$(python3 -c "c=float('$CURRENT_PRICE'); n=float('$ETH_PRICE'); print(abs(n-c)/c*100 if c else 999)") + if python3 -c "import sys; sys.exit(0 if float('$PRICE_DIFF') < 1 else 1)"; then + log_warn "Price difference is less than 1% (${PRICE_DIFF}%)" + log_info "Skipping update to save gas" + exit 0 + fi fi fi @@ -165,7 +194,8 @@ if [ -n "$PRIVATE_KEY" ]; then DEPLOYER_ADDR=$(cast wallet address --private-key "$PRIVATE_KEY" 2>/dev/null || echo "") if [ -n "$DEPLOYER_ADDR" ]; then log_info "Checking transmitter authorization..." - IS_TRANSMITTER=$(timeout 10 cast call "$AGGREGATOR_ADDRESS" "isTransmitter(address)(bool)" "$DEPLOYER_ADDR" --rpc-url "$RPC_URL" 2>/dev/null || echo "false") + TXRAW="$(eth_call_raw "$AGGREGATOR_ADDRESS" "isTransmitter(address)" "$DEPLOYER_ADDR")" + IS_TRANSMITTER="$(abi_decode_bool "${TXRAW:-0x0}")" if [ "$IS_TRANSMITTER" != "true" ]; then log_warn "Account $DEPLOYER_ADDR is NOT an authorized transmitter" log_info "Oracle requires transmitter role to update prices" @@ -177,7 +207,11 @@ if [ -n "$PRIVATE_KEY" ]; then log_info "Checking for transmitter addresses..." TX_COUNT=0 for i in 0 1 2 3 4 5; do - TX_ADDR=$(timeout 10 cast call "$AGGREGATOR_ADDRESS" "transmitters(uint256)(address)" "$i" --rpc-url "$RPC_URL" 2>/dev/null || echo "") + TRAW="$(eth_call_raw "$AGGREGATOR_ADDRESS" "transmitters(uint256)" "$i")" + TX_ADDR="" + if [ -n "$TRAW" ] && [ "$TRAW" != "0x" ]; then + TX_ADDR="$(TRAW="$TRAW" python3 -c "import os; h=os.environ['TRAW'].lower().replace('0x',''); print(('0x'+h[-40:]) if len(h)>=40 else '')")" + fi if [ -n "$TX_ADDR" ] && [ "$TX_ADDR" != "0x0000000000000000000000000000000000000000" ]; then log_info " Transmitter $TX_COUNT: $TX_ADDR" TX_COUNT=$((TX_COUNT + 1)) @@ -197,20 +231,24 @@ fi UPDATE_CONTRACT="$AGGREGATOR_ADDRESS" log_info "Updating aggregator contract: $UPDATE_CONTRACT" -# Send transaction (with timeout) +# Send transaction (with timeout). Do not use `set -e` inside $() — capture status explicitly. log_info "Sending transaction to aggregator (this may take 30-60 seconds)..." +GAS_PRICE_WEI="${ORACLE_UPDATE_GAS_PRICE_WEI:-1000000000}" +GAS_LIMIT_ORACLE="${ORACLE_UPDATE_GAS_LIMIT:-400000}" +set +e TX_OUTPUT=$(timeout 90 cast send "$UPDATE_CONTRACT" \ "$UPDATE_METHOD(uint256)" \ "$PRICE_DECIMALS" \ --rpc-url "$RPC_URL" \ --private-key "$PRIVATE_KEY" \ --legacy \ - --gas-price 20000000000 \ + --gas-price "$GAS_PRICE_WEI" \ + --gas-limit "$GAS_LIMIT_ORACLE" \ 2>&1) - -# Check if transaction was sent -if [ $? -ne 0 ]; then - log_error "Transaction failed or timed out" +TX_STAT=$? +set -e +if [ "$TX_STAT" -ne 0 ]; then + log_error "Transaction failed or timed out (exit $TX_STAT)" echo "$TX_OUTPUT" exit 1 fi @@ -250,21 +288,21 @@ sleep 5 # Verify update log_info "Verifying oracle update..." -NEW_ORACLE_DATA=$(cast call "$ORACLE_ADDRESS" \ - "latestRoundData()" \ - --rpc-url "$RPC_URL" 2>/dev/null || echo "") +NEW_LR="$(eth_call_raw "$LR_READ_CONTRACT" "latestRoundData()")" +NEW_ORACLE_DATA="$NEW_LR" -if [ -n "$NEW_ORACLE_DATA" ]; then - NEW_ANSWER=$(echo "$NEW_ORACLE_DATA" | cut -c 131-194) - NEW_PRICE=$(python3 << PYEOF -answer_hex = "$NEW_ANSWER" -answer_int = int(answer_hex, 16) -if answer_int > 2**255: - answer_int = answer_int - 2**256 -price = answer_int / 100000000 -print(price) -PYEOF -) +if [ -n "$NEW_ORACLE_DATA" ] && [ "$NEW_ORACLE_DATA" != "0x" ]; then + read -r _ NEW_ANS_INT <<< "$(python3 -c " +raw = '$NEW_LR'.lower().replace('0x', '') +if len(raw) < 128: + print('0 0') + raise SystemExit(0) +ans = int(raw[64:128], 16) +if ans >= 2**255: + ans -= 2**256 +print(0, ans) +")" + NEW_PRICE=$(python3 -c "print(${NEW_ANS_INT:-0} / 100000000.0)") log_success "Oracle updated successfully!" log_info "New oracle price: \$$(printf '%.2f' $NEW_PRICE)" else diff --git a/scripts/verify-bridge-prerequisites.sh b/scripts/verify-bridge-prerequisites.sh index bfbc242..56efd1c 100755 --- a/scripts/verify-bridge-prerequisites.sh +++ b/scripts/verify-bridge-prerequisites.sh @@ -3,16 +3,19 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" -# Load environment -if [ -f "$PROJECT_ROOT/.env" ]; then - source "$PROJECT_ROOT/.env" -elif [ -f "$PROJECT_ROOT/smom-dbis-138/.env" ]; then - source "$PROJECT_ROOT/smom-dbis-138/.env" +if [[ -f "$SCRIPT_DIR/lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/lib/deployment/dotenv.sh" + load_deployment_env --repo-root "$PROJECT_ROOT" +elif [ -f "$PROJECT_ROOT/.env" ]; then + set -a && source "$PROJECT_ROOT/.env" && set +a fi -RPC_URL="${RPC_URL:-${RPC_URL_138:-http://192.168.11.250:8545}}" +RPC_URL="${RPC_URL:-${RPC_URL_138:-http://192.168.11.211:8545}}" +RPC_URL="${RPC_URL%$'\r'}" +RPC_URL="${RPC_URL%$'\n'}" WETH9_ADDRESS="0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" WETH9_BRIDGE="0x971cD9D156f193df8051E48043C476e53ECd4693" ETHEREUM_SELECTOR="5009297550715157269" diff --git a/scripts/verify-bridge-setup-checklist.sh b/scripts/verify-bridge-setup-checklist.sh index 161224d..1867c20 100755 --- a/scripts/verify-bridge-setup-checklist.sh +++ b/scripts/verify-bridge-setup-checklist.sh @@ -6,7 +6,7 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" # Colors RED='\033[0;31m' @@ -20,15 +20,18 @@ log_success() { echo -e "${GREEN}[✓]${NC} $1"; } log_warn() { echo -e "${YELLOW}[⚠]${NC} $1"; } log_error() { echo -e "${RED}[✗]${NC} $1"; } -# Load environment -if [ -f "$PROJECT_ROOT/.env" ]; then - source "$PROJECT_ROOT/.env" -elif [ -f "$PROJECT_ROOT/smom-dbis-138/.env" ]; then - source "$PROJECT_ROOT/smom-dbis-138/.env" +if [[ -f "$SCRIPT_DIR/lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/lib/deployment/dotenv.sh" + load_deployment_env --repo-root "$PROJECT_ROOT" +elif [ -f "$PROJECT_ROOT/.env" ]; then + set -a && source "$PROJECT_ROOT/.env" && set +a fi # Configuration -RPC_URL="${RPC_URL:-${RPC_URL_138:-http://192.168.11.250:8545}}" +RPC_URL="${RPC_URL:-${RPC_URL_138:-http://192.168.11.211:8545}}" +RPC_URL="${RPC_URL%$'\r'}" +RPC_URL="${RPC_URL%$'\n'}" BRIDGE_ADDRESS="${CCIPWETH9_BRIDGE_CHAIN138:-0x971cD9D156f193df8051E48043C476e53ECd4693}" LINK_TOKEN="${LINK_TOKEN:-0xb7721dD53A8c629d9f1Ba31a5819AFe250002b03}" CCIP_ROUTER="${CCIP_ROUTER:-0x42DAb7b888Dd382bD5Adcf9E038dBF1fD03b4817}" diff --git a/scripts/wrap-and-bridge-weth9-to-mainnet.sh b/scripts/wrap-and-bridge-weth9-to-mainnet.sh index b5a0cf3..50bc89c 100755 --- a/scripts/wrap-and-bridge-weth9-to-mainnet.sh +++ b/scripts/wrap-and-bridge-weth9-to-mainnet.sh @@ -7,7 +7,7 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" # Colors RED='\033[0;31m' @@ -21,17 +21,18 @@ log_success() { echo -e "${GREEN}[✓]${NC} $1"; } log_warn() { echo -e "${YELLOW}[⚠]${NC} $1"; } log_error() { echo -e "${RED}[✗]${NC} $1"; } -# Load environment variables (try repo root = parent of scripts/, then workspace) -if [ -f "$SCRIPT_DIR/../.env" ]; then - set -a && source "$SCRIPT_DIR/../.env" && set +a +if [[ -f "$SCRIPT_DIR/lib/deployment/dotenv.sh" ]]; then + # shellcheck disable=SC1090 + source "$SCRIPT_DIR/lib/deployment/dotenv.sh" + load_deployment_env --repo-root "$PROJECT_ROOT" elif [ -f "$PROJECT_ROOT/.env" ]; then set -a && source "$PROJECT_ROOT/.env" && set +a -elif [ -f "$PROJECT_ROOT/smom-dbis-138/.env" ]; then - set -a && source "$PROJECT_ROOT/smom-dbis-138/.env" && set +a fi # Configuration (override WETH9_ADDRESS / WETH9_ADDRESS_CHAIN138 if Chain 138 uses a different WETH9) -RPC_URL="${RPC_URL:-${RPC_URL_138:-http://192.168.11.250:8545}}" +RPC_URL="${RPC_URL:-${RPC_URL_138:-http://192.168.11.211:8545}}" +RPC_URL="${RPC_URL%$'\r'}" +RPC_URL="${RPC_URL%$'\n'}" WETH9_ADDRESS="${WETH9_ADDRESS_CHAIN138:-${WETH9_ADDRESS:-0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2}}" WETH9_BRIDGE="${CCIPWETH9_BRIDGE_CHAIN138:-0x971cD9D156f193df8051E48043C476e53ECd4693}" EXPLORER_URL_138="${EXPLORER_URL_138:-https://explorer.d-bis.org}" diff --git a/services/relay/README.md b/services/relay/README.md index 233e4cc..a3facff 100644 --- a/services/relay/README.md +++ b/services/relay/README.md @@ -41,6 +41,16 @@ From repo root (loads `smom-dbis-138/.env` and relay `.env.bsc` for addresses): Wrap BNB to WETH on the deployer first (`cast send "deposit()" --value ...` on BSC) if needed. +### Fund Mainnet relay bridge (WETH) + +From repo root: + +```bash +./scripts/bridge/fund-mainnet-relay-bridge.sh --dry-run +./scripts/bridge/fund-mainnet-relay-bridge.sh # full deployer WETH → bridge +# ./scripts/bridge/fund-mainnet-relay-bridge.sh 1000000000000000 # 0.001 WETH wei +``` + ## Relay shedding (save destination gas) When **no** 138→Mainnet (or configured destination) relay deliveries are needed, pause **destination-chain** transactions so the relayer does not spend native gas on `relayMessage` / direct `ccipReceive`: diff --git a/services/token-aggregation/README.md b/services/token-aggregation/README.md index 3a88660..94d5aef 100644 --- a/services/token-aggregation/README.md +++ b/services/token-aggregation/README.md @@ -177,6 +177,18 @@ GET /api/v1/search?q=USDT&chainId=138 GET /api/v1/pools/:poolAddress?chainId=138 ``` +### Route Decision Tree +``` +GET /api/v1/routes/tree?chainId=138&tokenIn=0x...&tokenOut=0x...&amountIn=1000000&destinationChainId=1 +``` +Live route tree with current pool depth, freshness, bridge fallback, and destination-swap legs. + +### Route Depth Summary +``` +GET /api/v1/routes/depth?chainId=138&tokenIn=0x...&tokenOut=0x...&amountIn=1000000&destinationChainId=1 +``` +Compact summary of the same route tree for routing UIs. + ### CMC and CoinGecko Reporting (all tokens, liquidity, volume) Full API for all coins, tokens, liquidity, and reportable data in CMC/CoinGecko-friendly formats: diff --git a/services/token-aggregation/deploy-to-vmid.sh b/services/token-aggregation/deploy-to-vmid.sh index 30277a2..99b2904 100755 --- a/services/token-aggregation/deploy-to-vmid.sh +++ b/services/token-aggregation/deploy-to-vmid.sh @@ -26,7 +26,11 @@ log_ok "Built" # Package log_info "Creating package..." -(cd "$SCRIPT_DIR" && tar czf /tmp/token-agg.tar.gz --exclude=node_modules dist/ src/ package.json tsconfig.json .env.example) +PACKAGE_ITEMS=(dist src package.json tsconfig.json) +for optional in .env.example .env; do + [ -e "$SCRIPT_DIR/$optional" ] && PACKAGE_ITEMS+=("$optional") +done +(cd "$SCRIPT_DIR" && tar czf /tmp/token-agg.tar.gz --exclude=node_modules "${PACKAGE_ITEMS[@]}") # Deploy log_info "Deploying..." @@ -41,7 +45,9 @@ ssh "$PROXMOX_USER@$PROXMOX_HOST" " mkdir -p /opt/token-aggregation && cd /opt/token-aggregation tar xzf /tmp/token-agg.tar.gz pnpm install --prod - [ ! -f .env ] && cp .env.example .env + if [ ! -f .env ] && [ -f .env.example ]; then + cp .env.example .env + fi ' " diff --git a/services/token-aggregation/src/api/routes/heatmap.ts b/services/token-aggregation/src/api/routes/heatmap.ts index 83a2ad5..7101e89 100644 --- a/services/token-aggregation/src/api/routes/heatmap.ts +++ b/services/token-aggregation/src/api/routes/heatmap.ts @@ -1,6 +1,7 @@ import { Router, Request, Response } from 'express'; import { PoolRepository } from '../../database/repositories/pool-repo'; import { TokenRepository } from '../../database/repositories/token-repo'; +import { resolvePoolTokenDisplays } from '../../services/token-display'; import { HEATMAP_CHAINS, getRoutesList, @@ -37,12 +38,9 @@ router.get('/heatmap', cacheMiddleware(60 * 1000), async (req: Request, res: Res for (const pool of pools) { const tvl = pool.totalLiquidityUsd || 0; const half = tvl / 2; - const token0 = await tokenRepo.getToken(chainId, pool.token0Address); - const token1 = await tokenRepo.getToken(chainId, pool.token1Address); - const sym0 = token0?.symbol || ''; - const sym1 = token1?.symbol || ''; - if (assets.includes(sym0)) symbolToTvl[sym0] = (symbolToTvl[sym0] || 0) + half; - if (assets.includes(sym1)) symbolToTvl[sym1] = (symbolToTvl[sym1] || 0) + half; + const { token0, token1 } = await resolvePoolTokenDisplays(tokenRepo, chainId, pool.token0Address, pool.token1Address); + if (assets.includes(token0.symbol)) symbolToTvl[token0.symbol] = (symbolToTvl[token0.symbol] || 0) + half; + if (assets.includes(token1.symbol)) symbolToTvl[token1.symbol] = (symbolToTvl[token1.symbol] || 0) + half; } for (const asset of assets) { const val = metric === 'tvlUsd' ? (symbolToTvl[asset] || 0) : 0; @@ -77,15 +75,14 @@ router.get('/pools', cacheMiddleware(60 * 1000), async (req: Request, res: Respo const pools = await poolRepo.getPoolsByChain(chainId, 500); const list = await Promise.all( pools.map(async (p) => { - const token0 = await tokenRepo.getToken(chainId, p.token0Address); - const token1 = await tokenRepo.getToken(chainId, p.token1Address); + const { token0, token1 } = await resolvePoolTokenDisplays(tokenRepo, chainId, p.token0Address, p.token1Address); return { - poolId: `${chainId}:${(p.dexType || 'dodo').toLowerCase()}:${token0?.symbol || p.token0Address}-${token1?.symbol || p.token1Address}:${p.poolAddress}`, + poolId: `${chainId}:${(p.dexType || 'dodo').toLowerCase()}:${token0.symbol}-${token1.symbol}:${p.poolAddress}`, chainId: p.chainId, dex: p.dexType, poolAddress: p.poolAddress, - token0: { symbol: token0?.symbol || '?', address: p.token0Address }, - token1: { symbol: token1?.symbol || '?', address: p.token1Address }, + token0: { symbol: token0.symbol, name: token0.name, address: p.token0Address, source: token0.source }, + token1: { symbol: token1.symbol, name: token1.name, address: p.token1Address, source: token1.source }, liquidity: { tvlUsd: p.totalLiquidityUsd, reserve0: p.reserve0, diff --git a/services/token-aggregation/src/api/routes/report.ts b/services/token-aggregation/src/api/routes/report.ts index 242a890..df457a9 100644 --- a/services/token-aggregation/src/api/routes/report.ts +++ b/services/token-aggregation/src/api/routes/report.ts @@ -12,6 +12,7 @@ import { getCanonicalTokensByChain, getLogoUriForSpec, } from '../../config/canonical-tokens'; +import { resolvePoolTokenDisplays } from '../../services/token-display'; import { getSupportedChainIds } from '../../config/chains'; import { cacheMiddleware } from '../middleware/cache'; import { fetchRemoteJson } from '../utils/fetch-remote-json'; @@ -64,6 +65,20 @@ async function buildTokenReport(chainId: number) { poolRepo.getPoolsByToken(chainId, address), ]); + const resolvedPools = await Promise.all( + pools.map(async (p) => { + const { token0, token1 } = await resolvePoolTokenDisplays(tokenRepo, chainId, p.token0Address, p.token1Address); + return { + poolAddress: p.poolAddress, + dex: p.dexType, + token0, + token1, + tvl: p.totalLiquidityUsd, + volume24h: p.volume24h, + }; + }) + ); + out.push({ chainId, address: address.toLowerCase(), @@ -83,12 +98,14 @@ async function buildTokenReport(chainId: number) { lastUpdated: marketData.lastUpdated?.toISOString() ?? '', } : undefined, - pools: pools.map((p) => ({ + pools: resolvedPools.map((p) => ({ poolAddress: p.poolAddress, - dex: p.dexType, - token0: p.token0Address, - token1: p.token1Address, - tvl: p.totalLiquidityUsd, + dex: p.dex, + token0: p.token0.address, + token1: p.token1.address, + token0Symbol: p.token0.symbol, + token1Symbol: p.token1.symbol, + tvl: p.tvl, volume24h: p.volume24h, })), fromDb: !!dbToken, diff --git a/services/token-aggregation/src/api/routes/tokens.ts b/services/token-aggregation/src/api/routes/tokens.ts index ffb7cf2..c46f933 100644 --- a/services/token-aggregation/src/api/routes/tokens.ts +++ b/services/token-aggregation/src/api/routes/tokens.ts @@ -7,6 +7,7 @@ import { CoinGeckoAdapter } from '../../adapters/coingecko-adapter'; import { CoinMarketCapAdapter } from '../../adapters/cmc-adapter'; import { DexScreenerAdapter } from '../../adapters/dexscreener-adapter'; import { cacheMiddleware } from '../middleware/cache'; +import { resolvePoolTokenDisplays } from '../../services/token-display'; import { logger } from '../../utils/logger'; const router: Router = Router(); @@ -150,19 +151,34 @@ router.get('/tokens/:address/pools', cacheMiddleware(60 * 1000), async (req: Req const pools = await poolRepo.getPoolsByToken(chainId, address); res.json({ - pools: pools.map((pool) => ({ - address: pool.poolAddress, - dex: pool.dexType, - token0: pool.token0Address, - token1: pool.token1Address, - reserves: { - token0: pool.reserve0, - token1: pool.reserve1, - }, - tvl: pool.totalLiquidityUsd, - volume24h: pool.volume24h, - feeTier: pool.feeTier, - })), + pools: await Promise.all( + pools.map(async (pool) => { + const { token0, token1 } = await resolvePoolTokenDisplays(tokenRepo, chainId, pool.token0Address, pool.token1Address); + return { + address: pool.poolAddress, + dex: pool.dexType, + token0: { + address: pool.token0Address, + symbol: token0.symbol, + name: token0.name, + source: token0.source, + }, + token1: { + address: pool.token1Address, + symbol: token1.symbol, + name: token1.name, + source: token1.source, + }, + reserves: { + token0: pool.reserve0, + token1: pool.reserve1, + }, + tvl: pool.totalLiquidityUsd, + volume24h: pool.volume24h, + feeTier: pool.feeTier, + }; + }) + ), }); } catch (error) { logger.error('Error fetching pools:', error); @@ -272,8 +288,12 @@ router.get('/pools/:poolAddress', cacheMiddleware(60 * 1000), async (req: Reques pool: { address: pool.poolAddress, dex: pool.dexType, - token0: pool.token0Address, - token1: pool.token1Address, + token0: { + address: pool.token0Address, + }, + token1: { + address: pool.token1Address, + }, reserves: { token0: pool.reserve0, token1: pool.reserve1, diff --git a/services/token-aggregation/src/database/repositories/pool-repo.ts b/services/token-aggregation/src/database/repositories/pool-repo.ts index 94b4b00..9c2d8b1 100644 --- a/services/token-aggregation/src/database/repositories/pool-repo.ts +++ b/services/token-aggregation/src/database/repositories/pool-repo.ts @@ -43,114 +43,159 @@ export class PoolRepository { this.pool = getDatabasePool(); } - async getPool(chainId: number, poolAddress: string): Promise { - const result = await this.pool.query( - `SELECT id, chain_id, pool_address, token0_address, token1_address, dex_type, - factory_address, router_address, reserve0, reserve1, reserve0_usd, reserve1_usd, - total_liquidity_usd, volume_24h, fee_tier, created_at_block, created_at_timestamp, last_updated - FROM liquidity_pools - WHERE chain_id = $1 AND pool_address = $2`, - [chainId, poolAddress.toLowerCase()] - ); - - if (result.rows.length === 0) { - return null; + private isMissingRelationError(error: unknown): boolean { + if (!error || typeof error !== 'object') { + return false; } - return this.mapRowToPool(result.rows[0]); + const code = (error as { code?: string }).code; + const message = (error as { message?: string }).message || ''; + return code === '42P01' || message.includes('relation "') && message.includes('" does not exist'); + } + + async getPool(chainId: number, poolAddress: string): Promise { + try { + const result = await this.pool.query( + `SELECT id, chain_id, pool_address, token0_address, token1_address, dex_type, + factory_address, router_address, reserve0, reserve1, reserve0_usd, reserve1_usd, + total_liquidity_usd, volume_24h, fee_tier, created_at_block, created_at_timestamp, last_updated + FROM liquidity_pools + WHERE chain_id = $1 AND pool_address = $2`, + [chainId, poolAddress.toLowerCase()] + ); + + if (result.rows.length === 0) { + return null; + } + + return this.mapRowToPool(result.rows[0]); + } catch (error) { + if (this.isMissingRelationError(error)) { + return null; + } + throw error; + } } async getPoolsByChain(chainId: number, limit: number = 500): Promise { - const result = await this.pool.query( - `SELECT id, chain_id, pool_address, token0_address, token1_address, dex_type, - factory_address, router_address, reserve0, reserve1, reserve0_usd, reserve1_usd, - total_liquidity_usd, volume_24h, fee_tier, created_at_block, created_at_timestamp, last_updated - FROM liquidity_pools - WHERE chain_id = $1 - ORDER BY total_liquidity_usd DESC NULLS LAST - LIMIT $2`, - [chainId, limit] - ); - return result.rows.map((row) => this.mapRowToPool(row)); + try { + const result = await this.pool.query( + `SELECT id, chain_id, pool_address, token0_address, token1_address, dex_type, + factory_address, router_address, reserve0, reserve1, reserve0_usd, reserve1_usd, + total_liquidity_usd, volume_24h, fee_tier, created_at_block, created_at_timestamp, last_updated + FROM liquidity_pools + WHERE chain_id = $1 + ORDER BY total_liquidity_usd DESC NULLS LAST + LIMIT $2`, + [chainId, limit] + ); + return result.rows.map((row) => this.mapRowToPool(row)); + } catch (error) { + if (this.isMissingRelationError(error)) { + return []; + } + throw error; + } } async getPoolsByToken(chainId: number, tokenAddress: string): Promise { - const result = await this.pool.query( - `SELECT id, chain_id, pool_address, token0_address, token1_address, dex_type, - factory_address, router_address, reserve0, reserve1, reserve0_usd, reserve1_usd, - total_liquidity_usd, volume_24h, fee_tier, created_at_block, created_at_timestamp, last_updated - FROM liquidity_pools - WHERE chain_id = $1 AND (token0_address = $2 OR token1_address = $2) - ORDER BY total_liquidity_usd DESC`, - [chainId, tokenAddress.toLowerCase()] - ); + try { + const result = await this.pool.query( + `SELECT id, chain_id, pool_address, token0_address, token1_address, dex_type, + factory_address, router_address, reserve0, reserve1, reserve0_usd, reserve1_usd, + total_liquidity_usd, volume_24h, fee_tier, created_at_block, created_at_timestamp, last_updated + FROM liquidity_pools + WHERE chain_id = $1 AND (token0_address = $2 OR token1_address = $2) + ORDER BY total_liquidity_usd DESC`, + [chainId, tokenAddress.toLowerCase()] + ); - return result.rows.map((row) => this.mapRowToPool(row)); + return result.rows.map((row) => this.mapRowToPool(row)); + } catch (error) { + if (this.isMissingRelationError(error)) { + return []; + } + throw error; + } } async upsertPool(pool: LiquidityPool): Promise { - await this.pool.query( - `INSERT INTO liquidity_pools ( - chain_id, pool_address, token0_address, token1_address, dex_type, - factory_address, router_address, reserve0, reserve1, reserve0_usd, reserve1_usd, - total_liquidity_usd, volume_24h, fee_tier, created_at_block, created_at_timestamp, last_updated - ) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17) - ON CONFLICT (chain_id, pool_address) DO UPDATE SET - token0_address = EXCLUDED.token0_address, - token1_address = EXCLUDED.token1_address, - dex_type = EXCLUDED.dex_type, - factory_address = EXCLUDED.factory_address, - router_address = EXCLUDED.router_address, - reserve0 = EXCLUDED.reserve0, - reserve1 = EXCLUDED.reserve1, - reserve0_usd = EXCLUDED.reserve0_usd, - reserve1_usd = EXCLUDED.reserve1_usd, - total_liquidity_usd = EXCLUDED.total_liquidity_usd, - volume_24h = EXCLUDED.volume_24h, - fee_tier = EXCLUDED.fee_tier, - last_updated = EXCLUDED.last_updated`, - [ - pool.chainId, - pool.poolAddress.toLowerCase(), - pool.token0Address.toLowerCase(), - pool.token1Address.toLowerCase(), - pool.dexType, - pool.factoryAddress?.toLowerCase(), - pool.routerAddress?.toLowerCase(), - pool.reserve0, - pool.reserve1, - pool.reserve0Usd, - pool.reserve1Usd, - pool.totalLiquidityUsd, - pool.volume24h, - pool.feeTier, - pool.createdAtBlock, - pool.createdAtTimestamp, - pool.lastUpdated, - ] - ); + try { + await this.pool.query( + `INSERT INTO liquidity_pools ( + chain_id, pool_address, token0_address, token1_address, dex_type, + factory_address, router_address, reserve0, reserve1, reserve0_usd, reserve1_usd, + total_liquidity_usd, volume_24h, fee_tier, created_at_block, created_at_timestamp, last_updated + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17) + ON CONFLICT (chain_id, pool_address) DO UPDATE SET + token0_address = EXCLUDED.token0_address, + token1_address = EXCLUDED.token1_address, + dex_type = EXCLUDED.dex_type, + factory_address = EXCLUDED.factory_address, + router_address = EXCLUDED.router_address, + reserve0 = EXCLUDED.reserve0, + reserve1 = EXCLUDED.reserve1, + reserve0_usd = EXCLUDED.reserve0_usd, + reserve1_usd = EXCLUDED.reserve1_usd, + total_liquidity_usd = EXCLUDED.total_liquidity_usd, + volume_24h = EXCLUDED.volume_24h, + fee_tier = EXCLUDED.fee_tier, + last_updated = EXCLUDED.last_updated`, + [ + pool.chainId, + pool.poolAddress.toLowerCase(), + pool.token0Address.toLowerCase(), + pool.token1Address.toLowerCase(), + pool.dexType, + pool.factoryAddress?.toLowerCase(), + pool.routerAddress?.toLowerCase(), + pool.reserve0, + pool.reserve1, + pool.reserve0Usd, + pool.reserve1Usd, + pool.totalLiquidityUsd, + pool.volume24h, + pool.feeTier, + pool.createdAtBlock, + pool.createdAtTimestamp, + pool.lastUpdated, + ] + ); + } catch (error) { + if (this.isMissingRelationError(error)) { + return; + } + throw error; + } } async addReserveSnapshot(snapshot: PoolReserveSnapshot): Promise { - await this.pool.query( - `INSERT INTO pool_reserves_history ( - chain_id, pool_address, reserve0, reserve1, reserve0_usd, reserve1_usd, - total_liquidity_usd, block_number, timestamp - ) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`, - [ - snapshot.chainId, - snapshot.poolAddress.toLowerCase(), - snapshot.reserve0, - snapshot.reserve1, - snapshot.reserve0Usd, - snapshot.reserve1Usd, - snapshot.totalLiquidityUsd, - snapshot.blockNumber, - snapshot.timestamp, - ] - ); + try { + await this.pool.query( + `INSERT INTO pool_reserves_history ( + chain_id, pool_address, reserve0, reserve1, reserve0_usd, reserve1_usd, + total_liquidity_usd, block_number, timestamp + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`, + [ + snapshot.chainId, + snapshot.poolAddress.toLowerCase(), + snapshot.reserve0, + snapshot.reserve1, + snapshot.reserve0Usd, + snapshot.reserve1Usd, + snapshot.totalLiquidityUsd, + snapshot.blockNumber, + snapshot.timestamp, + ] + ); + } catch (error) { + if (this.isMissingRelationError(error)) { + return; + } + throw error; + } } async getReserveHistory( @@ -160,27 +205,34 @@ export class PoolRepository { to: Date, limit: number = 1000 ): Promise { - const result = await this.pool.query( - `SELECT chain_id, pool_address, reserve0, reserve1, reserve0_usd, reserve1_usd, - total_liquidity_usd, block_number, timestamp - FROM pool_reserves_history - WHERE chain_id = $1 AND pool_address = $2 AND timestamp >= $3 AND timestamp <= $4 - ORDER BY timestamp DESC - LIMIT $5`, - [chainId, poolAddress.toLowerCase(), from, to, limit] - ); + try { + const result = await this.pool.query( + `SELECT chain_id, pool_address, reserve0, reserve1, reserve0_usd, reserve1_usd, + total_liquidity_usd, block_number, timestamp + FROM pool_reserves_history + WHERE chain_id = $1 AND pool_address = $2 AND timestamp >= $3 AND timestamp <= $4 + ORDER BY timestamp DESC + LIMIT $5`, + [chainId, poolAddress.toLowerCase(), from, to, limit] + ); - return result.rows.map((row) => ({ - chainId: row.chain_id, - poolAddress: row.pool_address, - reserve0: row.reserve0, - reserve1: row.reserve1, - reserve0Usd: row.reserve0_usd ? parseFloat(row.reserve0_usd) : undefined, - reserve1Usd: row.reserve1_usd ? parseFloat(row.reserve1_usd) : undefined, - totalLiquidityUsd: row.total_liquidity_usd ? parseFloat(row.total_liquidity_usd) : undefined, - blockNumber: parseInt(row.block_number, 10), - timestamp: row.timestamp, - })); + return result.rows.map((row) => ({ + chainId: row.chain_id, + poolAddress: row.pool_address, + reserve0: row.reserve0, + reserve1: row.reserve1, + reserve0Usd: row.reserve0_usd ? parseFloat(row.reserve0_usd) : undefined, + reserve1Usd: row.reserve1_usd ? parseFloat(row.reserve1_usd) : undefined, + totalLiquidityUsd: row.total_liquidity_usd ? parseFloat(row.total_liquidity_usd) : undefined, + blockNumber: parseInt(row.block_number, 10), + timestamp: row.timestamp, + })); + } catch (error) { + if (this.isMissingRelationError(error)) { + return []; + } + throw error; + } } /* eslint-disable @typescript-eslint/no-explicit-any */ diff --git a/services/token-aggregation/src/indexer/pool-indexer.ts b/services/token-aggregation/src/indexer/pool-indexer.ts index f50bb36..07e0f6e 100644 --- a/services/token-aggregation/src/indexer/pool-indexer.ts +++ b/services/token-aggregation/src/indexer/pool-indexer.ts @@ -161,7 +161,7 @@ export class PoolIndexer { await this.poolRepo.upsertPool(pool); pools.push(pool); } catch (err) { - logger.error(`Error indexing DODO PMM pool ${poolAddress}:`, err); + logger.warn(`Skipping DODO PMM pool ${poolAddress}; it may have been removed from integration state.`, err); } } } catch (error) { diff --git a/terraform/phases/phase1/config/genesis-138.json b/terraform/phases/phase1/config/genesis-138.json index c6debb7..997fc7c 100644 --- a/terraform/phases/phase1/config/genesis-138.json +++ b/terraform/phases/phase1/config/genesis-138.json @@ -66,7 +66,7 @@ }, "0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f": { "balance": "0xd3c21bcecceda1000000", - "code": "0x6080604052600436106101b05760003560e01c806370a08231116100ec578063b760faf91161008a578063d0e30db011610064578063d0e30db01461087b578063d505accf14610883578063d9d98ce4146108ee578063dd62ed3e1461093457610202565b8063b760faf914610794578063cae9ca51146107c7578063cd0d00961461086657610202565b80638b28d32f116100c65780638b28d32f146106d45780639555a942146106e957806395d89b4114610739578063a9059cbb1461074e57610202565b806370a082311461063f5780637ecebe001461067f5780638237e538146106bf57610202565b806330adf81f116101595780634000aea0116101335780634000aea0146104295780635cffe9de146104c85780635ddb7d7e14610572578063613255ab146105ff57610202565b806330adf81f146103d4578063313ce567146103e95780633644e5151461041457610202565b8063205c28781161018a578063205c28781461031257806323b872dd1461035a5780632e1a7d4d146103aa57610202565b806306fdde0314610207578063095ea7b31461029157806318160ddd146102eb57610202565b366102025733600081815260208181526040808320805434908101909155815190815290517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3005b600080fd5b34801561021357600080fd5b5061021c61097c565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561025657818101518382015260200161023e565b50505050905090810190601f1680156102835780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561029d57600080fd5b506102d7600480360360408110156102b457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356109b5565b604080519115158252519081900360200190f35b3480156102f757600080fd5b50610300610a28565b60408051918252519081900360200190f35b34801561031e57600080fd5b506103586004803603604081101561033557600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610a30565b005b34801561036657600080fd5b506102d76004803603606081101561037d57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610b82565b3480156103b657600080fd5b50610358600480360360208110156103cd57600080fd5b5035610f24565b3480156103e057600080fd5b5061030061105f565b3480156103f557600080fd5b506103fe611083565b6040805160ff9092168252519081900360200190f35b34801561042057600080fd5b50610300611088565b34801561043557600080fd5b506102d76004803603606081101561044c57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8235169160208101359181019060608101604082013564010000000081111561048957600080fd5b82018360208201111561049b57600080fd5b803590602001918460018302840111640100000000831117156104bd57600080fd5b5090925090506110e8565b3480156104d457600080fd5b506102d7600480360360808110156104eb57600080fd5b73ffffffffffffffffffffffffffffffffffffffff82358116926020810135909116916040820135919081019060808101606082013564010000000081111561053357600080fd5b82018360208201111561054557600080fd5b8035906020019184600183028401116401000000008311171561056757600080fd5b5090925090506113dc565b6102d76004803603604081101561058857600080fd5b73ffffffffffffffffffffffffffffffffffffffff82351691908101906040810160208201356401000000008111156105c057600080fd5b8201836020820111156105d257600080fd5b803590602001918460018302840111640100000000831117156105f457600080fd5b5090925090506118c1565b34801561060b57600080fd5b506103006004803603602081101561062257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611a02565b34801561064b57600080fd5b506103006004803603602081101561066257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611a42565b34801561068b57600080fd5b50610300600480360360208110156106a257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611a54565b3480156106cb57600080fd5b50610300611a66565b3480156106e057600080fd5b50610300611a8a565b3480156106f557600080fd5b506103586004803603606081101561070c57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135611a90565b34801561074557600080fd5b5061021c611d49565b34801561075a57600080fd5b506102d76004803603604081101561077157600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135611d82565b610358600480360360208110156107aa57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611fa5565b3480156107d357600080fd5b506102d7600480360360608110156107ea57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8235169160208101359181019060608101604082013564010000000081111561082757600080fd5b82018360208201111561083957600080fd5b8035906020019184600183028401116401000000008311171561085b57600080fd5b509092509050612009565b34801561087257600080fd5b50610300612117565b61035861213b565b34801561088f57600080fd5b50610358600480360360e08110156108a657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c00135612188565b3480156108fa57600080fd5b506103006004803603604081101561091157600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356124c3565b34801561094057600080fd5b506103006004803603604081101561095757600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516612538565b6040518060400160405280601181526020017f577261707065642045746865722076313000000000000000000000000000000081525081565b33600081815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b600354470190565b3360009081526020819052604090205481811015610a7f5760405162461bcd60e51b81526004018080602001828103825260218152602001806126a16021913960400191505060405180910390fd5b336000818152602081815260408083208686039055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a360405160009073ffffffffffffffffffffffffffffffffffffffff85169084908381818185875af1925050503d8060008114610b21576040519150601f19603f3d011682016040523d82523d6000602084013e610b26565b606091505b5050905080610b7c576040805162461bcd60e51b815260206004820152601960248201527f574554483a20455448207472616e73666572206661696c656400000000000000604482015290519081900360640190fd5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff84163314610cbe5773ffffffffffffffffffffffffffffffffffffffff841660009081526002602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610cbc5782811015610c4e576040805162461bcd60e51b815260206004820152601f60248201527f574554483a2072657175657374206578636565647320616c6c6f77616e636500604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff85166000818152600260209081526040808320338085529083529281902087860390819055815181815291519094927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a3505b505b73ffffffffffffffffffffffffffffffffffffffff831615610db55773ffffffffffffffffffffffffffffffffffffffff841660009081526020819052604090205482811015610d3f5760405162461bcd60e51b81526004018080602001828103825260258152602001806126586025913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8086166000818152602081815260408083208887039055938816808352918490208054880190558351878152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a350610f1a565b73ffffffffffffffffffffffffffffffffffffffff841660009081526020819052604090205482811015610e1a5760405162461bcd60e51b81526004018080602001828103825260218152602001806126a16021913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff85166000818152602081815260408083208786039055805187815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3604051600090339085908381818185875af1925050503d8060008114610ebc576040519150601f19603f3d011682016040523d82523d6000602084013e610ec1565b606091505b5050905080610f17576040805162461bcd60e51b815260206004820152601960248201527f574554483a20455448207472616e73666572206661696c656400000000000000604482015290519081900360640190fd5b50505b5060019392505050565b3360009081526020819052604090205481811015610f735760405162461bcd60e51b81526004018080602001828103825260218152602001806126a16021913960400191505060405180910390fd5b336000818152602081815260408083208686039055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3604051600090339084908381818185875af1925050503d8060008114610fff576040519150601f19603f3d011682016040523d82523d6000602084013e611004565b606091505b505090508061105a576040805162461bcd60e51b815260206004820152601960248201527f574554483a20455448207472616e73666572206661696c656400000000000000604482015290519081900360640190fd5b505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601281565b6000467f000000000000000000000000000000000000000000000000000000000000000181146110c0576110bb81612555565b6110e2565b7f9d6861d4de8c156e6b3155e3283174a7c6c86fd27c1ff43e1f05cc2d417fbb655b91505090565b600073ffffffffffffffffffffffffffffffffffffffff8516156111c95733600090815260208190526040902054848110156111555760405162461bcd60e51b81526004018080602001828103825260258152602001806126586025913960400191505060405180910390fd5b33600081815260208181526040808320898603905573ffffffffffffffffffffffffffffffffffffffff8a168084529281902080548a019055805189815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a350611302565b33600090815260208190526040902054848110156112185760405162461bcd60e51b81526004018080602001828103825260218152602001806126a16021913960400191505060405180910390fd5b336000818152602081815260408083208986039055805189815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3604051600090339087908381818185875af1925050503d80600081146112a4576040519150601f19603f3d011682016040523d82523d6000602084013e6112a9565b606091505b50509050806112ff576040805162461bcd60e51b815260206004820152601960248201527f574554483a20455448207472616e73666572206661696c656400000000000000604482015290519081900360640190fd5b50505b8473ffffffffffffffffffffffffffffffffffffffff1663a4c0ed36338686866040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050602060405180830381600087803b1580156113a757600080fd5b505af11580156113bb573d6000803e3d6000fd5b505050506040513d60208110156113d157600080fd5b505195945050505050565b600073ffffffffffffffffffffffffffffffffffffffff85163014611448576040805162461bcd60e51b815260206004820152601c60248201527f574554483a20666c617368206d696e74206f6e6c792057455448313000000000604482015290519081900360640190fd5b6dffffffffffffffffffffffffffff8411156114955760405162461bcd60e51b815260040180806020018281038252602481526020018061267d6024913960400191505060405180910390fd5b600380548501908190556dffffffffffffffffffffffffffff1015611501576040805162461bcd60e51b815260206004820152601f60248201527f574554483a20746f74616c206c6f616e206c696d697420657863656564656400604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8616600081815260208181526040808320805489019055805188815290517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a37f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd98673ffffffffffffffffffffffffffffffffffffffff166323e30c8b333088600089896040518763ffffffff1660e01b8152600401808773ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff168152602001858152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050975050505050505050602060405180830381600087803b15801561164c57600080fd5b505af1158015611660573d6000803e3d6000fd5b505050506040513d602081101561167657600080fd5b5051146116ca576040805162461bcd60e51b815260206004820152601760248201527f574554483a20666c617368206c6f616e206661696c6564000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff861660009081526002602090815260408083203084529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146117e55784811015611777576040805162461bcd60e51b815260206004820152601f60248201527f574554483a2072657175657374206578636565647320616c6c6f77616e636500604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff87166000818152600260209081526040808320308085529083529281902089860390819055815181815291519094927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a3505b73ffffffffffffffffffffffffffffffffffffffff87166000908152602081905260409020548581101561184a5760405162461bcd60e51b81526004018080602001828103825260218152602001806126a16021913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff88166000818152602081815260408083208a8603905580518a815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3505060038054859003905550600195945050505050565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208054349081019091558151908152905192939284927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef928290030190a36040517fa4c0ed36000000000000000000000000000000000000000000000000000000008152336004820181815234602484018190526060604485019081526064850187905273ffffffffffffffffffffffffffffffffffffffff89169463a4c0ed36949389928992608401848480828437600081840152601f19601f82011690508083019250505095505050505050602060405180830381600087803b1580156119ce57600080fd5b505af11580156119e2573d6000803e3d6000fd5b505050506040513d60208110156119f857600080fd5b5051949350505050565b600073ffffffffffffffffffffffffffffffffffffffff82163014611a28576000611a3c565b6003546dffffffffffffffffffffffffffff035b92915050565b60006020819052908152604090205481565b60016020526000908152604090205481565b7f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd981565b60035481565b73ffffffffffffffffffffffffffffffffffffffff83163314611bca5773ffffffffffffffffffffffffffffffffffffffff831660009081526002602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611bc85781811015611b5a576040805162461bcd60e51b815260206004820152601f60248201527f574554483a2072657175657374206578636565647320616c6c6f77616e636500604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff84166000818152600260209081526040808320338085529083529281902086860390819055815181815291519094927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a3505b505b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015611c2f5760405162461bcd60e51b81526004018080602001828103825260218152602001806126a16021913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff84166000818152602081815260408083208686039055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a360405160009073ffffffffffffffffffffffffffffffffffffffff85169084908381818185875af1925050503d8060008114611ce7576040519150601f19603f3d011682016040523d82523d6000602084013e611cec565b606091505b5050905080611d42576040805162461bcd60e51b815260206004820152601b60248201527f574554483a204574686572207472616e73666572206661696c65640000000000604482015290519081900360640190fd5b5050505050565b6040518060400160405280600681526020017f574554483130000000000000000000000000000000000000000000000000000081525081565b600073ffffffffffffffffffffffffffffffffffffffff831615611e63573360009081526020819052604090205482811015611def5760405162461bcd60e51b81526004018080602001828103825260258152602001806126586025913960400191505060405180910390fd5b33600081815260208181526040808320878603905573ffffffffffffffffffffffffffffffffffffffff881680845292819020805488019055805187815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a350611f9c565b3360009081526020819052604090205482811015611eb25760405162461bcd60e51b81526004018080602001828103825260218152602001806126a16021913960400191505060405180910390fd5b336000818152602081815260408083208786039055805187815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3604051600090339085908381818185875af1925050503d8060008114611f3e576040519150601f19603f3d011682016040523d82523d6000602084013e611f43565b606091505b5050905080611f99576040805162461bcd60e51b815260206004820152601960248201527f574554483a20455448207472616e73666572206661696c656400000000000000604482015290519081900360640190fd5b50505b50600192915050565b73ffffffffffffffffffffffffffffffffffffffff8116600081815260208181526040808320805434908101909155815190815290517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a350565b33600081815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8916808552908352818420889055815188815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a38473ffffffffffffffffffffffffffffffffffffffff1662ba451f338686866040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050602060405180830381600087803b1580156113a757600080fd5b7f000000000000000000000000000000000000000000000000000000000000000181565b33600081815260208181526040808320805434908101909155815190815290517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3565b834211156121dd576040805162461bcd60e51b815260206004820152601460248201527f574554483a2045787069726564207065726d6974000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff80881660008181526001602081815260408084208054938401905580517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280820195909552948b166060850152608084018a905260a084019190915260c08084018990528451808503909101815260e09093019093528151919092012046917f000000000000000000000000000000000000000000000000000000000000000183146122aa576122a583612555565b6122cc565b7f9d6861d4de8c156e6b3155e3283174a7c6c86fd27c1ff43e1f05cc2d417fbb655b8260405160200180807f190100000000000000000000000000000000000000000000000000000000000081525060020183815260200182815260200192505050604051602081830303815290604052805190602001209050600060018288888860405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015612380573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116158015906123fb57508a73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b61244c576040805162461bcd60e51b815260206004820152601460248201527f574554483a20696e76616c6964207065726d6974000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff808c166000818152600260209081526040808320948f16808452948252918290208d905581518d815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a35050505050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff8316301461252f576040805162461bcd60e51b815260206004820152601c60248201527f574554483a20666c617368206d696e74206f6e6c792057455448313000000000604482015290519081900360640190fd5b50600092915050565b600260209081526000928352604080842090915290825290205481565b604080518082018252601181527f577261707065642045746865722076313000000000000000000000000000000060209182015281518083018352600181527f31000000000000000000000000000000000000000000000000000000000000009082015281517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818301527f5afefa023603a382ac22bd36644e004cefabbfaf61d4180000d8dc2b10c168b8818401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6606082015260808101939093523060a0808501919091528251808503909101815260c090930190915281519101209056fe574554483a207472616e7366657220616d6f756e7420657863656564732062616c616e6365574554483a20696e646976696475616c206c6f616e206c696d6974206578636565646564574554483a206275726e20616d6f756e7420657863656564732062616c616e6365a264697066735822122010a2e85d28f3cbb1bab01194294eeaad30a52826e3d85bf4b42223cb2b05e6a164736f6c63430007060033", + "code": "0x6080806040526004361015610025575b50361561001b57600080fd5b6100236108bd565b005b60003560e01c90816306fdde03146107c557508063095ea7b31461074c57806318160ddd1461073057806323b872dd146107015780632e1a7d4d14610668578063313ce5671461064c5780635cffe9de146102c4578063613255ab1461028757806370a082311461024d57806375d9ad1b1461021257806395d89b41146101d15780639d649e66146101b5578063a9059cbb14610183578063d0e30db01461016f578063d9d98ce4146101385763dd62ed3e146100e2573861000f565b34610133576040366003190112610133576100fb61086e565b610103610884565b9060018060a01b038091166000526001602052604060002091166000526020526020604060002054604051908152f35b600080fd5b346101335760403660031901126101335761016461015461086e565b6001600160a01b03163014610aa0565b602060405160008152f35b6000366003190112610133576100236108bd565b346101335760403660031901126101335760206101ab6101a161086e565b602435903361095f565b6040519015158152f35b3461013357600036600319011261013357602060405160008152f35b346101335760003660031901126101335761020e6040516101f181610809565b60048152630ae8aa8960e31b602082015260405191829182610825565b0390f35b346101335760003660031901126101335760206040517f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd98152f35b34610133576020366003190112610133576001600160a01b0361026e61086e565b1660005260006020526020604060002054604051908152f35b34610133576020366003190112610133576102a061086e565b6001600160a01b031630036102bb576020475b604051908152f35b602060006102b3565b34610133576080366003190112610133576001600160a01b036004358181168103610133576102f1610884565b67ffffffffffffffff60643511610133573660236064350112156101335767ffffffffffffffff60643560040135116101335736602460643560040135606435010111610133576103453084831614610aa0565b6044351561060e5760443547106105c95782821660005260006020526040600020610373604435825461089a565b905560405160443581526000600080516020610aed833981519152602086861693a382604051916323e30c8b60e01b835233600484015216602482015260443560448201526000606482015260a060848201526064356004013560a48201526064356004013560246064350160c4830137600060c46064356004013583010152601f1960208260c48184601f606435600401350116810103018160008888165af19081156105bd57600091610540575b507f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd99150036104f0578181166000526000602052604435604060002054106104ab57600080516020610aed83398151915260208360009484168552848252604085206104926044358254610952565b90556040519360443585521692a3602060405160018152f35b60405162461bcd60e51b815260206004820152601e60248201527f5745544831303a20696e73756666696369656e742072657061796d656e7400006044820152606490fd5b60405162461bcd60e51b815260206004820152602260248201527f5745544831303a20666c617368206c6f616e2063616c6c6261636b206661696c604482015261195960f21b6064820152608490fd5b602091503d82116105b5575b601f820116820182811067ffffffffffffffff82111761059f57602091839160405281010312610133577f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd9905184610423565b634e487b7160e01b600052604160045260246000fd5b3d915061054c565b6040513d6000823e3d90fd5b60405162461bcd60e51b815260206004820152601e60248201527f5745544831303a20696e73756666696369656e74206c697175696469747900006044820152606490fd5b60405162461bcd60e51b815260206004820152601660248201527515d155120c4c0e881a5b9d985b1a5908185b5bdd5b9d60521b6044820152606490fd5b3461013357600036600319011261013357602060405160128152f35b3461013357602036600319011261013357600435336000526000602052610696816040600020541015610906565b33600052600060205260406000206106af828254610952565b905580600081156106f8575b600080809381933390f1156105bd576040519081527f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b6560203392a2005b506108fc6106bb565b346101335760603660031901126101335760206101ab61071f61086e565b610727610884565b6044359161095f565b3461013357600036600319011261013357602047604051908152f35b346101335760403660031901126101335761076561086e565b60243533600052600160205260406000209160018060a01b03169182600052602052806040600020556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3602060405160018152f35b3461013357600036600319011261013357806107e361020e92610809565b600d81526c2bb930b83832b21022ba3432b960991b602082015260405191829182610825565b6040810190811067ffffffffffffffff82111761059f57604052565b6020808252825181830181905290939260005b82811061085a57505060409293506000838284010152601f8019910116010190565b818101860151848201604001528501610838565b600435906001600160a01b038216820361013357565b602435906001600160a01b038216820361013357565b919082018092116108a757565b634e487b7160e01b600052601160045260246000fd5b33600052600060205260406000206108d634825461089a565b90556040513481527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c60203392a2565b1561090d57565b60405162461bcd60e51b815260206004820152601c60248201527f5745544831303a20696e73756666696369656e742062616c616e6365000000006044820152606490fd5b919082039182116108a757565b91909160018060a01b038091169160009383855260209285845260409161098b84848920541015610906565b3386141580610a82575b6109e5575b918091600080516020610aed8339815191529594938789528886528289206109c3868254610952565b90551696878152808552206109d983825461089a565b905551908152a3600190565b858752600185528287203388528552838388205410610a3e57918091600080516020610aed83398151915295949387895260018652828920338a528652828920610a30868254610952565b90559150919293945061099a565b825162461bcd60e51b815260048101869052601e60248201527f5745544831303a20696e73756666696369656e7420616c6c6f77616e636500006044820152606490fd5b50858752600185528287203388528552828720546000191415610995565b15610aa757565b60405162461bcd60e51b815260206004820152601960248201527f5745544831303a20756e737570706f7274656420746f6b656e000000000000006044820152606490fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212207c34c26feecd05ff838fc85995144621f090e1740fb2223f2f4e272503c4754564736f6c63430008140033", "storage": {} }, "0x80226fc0Ee2b096224EeAc085Bb9a8cba1146f7D": { diff --git a/test/bridge/trustless/EnhancedSwapRouter.t.sol b/test/bridge/trustless/EnhancedSwapRouter.t.sol index d710330..45f36f0 100644 --- a/test/bridge/trustless/EnhancedSwapRouter.t.sol +++ b/test/bridge/trustless/EnhancedSwapRouter.t.sol @@ -12,9 +12,58 @@ contract MockERC20 is ERC20 { } } +contract MockLiquidityProvider { + mapping(address => mapping(address => bool)) public supported; + mapping(address => mapping(address => uint256)) public quotes; + + function setSupport(address tokenIn, address tokenOut, bool isSupported) external { + supported[tokenIn][tokenOut] = isSupported; + } + + function setQuote(address tokenIn, address tokenOut, uint256 amountOut) external { + quotes[tokenIn][tokenOut] = amountOut; + } + + function getQuote( + address tokenIn, + address tokenOut, + uint256 + ) external view returns (uint256 amountOut, uint256 slippageBps) { + if (!supported[tokenIn][tokenOut]) { + return (0, 10000); + } + return (quotes[tokenIn][tokenOut], 30); + } + + function executeSwap( + address tokenIn, + address tokenOut, + uint256 amountIn, + uint256 + ) external returns (uint256 amountOut) { + require(supported[tokenIn][tokenOut], "unsupported"); + amountOut = quotes[tokenIn][tokenOut]; + ERC20(tokenIn).transferFrom(msg.sender, address(this), amountIn); + ERC20(tokenOut).transfer(msg.sender, amountOut); + } + + function supportsTokenPair(address tokenIn, address tokenOut) external view returns (bool) { + return supported[tokenIn][tokenOut]; + } + + function providerName() external pure returns (string memory) { + return "Mock"; + } + + function estimateGas(address, address, uint256) external pure returns (uint256) { + return 150000; + } +} + contract EnhancedSwapRouterTest is Test { EnhancedSwapRouter public router; LiquidityPoolETH public liquidityPool; + MockLiquidityProvider public liquidityProvider; MockERC20 public weth; MockERC20 public usdt; @@ -39,6 +88,7 @@ contract EnhancedSwapRouterTest is Test { usdt = new MockERC20("Tether USD", "USDT"); usdc = new MockERC20("USD Coin", "USDC"); dai = new MockERC20("Dai Stablecoin", "DAI"); + liquidityProvider = new MockLiquidityProvider(); // Deploy liquidity pool liquidityPool = new LiquidityPoolETH(address(weth), 5, 11000); @@ -133,8 +183,43 @@ contract EnhancedSwapRouterTest is Test { function testSwapTokenToTokenRevertsWhenPoolNotSet() public { vm.prank(user); weth.approve(address(router), 1 ether); - vm.expectRevert("EnhancedSwapRouter: Dodoex pool not configured"); + vm.expectRevert(EnhancedSwapRouter.DodoRouteNotConfigured.selector); + router.swapTokenToToken(address(weth), address(usdt), 1 ether, 0); + } + + function testSetDodoLiquidityProvider() public { + vm.prank(deployer); + router.setDodoLiquidityProvider(address(liquidityProvider)); + assertEq(router.dodoLiquidityProvider(), address(liquidityProvider)); + } + + function testGetQuotesUsesDodoLiquidityProviderWhenRouteSupported() public { + vm.startPrank(deployer); + router.setDodoLiquidityProvider(address(liquidityProvider)); + router.setProviderEnabled(EnhancedSwapRouter.SwapProvider.UniswapV3, false); + router.setProviderEnabled(EnhancedSwapRouter.SwapProvider.Balancer, false); + vm.stopPrank(); + + liquidityProvider.setSupport(address(weth), address(usdt), true); + liquidityProvider.setQuote(address(weth), address(usdt), 1234); + + (EnhancedSwapRouter.SwapProvider[] memory providers, uint256[] memory amounts) = + router.getQuotes(address(usdt), 1 ether); + + assertEq(providers.length, 1); + assertEq(uint256(providers[0]), uint256(EnhancedSwapRouter.SwapProvider.Dodoex)); + assertEq(amounts[0], 1234); + } + + function testSwapTokenToTokenRevertsWhenProviderRouteMissing() public { + address mockPool = address(0xDD00); + vm.startPrank(deployer); + router.setDodoPoolAddress(address(weth), address(usdt), mockPool); + router.setDodoLiquidityProvider(address(liquidityProvider)); + vm.stopPrank(); + + vm.prank(user); + vm.expectRevert(EnhancedSwapRouter.DodoRouteNotConfigured.selector); router.swapTokenToToken(address(weth), address(usdt), 1 ether, 0); } } - diff --git a/test/dex/DODOPMMIntegration.t.sol b/test/dex/DODOPMMIntegration.t.sol index 8ef4b44..e753d75 100644 --- a/test/dex/DODOPMMIntegration.t.sol +++ b/test/dex/DODOPMMIntegration.t.sol @@ -11,6 +11,24 @@ contract MockERC20 is ERC20 { } } +contract MockDodoPool { + address public immutable baseToken; + address public immutable quoteToken; + + constructor(address baseToken_, address quoteToken_) { + baseToken = baseToken_; + quoteToken = quoteToken_; + } + + function _BASE_TOKEN_() external view returns (address) { + return baseToken; + } + + function _QUOTE_TOKEN_() external view returns (address) { + return quoteToken; + } +} + contract DODOPMMIntegrationTest is Test { DODOPMMIntegration public integration; address public dvm = address(0xdEaD); @@ -90,4 +108,66 @@ contract DODOPMMIntegrationTest is Test { true ); } + + function testImportExistingPoolRecordsMappings() public { + address baseToken = address(officialUSDT); + address quoteToken = address(compliantUSDC); + MockDodoPool pool = new MockDodoPool(baseToken, quoteToken); + + vm.prank(admin); + integration.importExistingPool( + address(pool), + baseToken, + quoteToken, + 3, + 1e18, + 0.5e18, + false + ); + + assertEq(integration.pools(baseToken, quoteToken), address(pool)); + assertEq(integration.pools(quoteToken, baseToken), address(pool)); + assertTrue(integration.isRegisteredPool(address(pool))); + + DODOPMMIntegration.PoolConfig memory config = integration.getPoolConfig(address(pool)); + assertEq(config.baseToken, baseToken); + assertEq(config.quoteToken, quoteToken); + } + + function testImportExistingPoolAcceptsReverseHintAndNormalizes() public { + address baseToken = address(officialUSDT); + address quoteToken = address(compliantUSDC); + MockDodoPool pool = new MockDodoPool(baseToken, quoteToken); + + vm.prank(admin); + integration.importExistingPool( + address(pool), + quoteToken, + baseToken, + 3, + 1e18, + 0.5e18, + false + ); + + DODOPMMIntegration.PoolConfig memory config = integration.getPoolConfig(address(pool)); + assertEq(config.baseToken, baseToken); + assertEq(config.quoteToken, quoteToken); + } + + function testImportExistingPoolRevertsOnMismatch() public { + MockDodoPool pool = new MockDodoPool(address(officialUSDT), address(compliantUSDC)); + + vm.prank(admin); + vm.expectRevert("DODOPMMIntegration: pool token mismatch"); + integration.importExistingPool( + address(pool), + address(officialUSDT), + address(compliantUSDT), + 3, + 1e18, + 0.5e18, + false + ); + } }