Summary
This proposal closes the idle sDOLA Chainlink CCIP integration. It removes every cross-chain lane, in both directions, across all five sDOLA token pools: the mainnet pool and the four L2 pools on Base, Optimism, Arbitrum, and Berachain. It also revokes each L2 pool’s minter permission on its receipt token. The L2 changes are batched through BridgeShutdownGovernor, a purpose-built contract that fires all 8 cross-chain shutdown messages in a single executeL2Shutdown() call. The mainnet pool is closed by one direct action.
The shutdown transfers no pool to a new owner. The mainnet pool stays owned by the timelock, and each L2 pool stays owned by its governance proxy. Only GovernanceSender ownership moves, to the governor and back to the timelock. GovernanceSender is delegated to the governor for the shutdown and handed back during execution.
Rationale
The sDOLA CCIP integration is not in use. Monitoring shows no live cross-chain activity and no deposits. While the integration sits idle, open bridge lanes are an unnecessary risk surface.
The safe configuration when idle is to close every lane at both ends. Removing a lane on the source pool stops new transfers from starting. Removing it on the destination pool rejects any message that still arrives. Closing only one side would let a user lock funds into a lane whose far end can no longer deliver, stranding the transfer. Reopening a lane later requires a fresh governance proposal. There is no standing shortcut by design.
The Shutdown Governor
BridgeShutdownGovernor (0x2A0FEC62992D2C0f1b0C598551c1627F18286F84) sends every L2 shutdown message from a single executeL2Shutdown() entrypoint. It is onlyOwner, with the owner set to the DAO governance timelock, and it is payable so forwarded ETH can pay the CCIP message fees. It holds a hardcoded L2_SHUTDOWN_MESSAGE_COUNT of 8. The plan is fixed. The contract cannot choose destination chains, targets, or calldata. The whole batch is hardcoded and guarded by an internal assert that the message count equals 8.
The shutdown removes lanes. It does not lower a rate limit. The 8 messages are four applyChainUpdates calls, one per L2 pool, that remove every remote chain from that pool, plus four setMinter calls that revoke each L2 pool’s mint permission on its receipt token. The removal lists differ in length, four for Base and Arbitrum and three for Optimism and Berachain, because Optimism and Berachain do not connect to each other on-chain. Each list matches its pool’s live getSupportedChains set exactly, so nothing reverts and no lane is left open.
The governor can only act once it owns the sDOLA GovernanceSender (0x4e521Fe7A9084067096d45A312B8FEeE39D5F1f3), which is the allowlisted origin for the cross-chain messages. The proposal transfers the sender to the governor, calls executeL2Shutdown(), recovers unspent fees with withdraw() while the governor still owns the sender, then transfers the sender back to the timelock.
The mainnet pool is a LockReleaseTokenPool and is not a minter of sDOLA, so it needs no minter revocation. Only its remote-chain connections are removed, and that runs as the direct mainnet action.
Configuration
Chain selectors:
| Chain | Selector |
|---|---|
| Ethereum | 5009297550715157269 |
| Base | 15971525489660198786 |
| Optimism | 3734403246176062136 |
| Arbitrum | 4949039107694359620 |
| Berachain | 1294465214383781161 |
Core contracts:
| Contract | Address |
|---|---|
| BridgeShutdownGovernor | 0x2A0FEC62992D2C0f1b0C598551c1627F18286F84 |
| GovernanceSender (sDOLA) | 0x4e521Fe7A9084067096d45A312B8FEeE39D5F1f3 |
| DAO governance timelock (owner) | 0x926dF14a23BE491164dCF93f4c468A50ef659D5B |
| Mainnet token pool (LockReleaseTokenPool) | 0x05eEe76f456C51Be0459EC1c0a78bf177B2c877C |
L2 token pools, receipt tokens, and governance proxies:
| Chain | Token pool | Receipt token | Governance proxy |
|---|---|---|---|
| Base | 0xd84e1B7e1a7A8D49167884855c3985ef4bCa45aB |
0xCa78ee4544ec5a33Af86F1E786EfC7d3652bf005 |
0x1C064265E053D23d120c518fDBB542e6537f82d1 |
| Optimism | 0x8404024d8F74Ad2D20E82c184816B64D4184A018 |
0xfc63C9c8Ba44AE89C01265453Ed4F427C80cBd4E |
0xaF956837AF704D825c1FCbE2651D5c3c37AD5289 |
| Arbitrum | 0xbbc28DB61DF26B76D5F7D5Eed17eD4D6C278460e |
0x7a1e123e41458aabaB8068BFed6010D8f9480898 |
0x607bCd974bB69C78eCdbf0B68748B791bBa24d94 |
| Berachain | 0x8Bbd036d018657E454F679E7C4726F7a8ECE2773 |
0x02eaa69646183c069FC2B64F15923F27B9CF3b03 |
0x1992AF61FBf8ee38741bcc57d636CAA22A1a7702 |
Action 3 carries the CCIP fee budget for the 8 messages. Fees are paid from the GovernanceSender balance, and unused ETH is recovered by action 4. Fund it by setting the value on action 3, or by sending ETH to the GovernanceSender before execution.
On-Chain Actions
Ownership moves through Chainlink’s two-step ConfirmedOwner pattern. Action 4 recovers unspent CCIP fees and must run after executeL2Shutdown() and before the sender is transferred back, while the governor still owns the sender.
| # | Target | Function | Value | Arguments |
|---|---|---|---|---|
| 1 | GovernanceSender 0x4e521Fe7A9084067096d45A312B8FEeE39D5F1f3 |
transferOwnership(address) |
0 | governor 0x2A0FEC62992D2C0f1b0C598551c1627F18286F84 |
| 2 | Governor 0x2A0FEC62992D2C0f1b0C598551c1627F18286F84 |
acceptGovernanceSenderOwnership() |
0 | 0x |
| 3 | Governor 0x2A0FEC62992D2C0f1b0C598551c1627F18286F84 |
executeL2Shutdown() |
CCIP fees | 0x (fires 8 L2 messages) |
| 4 | Governor 0x2A0FEC62992D2C0f1b0C598551c1627F18286F84 |
withdraw(address) |
0 | timelock 0x926dF14a23BE491164dCF93f4c468A50ef659D5B |
| 5 | Governor 0x2A0FEC62992D2C0f1b0C598551c1627F18286F84 |
transferGovernanceSenderOwnership(address) |
0 | timelock 0x926dF14a23BE491164dCF93f4c468A50ef659D5B |
| 6 | GovernanceSender 0x4e521Fe7A9084067096d45A312B8FEeE39D5F1f3 |
acceptOwnership() |
0 | 0x |
| 7 | Mainnet pool 0x05eEe76f456C51Be0459EC1c0a78bf177B2c877C |
applyChainUpdates(uint64[],ChainUpdate[]) |
0 | remove [15971525489660198786, 3734403246176062136, 4949039107694359620, 1294465214383781161]; add [] |