@@ -1067,50 +1067,64 @@ settlement is no longer correctness-critical, just hygiene.
10671067sequenceDiagram
10681068 autonumber
10691069 box Base
1070- actor Op as Operator
10711070 participant Master as Master Strategy
1072- participant Adapter as Adapter <<Outbound >>
1073- participant ReturnB as Adapter <<Inbound >>
1071+ participant Adapter as CCIPAdapter <<Master outbound >>
1072+ participant SuperBase as SuperbridgeAdapter <<Master inbound >>
10741073 end
10751074
1075+ actor Op as Operator
10761076 participant Bridge as CCIP DON
10771077
10781078 box Ethereum
1079- participant AdapterEth as Adapter <<Inbound >>
1079+ participant AdapterEth as CCIPAdapter <<Remote inbound >>
10801080 participant Remote as Remote Strategy
1081- participant ReturnA as Adapter <<Outbound >>
1081+ participant SuperEth as SuperbridgeAdapter <<Remote outbound >>
10821082 end
10831083
10841084 Note over Master: bridgeAdjustment = -10 (one BRIDGE_OUT for net=10 happened)<br/>Remote.bridgeAdjustment = -10 also
10851085 Op->>Master: requestSettlement{value: fee}()
10861086 Master->>Master: _getNextYieldNonce()
10871087 Note over Master: store lastYieldNonce = nonce<br/>returns nonce
10881088 Note over Master: store settlementSnapshot = -10<br/>persisted for ack handler
1089- Master->>Adapter: sendMessage(payload[SETTLE_BRIDGE_ACCOUNTING, nonce,<br/>abi.encode(int256(-10))])
1089+ Note over Master: body = abi.encode(int256(-10))<br/>payload = packPayload(SETTLE_BRIDGE_ACCOUNTING, nonce, body)
1090+ Master->>Adapter: quoteFee(address(0), 0, payload)
1091+ Adapter-->>Master: fee, feeToken = native, requiresExternalPayment = true
1092+ Note over Master: Master Strategy pays the CCIP fee from its own ETH balance<br/>operator msg.value can top up that balance
1093+ Master->>Adapter: sendMessage{value:fee}(payload)
1094+ Note over Master,Adapter: adapter call is payable<br/>fee is forwarded as msg.value
10901095 Note over Master: emit SettlementRequested(nonce, -10)<br/>Master.bridgeAdjustment STILL -10 (NOT zeroed yet)
1091- Adapter->>Bridge: ccipSend
1096+ Adapter->>Bridge: ccipSend{value:fee}(ETH_SELECTOR, ccipMessage)
10921097 Note over Adapter,Bridge: ccipMessage fields: receiver = peer adapter, data = envelope, tokenAmounts = empty, feeToken = native<br/>envelope = (envelopeSender, intendedAmount = 0, payload)
10931098
10941099 Note over Master,Bridge: (optional: a new BRIDGE_OUT for net=5 happens here.<br/>Master.bridgeAdjustment becomes -15. This is the in-flight case.)
10951100
1096- Bridge->>AdapterEth: ccipReceive
1097- AdapterEth->>Remote: receiveMessage(...)
1101+ Bridge->>AdapterEth: ccipReceive(message)
1102+ Note over Bridge,AdapterEth: ccipReceive gets the CCIP message<br/>message.data decodes to envelope = (envelopeSender, intendedAmount = 0, payload)
1103+ AdapterEth->>Remote: receiveMessage(Remote, 0, 0, payload)
1104+ Note over AdapterEth,Remote: params: sender = Remote, token = address(0), amountReceived = 0<br/>payload = packPayload(SETTLE_BRIDGE_ACCOUNTING, nonce, body)
10981105 Remote->>Remote: _processSettlement(nonce, body)
10991106 Note over Remote: subtract only the snapshot amount, do not reset to zero<br/>snapshot = -10, so store bridgeAdjustment -= -10<br/>no in-flight bridge: -10 - (-10) = 0<br/>new BRIDGE_OUT already applied: -15 - (-10) = -5<br/>new BRIDGE_OUT not applied yet: -10 - (-10) = 0
1100- Remote->>Remote: _viewCheckBalance()
1101- Note over Remote: yieldOnly = _viewCheckBalance() - bridgeAdjustment<br/>yield-only baseline preserves consistency across orderings
1102- Remote->>ReturnA: sendMessage(payload[SETTLE_BRIDGE_ACCOUNTING_ACK, nonce,<br/>abi.encode(yieldOnly)])
1107+ Remote->>Remote: _yieldOnlyBaseline()
1108+ Note over Remote: yieldBaseline = _viewCheckBalance() - bridgeAdjustment, clamped to 0<br/>yield-only baseline preserves consistency across orderings
1109+ Note over Remote: body = abi.encode(yieldBaseline)<br/>payload = packPayload(SETTLE_BRIDGE_ACCOUNTING_ACK, nonce, body)
1110+ Remote->>SuperEth: quoteFee(address(0), 0, payload)
1111+ SuperEth-->>Remote: fee, feeToken = native, requiresExternalPayment = true
1112+ Note over Remote: Remote Strategy pays the CCIP fee from its own ETH balance
1113+ Remote->>SuperEth: sendMessage{value:fee}(payload)
1114+ Note over Remote,SuperEth: adapter call is payable<br/>fee is forwarded as msg.value
11031115 Remote->>Remote: _acceptYieldNonce(nonce)
11041116 Note over Remote: store lastYieldNonce = nonce<br/>store nonceProcessed[nonce] = true
1105- ReturnA->>Bridge: ccipSend
1106- Note over ReturnA,Bridge: ccipMessage fields: receiver = peer adapter, data = envelope, tokenAmounts = empty, feeToken = native<br/>envelope = (envelopeSender, intendedAmount = 0, payload)
1107- Bridge->>ReturnB: ccipReceive
1108- ReturnB->>Master: receiveMessage(...)
1109- Master->>Master: _processSettlementAck
1117+ SuperEth->>Bridge: ccipSend{value:fee}(BASE_SELECTOR, ccipMessage)
1118+ Note over SuperEth,Bridge: ccipMessage fields: receiver = peer adapter, data = envelope, tokenAmounts = empty, feeToken = native<br/>envelope = (envelopeSender, intendedAmount = 0, payload)
1119+ Bridge->>SuperBase: ccipReceive(message)
1120+ Note over Bridge,SuperBase: ccipReceive gets the CCIP message<br/>message.data decodes to envelope = (envelopeSender, intendedAmount = 0, payload)
1121+ SuperBase->>Master: receiveMessage(Master, 0, 0, payload)
1122+ Note over SuperBase,Master: params: sender = Master, token = address(0), amountReceived = 0<br/>payload = packPayload(SETTLE_BRIDGE_ACCOUNTING_ACK, nonce, body)
1123+ Master->>Master: _processSettlementAck(nonce, body)
11101124 Master->>Master: _markYieldNonceProcessed(nonce)
11111125 Note over Master: lastYieldNonce stays nonce<br/>store nonceProcessed[nonce] = true
1112- Note over Master: subtract only settlementSnapshot, do not reset to zero<br/>settlementSnapshot = -10, so store bridgeAdjustment -= -10<br/>no in-flight bridge: -10 - (-10) = 0<br/>new BRIDGE_OUT happened: -15 - (-10) = -5<br/>then store settlementSnapshot = 0 and store remoteStrategyBalance = yieldOnly
1113- Note over Master: emit SettlementAcked(nonce, yieldOnly )
1126+ Note over Master: subtract only settlementSnapshot, do not reset to zero<br/>settlementSnapshot = -10, so store bridgeAdjustment -= -10<br/>no in-flight bridge: -10 - (-10) = 0<br/>new BRIDGE_OUT happened: -15 - (-10) = -5<br/>then store settlementSnapshot = 0 and store remoteStrategyBalance = yieldBaseline
1127+ Note over Master: emit SettlementAcked(nonce, yieldBaseline )
11141128```
11151129
11161130### Why snapshot-subtract instead of ` = 0 `
0 commit comments