Git Product home page Git Product logo

custom-supertokens's Introduction

Custom Super Tokens

This repository shows how to implement custom SuperTokens.

A custom SuperToken contract typically consists of:

  • (immutable) proxy contract with custom logic
  • (upgradable) logic contract containing ERC20 and SuperToken functionality

By convention, SuperToken contracts are instances of UUPSProxy. A custom Super Token has custom logic added to this proxy contract.

PureSuperTokenProxy.sol is the simplest variant of a custom SuperToken. It's a Pure SuperToken (no underlying ERC20) which has its supply minted on creation.

CustomERC20WrapperProxy.sol shows how a Wrapper SuperToken (has an unerlying ERC20) could be customized.

xchain contains more advanced variants of Custom SuperTokens, suited for cross-chain deployments (e.g. bridging ERC20 <-> SuperToken). See the dedicated section for more.

Setup

To set up the repo for development, start by cloning the repo

git clone https://github.com/superfluid-finance/custom-supertokens
cd custom-supertokens

Installing Foundry

Make sure you have installed Foundry. If you don't have Foundry on your development environment, please refer to Foundry Book.

Install dependencies

Once Foundry has been installed, you can run the following command to install dependencies

forge install

This command will install the @superfluid-finance packages, and the @openzeppelin-contracts (v4.9.3) packages, in addition to to forge-std.

Create your Custom Super Token

As an example of creating your own Custom Super Token, we can take a look at the PureSuperToken.sol contract.

contract PureSuperTokenProxy is CustomSuperTokenBase, UUPSProxy {
	// This shall be invoked exactly once after deployment, needed for the token contract to become operational.
	function initialize(
		ISuperTokenFactory factory,
		string memory name,
		string memory symbol,
		address receiver,
		uint256 initialSupply
	) external {
		// This call to the factory invokes `UUPSProxy.initialize`, which connects the proxy to the canonical SuperToken implementation.
		// It also emits an event which facilitates discovery of this token.
		ISuperTokenFactory(factory).initializeCustomSuperToken(address(this));

		// This initializes the token storage and sets the `initialized` flag of OpenZeppelin Initializable.
		// This makes sure that it will revert if invoked more than once.
		ISuperToken(address(this)).initialize(
			IERC20(address(0)),
			18,
			name,
			symbol
		);

		// This mints the specified initial supply to the specified receiver.
		ISuperToken(address(this)).selfMint(receiver, initialSupply, "");
	}
}

This contract simply creates a new UUPSProxy with a custom initialize method. This method calls SuperTokenFactory.initializeCustomSuperToken (which emits events facilitating discovery of the SuperToken), then mints the full supply of the token to the receiver.

For more information on the creation of Custom Super Tokens, please refer to the Technical Documentation or the Protocol Wiki.

Test your Custom Super Token Contract

Once you created your custom logic in the Custom Super Token Contract, you can now go ahead and write tests of your Custom Super Token.

Going back to the previous example of the Pure Super Token contract, we can see that the file including the tests of PureSuperToken contract is PureSuperToken.t.sol.

This file contains a deployment of the protocol in the method setUp as such:

function setUp() public {
		vm.etch(ERC1820RegistryCompiled.at, ERC1820RegistryCompiled.bin);
		SuperfluidFrameworkDeployer sfDeployer = new SuperfluidFrameworkDeployer();
		sfDeployer.deployTestFramework();
		_sf = sfDeployer.getFramework();
	}

Then the file contains 2 tests, one of deployment and the other to check the receiver's balance

	function testDeploy() public {
		_superTokenProxy = new PureSuperTokenProxy();
		assert(address(_superTokenProxy) != address(0));
	}

	function testSuperTokenBalance() public {
		_superTokenProxy = new PureSuperTokenProxy();
		_superTokenProxy.initialize(
			_sf.superTokenFactory,
			"TestToken",
			"TST",
			_OWNER,
			1000
		);
		ISuperToken superToken = ISuperToken(address(_superTokenProxy));
		uint balance = superToken.balanceOf(_OWNER);
		assert(balance == 1000);
	}

To run these tests you can run the test command from Foundry:

forge test

Deployment

There are multiple ways to manage the deployment of a Custom Super Token. One of them is using the following command line by replacing the proper arguments with your requirements:

forge create --rpc-url <RPC_URL_OF_DESIRED_CHAIN> --private-key <YOUR_PRIVATE_KEY> --etherscan-api-key <YOUR_ETHERSCAN_API_KEY> --verify --via-ir src/PureSuperToken.sol:PureSuperTokenProxy

Learn more about Custom Super Tokens

To learn more about Custom Super Tokens, check the following resources:

Bridging with xERC20

xERC20 is a bridge-agnostic protocol which allows token issuers to deploy crosschain native tokens with zero slippage, perfect fungibility, and granular risk settings — all while maintaining ownership of your token contracts..

BridgedSuperToken.sol extends a Pure SuperToken with the xerc20 interface. The core functions are mint and burn. They leverage the hooks selfMint and selfBurn provided by the canonical Super Token implementation. The rest of the logic is mostly about setting and enforcing rate limits per bridge. The limits are defined as the maximum token amount a bridge can mint or burn per 24 hours (rolling time window).

Optimism / Superchain Standard Bridge

L2's based on the OP / Superchain stack can use the native Standard Bridge for maximum security.

OPBridgedSuperToken.sol allows that by implementing the required ´IOptimismMintableERC20interface. Itsmint()andburn()match those of IXERC20, but it addsbridge()(address of the bridge contract),remoteToken()(address of the token on L1) andsupportsInterface()` (ERC165 interface detection).

HomeERC20

Is a plain OpenZeppelin based ERC20 with ERC20Votes extension. It's suitable for multichain token deployments which want an ERC20 representation on L1 and Super Token representations on L2s.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.