WIP: Zedxion bridge, GRU monetary policy gate, LiIndex flash vault, cw-settlement
This commit is contained in:
@@ -4,7 +4,9 @@ pragma solidity ^0.8.19;
|
||||
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
||||
|
||||
import "../ccip/IRouterClient.sol";
|
||||
import {IRouterClient} from "@chainlink/contracts-ccip/contracts/interfaces/IRouterClient.sol";
|
||||
import {Client} from "@chainlink/contracts-ccip/contracts/libraries/Client.sol";
|
||||
import {IAny2EVMMessageReceiver} from "@chainlink/contracts-ccip/contracts/interfaces/IAny2EVMMessageReceiver.sol";
|
||||
|
||||
interface ICWMintBurnToken is IERC20 {
|
||||
function mint(address to, uint256 amount) external;
|
||||
@@ -15,14 +17,16 @@ interface ICWMintBurnToken is IERC20 {
|
||||
* @title CWMultiTokenBridgeL2
|
||||
* @notice Destination/public-chain bridge for minting and burning cW* assets without prefunding.
|
||||
* @dev Supports multiple canonical -> mirrored token pairs behind one bridge address.
|
||||
* Outbound CCIP uses Chainlink Client.EVM2AnyMessage encoding (required by public routers).
|
||||
*/
|
||||
contract CWMultiTokenBridgeL2 {
|
||||
contract CWMultiTokenBridgeL2 is IAny2EVMMessageReceiver {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
IRouterClient public sendRouter;
|
||||
address public receiveRouter;
|
||||
address public feeToken;
|
||||
address public admin;
|
||||
uint256 public ccipGasLimit;
|
||||
|
||||
struct DestinationConfig {
|
||||
address receiverBridge;
|
||||
@@ -64,6 +68,7 @@ contract CWMultiTokenBridgeL2 {
|
||||
event SendRouterUpdated(address indexed newRouter);
|
||||
event ReceiveRouterUpdated(address indexed newRouter);
|
||||
event FeeTokenUpdated(address indexed newFeeToken);
|
||||
event CcipGasLimitUpdated(uint256 newGasLimit);
|
||||
event AdminChanged(address indexed newAdmin);
|
||||
|
||||
modifier onlyAdmin() {
|
||||
@@ -83,6 +88,7 @@ contract CWMultiTokenBridgeL2 {
|
||||
receiveRouter = _receiveRouter;
|
||||
feeToken = _feeToken;
|
||||
admin = msg.sender;
|
||||
ccipGasLimit = 300_000;
|
||||
}
|
||||
|
||||
function configureTokenPair(address canonicalToken, address mirroredToken) external onlyAdmin {
|
||||
@@ -148,6 +154,12 @@ contract CWMultiTokenBridgeL2 {
|
||||
emit FeeTokenUpdated(newFeeToken);
|
||||
}
|
||||
|
||||
function setCcipGasLimit(uint256 newGasLimit) external onlyAdmin {
|
||||
require(newGasLimit > 0, "CWMultiTokenBridgeL2: zero gas limit");
|
||||
ccipGasLimit = newGasLimit;
|
||||
emit CcipGasLimitUpdated(newGasLimit);
|
||||
}
|
||||
|
||||
function changeAdmin(address newAdmin) external onlyAdmin {
|
||||
require(newAdmin != address(0), "CWMultiTokenBridgeL2: zero admin");
|
||||
admin = newAdmin;
|
||||
@@ -164,7 +176,10 @@ contract CWMultiTokenBridgeL2 {
|
||||
require(canonicalToken != address(0), "CWMultiTokenBridgeL2: token not configured");
|
||||
DestinationConfig memory dest = destinations[destinationChainSelector];
|
||||
require(dest.enabled, "CWMultiTokenBridgeL2: destination disabled");
|
||||
return sendRouter.getFee(destinationChainSelector, _buildMessage(dest.receiverBridge, canonicalToken, recipient, amount));
|
||||
return sendRouter.getFee(
|
||||
destinationChainSelector,
|
||||
_buildMessage(dest.receiverBridge, canonicalToken, recipient, amount)
|
||||
);
|
||||
}
|
||||
|
||||
function circulatingSupply(address mirroredToken) external view returns (uint256) {
|
||||
@@ -173,7 +188,7 @@ contract CWMultiTokenBridgeL2 {
|
||||
return totalMinted > totalBurned ? totalMinted - totalBurned : 0;
|
||||
}
|
||||
|
||||
function ccipReceive(IRouterClient.Any2EVMMessage calldata message) external onlyReceiveRouter {
|
||||
function ccipReceive(Client.Any2EVMMessage calldata message) external onlyReceiveRouter {
|
||||
require(!processed[message.messageId], "CWMultiTokenBridgeL2: replayed");
|
||||
|
||||
(address canonicalToken, address recipient, uint256 amount) =
|
||||
@@ -229,13 +244,13 @@ contract CWMultiTokenBridgeL2 {
|
||||
IERC20(mirroredToken).totalSupply()
|
||||
);
|
||||
|
||||
IRouterClient.EVM2AnyMessage memory message =
|
||||
Client.EVM2AnyMessage memory message =
|
||||
_buildMessage(dest.receiverBridge, canonicalToken, recipient, amount);
|
||||
uint256 fee = sendRouter.getFee(destinationChainSelector, message);
|
||||
|
||||
_collectAndApproveFee(fee);
|
||||
|
||||
(messageId, ) = feeToken == address(0)
|
||||
messageId = feeToken == address(0)
|
||||
? sendRouter.ccipSend{value: fee}(destinationChainSelector, message)
|
||||
: sendRouter.ccipSend(destinationChainSelector, message);
|
||||
|
||||
@@ -260,13 +275,13 @@ contract CWMultiTokenBridgeL2 {
|
||||
address canonicalToken,
|
||||
address recipient,
|
||||
uint256 amount
|
||||
) internal view returns (IRouterClient.EVM2AnyMessage memory message) {
|
||||
message = IRouterClient.EVM2AnyMessage({
|
||||
) internal view returns (Client.EVM2AnyMessage memory message) {
|
||||
message = Client.EVM2AnyMessage({
|
||||
receiver: abi.encode(receiverBridge),
|
||||
data: abi.encode(canonicalToken, recipient, amount),
|
||||
tokenAmounts: new IRouterClient.TokenAmount[](0),
|
||||
tokenAmounts: new Client.EVMTokenAmount[](0),
|
||||
feeToken: feeToken,
|
||||
extraArgs: ""
|
||||
extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: ccipGasLimit}))
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user