Contract Name:
CircleTokenAdapter
Contract Source Code:
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.27;
import {ICircleFiatToken} from "./interfaces/ICircleFiatToken.sol";
import {IMintedBurnableERC20} from "./interfaces/IMintedBurnableERC20.sol";
/// Adapter in between a Circle stablecoin (USDC/EURC) and the Bridge contract.
/// Implements methods required in tokens by the Bridge, translates their calls
/// to calling methods of the target stablecoin.
/// The contract should be deployable as implementation of deprecated FiatToken,
/// therefore it must be careful in using any storage.
/// @custom:security-contact [email protected]
contract CircleTokenAdapter is IMintedBurnableERC20 {
// All variables should be immutable to be compiled into the contract bytecode.
/// @notice Target stablecoin token.
ICircleFiatToken public immutable token;
/// @notice The bridge contract (allowed to call methods of the adapter).
address public immutable bridge;
constructor(ICircleFiatToken _token, address _bridge) {
require(address(_token) != address(0), "Token not set");
require(_bridge != address(0), "Bridge not set");
token = _token;
bridge = _bridge;
}
/// @notice Mint fiat tokens to an address.
/// @param account The address that will receive the minted tokens.
/// @param amount The amount of tokens to mint.
/// @return True if the operation was successful.
function mint(address account, uint256 amount) external returns (bool) {
require(msg.sender == bridge, "Sender is not bridge");
return token.mint(account, amount);
}
/// @notice Burn tokens from `account` account.
/// @param account The address whose tokens will be burned.
/// @param value the amount of tokens to be burned.
function burnFrom(address account, uint256 value) external {
require(msg.sender == bridge, "Sender is not bridge");
require(token.transferFrom(account, address(this), value), "TransferFrom failed");
token.burn(value);
}
/// Unsupported - only for compliance with IMintedBurnableERC20 interface.
function burn(uint256) external pure {
revert("Burn unsupported");
}
}
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.27;
/// Circle's FiatToken interface.
/// @custom:security-contact [email protected]
interface ICircleFiatToken {
/**
* @dev Mint `amount` of tokens to given `account`.
*/
function mint(address _to, uint256 _amount) external returns (bool);
/**
* @dev Destroys a `value` amount of tokens from the caller.
*/
function burn(uint256 _amount) external;
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.27;
/// Minted ERC-20 tokens represents an Ethereum ERC-20 tokens on L2.
/// @custom:security-contact [email protected]
interface IMintedBurnableERC20 {
/**
* @dev Mint `amount` of tokens to given `account`.
*/
function mint(address account, uint256 amount) external returns (bool);
/**
* @dev Destroys a `value` amount of tokens from the caller.
*/
function burn(uint256 value) external;
/**
* @dev Destroys a `value` amount of tokens from `account`, deducting from the caller's allowance.
*
* Requirements:
*
* - the caller must have allowance for ``accounts``'s tokens of at least `value`.
*/
function burnFrom(address account, uint256 value) external;
}