Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .changeset/add-tron-support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@openzeppelin/wizard': patch
'@openzeppelin/wizard-common': patch
'@openzeppelin/contracts-mcp': patch
'@openzeppelin/contracts-cli': patch
---

Add support for TRON Contracts.
- Covers TRC20, TRC721, TRC1155, Governor, and Custom contracts.
- On TRON, the Governor's `blockTime` defaults to 3 seconds to match its block production.
43 changes: 42 additions & 1 deletion packages/cli/src/cli.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { execFileSync } from 'node:child_process';
import { readdir, readFile } from 'node:fs/promises';
import { join } from 'node:path';

import { erc20, stablecoin } from '@openzeppelin/wizard';
import { erc20, stablecoin, buildGeneric, printContract, tronPrintProfile } from '@openzeppelin/wizard';
import { registry } from './registry';

const CLI = join(__dirname, '..', 'dist', 'index.js');
Expand Down Expand Up @@ -195,3 +195,44 @@ test('nested dot options with multiple fields', t => {
}),
);
});

// --- TRON ---

test('tron-trc20 rewrites ERC20 to TRC20', t => {
const output = run('tron-trc20', '--name', 'TestToken', '--symbol', 'TST');
t.is(output, printContract(buildGeneric({ kind: 'ERC20', name: 'TestToken', symbol: 'TST' }), tronPrintProfile));
t.true(output.includes('TRC20'), 'output should contain TRC20');
t.true(
output.includes('@openzeppelin/tron-contracts/token/TRC20/TRC20.sol'),
'output should import from @openzeppelin/tron-contracts',
);
});

test('tron-trc721 rewrites ERC721 to TRC721', t => {
const output = run('tron-trc721', '--name', 'TestNFT', '--symbol', 'TNFT');
t.is(output, printContract(buildGeneric({ kind: 'ERC721', name: 'TestNFT', symbol: 'TNFT' }), tronPrintProfile));
t.true(output.includes('TRC721'), 'output should contain TRC721');
});

test('tron-trc1155 rewrites ERC1155 to TRC1155', t => {
const output = run('tron-trc1155', '--name', 'TestMulti', '--uri', 'ipfs://example/{id}');
t.is(
output,
printContract(buildGeneric({ kind: 'ERC1155', name: 'TestMulti', uri: 'ipfs://example/{id}' }), tronPrintProfile),
);
t.true(output.includes('TRC1155'), 'output should contain TRC1155');
});

test('tron-trc20 caps pragma at 0.8.26', t => {
const output = run('tron-trc20', '--name', 'TestToken', '--symbol', 'TST');
t.true(output.includes('pragma solidity ^0.8.26;'), 'pragma should be capped at 0.8.26');
t.false(output.includes('pragma solidity ^0.8.27'), 'pragma should not be 0.8.27 (above tron-solc max)');
});

test('tron-trc20 renames the library but never user name/symbol literals', t => {
// A name and symbol that embed a token standard: only the inherited base is
// renamed to TRC20; the user's deployed name() and symbol() are untouched.
const output = run('tron-trc20', '--name', 'My ERC20 Token', '--symbol', 'ERC20');
t.true(output.includes('contract MyERC20Token is TRC20'), 'base renamed, contract name kept');
t.true(output.includes('TRC20("My ERC20 Token", "ERC20")'), 'name/symbol literals preserved');
});
127 changes: 125 additions & 2 deletions packages/cli/src/cli.test.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Generated by [AVA](https://avajs.dev).
`Usage: npx @openzeppelin/contracts-cli <command> [options]␊
Commands:␊
solidity-erc20, solidity-erc721, solidity-erc1155, solidity-stablecoin, solidity-rwa, solidity-account, solidity-governor, solidity-custom, cairo-erc20, cairo-erc721, cairo-erc1155, cairo-account, cairo-multisig, cairo-governor, cairo-vesting, cairo-custom, stellar-fungible, stellar-governor, stellar-stablecoin, stellar-non-fungible, stylus-erc20, stylus-erc721, stylus-erc1155, confidential-erc7984, uniswap-hooks␊
solidity-erc20, solidity-erc721, solidity-erc1155, solidity-stablecoin, solidity-rwa, solidity-account, solidity-governor, solidity-custom, cairo-erc20, cairo-erc721, cairo-erc1155, cairo-account, cairo-multisig, cairo-governor, cairo-vesting, cairo-custom, stellar-fungible, stellar-governor, stellar-stablecoin, stellar-non-fungible, stylus-erc20, stylus-erc721, stylus-erc1155, confidential-erc7984, uniswap-hooks, tron-trc20, tron-trc721, tron-trc1155, tron-governor, tron-custom
Generated contract source code is printed to stdout.␊
Expand All @@ -25,7 +25,7 @@ Generated by [AVA](https://avajs.dev).
`Usage: npx @openzeppelin/contracts-cli <command> [options]␊
Commands:␊
solidity-erc20, solidity-erc721, solidity-erc1155, solidity-stablecoin, solidity-rwa, solidity-account, solidity-governor, solidity-custom, cairo-erc20, cairo-erc721, cairo-erc1155, cairo-account, cairo-multisig, cairo-governor, cairo-vesting, cairo-custom, stellar-fungible, stellar-governor, stellar-stablecoin, stellar-non-fungible, stylus-erc20, stylus-erc721, stylus-erc1155, confidential-erc7984, uniswap-hooks␊
solidity-erc20, solidity-erc721, solidity-erc1155, solidity-stablecoin, solidity-rwa, solidity-account, solidity-governor, solidity-custom, cairo-erc20, cairo-erc721, cairo-erc1155, cairo-account, cairo-multisig, cairo-governor, cairo-vesting, cairo-custom, stellar-fungible, stellar-governor, stellar-stablecoin, stellar-non-fungible, stylus-erc20, stylus-erc721, stylus-erc1155, confidential-erc7984, uniswap-hooks, tron-trc20, tron-trc721, tron-trc1155, tron-governor, tron-custom
Generated contract source code is printed to stdout.␊
Expand Down Expand Up @@ -663,6 +663,129 @@ Generated by [AVA](https://avajs.dev).
--info.license <string> The license used by the contract, default is "MIT"␊
`

## tron-trc20 --help

> Snapshot 1

`tron-trc20: Make a fungible token per the TRC-20 standard, targeting the TRON Virtual Machine.␊
Required:␊
--name <string> The name of the contract␊
--symbol <string> The short symbol for the token␊
Options:␊
--decimals <string> The number of decimals used to represent token amounts. Defaults to 18.␊
--burnable Whether token holders will be able to destroy their tokens␊
--pausable Whether privileged accounts will be able to pause specifically marked functionality. Useful for emergency response.␊
--premint <string> The number of tokens to premint for the deployer.␊
--premintChainId <string> The chain ID of the network on which to premint tokens.␊
--mintable Whether privileged accounts will be able to create more supply or emit more tokens␊
--callback Whether to include support for code execution after transfers and approvals on recipient contracts in a single transaction.␊
--permit Whether without paying gas, token holders will be able to allow third parties to transfer from their account.␊
--votes <blocknumber|timestamp> Whether to keep track of historical balances for voting in on-chain governance. Voting durations can be expressed as block numbers or timestamps.␊
--flashmint Whether to include built-in flash loans to allow lending tokens without requiring collateral as long as they're returned in the same transaction.␊
--crossChainBridging <custom|erc7786native|superchain> Whether to allow authorized bridge contracts to mint and burn tokens for cross-chain transfers. Options are to use custom bridges on any chain, to embed an ERC-7786 based bridge directly in the token contract, or to use the SuperchainERC20 standard with the predeployed SuperchainTokenBridge. The SuperchainERC20 feature is only available on chains in the Superchain, and requires deploying your contract to the same address on every chain in the Superchain.␊
--crossChainLinkAllowOverride Whether to allow replacing a crosschain link that has already been registered. Only used if crossChainBridging is set to "erc7786native".␊
--namespacePrefix <string> The prefix for ERC-7201 namespace identifiers. It should be derived from the project name or a unique naming convention specific to the project. Used only if the contract includes storage variables and upgradeability is enabled. Default is "myProject".␊
--access <ownable|roles|managed> The type of access control to provision. Ownable is a simple mechanism with a single account authorized for all privileged actions. Roles is a flexible mechanism with a separate role for each privileged action. A role can have many authorized accounts. Managed enables a central contract to define a policy that allows certain callers to access certain functions.␊
--upgradeable <transparent|uups> Whether the smart contract is upgradeable. Transparent uses more complex proxy with higher overhead, requires less changes in your contract. Can also be used with beacons. UUPS uses simpler proxy with less overhead, requires including extra code in your contract. Allows flexibility for authorizing upgrades.␊
--info.securityContact <string> Email where people can contact you to report security issues. Will only be visible if contract source code is verified.␊
--info.license <string> The license used by the contract, default is "MIT"␊
`

## tron-trc721 --help

> Snapshot 1

`tron-trc721: Make a non-fungible token per the TRC-721 standard, targeting the TRON Virtual Machine.␊
Required:␊
--name <string> The name of the contract␊
--symbol <string> The short symbol for the token␊
Options:␊
--baseUri <string> A base uri for the token␊
--enumerable Whether to allow on-chain enumeration of all tokens or those owned by an account. Increases gas cost of transfers.␊
--uriStorage Allows updating token URIs for individual token IDs␊
--burnable Whether token holders will be able to destroy their tokens␊
--pausable Whether privileged accounts will be able to pause specifically marked functionality. Useful for emergency response.␊
--mintable Whether privileged accounts will be able to create more supply or emit more tokens␊
--incremental Whether new tokens will be automatically assigned an incremental id␊
--votes <blocknumber|timestamp> Whether to keep track of individual units for voting in on-chain governance. Voting durations can be expressed as block numbers or timestamps (defaulting to block number if not specified).␊
--access <ownable|roles|managed> The type of access control to provision. Ownable is a simple mechanism with a single account authorized for all privileged actions. Roles is a flexible mechanism with a separate role for each privileged action. A role can have many authorized accounts. Managed enables a central contract to define a policy that allows certain callers to access certain functions.␊
--upgradeable <transparent|uups> Whether the smart contract is upgradeable. Transparent uses more complex proxy with higher overhead, requires less changes in your contract. Can also be used with beacons. UUPS uses simpler proxy with less overhead, requires including extra code in your contract. Allows flexibility for authorizing upgrades.␊
--info.securityContact <string> Email where people can contact you to report security issues. Will only be visible if contract source code is verified.␊
--info.license <string> The license used by the contract, default is "MIT"␊
--namespacePrefix <string> The prefix for ERC-7201 namespace identifiers. It should be derived from the project name or a unique naming convention specific to the project. Used only if the contract includes storage variables and upgradeability is enabled. Default is "myProject".␊
`

## tron-trc1155 --help

> Snapshot 1

`tron-trc1155: Make a multi-token contract per the TRC-1155 standard, targeting the TRON Virtual Machine.␊
Required:␊
--name <string> The name of the contract␊
--uri <string> The location of the metadata for the token. Clients will replace any instance of {id} in this string with the tokenId.␊
Options:␊
--burnable Whether token holders will be able to destroy their tokens␊
--pausable Whether privileged accounts will be able to pause specifically marked functionality. Useful for emergency response.␊
--mintable Whether privileged accounts will be able to create more supply or emit more tokens␊
--supply Whether to keep track of total supply of tokens␊
--updatableUri Whether privileged accounts will be able to set a new URI for all token types␊
--access <ownable|roles|managed> The type of access control to provision. Ownable is a simple mechanism with a single account authorized for all privileged actions. Roles is a flexible mechanism with a separate role for each privileged action. A role can have many authorized accounts. Managed enables a central contract to define a policy that allows certain callers to access certain functions.␊
--upgradeable <transparent|uups> Whether the smart contract is upgradeable. Transparent uses more complex proxy with higher overhead, requires less changes in your contract. Can also be used with beacons. UUPS uses simpler proxy with less overhead, requires including extra code in your contract. Allows flexibility for authorizing upgrades.␊
--info.securityContact <string> Email where people can contact you to report security issues. Will only be visible if contract source code is verified.␊
--info.license <string> The license used by the contract, default is "MIT"␊
`

## tron-governor --help

> Snapshot 1

`tron-governor: Make a contract to implement governance, such as for a DAO, targeting the TRON Virtual Machine.␊
Required:␊
--name <string> The name of the contract␊
--delay <string> The delay since proposal is created until voting starts, default is "1 day"␊
--period <string> The length of period during which people can cast their vote, default is "1 week"␊
Options:␊
--votes <erc20votes|erc721votes> The type of voting to use␊
--clockMode <blocknumber|timestamp> The clock mode used by the voting token. For Governor, this must be chosen to match what the ERC20 or ERC721 voting token uses.␊
--timelock <false|openzeppelin|compound> The type of timelock to use␊
--blockTime <number> The block time of the chain in seconds, default is 3.␊
--decimals <number> The number of decimals to use for the contract, default is 18 for ERC20Votes and 0 for ERC721Votes (because it does not apply to ERC721Votes)␊
--proposalThreshold <string> Minimum number of votes an account must have to create a proposal, default is 0.␊
--quorumMode <percent|absolute> The type of quorum mode to use␊
--quorumPercent <number> The percent required, in cases of quorumMode equals percent␊
--quorumAbsolute <string> The absolute quorum required, in cases of quorumMode equals absolute␊
--storage Enable storage of proposal details and enumerability of proposals␊
--settings Allow governance to update voting settings (delay, period, proposal threshold)␊
--upgradeable <transparent|uups> Whether the smart contract is upgradeable. Transparent uses more complex proxy with higher overhead, requires less changes in your contract. Can also be used with beacons. UUPS uses simpler proxy with less overhead, requires including extra code in your contract. Allows flexibility for authorizing upgrades.␊
--info.securityContact <string> Email where people can contact you to report security issues. Will only be visible if contract source code is verified.␊
--info.license <string> The license used by the contract, default is "MIT"␊
`

## tron-custom --help

> Snapshot 1

`tron-custom: Make a custom smart contract, targeting the TRON Virtual Machine.␊
Required:␊
--name <string> The name of the contract␊
Options:␊
--pausable Whether privileged accounts will be able to pause specifically marked functionality. Useful for emergency response.␊
--access <ownable|roles|managed> The type of access control to provision. Ownable is a simple mechanism with a single account authorized for all privileged actions. Roles is a flexible mechanism with a separate role for each privileged action. A role can have many authorized accounts. Managed enables a central contract to define a policy that allows certain callers to access certain functions.␊
--upgradeable <transparent|uups> Whether the smart contract is upgradeable. Transparent uses more complex proxy with higher overhead, requires less changes in your contract. Can also be used with beacons. UUPS uses simpler proxy with less overhead, requires including extra code in your contract. Allows flexibility for authorizing upgrades.␊
--info.securityContact <string> Email where people can contact you to report security issues. Will only be visible if contract source code is verified.␊
--info.license <string> The license used by the contract, default is "MIT"␊
`

## unknown command

> Snapshot 1
Expand Down
Binary file modified packages/cli/src/cli.test.ts.snap
Binary file not shown.
Loading
Loading