CCTPHookVault
Inherits: ICCTPHookReceiver
Title: CCTPHookVault
Author: David Dada <daveproxy80@gmail.com> (https://github.com/dadadave80)
Example CCTP v2 hook receiver: an auto-credit USDC vault. When USDC is bridged to this vault with a
Lattice hook envelope, the source diamond's CCTPHookExecutor calls onCCTPHook AFTER the mint and
the vault books the freshly-minted amount to the beneficiary encoded in payload — a "programmable
USDC" primitive where ONE attested cross-chain message both MOVES funds and CREDITS an account. The
beneficiary later withdraws their booked balance.
SECURITY MODEL. Two invariants keep the vault solvent (booked credits are always backed 1:1 by USDC the vault actually holds):
- AUTHENTICITY — onCCTPHook accepts calls ONLY from
executor, the per-diamond, role-less, fund-less CCTPHookExecutor that fires solely on a real Iris-attested burn addressed to its diamond. - BACKING — it requires the attested
mintRecipientto be THIS vault, so theamountcredited is USDC that was just minted here (the interface warns targets MUST NOT assume the mint went to them: an attacker may set the hooktargetto this vault while minting the USDC elsewhere).amountis the attested NET-MINTED value (burn amount minus attested feeExecuted), so a credit equals USDC received.payloadis attacker-controlled, but it selects only WHO is credited — never HOW MUCH (that comes from the attested mint) — so a hostile payload can at worst mis-address a credit it also funded. A revert here is swallowed by the executor (the mint stands, the CCTP nonce is consumed). TESTNET SHOWCASE contract; not audited.
Note:
- security-contact: daveproxy80@gmail.com
Constants
executor
The source diamond's CCTPHookExecutor — the ONLY authorized caller of onCCTPHook.
address public immutable executor;usdc
The USDC minted into this vault (e.g. Base Sepolia USDC in the showcase).
address public immutable usdc;State Variables
creditOf
USDC booked to each beneficiary, withdrawable by them.
mapping(address beneficiary => uint256 amount) public creditOf;totalCredited
Total USDC booked across all beneficiaries (== the USDC this vault holds against credits).
uint256 public totalCredited;Functions
constructor
constructor(address executor_, address usdc_);Parameters
| Name | Type | Description |
|---|---|---|
| executor_ | address | The diamond's CCTPHookExecutor (read from ICCTPBridgeAdapter.hookExecutor()). |
| usdc_ | address | The destination-chain USDC that CCTP mints into this vault. |
onCCTPHook
Invoked by the CCTPHookExecutor after the attested USDC mint, with Circle-attested context.
Books amount (attested net-minted USDC) to the beneficiary in the first 20 bytes of payload.
function onCCTPHook(
uint32 sourceDomain,
bytes32 sender,
bytes32 mintRecipient,
uint256 amount,
bytes calldata payload
) external;Parameters
| Name | Type | Description |
|---|---|---|
| sourceDomain | uint32 | The CCTP domain the burn originated on (from the attested message header). |
| sender | bytes32 | The burner on the source domain, as a right-aligned bytes32 (attested). |
| mintRecipient | bytes32 | The bytes32 recipient the USDC was minted to on this chain (attested). |
| amount | uint256 | The USDC amount actually minted to mintRecipient (attested burn amount minusattested feeExecuted). |
| payload | bytes | ATTACKER-CONTROLLED hook payload bytes (the Lattice envelope's tail). Untrusted. |
withdraw
Withdraw amount of the caller's booked USDC to the caller (checks-effects-interactions).
function withdraw(uint256 amount) external;Parameters
| Name | Type | Description |
|---|---|---|
| amount | uint256 |
Events
Credited
event Credited(address indexed beneficiary, uint256 amount, uint32 sourceDomain, bytes32 sender);Parameters
| Name | Type | Description |
|---|---|---|
| beneficiary | address | |
| amount | uint256 | |
| sourceDomain | uint32 | |
| sender | bytes32 |
Withdrawn
event Withdrawn(address indexed beneficiary, uint256 amount);Parameters
| Name | Type | Description |
|---|---|---|
| beneficiary | address | |
| amount | uint256 |
Errors
CCTPHookVault__ZeroAddress
error CCTPHookVault__ZeroAddress();CCTPHookVault__NotExecutor
error CCTPHookVault__NotExecutor();CCTPHookVault__NotMintRecipient
error CCTPHookVault__NotMintRecipient();CCTPHookVault__BadPayload
error CCTPHookVault__BadPayload();CCTPHookVault__InsufficientCredit
error CCTPHookVault__InsufficientCredit();