@@ -775,39 +775,51 @@ other yield ops.
775775sequenceDiagram
776776 autonumber
777777 box Base
778- actor Op as Operator
779778 participant Master as Master Strategy
780- participant Adapter as Adapter <<Outbound >>
781- participant ReturnB as Adapter <<Inbound >>
779+ participant Adapter as CCIPAdapter <<Master outbound >>
780+ participant SuperBase as SuperbridgeAdapter <<Master inbound >>
782781 end
783782
783+ actor Op as Operator
784784 participant Bridge as CCIP DON
785785
786786 box Ethereum
787- participant AdapterEth as Adapter <<Inbound >>
787+ participant AdapterEth as CCIPAdapter <<Remote inbound >>
788788 participant Remote as Remote Strategy
789- participant ReturnA as Adapter <<Outbound >>
789+ participant SuperEth as SuperbridgeAdapter <<Remote outbound >>
790790 end
791791
792792 Note over Master: lastYieldNonce = N (any value)<br/>bridgeAdjustment = B (any value)
793793 Op->>Master: requestBalanceCheck{value: optionalTopUp}()
794- Master->>Adapter: sendMessage(payload[BALANCE_CHECK_REQUEST, nonce=N, timestamp])
794+ Note over Master: timestamp = block.timestamp<br/>body = abi.encode(timestamp)<br/>payload = packPayload(BALANCE_CHECK_REQUEST, N, body)
795+ Master->>Adapter: quoteFee(address(0), 0, payload)
796+ Adapter-->>Master: fee, feeToken = native, requiresExternalPayment = true
797+ Note over Master: Master Strategy pays the CCIP fee from its own ETH balance
798+ Master->>Adapter: sendMessage{value:fee}(payload)
799+ Note over Master,Adapter: adapter call is payable<br/>fee is forwarded as msg.value
795800 Note over Master: NONCE ECHOED, NOT ADVANCED.<br/>lastYieldNonce stays N.
796- Adapter->>Bridge: ccipSend
801+ Adapter->>Bridge: ccipSend{value:fee}(ETH_SELECTOR, ccipMessage)
797802 Note over Adapter,Bridge: ccipMessage fields: receiver = peer adapter, data = envelope, tokenAmounts = empty, feeToken = native<br/>envelope = (envelopeSender, intendedAmount = 0, payload)
798- Bridge->>AdapterEth: ccipReceive
799- AdapterEth->>Remote: receiveMessage(...)
800- Note over Remote: yieldOnly = _viewCheckBalance() - bridgeAdjustment<br/>(cancels bridge channel effects: see comment in code)
801- Remote->>Remote: clamp yieldOnly to 0 if negative<br/>4626 rounding dust only<br/>never significantly negative — no negative rebase
802- Remote->>ReturnA: sendMessage(payload[BALANCE_CHECK_RESPONSE,<br/>nonce=N, abi.encode(yieldOnly, srcTimestamp)])
803- Note over Remote: DOES NOT call _acceptYieldNonce.<br/>Read-only on Remote's side.
804- ReturnA->>Bridge: ccipSend
805- Note over ReturnA,Bridge: ccipMessage fields: receiver = peer adapter, data = envelope, tokenAmounts = empty, feeToken = native<br/>envelope = (envelopeSender, intendedAmount = 0, payload)
806- Bridge->>ReturnB: ccipReceive(message)
807- Note over Bridge,ReturnB: ccipReceive gets the CCIP message<br/>message.data decodes to envelope = (envelopeSender, intendedAmount = 0, payload)
808- ReturnB->>Master: receiveMessage(Master, 0, 0, payload)
809- Note over ReturnB,Master: params: sender = Master, token = address(0), amountReceived = 0<br/>payload = packPayload(BALANCE_CHECK_RESPONSE, N, body)
810- Master->>Master: _processBalanceCheckResponse(N, body):<br/>guard 1: if isYieldOpInFlight() → return<br/>guard 2: if respNonce != lastYieldNonce → return<br/>guard 3: if respTimestamp <= lastBalanceCheckTimestamp → return
803+ Bridge->>AdapterEth: ccipReceive(message)
804+ Note over Bridge,AdapterEth: ccipReceive gets the CCIP message<br/>message.data decodes to envelope = (envelopeSender, intendedAmount = 0, payload)
805+ AdapterEth->>Remote: receiveMessage(Remote, 0, 0, payload)
806+ Note over AdapterEth,Remote: params: sender = Remote, token = address(0), amountReceived = 0<br/>payload = packPayload(BALANCE_CHECK_REQUEST, N, body)
807+ Remote->>Remote: _yieldOnlyBaseline()
808+ Note over Remote: yieldBaseline = _viewCheckBalance() - bridgeAdjustment, clamped to 0<br/>clamp only covers tiny 4626 rounding dust
809+ Note over Remote: srcTimestamp = timestamp from request body<br/>body = encode(yieldBaseline, srcTimestamp)<br/>payload = packPayload(BALANCE_CHECK_RESPONSE, N, body)
810+ Remote->>SuperEth: quoteFee(address(0), 0, payload)
811+ SuperEth-->>Remote: fee, feeToken = native, requiresExternalPayment = true
812+ Note over Remote: Remote Strategy pays the CCIP fee from its own ETH balance
813+ Remote->>SuperEth: sendMessage{value:fee}(payload)
814+ Note over Remote,SuperEth: DOES NOT call _acceptYieldNonce<br/>read-only on Remote Strategy<br/>adapter call is payable and forwards fee as msg.value
815+ SuperEth->>Bridge: ccipSend{value:fee}(BASE_SELECTOR, ccipMessage)
816+ Note over SuperEth,Bridge: ccipMessage fields: receiver = peer adapter, data = envelope, tokenAmounts = empty, feeToken = native<br/>envelope = (envelopeSender, intendedAmount = 0, payload)
817+ Bridge->>SuperBase: ccipReceive(message)
818+ Note over Bridge,SuperBase: ccipReceive gets the CCIP message<br/>message.data decodes to envelope = (envelopeSender, intendedAmount = 0, payload)
819+ SuperBase->>Master: receiveMessage(Master, 0, 0, payload)
820+ Note over SuperBase,Master: params: sender = Master, token = address(0), amountReceived = 0<br/>payload = packPayload(BALANCE_CHECK_RESPONSE, N, body)
821+ Master->>Master: _processBalanceCheckResponse(N, body)
822+ Note over Master: guard 1: if isYieldOpInFlight() then return<br/>guard 2: if response nonce != lastYieldNonce then return<br/>guard 3: if response timestamp <= lastBalanceCheckTimestamp then return
811823 alt all guards pass
812824 Note over Master: store lastBalanceCheckTimestamp = respTimestamp<br/>store remoteStrategyBalance = yieldBaseline
813825 Note over Master: emit BalanceCheckResponded
0 commit comments