Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
610 changes: 610 additions & 0 deletions content/tron-contracts/access-control.mdx

Large diffs are not rendered by default.

51 changes: 51 additions & 0 deletions content/tron-contracts/backwards-compatibility.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
title: "Backwards Compatibility"
---

OpenZeppelin Contracts uses semantic versioning to communicate backwards compatibility of its API and storage layout. Patch and minor updates will generally be backwards compatible, with rare exceptions as detailed below. Major updates should be assumed incompatible with previous releases. On this page, we provide details about these guarantees.

## API

In backwards compatible releases, all changes should be either additions or modifications to internal implementation details. Most code should continue to compile and behave as expected. The exceptions to this rule are listed below.

### Security

Infrequently a patch or minor update will remove or change an API in a breaking way, but only if the previous API is considered insecure. These breaking changes will be noted in the changelog and release notes, and published along with a security advisory.

### Draft or Pre-Final ERCs

ERCs that are not Final can change in incompatible ways. For this reason, we avoid shipping implementations of ERCs before they are Final. Some exceptions are made for ERCs that have been published for a long time and seem unlikely to change. Implementations for ERCs that may have breaking changes are published in files named `draft-*.sol` to make that condition explicit. There is no backwards compatibility guarantee for content in files prefixed with `draft`.

Standards that have achieved widespread adoption with strong backwards compatibility expectations from the community may be treated as de-facto finalized and published without the `draft-` prefix, as extensive ecosystem reliance makes breaking changes highly unlikely.

### Virtual & Overrides

Almost all functions in this library are virtual with some exceptions, but this does not mean that overrides are encouraged. There is a subset of functions that are designed to be overridden. By defining overrides outside of this subset you are potentially relying on internal implementation details. We make efforts to preserve backwards compatibility even in these cases but it is extremely difficult and easy to accidentally break. Caution is advised.

Additionally, some minor updates may result in new compilation errors of the kind "two or more base classes define function with same name and parameter types" or "need to specify overridden contract", due to what Solidity considers ambiguity in inherited functions. This should be resolved by adding an override that invokes the function via `super`.

See [Extending Contracts](/tron-contracts/extending-contracts) for more about virtual and overrides.

### Structs

Struct members with an underscore prefix should be considered "private" and may break in minor versions. Struct data should only be accessed and modified through library functions.

### Errors

The specific error format and data that is included with reverts should not be assumed stable unless otherwise specified.

### Major Releases

Major releases should be assumed incompatible. Nevertheless, the external interfaces of contracts will remain compatible if they are standardized, or if the maintainers judge that changing them would cause significant strain on the ecosystem.

An important aspect that major releases may break is "upgrade compatibility", in particular storage layout compatibility. It will never be safe for a live contract to upgrade from one major release to another.

## Storage Layout

Minor and patch updates always preserve storage layout compatibility. This means that a live contract can be upgraded from one minor to another without corrupting the storage layout. In some cases it may be necessary to initialize new state variables when upgrading, although we expect this to be infrequent.

We recommend using OpenZeppelin Upgrades Plugins or CLI to ensure storage layout safety of upgrades.

## Solidity Version

The minimum Solidity version required to compile the contracts will remain unchanged in minor and patch updates. New contracts introduced in minor releases may make use of newer Solidity features and require a more recent version of the compiler.
84 changes: 84 additions & 0 deletions content/tron-contracts/extending-contracts.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
---
title: "Extending Contracts"
---

Most of the OpenZeppelin Contracts are expected to be used via [inheritance](https://solidity.readthedocs.io/en/latest/contracts.html#inheritance): you will _inherit_ from them when writing your own contracts.

This is the commonly found `is` syntax, like in `contract MyToken is TRC20`.

<Callout>
Unlike ``contract``s, Solidity ``library``s are not inherited from and instead rely on the [`using for`](https://solidity.readthedocs.io/en/latest/contracts.html#using-for) syntax.

OpenZeppelin Contracts has some ``library``s: most are in the Utils directory.
</Callout>

## Overriding

Inheritance is often used to add the parent contract's functionality to your own contract, but that's not all it can do. You can also _change_ how some parts of the parent behave using _overrides_.

For example, imagine you want to change `AccessControl` so that `revokeRole` can no longer be called. This can be achieved using overrides:

```solidity
// contracts/AccessControlModified.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {AccessControl} from "@openzeppelin/tron-contracts/access/AccessControl.sol";

contract AccessControlModified is AccessControl {
error AccessControlNonRevocable();

// Override the revokeRole function
function revokeRole(bytes32, address) public pure override {
revert AccessControlNonRevocable();
}
}
```

The old `revokeRole` is then replaced by our override, and any calls to it will immediately revert. We cannot _remove_ the function from the contract, but reverting on all calls is good enough.

### Calling `super`

Sometimes you want to _extend_ a parent's behavior, instead of outright changing it to something else. This is where `super` comes in.

The `super` keyword will let you call functions defined in a parent contract, even if they are overridden. This mechanism can be used to add additional checks to a function, emit events, or otherwise add functionality as you see fit.

<Callout>
For more information on how overrides work, head over to the [official Solidity documentation](https://solidity.readthedocs.io/en/latest/contracts.html#index-17).
</Callout>

Here is a modified version of `AccessControl` where `revokeRole` cannot be used to revoke the `DEFAULT_ADMIN_ROLE`:

```solidity
// contracts/AccessControlNonRevokableAdmin.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {AccessControl} from "@openzeppelin/tron-contracts/access/AccessControl.sol";

contract AccessControlNonRevokableAdmin is AccessControl {
error AccessControlNonRevokable();

function revokeRole(bytes32 role, address account) public override {
if (role == DEFAULT_ADMIN_ROLE) {
revert AccessControlNonRevokable();
}

super.revokeRole(role, account);
}
}
```

The `super.revokeRole` statement at the end will invoke ``AccessControl``'s original version of `revokeRole`, the same code that would've run if there were no overrides in place.

<Callout>
The same rule is implemented and extended in `AccessControlDefaultAdminRules`, an extension that also adds enforced security measures for the `DEFAULT_ADMIN_ROLE`.
</Callout>

## Security

The maintainers of OpenZeppelin Contracts are mainly concerned with the correctness and security of the code as published in the library, and the combinations of base contracts with the official extensions from the library.

Custom overrides, especially to hooks, can disrupt important assumptions and may introduce security risks in the code that was previously secure. While we try to ensure the contracts remain secure in the face of a wide range of potential customizations, this is done in a best-effort manner. While we try to document all important assumptions, this should not be relied upon. Custom overrides should be carefully reviewed and checked against the source code of the contract they are customizing to fully understand their impact and guarantee their security.

The way functions interact internally should not be assumed to stay stable across releases of the library. For example, a function that is used in one context in a particular release may not be used in the same context in the next release. Contracts that override functions should revalidate their assumptions when updating the version of OpenZeppelin Contracts they are built on.
15 changes: 15 additions & 0 deletions content/tron-contracts/faq.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
title: "Frequently Asked Questions"
---

## Can I restrict a function to EOAs only?

When calling external addresses from your contract it is unsafe to assume that an address is an externally-owned account (EOA) and not a contract. Attempting to prevent calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract constructor.

Although checking that the address has code, `address.code.length > 0`, may seem to differentiate contracts from EOAs, it can only say that an address is currently a contract, and its negation (that an address is not currently a contract) does not imply that the address is an EOA. Some counterexamples are:

- address of a contract in construction
- address where a contract will be created
- address where a contract lived, but was destroyed

Furthermore, an address will be considered a contract within the same transaction where it is scheduled for destruction by `SELFDESTRUCT`, which only has an effect at the end of the entire transaction.
Loading