Skip to content

Latest commit

 

History

203 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OpenZeppelin Contracts for TRON

License: MIT

A library for secure smart contract development on TRON. A port of OpenZeppelin Contracts to the TRON Virtual Machine (TVM), adapted to TRON's standards (TIPs / TRCs) and to the ways the TVM differs from the EVM.

Overview

@openzeppelin/tron-contracts is based on OpenZeppelin Contracts — versions match upstream by major and minor (see Versioning) — and keeps its battle-tested implementations, while:

  • Renaming the standards that TRON publishes under its own identifiers — for example ERC20TRC20, ERC165TRC165, EIP712TIP712 — and dual-citing both the TRON (TIP / TRC) and Ethereum (EIP / ERC) specifications in the documentation.
  • Adapting the implementations where the TVM diverges from the EVM (e.g. CREATE2 address derivation, the block.chainid used in EIP-712 domain separators, the TRC-721 receiver hook, and tokens such as TRON USDT whose transfer returns false on success).

Where TRON only publishes a signing or utility spec (rather than a renamable contract standard), the contract keeps its descriptive name (e.g. ECDSA, MessageHashUtils, P256) and simply references the relevant TIP.

Versioning

Versions track OpenZeppelin Contracts by major and minor: each @openzeppelin/tron-contracts minor ports the feature set of the same-numbered upstream release, and new upstream features arrive only with a new matching minor. Patch numbers are independent — each library patches on its own schedule, so a given patch number does not refer to the same-numbered upstream patch (for example, this library may release a 5.6.0 while OpenZeppelin Contracts is already at 5.6.1). Upstream fixes that affect ported code are backported regardless of which upstream release carried them.

Installation

npm install @openzeppelin/tron-contracts

Usage

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {TRC20} from "@openzeppelin/tron-contracts/token/TRC20/TRC20.sol";

contract MyToken is TRC20 {
    constructor() TRC20("MyToken", "MTK") {
        _mint(msg.sender, 1000 * 10 ** decimals());
    }
}

TRON ↔ Ethereum standards

The TVM is EVM-compatible, but TRON standardizes many interfaces under its own TIP (TRON Improvement Proposal) and TRC numbers. This library references the TRON standard and dual-cites the Ethereum equivalent where one exists.

Ported (renamed to the TRON identifier)

Domain TRON Ethereum Contracts
Fungible token TRC-20 ERC-20 TRC20 (+ extensions)
Non-fungible token TRC-721 ERC-721 TRC721 (+ extensions)
Multi-token TRC-1155 ERC-1155 TRC1155 (+ extensions)
Tokenized vault TRC-4626 ERC-4626 TRC4626
Permit (gasless approval) TIP-2612 ERC-2612 TRC20Permit, ITRC20Permit
Interface introspection TRC-165 ERC-165 TRC165, TRC165Checker, ITRC165
Proxy storage slots TRC-1967 ERC-1967 TRC1967Proxy, TRC1967Utils, ITRC1967
Meta-transactions TRC-2771 ERC-2771 TRC2771Context, TRC2771Forwarder
Contract signature validation TRC-1271 ERC-1271 ITRC1271, SignatureChecker
Typed structured data TIP-712 EIP-712 TIP712

Referenced (descriptive name kept; TIP cited)

Domain TRON Ethereum Contracts
Signed data (0x19 prefix) TIP-191 ERC-191 MessageHashUtils
ECDSA signature encoding TIP-120 ECDSA
secp256r1 (P256) precompile TIP-7951 EIP-7951 / RIP-7212 P256
Namespaced storage layout TIP-7201 ERC-7201 Initializable, SlotDerivation
CREATE2 address derivation TIP-26 EIP-1014 Create2, Clones

Note

Several of these carry TVM-specific behavior documented in the affected contract's NatSpec — for example: the TIP-712 domain separator masks chainId to its low four bytes (the value TRON exposes via eth_chainId); CREATE2 derives addresses with a 0x41 prefix; and TRON USDT's transfer returns false even on a successful transfer, which SafeTRC20.safeTransferChecked handles by verifying the caller's balance delta (the sender's debit).

TVM differences

This port adapts non-obvious differences between the TVM and the EVM, including CREATE2 / plain CREATE address derivation, the block.chainid value used in TIP-712 domain separators, the TRC-721 receiver-hook magic value, and the handling of tokens that return false on a successful transfer. Each adaptation is documented in the affected contract's NatSpec.

Native TRC-10 assets

This library works with contract-based tokens: TRC-20, TRC-721, TRC-1155 and the other TRC standards listed above. Native TRC-10 assets, which a TRON account can hold alongside TRX, are outside its scope.

Moving a TRC-10 requires the TVM's token-aware call — address.transferToken(amount, id), compiling to CALLTOKEN. Every value-bearing path here uses an ordinary call, which carries TRX only. A TRC-10 credited to a contract built on this library therefore stays with that contract, and no supplied path forwards or withdraws it. This includes the governance executors: Governor.relay, Governor.execute and TimelockController.execute/executeBatch accept TRX through value, and their proposal and operation hashes bind targets, TRX values and calldata, with no field for a token identifier or amount.

Hold assets that contracts need to move as TRC-20 — either natively or by wrapping the TRC-10.

Important

Addresses embedded inside bytes payloads MUST use the 20-byte EVM form. During execution the TVM represents every address as the low 20 bytes, so msg.sender, address(this), and address-typed arguments are identical to the EVM. The 21-byte 0x41-prefixed and Base58Check (T…) forms that TRON tooling (TronWeb, node APIs) works with are off-chain encodings only — they never appear on-chain. When an address is carried inside a bytes argument — an ERC-7930 interoperable address, a crosschain bridge message, an ERC-7913 signer (verifier || key), or any packed calldata — it must be the raw 20-byte value. The 21-byte form is rejected where the format is self-describing (InteroperableAddress.parseEvmV1 and BridgeFungible revert on a non-20-byte address) and would otherwise be silently mis-parsed into the wrong address. Strip the 0x41 prefix at the encoding boundary (e.g. in your TronWeb integration) before placing an address in a bytes payload.

Security

Please report any security issues responsibly via the security policy rather than opening a public issue.

License

OpenZeppelin Contracts for TRON is released under the MIT License.

About

No description, website, or topics provided.

Resources

Code of conduct

Security policy

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages