Files
smom-dbis-138/contracts/relay/CCIPRelayBridgeLINK.sol
defiQUG c336809676
Some checks failed
CI/CD Pipeline / Solidity Contracts (push) Failing after 1m3s
CI/CD Pipeline / Security Scanning (push) Successful in 2m18s
CI/CD Pipeline / Lint and Format (push) Failing after 34s
CI/CD Pipeline / Terraform Validation (push) Failing after 20s
CI/CD Pipeline / Kubernetes Validation (push) Successful in 22s
Deploy ChainID 138 / Deploy ChainID 138 (push) Failing after 40s
HYBX OMNL TypeScript & anchor / token-aggregation build + reconcile artifact (push) Failing after 49s
OMNL reconcile anchor / Run omnl:reconcile and upload artifacts (push) Failing after 21s
Validation / validate-genesis (push) Successful in 25s
Validation / validate-terraform (push) Failing after 21s
Validation / validate-kubernetes (push) Failing after 8s
Validation / validate-smart-contracts (push) Failing after 8s
Validation / validate-security (push) Failing after 1m11s
Validation / validate-documentation (push) Failing after 14s
Verify Deployment / Verify Deployment (push) Failing after 45s
Add mainnet checkpoint stack: ISO attestation, participant Etherscan surface, and services.
Ship AddressActivityRegistry V1/V2, ISO20022IntakeGateway, Chain138ParticipantSurface,
checkpoint hub contracts, checkpoint-core package, aggregator/indexer/sdk services,
relay profile guards, M00 diamond bridge facet, and OMNL compliance contracts.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-25 00:30:45 -07:00

69 lines
2.7 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import "../ccip/IRouterClient.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
/**
* @title CCIP Relay Bridge (LINK)
* @notice Accepts relayed CCIP messages carrying canonical LINK on the destination chain.
* @dev Companion to CCIPRelayBridge (WETH9-only). Grant ROUTER_ROLE to the same CCIPRelayRouter.
*/
contract CCIPRelayBridgeLINK is AccessControl {
bytes32 public constant ROUTER_ROLE = keccak256("ROUTER_ROLE");
address public immutable link;
address public relayRouter;
mapping(bytes32 => bool) public processedTransfers;
event CrossChainTransferCompleted(
bytes32 indexed messageId,
uint64 indexed sourceChainSelector,
address indexed recipient,
uint256 amount
);
constructor(address _link, address _relayRouter) {
require(_link != address(0), "CCIPRelayBridgeLINK: zero LINK");
require(_relayRouter != address(0), "CCIPRelayBridgeLINK: zero router");
link = _link;
relayRouter = _relayRouter;
_grantRole(ROUTER_ROLE, _relayRouter);
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
}
function updateRelayRouter(address newRelayRouter) external onlyRole(DEFAULT_ADMIN_ROLE) {
require(newRelayRouter != address(0), "CCIPRelayBridgeLINK: zero address");
_revokeRole(ROUTER_ROLE, relayRouter);
relayRouter = newRelayRouter;
_grantRole(ROUTER_ROLE, newRelayRouter);
}
function ccipReceive(IRouterClient.Any2EVMMessage calldata message) external onlyRole(ROUTER_ROLE) {
require(!processedTransfers[message.messageId], "CCIPRelayBridgeLINK: already processed");
processedTransfers[message.messageId] = true;
require(message.tokenAmounts.length > 0, "CCIPRelayBridgeLINK: no tokens");
require(message.tokenAmounts[0].token == link, "CCIPRelayBridgeLINK: invalid token");
uint256 amount = message.tokenAmounts[0].amount;
require(amount > 0, "CCIPRelayBridgeLINK: invalid amount");
address recipient;
if (message.data.length == 64) {
(recipient, ) = abi.decode(message.data, (address, uint256));
} else if (message.data.length >= 128) {
(recipient, , , ) = abi.decode(message.data, (address, uint256, address, uint256));
} else {
revert("CCIPRelayBridgeLINK: invalid data");
}
require(recipient != address(0), "CCIPRelayBridgeLINK: zero recipient");
require(IERC20(link).transfer(recipient, amount), "CCIPRelayBridgeLINK: transfer failed");
emit CrossChainTransferCompleted(message.messageId, message.sourceChainSelector, recipient, amount);
}
}