Skip to content

Commit 869adbe

Browse files
committed
add v5.2.0 mainnet snapshot
1 parent 48433ce commit 869adbe

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+17291
-1
lines changed

.gitignore

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Mac
2+
.DS_Store
3+
4+
# dependency
5+
node_modules/
6+
7+
# Hardhat files
8+
cache/
9+
artifacts/
10+
11+
# Typechain artifacts
12+
typechain-types/
13+

.prettierignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# dependency
2+
node_modules/
3+
4+
# Hardhat files
5+
cache/
6+
artifacts/
7+
8+
# Typechain artifacts
9+
typechain-types/
10+

.prettierrc

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"printWidth": 100,
3+
"tabWidth": 4,
4+
"semi": false,
5+
"singleQuote": false,
6+
"trailingComma": "all",
7+
"bracketSpacing": true,
8+
"overrides": [
9+
{
10+
"files": ["*.json", "*.yaml", "*.yml"],
11+
"options": {
12+
"tabWidth": 2
13+
}
14+
},
15+
{
16+
"files": ["*.sol"],
17+
"options": {
18+
"printWidth": 160,
19+
"semi": true
20+
}
21+
}
22+
]
23+
}

.yarnrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ignore-scripts true

README.md

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,49 @@
1-
# tokenlon-contract
1+
# Tokenlon
2+
3+
Tokenlon is a decentralized exchange and payment settlement protocol based on blockchain technology. Visit [tokenlon.im](https://tokenlon.im/)
4+
5+
## Architecture
6+
7+
![image info](./tokenlon_architecture.png)
8+
9+
## Deployed contracts (Mainnet)
10+
11+
| Contracts | Address | Module |
12+
| -------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ---------------- |
13+
| LON | [0x0000000000095413afC295d19EDeb1Ad7B71c952](https://etherscan.io/address/0x0000000000095413afC295d19EDeb1Ad7B71c952) | Token |
14+
| Tokenlon | [0x03f34bE1BF910116595dB1b11E9d1B2cA5D59659](https://etherscan.io/address/0x03f34bE1BF910116595dB1b11E9d1B2cA5D59659) | Tokenlon |
15+
| UserProxy | [0xe25ff902295Bc085bd548955B0595B518d4c46D2](https://etherscan.io/address/0xe25ff902295Bc085bd548955B0595B518d4c46D2) | Tokenlon |
16+
| PermanentStorage | [0x1A286652288691D086006B81655e4EfA895Df84D](https://etherscan.io/address/0x1A286652288691D086006B81655e4EfA895Df84D) | Tokenlon |
17+
| PermanentStorage (Upgrade Proxy) | [0x6D9Cc14a1d36E6fF13fc6efA9e9326FcD12E7903](https://etherscan.io/address/0x6D9Cc14a1d36E6fF13fc6efA9e9326FcD12E7903) | Tokenlon |
18+
| Spender | [0x3c68dfc45dc92C9c605d92B49858073e10b857A6](https://etherscan.io/address/0x3c68dfc45dc92C9c605d92B49858073e10b857A6) | Tokenlon |
19+
| AllowanceTarget | [0x8A42d311D282Bfcaa5133b2DE0a8bCDBECea3073](https://etherscan.io/address/0x8A42d311D282Bfcaa5133b2DE0a8bCDBECea3073) | Tokenlon |
20+
| PMM | [0x8D90113A1e286a5aB3e496fbD1853F265e5913c6](https://etherscan.io/address/0x8D90113A1e286a5aB3e496fbD1853F265e5913c6) | Tokenlon |
21+
| AMMQuoter | [0x7839254CfF8aaFBdC2da66fe709eB8f17cE09fe5](https://etherscan.io/address/0x7839254CfF8aaFBdC2da66fe709eB8f17cE09fe5) | Tokenlon |
22+
| AMMWrapperWithPath | [0x4a14347083B80E5216cA31350a2D21702aC3650d](https://etherscan.io/address/0x4a14347083B80E5216cA31350a2D21702aC3650d) | Tokenlon |
23+
| RFQ | [0xfD6C2d2499b1331101726A8AC68CCc9Da3fAB54F](https://etherscan.io/address/0xfD6C2d2499b1331101726A8AC68CCc9Da3fAB54F) | Tokenlon |
24+
| xLON | [0xf88506b0f1d30056b9e5580668d5875b9cd30f23](https://etherscan.io/address/0xf88506b0f1d30056b9e5580668d5875b9cd30f23) | Staking |
25+
| LONStaking (Logic contract) | [0x413ecce5d56204962090eef1dead4c0a247e289b](https://etherscan.io/address/0x413ecce5d56204962090eef1dead4c0a247e289b) | Staking |
26+
| MiningTreasury | [0x292a6921Efc261070a0d5C96911c102cBF1045E4](https://etherscan.io/address/0x292a6921Efc261070a0d5C96911c102cBF1045E4) | Mining Reward |
27+
| TreasuryVesterFactory | [0x000000003A8DBF47cD362EDA39B3a5F3FC6E99ce](https://etherscan.io/address/0x000000003A8DBF47cD362EDA39B3a5F3FC6E99ce) | Vesting |
28+
| MerkleRedeem | [0x0000000006a0403952389B70d8EE4E45479023db](https://etherscan.io/address/0x0000000006a0403952389B70d8EE4E45479023db) | Reward |
29+
| RewardDistributor | [0xbF1C2c17CC77e7Dec3466B96F46f93c09f02aB07](https://etherscan.io/address/0xbF1C2c17CC77e7Dec3466B96F46f93c09f02aB07) | Buyback |
30+
| StakingRewards (LON/ETH) | [0xb6bC1a713e4B11fa31480d31C825dCFd7e8FaBFD](https://etherscan.io/address/0xb6bC1a713e4B11fa31480d31C825dCFd7e8FaBFD) | Liquidity mining |
31+
| StakingRewards (LON/USDT) | [0x9648B119f442a3a096C0d5A1F8A0215B46dbb547](https://etherscan.io/address/0x9648B119f442a3a096C0d5A1F8A0215B46dbb547) | Liquidity mining |
32+
33+
## Prerequisite
34+
35+
- node (>=14.0.0 <16)
36+
- yarn (^1.22.10)
37+
38+
## Installation
39+
40+
```bash
41+
$ yarn install --frozen-lockfile
42+
```
43+
44+
## Compile contracts
45+
46+
```bash
47+
$ npx hardhat compile --force
48+
```
49+
431 KB
Binary file not shown.
465 KB
Binary file not shown.

audit/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Tokenlon Security
2+
3+
To keep our product safe and reliable we have "Tokenlon Security-vulnerabilities and Threat-intelligence Bounty Program" in conjunction with the SlowMist Team.
4+
5+
More information can be found on the [website](https://tokenlon.gitbook.io/docs/contribute-gong-xian/bounty-programme).

contracts/AMMQuoter.sol

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
pragma solidity ^0.6.0;
2+
3+
import "@openzeppelin/contracts/math/SafeMath.sol";
4+
import "./interfaces/IUniswapExchange.sol";
5+
import "./interfaces/IUniswapFactory.sol";
6+
import "./interfaces/IUniswapRouterV2.sol";
7+
import "./interfaces/ICurveFi.sol";
8+
import "./interfaces/IWeth.sol";
9+
import "./interfaces/IPermanentStorage.sol";
10+
11+
contract AMMQuoter {
12+
using SafeMath for uint256;
13+
/* Constants */
14+
string public constant version = "5.1.0";
15+
address private constant ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
16+
address private constant ZERO_ADDRESS = address(0);
17+
address public constant UNISWAP_V2_ROUTER_02_ADDRESS = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
18+
address public constant SUSHISWAP_ROUTER_ADDRESS = 0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F;
19+
address public immutable weth;
20+
IPermanentStorage public immutable permStorage;
21+
22+
event CurveTokenAdded(address indexed makerAddress, address indexed assetAddress, int128 index);
23+
24+
constructor(IPermanentStorage _permStorage, address _weth) public {
25+
permStorage = _permStorage;
26+
weth = _weth;
27+
}
28+
29+
function isETH(address assetAddress) public pure returns (bool) {
30+
return (assetAddress == ZERO_ADDRESS || assetAddress == ETH_ADDRESS);
31+
}
32+
33+
function getMakerOutAmount(
34+
address _makerAddr,
35+
address _takerAssetAddr,
36+
address _makerAssetAddr,
37+
uint256 _takerAssetAmount
38+
) public view returns (uint256) {
39+
uint256 makerAssetAmount;
40+
if (_makerAddr == UNISWAP_V2_ROUTER_02_ADDRESS || _makerAddr == SUSHISWAP_ROUTER_ADDRESS) {
41+
IUniswapRouterV2 router = IUniswapRouterV2(_makerAddr);
42+
address[] memory path = new address[](2);
43+
if (isETH(_takerAssetAddr)) {
44+
path[0] = weth;
45+
path[1] = _makerAssetAddr;
46+
} else if (isETH(_makerAssetAddr)) {
47+
path[0] = _takerAssetAddr;
48+
path[1] = weth;
49+
} else {
50+
path[0] = _takerAssetAddr;
51+
path[1] = _makerAssetAddr;
52+
}
53+
uint256[] memory amounts = router.getAmountsOut(_takerAssetAmount, path);
54+
makerAssetAmount = amounts[1];
55+
} else {
56+
address curveTakerIntenalAsset = isETH(_takerAssetAddr) ? ETH_ADDRESS : _takerAssetAddr;
57+
address curveMakerIntenalAsset = isETH(_makerAssetAddr) ? ETH_ADDRESS : _makerAssetAddr;
58+
(int128 fromTokenCurveIndex, int128 toTokenCurveIndex, uint16 swapMethod, ) = permStorage.getCurvePoolInfo(
59+
_makerAddr,
60+
curveTakerIntenalAsset,
61+
curveMakerIntenalAsset
62+
);
63+
if (fromTokenCurveIndex > 0 && toTokenCurveIndex > 0) {
64+
require(swapMethod != 0, "AMMQuoter: swap method not registered");
65+
// Substract index by 1 because indices stored in `permStorage` starts from 1
66+
fromTokenCurveIndex = fromTokenCurveIndex - 1;
67+
toTokenCurveIndex = toTokenCurveIndex - 1;
68+
ICurveFi curve = ICurveFi(_makerAddr);
69+
if (swapMethod == 1) {
70+
makerAssetAmount = curve.get_dy(fromTokenCurveIndex, toTokenCurveIndex, _takerAssetAmount).sub(1);
71+
} else if (swapMethod == 2) {
72+
makerAssetAmount = curve.get_dy_underlying(fromTokenCurveIndex, toTokenCurveIndex, _takerAssetAmount).sub(1);
73+
}
74+
} else {
75+
revert("AMMQuoter: Unsupported makerAddr");
76+
}
77+
}
78+
return makerAssetAmount;
79+
}
80+
81+
function getBestOutAmount(
82+
address[] calldata _makerAddresses,
83+
address _takerAssetAddr,
84+
address _makerAssetAddr,
85+
uint256 _takerAssetAmount
86+
) external view returns (address bestMaker, uint256 bestAmount) {
87+
bestAmount = 0;
88+
uint256 poolLength = _makerAddresses.length;
89+
for (uint256 i = 0; i < poolLength; i++) {
90+
address makerAddress = _makerAddresses[i];
91+
uint256 makerAssetAmount = getMakerOutAmount(makerAddress, _takerAssetAddr, _makerAssetAddr, _takerAssetAmount);
92+
if (makerAssetAmount > bestAmount) {
93+
bestAmount = makerAssetAmount;
94+
bestMaker = makerAddress;
95+
}
96+
}
97+
return (bestMaker, bestAmount);
98+
}
99+
100+
function getTakerInAmount(
101+
address _makerAddr,
102+
address _takerAssetAddr,
103+
address _makerAssetAddr,
104+
uint256 _makerAssetAmount
105+
) public view returns (uint256) {
106+
uint256 takerAssetAmount;
107+
if (_makerAddr == UNISWAP_V2_ROUTER_02_ADDRESS || _makerAddr == SUSHISWAP_ROUTER_ADDRESS) {
108+
IUniswapRouterV2 router = IUniswapRouterV2(_makerAddr);
109+
address[] memory path = new address[](2);
110+
if (isETH(_takerAssetAddr)) {
111+
path[0] = weth;
112+
path[1] = _makerAssetAddr;
113+
} else if (isETH(_makerAssetAddr)) {
114+
path[0] = _takerAssetAddr;
115+
path[1] = weth;
116+
} else {
117+
path[0] = _takerAssetAddr;
118+
path[1] = _makerAssetAddr;
119+
}
120+
uint256[] memory amounts = router.getAmountsIn(_makerAssetAmount, path);
121+
takerAssetAmount = amounts[0];
122+
} else {
123+
address curveTakerIntenalAsset = isETH(_takerAssetAddr) ? ETH_ADDRESS : _takerAssetAddr;
124+
address curveMakerIntenalAsset = isETH(_makerAssetAddr) ? ETH_ADDRESS : _makerAssetAddr;
125+
(int128 fromTokenCurveIndex, int128 toTokenCurveIndex, uint16 swapMethod, bool supportGetDx) = permStorage.getCurvePoolInfo(
126+
_makerAddr,
127+
curveTakerIntenalAsset,
128+
curveMakerIntenalAsset
129+
);
130+
if (fromTokenCurveIndex > 0 && toTokenCurveIndex > 0) {
131+
require(swapMethod != 0, "AMMQuoter: swap method not registered");
132+
// Substract index by 1 because indices stored in `permStorage` starts from 1
133+
fromTokenCurveIndex = fromTokenCurveIndex - 1;
134+
toTokenCurveIndex = toTokenCurveIndex - 1;
135+
ICurveFi curve = ICurveFi(_makerAddr);
136+
if (supportGetDx) {
137+
if (swapMethod == 1) {
138+
takerAssetAmount = curve.get_dx(fromTokenCurveIndex, toTokenCurveIndex, _makerAssetAmount);
139+
} else if (swapMethod == 2) {
140+
takerAssetAmount = curve.get_dx_underlying(fromTokenCurveIndex, toTokenCurveIndex, _makerAssetAmount);
141+
}
142+
} else {
143+
if (swapMethod == 1) {
144+
// does not support get_dx_underlying, try to get an estimated rate here
145+
takerAssetAmount = curve.get_dy(toTokenCurveIndex, fromTokenCurveIndex, _makerAssetAmount);
146+
} else if (swapMethod == 2) {
147+
takerAssetAmount = curve.get_dy_underlying(toTokenCurveIndex, fromTokenCurveIndex, _makerAssetAmount);
148+
}
149+
}
150+
} else {
151+
revert("AMMQuoter: Unsupported makerAddr");
152+
}
153+
}
154+
return takerAssetAmount;
155+
}
156+
157+
function getBestInAmount(
158+
address[] calldata _makerAddresses,
159+
address _takerAssetAddr,
160+
address _makerAssetAddr,
161+
uint256 _makerAssetAmount
162+
) external view returns (address bestMaker, uint256 bestAmount) {
163+
bestAmount = 2**256 - 1;
164+
uint256 poolLength = _makerAddresses.length;
165+
for (uint256 i = 0; i < poolLength; i++) {
166+
address makerAddress = _makerAddresses[i];
167+
uint256 takerAssetAmount = getTakerInAmount(makerAddress, _takerAssetAddr, _makerAssetAddr, _makerAssetAmount);
168+
if (takerAssetAmount < bestAmount) {
169+
bestAmount = takerAssetAmount;
170+
bestMaker = makerAddress;
171+
}
172+
}
173+
return (bestMaker, bestAmount);
174+
}
175+
}

0 commit comments

Comments
 (0)