Appearance
Token Types Using Skucode Contract
Token Types are managed on the platform using Ethereum-based Token Management Contract named Skucode
.
Overview
This contract implements a customizable ERC20 token with additional functionalities for wrapping and unwrapping tokens, attachments, and wrap ratios. The contract is based on OpenZeppelin's ERC20 implementation and includes security features like ownership and reentrancy protection.
Imports
ERC20
solidityimport {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
Standard ERC20 implementation from OpenZeppelin.
Ownable
solidityimport {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
Provides a basic access control mechanism for ownership.
UD60x18
solidityimport {UD60x18, ud} from "@prb/math/src/UD60x18.sol";
Implements fixed-point arithmetic operations using the UD60x18 type.
ReentrancyGuard
solidityimport {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
Prevents reentrant calls to certain functions.
IERC20Receiver
(Interface)solidityinterface IERC20Receiver { function onReceiveERC20(address from, uint256 value) external returns (bytes4); }
Interface for contracts that want to handle receiving ERC20 tokens.
Events
AttachmentAdded
solidityevent AttachmentAdded(string cid, address indexed submitter);
Emitted when an attachment (identified by a
cid
) is added to the contract.WrapRatioAdded
solidityevent WrapRatioAdded(address childSkucodeAddress, uint256 ratio);
Emitted when a wrap ratio is set for a child Skucode.
WrapRatioReceived
solidityevent WrapRatioReceived(address skucodeAddress, uint256 ratio);
Emitted when the contract receives a wrap ratio from another Skucode.
Functions
Constructor
solidityconstructor( address _initialOwner, string memory _tokenName, string memory _tokenSymbol, uint256 _initialSupply, SkucodeType _skucodeType )
Initializes the
Skucode
contract with an initial owner, token name, symbol, initial supply, and type.Parameters:
_initialOwner
: Address of the initial owner._tokenName
: Name of the token._tokenSymbol
: Symbol of the token._initialSupply
: Initial token supply._skucodeType
: Type of the Skucode (Mintable
orWrappable
).
mint(address account, uint256 value) →
external
solidityfunction mint(address account, uint256 value) external onlyOwner
Mints new tokens to a specified account.
Conditions:
- Only the owner can call this function.
- The contract must be of type
Mintable
.
wrap(uint256 value, address wrapperSkucode, address to) →
external
solidityfunction wrap(uint256 value, address wrapperSkucode, address to) external nonReentrant
Wraps the specified token amount into another Skucode.
Conditions:
- Requires a valid wrap ratio for the target Skucode.
- Transfers tokens to the target Skucode and calls
onReceiveWrappedTokens
.
unwrap(uint256 value, address wrappedSkucode, address to) →
external
solidityfunction unwrap(uint256 value, address wrappedSkucode, address to) external nonReentrant onlyOwner
Unwraps tokens from another Skucode and returns them to the specified address.
Conditions:
- Only the owner can call this function.
- Requires a valid wrap ratio from the target Skucode.
onReceiveWrappedTokens(uint256 value, address to) →
external
solidityfunction onReceiveWrappedTokens(uint256 value, address to) external nonReentrant
Handles the receipt of wrapped tokens from another Skucode.
Conditions:
- Verifies the sender's contract bytecode.
setWrapRatio(address childSkucodeAddress, uint256 ratio) →
external
solidityfunction setWrapRatio(address childSkucodeAddress, uint256 ratio) external nonReentrant
Sets the wrap ratio for a child Skucode.
Conditions:
- The sender must own the target Skucode.
- Verifies the target's contract bytecode.
getWrapRatio(address skucodeAddress) →
external view returns (uint256)
solidityfunction getWrapRatio(address skucodeAddress) external view returns (uint256)
Returns the wrap ratio for a specific Skucode.
onReceiveWrapRatio(uint256 ratio) →
external
solidityfunction onReceiveWrapRatio(uint256 ratio) external
Handles receiving a wrap ratio from a parent Skucode.
Conditions:
- Verifies the sender's contract bytecode.
transfer(address to, uint256 value) →
public virtual override nonReentrant returns (bool)
solidityfunction transfer(address to, uint256 value) public virtual override nonReentrant returns (bool)
Transfers tokens to another address. If the recipient is a contract, it performs a validation check.
Overrides: ERC20's
transfer
.transferFrom(address from, address to, uint256 value) →
public virtual override nonReentrant returns (bool)
solidityfunction transferFrom(address from, address to, uint256 value) public virtual override nonReentrant returns (bool)
Transfers tokens on behalf of another address. If the recipient is a contract, it performs a validation check.
Overrides: ERC20's
transferFrom
.addAttachment(string calldata cid) →
external onlyOwner
solidityfunction addAttachment(string calldata cid) external onlyOwner
Adds an attachment identified by
cid
.Conditions:
- Only the owner can add attachments.
- Emits the
AttachmentAdded
event.
Custom Errors
MintingNotAllowed
- Raised if minting is attempted on a non-mintable Skucode.UnauthorizedSkucodeOwner
- Raised if a wrap ratio is set by a non-owner.InvalidTwinContract(address target)
- Raised if the target contract bytecode does not match.WrapRatioNotRegistered(address target)
- Raised if a wrap ratio is not registered.InsufficientBalanceForWrap(uint256 available, uint256 required)
- Raised if the user lacks sufficient tokens.ERC20ReceiverError(address to, bytes error)
- Raised if the receiver contract rejects tokens.ERC20TransferError(address to, uint256 value)
- Raised if a transfer operation fails.AttachmentAlreadyAdded(string cid)
- Raised if an attachment already exists.