Smart Contract Guidelines

Building on Relix means you are deploying code that moves value and can’t be silently patched once live. This section outlines practical guidelines for writing, reviewing, and operating smart contracts on Relix, with an emphasis on security, clarity, and long-term maintainability.

Most of the principles are the same as on other EVM networks; the difference is that here they apply to RLX and the Relix ecosystem.


1. Design for simplicity first

Complexity is the enemy of security. Before writing a single line of Solidity:

  • Define the minimal feature set Ask what the contract really needs to do in v1. Extra features can often be shipped later, in separate modules.

  • Avoid overloading contracts Split responsibilities across multiple contracts instead of putting everything in one “god contract”. Common splits:

    • Core logic

    • Access control / roles

    • Upgrade or configuration layer

    • Treasury or fee collection

  • Prefer battle-tested patterns Use standard token interfaces, well-known upgrade patterns, and common modifiers instead of inventing entirely new abstractions for basic needs.

A smaller, cleaner surface is easier to reason about, easier to audit, and less prone to exploitable edge cases.


2. Follow strong access control practices

Many incidents start with access control mistakes rather than low-level EVM bugs.

  • Use explicit roles Leverage patterns such as Ownable, AccessControl, or role-based modules:

    • Separate roles for admin, operator, pauser, treasury, etc.

    • Avoid a single key that can do everything if it is not strictly necessary.

  • Minimize privileges Give each role only what it needs. For example:

    • Operators can change operational parameters within safe ranges.

    • Admins can update critical addresses or pause the system, but not drain funds.

  • Plan for key rotation Include functions to change admin or role addresses in a controlled way. Document the process (multisig, time delay, off-chain approvals) before mainnet.

  • Favor multisig for powerful roles For production deployments, critical roles should be held by multisig wallets rather than individual EOAs, to reduce single-key risk.


3. Guard against common Solidity pitfalls

Even on Solidity 0.8.x (with built-in overflow checks), traditional mistakes still apply:

  • Reentrancy

    • Use the checks–effects–interactions pattern.

    • Prefer internal balance updates before external calls.

    • Where appropriate, use a reentrancy guard for sensitive entry points (e.g. withdrawals).

  • Unchecked external assumptions

    • Do not assume external contracts behave “nicely”.

    • Validate return values and states after external calls where possible.

    • Avoid blindly trusting token contracts (e.g. some tokens may not revert on failure).

  • Dangerous delegatecall usage

    • Restrict delegatecall to well-defined upgrade mechanisms.

    • Never allow arbitrary addresses to be used as delegation targets by untrusted users.

  • Timestamp and block-based logic

    • Use block.timestamp with tolerance; avoid exact equality checks.

    • Do not rely on block numbers for time in environments where block time can vary.

Make sure every external call and every state-changing function has been reviewed specifically for reentrancy, access control, and correct ordering of effects.


4. Handle tokens and value transfers carefully

On Relix, RLX is the native asset, and ERC-style tokens will be common. Treat both with care:

  • Use standard interfaces

    • ERC-20, ERC-721, ERC-1155 for tokens.

    • Avoid custom “almost-ERC” implementations unless there is a compelling, well-documented reason.

  • Support non-standard ERC-20 behavior

    • Some tokens do not return a boolean on transfer / transferFrom.

    • Others may have fees or deflationary mechanics.

    • Use safe wrappers when interacting with arbitrary tokens.

  • Do not assume msg.value equals the meaningful deposit

    • For contracts that accept RLX, validate expected value and define clear refund logic for excess.

  • Avoid forced transfers to contracts without withdrawal paths

    • Design clear escape hatches for stuck funds where appropriate, with transparent governance or time-locks around their use.


5. Be deliberate about upgradeability

Upgradeability adds flexibility, but also risk and complexity.

  • Decide whether you really need it If the contract is simple, time-limited, or replaceable, consider a non-upgradeable deployment.

  • If you do use upgradeable patterns, document them clearly

    • Proxy model used (transparent, UUPS, beacon, custom).

    • Who can upgrade and how (admin, multisig, governance).

    • What guarantees users have (e.g. time-locks, on-chain voting).

  • Lock down implementation contracts

    • Prevent direct interaction where possible.

    • Use storage layout carefully to avoid collisions and unintended variable overwrites.

  • Plan for deprecation Even with upgrades, there should be a path to gracefully migrate users to a newer system over time rather than relying on indefinite extension of v1 contracts.


6. Build with testing and formal review in mind

Good testing is not optional for contracts that will be deployed to Relix.

  • Unit tests

    • Cover normal flows, edge cases, and expected failures.

    • Validate events, not just state changes.

  • Property-based tests (where feasible)

    • Use fuzzing or property-based frameworks to exercise a wide range of inputs.

  • Integration tests on Relix Testnet (chain ID 4127)

    • Test against https://rpc-testnet.relixchain.com.

    • Verify behavior under realistic gas conditions and block timing.

    • Interact via real wallets to confirm end-user flows.

  • Independent review or audit

    • For contracts holding meaningful value, an external security review is strongly recommended.

    • Provide reviewers with good documentation, threat models, and test coverage to make their work effective.

Formal verification or specialized analysis tools can add an extra layer of assurance for high-value or protocol-critical components.


7. Design with failure and pausing in mind

Even well-written contracts may need emergency controls.

  • Pausable mechanisms

    • Implement pause or circuit-breaker functions where it makes sense.

    • Ensure pausing is scoped: sometimes it should block deposits but still allow withdrawals.

  • Rate limits and caps

    • Use per-transaction or per-period limits to reduce blast radius.

    • Cap maximum positions, withdrawals, or minting in line with your risk model.

  • Fail-safe defaults

    • When something goes wrong (for example, an oracle is offline), err on the side of not executing risky actions.

  • Clear owner/operator playbooks

    • Document how and when pause, unpause, or configuration changes should be used.

    • Avoid ad-hoc, undocumented “admin interventions”.

These mechanisms must be transparent to users: powerful controls are acceptable when they are clearly communicated and governed, not hidden.


8. Treat dependencies as part of your attack surface

Every external dependency adds risk:

  • Libraries and frameworks

    • Pin versions in package.json / foundry.toml / hardhat.config.

    • Monitor upstream projects for security advisories.

  • Oracles and external data

    • Understand how prices or other feeds are aggregated and updated.

    • Plan for stale, manipulated, or temporarily unavailable data.

  • Bridges and cross-chain components

    • Recognize that bridging external assets or messages introduces additional failure modes and trust assumptions.

Whenever a contract relies on an external system, state in your documentation:

  • What that dependency does

  • How it can fail or be attacked

  • What mitigations are in place on your side


9. Be transparent with users and integrators

Smart contract security is not only about code; it is about expectations.

At a minimum, publish:

  • High-level architecture What the contract does, how it interacts with other contracts, and which addresses are critical.

  • Admin and governance model Who controls upgrades, pauses, fee changes, and other parameters.

  • Risk disclosures Known limitations, economic risks (e.g. oracle manipulation), and assumptions your design depends on.

  • Deployment details on Relix Contract addresses, network (Relix Testnet vs future mainnet), and links to the official explorer at https://testnet.relixchain.com for verification.

Clear documentation reduces misunderstandings, helps auditors and other teams integrate safely, and makes it easier to respond if an issue is found.


10. Use Relix Testnet for real-world rehearsal

Before deploying on mainnet, use Relix Testnet (chain ID 4127) as a realistic rehearsal environment:

  • Deploy the same contracts with the same parameters wherever possible.

  • Run full user flows: staking, swapping, minting, redeeming, upgrading.

  • Simulate stress: higher transaction volume, edge cases, and malicious behavior.

Treat testnet incidents as serious learning opportunities. Fixes identified there are almost always cheaper than fixing the same issue after assets are at risk on mainnet.


These guidelines are not a complete checklist, but they capture the mindset expected of teams deploying on Relix: careful design, conservative assumptions, transparent governance, and respect for the fact that once code is on-chain, users are relying on it to behave correctly every time.

Last updated