Skip to content

Commit bbaee69

Browse files
committed
Check balance diagram changes
1 parent 65c881a commit bbaee69

1 file changed

Lines changed: 32 additions & 20 deletions

File tree

  • contracts/contracts/strategies/crosschainV3

contracts/contracts/strategies/crosschainV3/FLOWS.md

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -775,39 +775,51 @@ other yield ops.
775775
sequenceDiagram
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

Comments
 (0)