-
Notifications
You must be signed in to change notification settings - Fork 42
Expand file tree
/
Copy pathCCTPLib.sol
More file actions
143 lines (120 loc) · 5.29 KB
/
Copy pathCCTPLib.sol
File metadata and controls
143 lines (120 loc) · 5.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.21;
import { IERC20 } from "../../lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import { IRateLimits } from "../interfaces/IRateLimits.sol";
import { IALMProxy } from "../interfaces/IALMProxy.sol";
import { ICCTPLike } from "../interfaces/CCTPInterfaces.sol";
import { RateLimitHelpers } from "../RateLimitHelpers.sol";
library CCTPLib {
/**********************************************************************************************/
/*** Structs ***/
/**********************************************************************************************/
struct TransferUSDCToCCTPParams {
IALMProxy proxy;
IRateLimits rateLimits;
ICCTPLike cctp;
IERC20 usdc;
bytes32 domainRateLimitId;
bytes32 cctpRateLimitId;
bytes32 mintRecipient;
uint32 destinationDomain;
uint256 usdcAmount;
}
/**********************************************************************************************/
/*** Events ***/
/**********************************************************************************************/
// NOTE: This is used to track individual transfers for offchain processing of CCTP transactions
event CCTPTransferInitiated(
uint64 indexed nonce,
uint32 indexed destinationDomain,
bytes32 indexed mintRecipient,
uint256 usdcAmount
);
/**********************************************************************************************/
/*** External functions ***/
/**********************************************************************************************/
function transferUSDCToCCTP(TransferUSDCToCCTPParams calldata params) external {
_rateLimited(params.rateLimits, params.cctpRateLimitId, params.usdcAmount);
_rateLimited(
params.rateLimits,
RateLimitHelpers.makeUint32Key(params.domainRateLimitId, params.destinationDomain),
params.usdcAmount
);
require(params.mintRecipient != 0, "MC/domain-not-configured");
// Approve USDC to CCTP from the proxy (assumes the proxy has enough USDC)
_approve(params.proxy, address(params.usdc), address(params.cctp), params.usdcAmount);
// If amount is larger than limit it must be split into multiple calls
uint256 burnLimit = params.cctp.localMinter().burnLimitsPerMessage(address(params.usdc));
// This variable will get reduced in the loop below
uint256 usdcAmountTemp = params.usdcAmount;
while (usdcAmountTemp > burnLimit) {
_initiateCCTPTransfer(
params.proxy,
params.cctp,
params.usdc,
burnLimit,
params.mintRecipient,
params.destinationDomain
);
usdcAmountTemp -= burnLimit;
}
// Send remaining amount (if any)
if (usdcAmountTemp > 0) {
_initiateCCTPTransfer(
params.proxy,
params.cctp,
params.usdc,
usdcAmountTemp,
params.mintRecipient,
params.destinationDomain
);
}
}
/**********************************************************************************************/
/*** Relayer helper functions ***/
/**********************************************************************************************/
// NOTE: As USDC is the only asset transferred using CCTP, _forceApprove logic is unnecessary.
function _approve(
IALMProxy proxy,
address token,
address spender,
uint256 amount
)
internal
{
proxy.doCall(token, abi.encodeCall(IERC20.approve, (spender, amount)));
}
function _initiateCCTPTransfer(
IALMProxy proxy,
ICCTPLike cctp,
IERC20 usdc,
uint256 usdcAmount,
bytes32 mintRecipient,
uint32 destinationDomain
)
internal
{
uint64 nonce = abi.decode(
proxy.doCall(
address(cctp),
abi.encodeCall(
cctp.depositForBurn,
(
usdcAmount,
destinationDomain,
mintRecipient,
address(usdc)
)
)
),
(uint64)
);
emit CCTPTransferInitiated(nonce, destinationDomain, mintRecipient, usdcAmount);
}
/**********************************************************************************************/
/*** Rate Limit helper functions ***/
/**********************************************************************************************/
function _rateLimited(IRateLimits rateLimits, bytes32 key, uint256 amount) internal {
rateLimits.triggerRateLimitDecrease(key, amount);
}
}