octopus-network / oct-token-eth

2 stars 7 forks source link

oct-token-eth

This repository contains contracts for OCT token on Ethereum network.

Contents

Contract 'OctToken'

This is a contract based on standard openzeppelin-contracts ERC20 and Ownable, with following functions added:

Contract 'UnsupervisedTimelock'

This contract will lock a certain amount of OCT token and release them linearly by the passed days in timelock duration.

This contract have the following constants and state variables:

    // Seconds of a day
    uint256 private constant SECONDS_OF_A_DAY = 86400;
    // beneficiary of tokens after they are released
    address private immutable _beneficiary;
    // The start timestamp of token release period.
    //
    // Before this time, the beneficiary can NOT withdraw any token from this contract.
    uint256 private immutable _releaseStartTime;
    // The days that the timelock will last.
    uint256 private immutable _daysOfTimelock;
    // The OctToken contract
    IERC20 private immutable _token;
    // Total balance of benefit
    uint256 private immutable _totalBenefit;
    // The amount of withdrawed balance of the beneficiary.
    //
    // This value will be updated on each withdraw operation.
    uint256 private _withdrawedBalance;

This contract will be initialized by following parameters:

The value of this parameters will be used to initialize the state variables of this contract. The releaseStartTime_ will be truncated to 00:00:00 of the day which the releaseStartTime_ is in.

The address of beneficiary_ should be address of an EOA. To simplify the opertion of beneficiary, we'll check this manually (off-chain).

The benefit issuer should transfer the totalBenefit_ amount of OCT token to this contract after the contract is deployed.

This contract has only one function which can change the state of the contract: withdraw(), with no parameter. Anyone can call this function to transfer a certain amount of OCT token that is locked in this contract to the _beneficiary.

The processing steps of function withdraw() are as follow:

releasedBalance = <totalBenefit_> * <the days passed since releaseStartTime_> / <daysOfTimelock_>
transferAmount = releasedBalance - _withdrawedBalance

This contract also have view functions for querying the value of unreleasedBalance, releasedBalance and withdrawedBalance.

Contract 'SupervisedTimelock'

This contract will lock a certain amount of OCT token and release them linearly by the passed days in timelock duration. The owner of the contract can terminate it at any time, and withdraw unreleased benefit at the time.

This contract have the following constants and state variables:

    // Seconds of a day
    uint256 private constant SECONDS_OF_A_DAY = 86400;
    // The OctToken contract
    IERC20 private immutable _token;
    // beneficiary of tokens after they are released
    address private immutable _beneficiary;
    // The start timestamp of token release period.
    //
    // Before this time, the beneficiary can NOT withdraw any token from this contract.
    uint256 private immutable _releaseStartTime;
    // The end timestamp of token release period.
    //
    // After this time, the beneficiary can withdraw all amount of benefit.
    uint256 private _releaseEndTime;
    // Total balance of benefit
    uint256 private _totalBenefit;
    // The amount of withdrawed balance of the beneficiary.
    //
    // This value will be updated on each withdraw operation.
    uint256 private _withdrawedBalance;
    // The flag of whether this contract is terminated.
    bool private _isTerminated;

This contract will be initialized by following parameters:

The address of beneficiary_ should be address of an EOA. To simplify the opertion of beneficiary, we'll check this manually (off-chain).

The value of this parameters will be used to initialize the state variables of this contract. The releaseStartTime_ will be truncated to 00:00:00 of the day which the releaseStartTime_ is in. The _withdrawedBlance is set to 0. The _isTerminated is set to false. And the _releaseEndTime is calculated by:

_releaseEndTime = releaseStartTime_ + SECONDS_OF_A_DAY * daysOfTimelock_

The benefit issuer should transfer the totalBenefit_ amount of OCT token to this contract after the contract is deployed.

This contract has a function withdraw(). Anyone can call this function to transfer a certain amount of OCT token that is locked in this contract to the _beneficiary. The processing steps of the function are as follow:

releasedBalance = _totalBenefit * <the days passed since _releaseStartTime> / <total days from _releaseStartTime to _releaseEndTime>
transferAmount = releasedBalance - _withdrawedBalance

This contract also has a function terminate(). Only the owner of this contract can call this function while _isTerminated is false, to teminate this contract and withdraw all unreleased benefit. The processing steps of this function are as follow:

This contract also have view functions for querying the value of totalBenefit, unreleasedBalance, releasedBalance and withdrawedBalance.

Contract 'SupervisedMultiTimelock'

This contract will serve for multiple beneficiaries specified by the owner. The contract can release a certain amount of OCT token to beneficiaries, linearly by the passed days in timelock duration.

The token contract of OCT token should be specified at the construction time of this contract, and it can not be changed after the construction.

The owner of the contract can perform following actions:

The beneficiaries specified by the owner of this contract can withdraw their benefit (OCT token) at any time. This contract will use the given release start time and timelock duration (in days) to release OCT token to a certain beneficiary linearly, and record the withdrawn amount of the beneficiary. If the withdrawn amount of the beneficiary is less than the released amount of benefit at the time the withdrawal is performed, the remaining unwithdrawal amount of OCT token will be transfered to the beneficiary.

This contract should also provide view functions for querying the issued benefit of a beneficiary, withdrawn amount of a beneficiary, released amount of a beneficiary and unreleased amount of a beneficiary.

This contract will not record the change history of beneficiaries. That is, a beneficiary information (account address, benefit amount, release start time, timelock duration and withdrawn amount) can only have one version in this contract.

Installation

Install dependencies

Install openzeppelin/contracts.

npm install @openzeppelin/contracts

Install dependencies for development

Install hardhat for testing.

npm install --save-dev hardhat

Install modules for running testing scripts compatible with Waffle.

npm install --save-dev @nomiclabs/hardhat-waffle ethereum-waffle chai @nomiclabs/hardhat-ethers ethers

Test

You can run the tests by:

npx hardhat test

or

npm run test

Audit

These contracts had audited by SlowMist Security Team.