Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

ERC20xTransferWithAuthorize

isol/contracts/modular/ERC20xTransferWithAuthorize.sol

Modular The ERC20xTransferWithAuthorize is an ERC20 extension for modular, off-chain authorized transfers and burns using EIP-712 signatures. It enables meta-transactions, relayer support, and gasless transfers by allowing anyone to submit signed authorizations for transfers or burns. Designed for flexible integration with other contracts or features.

Import

import "isol/contracts/modular/ERC20xTransferWithAuthorize.sol";

Usage

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
 
import "isol/contracts/kit/KitxERC20.sol";
import "isol/contracts/modular/ERC20xTransferWithAuthorize.sol";
 
contract ERC20xAuth is KitxERC20, ERC20xTransferWithAuthorize {
	constructor() 
		KitxERC20("MyToken", "MTK", 1000000)
        ERC20xTransferWithAuthorize(
            "MyToken", 
            "1"
        )
	{}
}

Arguments

ParameterTypeDescription
domainNamestringEIP-712 domain name for signature verification
domainVersionstringEIP-712 domain version for signature verification

domainName

  • Type: string

The EIP-712 domain name used for signature verification, e.g., "MyToken".

contract ERC20xAuth is ERC20xTransferWithAuthorize {
	constructor() 
		ERC20xTransferWithAuthorize(
			"ERC20xAuth Token", // Name (string)
			"AUTH", // Symbol (string)
			1000000, // Initial Supply (number: uint256)
            "ERC20xAuth Token", // Domain Name (string)
            "1" // Domain Version (string)
		)
	{}
}

domainVersion

  • Type: string

The EIP-712 domain version used for signature verification, e.g., "1".

contract ERC20xAuth is ERC20xTransferWithAuthorize {
	constructor() 
		ERC20xTransferWithAuthorize(
			"ERC20xAuth Token", // Name (string)
			"AUTH", // Symbol (string)
			1000000, // Initial Supply (number: uint256)
            "ERC20xAuth Token", // Domain Name (string)
            "1" // Domain Version (string)
		)
	{}
}

Functions

Read

FunctionArgumentsDescription
BURN_TYPEHASH-Check the typehash used for burn authorization
TRANSFER_TYPEHASH-Check the typehash used for transfer authorization
allowanceowner (address), spender (address)Check approved amount for spender
authorizeStateauthorizer (address), nonce (bytes32)Check authorization state
balanceOfaccount (address)Get token balance of an address
decimals-Get number of decimals used by the token
eip712Domain-Check the EIP-712 domain used for signature verification
name-Get the name of the token
symbol-Get the symbol of the token
totalSupply-Get the total supply of the token

Write

FunctionInteractArgumentsDescription
approveuserspender (address), value (uint256)Allow spender to use your tokens
burnWithAuthorizeuserfrom (address), value (uint256), createTime (uint256), expireTime (uint256), nonce (bytes32), auth (bytes)Burn tokens with authorization
transferuserto (address), value (uint256)Send tokens to another address
transferFromuserfrom (address), to (address), value (uint256)Move tokens using allowance
transferWithAuthorizeuserfrom (address), to (address), value (uint256), createTime (uint256), expireTime (uint256), nonce (bytes32), auth (bytes)Transfer tokens with authorization

Events

Logs
Transfer(address indexed from, address indexed to, uint256 value)
Approval(address indexed owner, address indexed spender, uint256 value)
BurnWithAuthorize(address sender, address from, uint256 value, uint256 createTime, uint256 expireTime, bytes32 nonce, bytes auth)
TransferWithAuthorize(address sender, address from, address to, uint256 value, uint256 createTime, uint256 expireTime, bytes32 nonce, bytes auth)

Features

Functions are inherited from BasexERC20, with additional new features below.

FunctionTypeInteractArgumentsDescription
BURN_TYPEHASHread--Check the typehash used for burn authorization
TRANSFER_TYPEHASHread--Check the typehash used for transfer authorization
authorizeStateread-authorizer (address), nonce (bytes32)Check authorization state
eip712Domainread--Check the EIP-712 domain used for signature verification
burnWithAuthorizewriteuserfrom (address), value (uint256), createTime (uint256), expireTime (uint256), nonce (bytes32), auth (bytes)Burn tokens with authorization
transferWithAuthorizewriteuserfrom (address), to (address), value (uint256), createTime (uint256), expireTime (uint256), nonce (bytes32), auth (bytes)Transfer tokens with authorization

References

Source code: ERC20xTransferWithAuthorize
OpenZeppelin: ERC20, ReentrancyGuard

Examples

Deploy

./MyToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
 
import "isol/contracts/modular/ERC20xTransferWithAuthorize.sol"; // Add modular ERC20xTransferWithAuthorize for advanced transfer with authorization
import "isol/contracts/kit/KitxERC20.sol"; // Add kit KitxERC20 for base ERC20 functionalities
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol"; // Sample additional custom feature
 
contract MyToken is ERC20xTransferWithAuthorize, KitxERC20, ERC20Pausable { // initialize ERC20xTransferWithAuthorize
    constructor()
        KitxERC20("MyToken", "MTK", 1000000)
        ERC20xTransferWithAuthorize( // use ERC20xTransferWithAuthorize constructor
            "MyToken", // Domain Name (string)
            "1" // Domain Version (string)
        )
    {}
 
    function pause() public onlyOwner {
        _pause();
    }
 
    function unpause() public onlyOwner {
        _unpause();
    }
 
    function mint(address to, uint256 amount) public onlyOwner {
        _mint(to, amount);
    }
 
    function _update(address from, address to, uint256 value)
        internal
        override(ERC20, ERC20Pausable)
    {
        super._update(from, to, value);
    }
}

Interact

./interact.ts
import { daccSignTypedData } from "dacc-js";
import { createWalletClient, http } from 'viem';
import { parseAbi, toHex } from "viem";
import { privateKeyToAccount } from 'viem/accounts';
import { optimismSepolia } from "viem/chains";
 
// ==========================================
// CONFIG FOR SIGNING
// ==========================================
const domainName = "ERC20_X_AUTH";
const domainVersion = "VERSION";
const chainId = 11155420; // number
const contract = "ERC20_X_AUTH...CONTRACT_ADDRESS";
const walletAddress = "FROM...WALLET_ADDRESS";
const toAddress = "TO...WALLET_ADDRESS";
const amount = 1000000000000000000n; // decimal
 
const nonce = crypto.getRandomValues(new Uint8Array(32)); // bytes32
const now = Math.floor(Date.now() / 1000);
const createTime = now - 60;
const expireTime = now + 3600;
 
const daccID = "DACC_PUBLIC_KEY";
const daccPassword = "DACC_PASSWORD_SECRETKEY";
 
const sponsorPrivateKey = "0X...PRIVEATE_KEY";
 
// ==========================================
// SIGNING WITH DACC-JS
// ==========================================
const signed = await daccSignTypedData({
  daccPublickey: daccID,
  passwordSecretkey: daccPassword,
  network: optimismSepolia,
  domain: {
    name: domainName,
    version: domainVersion,
    chainId: chainId,
    verifyingContract: contract
  },
  types: {
    TransferWithAuthorize: [
        { name: "from", type: "address" },
        { name: "to", type: "address" },
        { name: "value", type: "uint256" },
        { name: "createTime", type: "uint256" },
        { name: "expireTime", type: "uint256" },
        { name: "nonce", type: "bytes32" }
    ]
  },
  primaryType: "TransferWithAuthorize",
  message: {
    from: walletAddress,
    to: toAddress,
    value: amount,
    createTime,
    expireTime,
    nonce: toHex(nonce)
  }
});
// console.log('Signed Data:', signed);
 
// ==========================================
// SEND TRANSACTION WITH VIEM
// ==========================================
const walletClient = createWalletClient({
  account: privateKeyToAccount(sponsorPrivateKey as `0x${string}`),
  chain: optimismSepolia,
  transport: http(),
});
 
const abiContract = parseAbi([
  'function transferWithAuthorize(address from, address to, uint256 value, uint256 createTime, uint256 expireTime, bytes32 nonce, bytes calldata auth)',
]);
 
const tx = await walletClient.writeContract({
    address: contract as `0x${string}`,
    abi: abiContract,
    functionName: "transferWithAuthorize",
    args: [
        walletAddress as `0x${string}`,
        toAddress as `0x${string}`,
        BigInt(amount),
        BigInt(createTime),
        BigInt(expireTime),
        toHex(nonce),
        signed.signature
    ],
});
console.log('Transaction Hash:', tx);