// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.0; /// @title MultiCurrency Predeploy Contract Library /// @author Acala Developers /// @notice You can use this predeploy contract to call currencies pallet /// @dev This contracts will interact with currencies pallet library MultiCurrency { /// @dev The MultiCurrency precompile address. address private constant PRECOMPILE = address(0x0000000000000000000000000000000000000400); function name() internal view returns (string memory) { (bool success, bytes memory returnData) = PRECOMPILE.staticcall( abi.encodeWithSignature("name()") ); assembly { if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) } } return abi.decode(returnData, (string)); } function symbol() internal view returns (string memory) { (bool success, bytes memory returnData) = PRECOMPILE.staticcall( abi.encodeWithSignature("symbol()") ); assembly { if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) } } return abi.decode(returnData, (string)); } function decimals() internal view returns (uint8) { (bool success, bytes memory returnData) = PRECOMPILE.staticcall( abi.encodeWithSignature("decimals()") ); assembly { if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) } } return abi.decode(returnData, (uint8)); } function totalSupply() internal view returns (uint256) { (bool success, bytes memory returnData) = PRECOMPILE.staticcall( abi.encodeWithSignature("totalSupply()") ); assembly { if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) } } return abi.decode(returnData, (uint256)); } function balanceOf(address account) internal view returns (uint256) { (bool success, bytes memory returnData) = PRECOMPILE.staticcall( abi.encodeWithSignature("balanceOf(address)", account) ); assembly { if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) } } return abi.decode(returnData, (uint256)); } function transfer( address sender, address recipient, uint256 amount ) internal { (bool success, bytes memory returnData) = PRECOMPILE.call( abi.encodeWithSignature( "transfer(address,address,uint256)", sender, recipient, amount ) ); assembly { if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) } } } function transferToAccountId( address sender, bytes32 recipient, uint256 amount ) internal { (bool success, bytes memory returnData) = PRECOMPILE.call( abi.encodeWithSignature( "transferToAccountId(address,bytes32,uint256)", sender, recipient, amount ) ); assembly { if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) } } } }