Skip to content

Token Ledgers Implementation Using Skuset Contract

Token Ledgers are managed on the platform using Skuset.

Overview

The Skuset contract is an implementation of an ERC-1155 multi-token standard, designed for managing Skucode-backed tokens within a Skuset. It supports attachments, exchange of ERC-20 tokens, and advanced minting/burning capabilities, with an emphasis on security, including pauseable operations and re-entrance protection.


Imports

  1. ERC1155

    solidity
    import {ERC1155} from "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";

    Standard implementation of the ERC1155 multi-token standard from OpenZeppelin.

  2. Ownable

    solidity
    import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";

    Provides a basic access control mechanism, allowing for ownership management.

  3. Pausable

    solidity
    import {Pausable} from "@openzeppelin/contracts/utils/Pausable.sol";

    Allows the contract to be paused and unpaused, providing a safety mechanism during emergencies.

  4. IERC20

    solidity
    import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

    Interface for ERC20 tokens, allowing interactions with other ERC20 contracts.

  5. ReentrancyGuard

    solidity
    import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";

    Prevents reentrant calls to functions, enhancing security against certain types of attacks.

  6. IERC20Receiver

    solidity
    import {IERC20Receiver} from "./skucode.sol";

    Interface for contracts that want to handle receiving ERC20 tokens.

  7. ud

    solidity
    import {ud} from "@prb/math/src/UD60x18.sol";

    Provides fixed-point arithmetic operations using the UD60x18 type.


Enum: SkusetType

Represents the type of Skuset.

  • Regular: Standard Skuset type.
  • Locked: Restricts some operations to only the owner.

State Variables

  1. skusetType:
    (SkusetType) — Defines the Skuset's operational type, either Regular or Locked.

  2. whitelistedSkucodeHashes:
    (mapping(bytes32 => bool)) — Stores the whitelisted bytecode hashes of Skucode contracts for security purposes.

  3. attachments:
    (mapping(string => address)) — Tracks attachments by storing a CID linked to the sender's address.

  4. exchangeInfo:
    (mapping(uint256 => mapping(uint256 => ExchangeInfo))) — Maintains exchange information between token IDs, storing depositor details and exchange ratios.


Struct: ExchangeInfo

Stores information about token exchange.

  • depositor: (address) — Address of the user holding the tokens for exchange.
  • exchangeRatio: (uint256) — Ratio used to determine exchange amounts between tokens.

Constructor

Initializes the Skuset contract with a specified owner, metadata URI, and Skuset type.

solidity
constructor(
    address _initialOwner,
    string memory _erc1155uri,
    SkusetType _skusetType
)
  • Parameters:
    • _initialOwner: Address of the contract's initial owner.
    • _erc1155uri: URI for the ERC-1155 metadata.
    • _skusetType: Type of Skuset (Regular or Locked).

Events

  1. AttachmentAdded:
    Triggered when a new attachment is added.

    • Parameters: cid (string), submitter (address)
  2. ERC20Deposited:
    Triggered when ERC-20 tokens are deposited.

    • Parameters: sender (address), token (address), value (uint256)
  3. ERC20Withdrawn:
    Triggered when ERC-20 tokens are withdrawn.

    • Parameters: sender (address), token (address), value (uint256), to (address)
  4. ExchangeTokensDeposited:
    Triggered when tokens are deposited for an exchange.

    • Parameters: fromSkucode (uint256), toSkucode (uint256), user (address), value (uint256), exchangeRatio (uint256)
  5. TokensExchanged:
    Triggered when tokens are successfully exchanged.

    • Parameters: fromSkucode (uint256), toSkucode (uint256), user (address), value (uint256), exchangeRatio (uint256)

Public Functions

  1. onReceiveERC20 Handles receipt of ERC-20 tokens and mints equivalent ERC-1155 tokens.

    solidity
    function onReceiveERC20(address from, uint256 value) external returns (bytes4)
  2. withdraw Burns ERC-1155 tokens and withdraws the corresponding ERC-20 tokens.

    solidity
    function withdraw(uint256 id, uint256 value, address to) external
  3. addAttachment Adds a new attachment.

    solidity
    function addAttachment(string calldata cid) external
  4. exchangeDeposit Deposits tokens for exchange.

    solidity
    function exchangeDeposit(address fromSkucode, address toSkucode, uint256 exchangeRatio, uint256 value) external
  5. exchangeWithdraw Handles the exchange of tokens and withdrawal in a single step.

    solidity
    function exchangeWithdraw(address fromSkucode, address toSkucode, uint256 value) external
  6. mint Mints ERC-1155 tokens to a specified address.

    solidity
    function mint(address to, uint256 id, uint256 value, bytes calldata data) public
  7. mintBatch Mints multiple ERC-1155 tokens in a batch.

    solidity
    function mintBatch(address to, uint256[] calldata ids, uint256[] calldata values, bytes calldata data) external
  8. burn Burns a specified amount of ERC-1155 tokens.

    solidity
    function burn(address from, uint256 id, uint256 value) external
  9. burnBatch Burns multiple ERC-1155 tokens in a batch.

    solidity
    function burnBatch(address from, uint256[] calldata ids, uint256[] calldata values) external
  10. pause / unpause Pauses or unpauses the contract (onlyOwner).

    solidity
    function pause() external
    function unpause() external

Modifiers

  1. onlyOwnerWhenLocked:
    Restricts operations to the owner when the Skuset type is Locked.

Internal Utility Functions

  1. _getSkucodeTokenId
    Computes a token ID based on the ERC-20 token address.

    solidity
    function _getSkucodeTokenId(address token) internal pure returns (uint256)
  2. _uint256ToAddress
    Converts a uint256 to an Ethereum address.

    solidity
    function _uint256ToAddress(uint256 value) internal pure returns (address)

Custom Errors

  1. InvalidTokenId: Thrown when an invalid token ID is used.
  2. TransferFailed: Thrown if a token transfer operation fails.
  3. UnsafeSkucode: Thrown if the Skucode's bytecode is not whitelisted.
  4. AttachmentAlreadyAdded: Thrown if the same attachment has been previously added.
  5. ExchangeInfoAlreadyAdded: Thrown if exchange info already exists for a given token pair.
  6. ExchangeInfoUnavailable: Thrown if exchange information is not available for the specified token pair.
  7. InsufficientExchangeTokens: Thrown if there aren't enough tokens available for an exchange.
  8. InsufficientExchangeAllowance: Thrown if the allowance for token transfers is insufficient.
  9. ContractSenderUnauthorized: Thrown if a contract, instead of an externally owned account (EOA), attempts to interact.
  10. UnauthorizedOnLockedSkuset: Thrown if a restricted operation is attempted on a Locked Skuset.