Skip to content

Commit e1dfa8d

Browse files
committed
Bridge out and in sequence diagrams
1 parent bbaee69 commit e1dfa8d

1 file changed

Lines changed: 76 additions & 25 deletions

File tree

  • contracts/contracts/strategies/crosschainV3

contracts/contracts/strategies/crosschainV3/FLOWS.md

Lines changed: 76 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -897,57 +897,108 @@ sequenceDiagram
897897
actor Alice as User (Alice)
898898
participant Master as Master Strategy
899899
participant L2V as L2 OETHb Vault
900-
participant Adapter as CCIPAdapter <<Outbound>>
900+
participant Adapter as CCIPAdapter <<Master outbound>>
901901
end
902902
903903
participant Bridge as CCIP DON
904904
905905
box Ethereum
906-
participant AdapterEth as CCIPAdapter <<Inbound>>
906+
participant AdapterEth as CCIPAdapter <<Remote inbound>>
907907
participant Remote as Remote Strategy
908908
participant wOETH as wOETH <<4626>>
909909
actor AliceEth as Alice
910910
end
911911
912912
Alice->>Master: approve(Master, X) [OETHb]
913913
Alice->>Master: bridgeOTokenToPeer{value: fee}(X, alice_eth, "0x", 0)
914-
Master->>Master: fee = X * bridgeFeeBps / 10_000<br/>net = X - fee<br/>require(net > 0)
915-
Master->>Master: liquidity gate:<br/>require(net <= availableBridgeLiquidity())<br/>(rsb + bridgeAdjustment - pendingWithdrawalAmount)
914+
Note over Master: bridgeFee = X * bridgeFeeBps / 10_000<br/>net = X - bridgeFee<br/>net must be greater than 0
915+
Note over Master: net must fit within available bridge liquidity<br/>available = remoteStrategyBalance + bridgeAdjustment - pendingWithdrawalAmount
916+
Note over Master: transfers X OETHb from Alice to Master Strategy
916917
Master->>L2V: burnForStrategy(X)
917-
Alice-->>L2V: «OETHb X» transferred from Alice and burned
918918
Note over Master: store bridgeAdjustment -= net (NOT -= X)<br/>store bridgeIdCounter += 1<br/>store bridgeId = keccak256(strategy, counter)
919-
Master->>Master: _send(userFunded=true):<br/>require(msg.value >= ccipFee)<br/>(pool NOT consulted)
920-
Master->>Adapter: sendMessage{value: fee}(payload[BRIDGE_OUT, 0, BridgeUserPayload{<br/> bridgeId, amount=net, recipient=alice_eth, callData, callGasLimit<br/>}])
921-
Adapter->>Bridge: ccipSend
919+
Note over Master: body = encode(bridgeId, net, alice_eth, callData, callGasLimit)<br/>payload = packPayload(BRIDGE_OUT, 0, body)
920+
Master->>Adapter: quoteFee(address(0), 0, payload)
921+
Adapter-->>Master: ccipFee, feeToken = native, requiresExternalPayment = true
922+
Note over Master: user pays CCIP fee with msg.value<br/>strategy ETH pool is not used
923+
Master->>Adapter: sendMessage{value:ccipFee}(payload)
924+
Note over Master,Adapter: adapter call is payable<br/>ccipFee is forwarded as msg.value<br/>excess user msg.value remains in Master Strategy
925+
Adapter->>Bridge: ccipSend{value:ccipFee}(ETH_SELECTOR, ccipMessage)
922926
Note over Adapter,Bridge: ccipMessage fields: receiver = peer adapter, data = envelope, tokenAmounts = empty, feeToken = native<br/>envelope = (envelopeSender, intendedAmount = 0, payload)
923-
Note over Master: emit BridgeRequested(bridgeId, alice, alice_eth, net, fee, ...)
924-
Bridge->>AdapterEth: ccipReceive
927+
Note over Master: emit BridgeRequested(bridgeId, alice, alice_eth, net, bridgeFee, ...)
928+
Bridge->>AdapterEth: ccipReceive(message)
929+
Note over Bridge,AdapterEth: ccipReceive gets the CCIP message<br/>message.data decodes to envelope = (envelopeSender, intendedAmount = 0, payload)
925930
AdapterEth->>Remote: receiveMessage(Remote, 0, 0, payload)
926-
Remote->>Remote: unpack BRIDGE_OUT and decode BridgeUserPayload
931+
Note over AdapterEth,Remote: params: sender = Remote, token = address(0), amountReceived = 0<br/>payload = packPayload(BRIDGE_OUT, 0, body)
932+
Remote->>Remote: unpackPayload(payload)
933+
Note over Remote: body decodes to BridgeUserPayload<br/>bridgeId, amount = net, recipient = alice_eth, callData, callGasLimit
927934
Note over Remote: require(!consumedBridgeIds[bridgeId])<br/>store consumedBridgeIds[bridgeId] = true<br/>store bridgeAdjustment -= net
928-
Remote->>wOETH: withdraw(net, Remote, Remote) [shares→OETH]
935+
Remote->>wOETH: withdraw(net, Remote, Remote)
936+
Note over Remote,wOETH: unwrap wOETH shares to OETH
929937
wOETH-->>Remote: «OETH net» unwrapped
930-
Remote->>AliceEth: «OETH net» transfer
938+
Note over Remote: transfers net OETH from Remote Strategy to Alice
931939
Note over Remote: emit BridgeDelivered(bridgeId, alice_eth, net)
932940
opt callData provided
933-
Remote->>Remote: _postDeliveryCall(p):<br/>recipient.call{value:0, gas:p.callGasLimit}(p.callData)
941+
Remote->>Remote: _postDeliveryCall(p)
942+
Note over Remote: recipient.call{value:0, gas:callGasLimit}(callData)
934943
Note over Remote: emit BridgeCallSucceeded / BridgeCallFailed
935944
end
936945
```
937946

938947
### BRIDGE_IN (Remote wraps, Master mints) — mirror image
939948

940-
Same structure with the roles flipped:
941-
942-
- Bob calls `Remote.bridgeOTokenToPeer{value: fee}(Y, bob_base, ...)` on
943-
Ethereum.
944-
- Remote wraps **full Y** OETH into wOETH shares.
945-
- `bridgeAdjustment += net` on Remote.
946-
- Sends BRIDGE_IN envelope to Master via `SuperbridgeAdapter` (message-only;
947-
no canonical bridge leg needed for bridge channel).
948-
- Master receives, decodes BRIDGE_IN, mints **only `net`** OETHb via L2 vault,
949-
transfers to `bob_base`.
950-
- `bridgeAdjustment += net` on Master.
949+
```mermaid
950+
sequenceDiagram
951+
autonumber
952+
box Ethereum
953+
actor Bob as User (Bob)
954+
participant Remote as Remote Strategy
955+
participant wOETH as wOETH <<4626>>
956+
participant SuperEth as SuperbridgeAdapter <<Remote outbound>>
957+
end
958+
959+
participant Bridge as CCIP DON
960+
961+
box Base
962+
participant SuperBase as SuperbridgeAdapter <<Master inbound>>
963+
participant Master as Master Strategy
964+
participant L2V as L2 OETHb Vault
965+
actor BobBase as Bob
966+
end
967+
968+
Bob->>Remote: approve(Remote, Y) [OETH]
969+
Bob->>Remote: bridgeOTokenToPeer{value: fee}(Y, bob_base, callData, callGasLimit)
970+
Note over Remote: bridgeFee = Y * bridgeFeeBps / 10_000<br/>net = Y - bridgeFee<br/>net must be greater than 0
971+
Note over Remote: callGasLimit must be within MAX_BRIDGE_CALL_GAS<br/>callData requires nonzero callGasLimit
972+
Note over Remote: transfers Y OETH from Bob to Remote Strategy
973+
Remote->>wOETH: deposit(Y, Remote)
974+
Note over Remote,wOETH: wrap full Y OETH into wOETH shares held by Remote Strategy
975+
Note over Remote: store bridgeAdjustment += net<br/>store bridgeIdCounter += 1<br/>store bridgeId = keccak256(strategy, counter)
976+
Note over Remote: body = encode(bridgeId, net, bob_base, callData, callGasLimit)<br/>payload = packPayload(BRIDGE_IN, 0, body)
977+
Remote->>SuperEth: quoteFee(address(0), 0, payload)
978+
SuperEth-->>Remote: ccipFee, feeToken = native, requiresExternalPayment = true
979+
Note over Remote: user pays CCIP fee with msg.value<br/>strategy ETH pool is not used
980+
Remote->>SuperEth: sendMessage{value:ccipFee}(payload)
981+
Note over Remote,SuperEth: adapter call is payable<br/>ccipFee is forwarded as msg.value<br/>excess user msg.value remains in Remote Strategy
982+
Note over SuperEth: message-only send through CCIP leg<br/>no canonical bridge transfer
983+
SuperEth->>Bridge: ccipSend{value:ccipFee}(BASE_SELECTOR, ccipMessage)
984+
Note over SuperEth,Bridge: ccipMessage fields: receiver = peer adapter, data = envelope, tokenAmounts = empty, feeToken = native<br/>envelope = (envelopeSender, intendedAmount = 0, payload)
985+
Note over Remote: emit BridgeRequested(bridgeId, bob, bob_base, net, bridgeFee, ...)
986+
Bridge->>SuperBase: ccipReceive(message)
987+
Note over Bridge,SuperBase: ccipReceive gets the CCIP message<br/>message.data decodes to envelope = (envelopeSender, intendedAmount = 0, payload)
988+
SuperBase->>Master: receiveMessage(Master, 0, 0, payload)
989+
Note over SuperBase,Master: params: sender = Master, token = address(0), amountReceived = 0<br/>payload = packPayload(BRIDGE_IN, 0, body)
990+
Master->>Master: unpackPayload(payload)
991+
Note over Master: body decodes to BridgeUserPayload<br/>bridgeId, amount = net, recipient = bob_base, callData, callGasLimit
992+
Note over Master: require(!consumedBridgeIds[bridgeId])<br/>store consumedBridgeIds[bridgeId] = true<br/>store bridgeAdjustment += net
993+
Master->>L2V: mintForStrategy(net)
994+
Note over Master: transfers net OETHb from Master Strategy to Bob
995+
Note over Master: emit BridgeDelivered(bridgeId, bob_base, net)
996+
opt callData provided
997+
Master->>Master: _postDeliveryCall(p)
998+
Note over Master: recipient.call{value:0, gas:callGasLimit}(callData)
999+
Note over Master: emit BridgeCallSucceeded / BridgeCallFailed
1000+
end
1001+
```
9511002

9521003
### Yield retention math
9531004

0 commit comments

Comments
 (0)