Deploy and verify L1BTCDepositorNttWithExecutor on Ethereum Mainnet and Sepolia#908
Deploy and verify L1BTCDepositorNttWithExecutor on Ethereum Mainnet and Sepolia#908jose-compu wants to merge 27 commits intothreshold-network:mainfrom
Conversation
077528e to
c9f759e
Compare
piotr-roslaniec
left a comment
There was a problem hiding this comment.
If you decide to use LLMs in development, please make sure the code and the comments are accurate and that the comments are not redundant.
solidity/test/cross-chain/wormhole/L1BTCDepositorNttWithExecutor.executor.test.ts
Show resolved
Hide resolved
solidity/contracts/cross-chain/wormhole/L1BTCDepositorNttWithExecutor.sol
Outdated
Show resolved
Hide resolved
- Add simple-deploy.ts for L1BTCDepositorNttWithExecutor deployment - Update hardhat.config.ts to use Etherscan API V2 and environment variables
solidity/contracts/cross-chain/wormhole/L1BTCDepositorNttWithExecutor.sol
Show resolved
Hide resolved
…us fee parameters (MB-C1) Add validation in setExecutorParameters() to enforce that feeArgs.payee must match defaultPlatformFeeRecipient, preventing attackers from redirecting platform fees to arbitrary addresses. Initialize defaultPlatformFeeRecipient to Threshold Committee wallet (0x9F6e831c8F8939DC0C830C6e492e7cEf4f9C2F5f) on contract initialization. Changes: - Add payee validation in setExecutorParameters() requiring match with defaultPlatformFeeRecipient - Set defaultPlatformFeeRecipient to 0x9F6e831c8F8939DC0C830C6e492e7cEf4f9C2F5f in initialize() - Add comprehensive test suite demonstrating vulnerability and fix effectiveness - Update existing tests to align with new validation requirements The vulnerability allowed malicious actors to set arbitrary fee recipients when calling setExecutorParameters(), enabling them to steal platform fees from legitimate deposits. This fix ensures all fees are directed to the protocol-designated recipient. Tests: 164 passing in L1BTCDepositorNttWithExecutor test suite
…meter validation (MB-C2) Add comprehensive parameter validation to prevent deposit loss scenarios: 1. Extract and validate embedded expiry timestamp from signed quotes 2. Validate total payment includes both executor cost and NTT delivery price 3. Remove timestamp refresh to prevent artificial quote expiry extension Changes: - Add _validateAndExtractQuoteExpiry() to extract and validate quote expiry at byte offset 60 - Enhance _transferTbtcWithExecutor() to validate msg.value >= executorArgs.value + nttDeliveryPrice - Remove timestamp refresh in setExecutorParameters() to preserve original expiration tracking - Add comprehensive C2 vulnerability test suite with 5 tests - Add contract size validation test confirming 19.6 KB (within 24 KB Ethereum limit) The vulnerability allowed deposits to be finalized with expired quotes or insufficient payment, resulting in cross-chain transfer failures and loss of deposited funds. This fix ensures deposits only finalize when they can actually be delivered cross-chain. Tests: 169 passing (includes C1 + C2 vulnerability tests) Contract size: 19.6 KB (80% of 24 KB Ethereum mainnet limit)
…nd vulnerability fixes Introduces AbstractL1BTCDepositorV2 to address three refund-related vulnerabilities in deposit finalization, isolated to NTT contracts only. MB-H1 (Refund Order): Finalization refund calculated before initialization refund to prevent gas double-counting attacks via malicious receiver fallbacks. MB-H2 (Refund Blocking): Added try-catch protection and claimReimbursement() function to prevent deposit blocking when ReimbursementPool is unavailable. MB-H3 (Gas Price Arbitrage): GasReimbursement struct stores exact wei amounts locked at initialization gas price to prevent arbitrage between init and finalize. L1BTCDepositorNttWithExecutor now inherits from V2 while other depositor implementations remain on AbstractL1BTCDepositor unchanged.
The deployed Wormhole NttManagerWithExecutor contract doesn't expose quoteDeliveryPrice(). Fixed by querying the underlying NTT manager directly in all quote functions. Changes: - quoteFinalizeDeposit() now queries INttManager(underlyingNttManager) - quoteFinalizeDeposit(uint16) now queries INttManager(underlyingNttManager) - Both calculate total cost as: nttDeliveryPrice + executorArgs.value Compatible with deployed Wormhole contracts. All 183 tests passing.
NttManagerWithExecutor uses 100000 divisor. Updated all comments and error messages to correctly state MAX_BPS = 10000 = 10%.
1. Add gas limit validation in setDefaultParameters() 2. Add ExecutorParametersCleared event for monitoring 3. Remove redundant signed quote length checks Contract size reduced by 0.147 KB through eliminating duplicate validations.
Store absolute expiryTimestamp in ExecutorParameterSet to prevent governance changes from retroactively affecting existing parameters. Adds expiryTimestamp field set to block.timestamp + parameterExpirationTime at creation.
antomor
left a comment
There was a problem hiding this comment.
@jose-blockchain I haven't focussed the review on the sc as I don't have context for the reasons behind those changes, but I've left some comments on the deployment scripts. Apart from them, I'd try to avoid any as much as possible to get the most from ts. Furthermore, although not linked to this PR, I could see from npm i that some packages require security fixes that could be quickly applied with npm audit fix.
|
@antomor thanks a lot! For merging, it seems I still need code review from leo or piotr still as they are code owners |
Ethereum:
0xf79b82b345573F7087375ed758eDAa33acCDeCED0x2353A3BCE0703c73F8B1F9e036034AC2BA7feAF6Sepolia:
0x1C805997c6D8Ed2aC38323fd810130c601435f83(proxy)0x156C78f7c3754D79FA873c942116a0b84846c85dKey Changes:
getUserNonceSequence(address user)getter function to save bytecodeuserNonceCountermappingchainid=1parameterethereum.publicnode.comfor reliable deploymentContract Features:
Nonce System:
userNonceCounter) that increments with each new parameter setkeccak256(user_address, sequence)to support parallel workflows across multiple usersgetUserNonceSequence()function was removed during size optimization. Nonce information remains accessible throughgetUserWorkflowInfo()andgetUserWorkflowStatus()for active workflowsReady for production use on Ethereum Mainnet.