Initial Twitter Offering (ITO) is a Dapplet based on the Mask browser extension. It consists of two components, the browser extension and the Ethereum smart contract. This repo covers the design and the implementation of the smart contract only.
ITO is basically a token swap pool that can be initiated by any Ethereum user. Users can transfer an amount of a target token (now supporting ETH and ERC20 tokens) into the pool and set the swap ratios, e.g. {1 ETH: 10000 TOKEN, 1 DAI: 10 TOKEN}. Users can also set the swap limit (ceiling) to control how many tokens to be swapped by a single address, e.g. 10000 TOKEN. After the pool is expired (also set on initiation) or the target token is out of stock, the pool creator can withdraw any target token left and all the swapped tokens. The pool will be destructed after the withdraw.
Participants only need to approve one of the specified tokens according to the pool ratio
and call the swap()
function to swap the target token out. The swapped amount is automatically calculated by the smart contract and the users can receive the target token instantly after a successful call of the swap()
. Pool creator can also set an unlock time for ITO which means to receive the target token participants need to wait after that unlock time by calling claim()
function.
This is a standard truffle project. To install:
npm ci
To build the project:
npm run compile
To test the project:
npm test
To deploy contract on ropsten
:
npm run deploy ropsten
To debug:
//...
import "hardhat/console.sol";
function debug_param (address _token_addr) public {
console.log('_token_addr', _token_addr);
}
The ITO smart contract adopts the Proxy Upgrade Pattern
to improve user experience. Hence, the addresses in later section are actually the deployed TransparentUpgradeableProxy
smart contract addresses.
Another smart contract interface IQLF
(source code) is also introduced to provide an API logQualified()
that returns a boolean indicating if the given address is qualified. Custom qualification contract SHOULD implement contract IQLF
rather than ERC-165 to further ensure the required interface is implemented since IQLF
is compliant with ERC-165 and has implemented the details of supportsInterface
function.
To prevent a malicious attack, you can set a swap_start_time
in your custom qualification contract, then add accounts who swap before that time to a blacklist, they will no longer be able to access your ITO. Please confirm the swap_start_time
carefully, it must be less than the end time of ITO, otherwise, nobody can access your ITO at all. To let Mask browser extension help you check if swap_start_time
is less than the end time of ITO. You need to append interfaceId == this.get_start_time.selector;
to supportsInterface()
(Notice the getter function MUST be named get_start_time()
to keep the same with the browser extension code), just copy the implementation of our default qualification contract.
Chain | ITO | Dummy Qualification |
---|---|---|
Mainnet | 0xc2CFbF22 |
0x4dC5f343 |
Ropsten | 0xcdE281B3 |
0xd5e6434b |
Rinkeby | 0xBe62f180 |
0x8440b99B |
BSC | 0x96c7D011 |
0xAb7B1bE4 |
BSC_test | 0xbc558E76 |
0xaaC2362f |
Matic | 0xF9F7C149 |
0x2cf91AD8 |
Arbitrum_rinkeby | 0x9b3649eC |
0xEbd753E6 |
Arbitrum | 0x71834a3F |
0x913975af |
xDai | 0x913975af |
0x71834a3F |
Goerli | 0x3475255F |
0x957DCb39 |
Fantom | 0x981be454 |
0x83D6b366 |
Celo | 0x54a0A221 |
0x2cB220F9 |
Avalanche | 0x02Ea0720 |
0x54a0A221 |
Optimism_kovan | 0x88edAC7a |
0x57E2AAB7 |
Optimism | 0x71834a3F |
0x913975af |
Aurora | 0x2cf91AD8 |
0x578a7Fee |
Fuse | 0xF9F7C149 |
0x2cf91AD8 |
Boba | 0x981be454 |
0x83D6b366 |
Moonriver | 0x981be454 |
0x83D6b366 |
Conflux_espace_test | 0x83D6b366 |
0x96c7D011 |
Conflux_espace | 0x066804d9 |
0x05ee315E |
Harmony | 0x5B966f3a |
0x02Ea0720 |
Harmony_test | 0x578a7Fee |
0x81246335 |
Metis_test | 0x71834a3F |
|
Metis | 0x5B966f3a |
|
Kardia | 0x224e8327 |
0x0cE6df81 |
Astar | 0x1D720657 |
0xdd2Cf3fF |
Chain | v1.0 | v2.0 |
---|---|---|
Mainnet | 12689616 | 12766513 |
Ropsten | 10468221 | 10572050 |
BSC | 8508077 | 8885927 |
Matic | 16002769 | 16516643 |
Arbitrum_rinkeby | 708696 | |
Arbitrum | 102022 | |
xDai | 17865755 | |
Goerli | 6028660 | |
Fantom | 25071597 | |
Celo | 10406511 | |
Avalanche | 8289892 | |
Optimism_kovan | 47716 | |
Optimism | 8994 | |
Aurora | 57350598 | |
Fuse | 14951572 | |
Boba | 290600 | |
Moonriver | 1314566 | |
Conflux_espace_test | 66092470 | |
Conflux_espace | 37722805 | |
Harmony | 24133305 | |
Harmony_test | 22744597 | |
Metis_test | 5207086 | |
Metis | 1701875 | |
Kardia | 7566530 | |
Astar | 915536 |
The Solidity code in this repository has been audited by blockchain security experts from SlowMist. If you are interested, here are the audit reports:
If you have any security issue to report, please send to security@mask.io.
Any contribution is welcomed to make it more secure and powerful. Had you any questions, please do not hesitate to create an issue to let us know.
InitialTwitterOffering is released under the MIT LICENSE.