├── .circleci
└── config.yml
├── .eslintrc.json
├── .github
└── workflows
│ └── abigen.yml
├── .gitignore
├── LICENSE
├── README.md
├── Security-Audit-Report-31052023.md
├── abi
├── BurnableToken.js
├── BurnableToken.json
├── IAugustusSwapper.js
├── IAugustusSwapper.json
├── IBarn.js
├── IBarn.json
├── IBurnableToken.js
├── IBurnableToken.json
├── IERC20.js
├── IERC20.json
├── IParams.js
├── IParams.json
├── IParaswap.js
├── IParaswap.json
├── ISwapContract.js
├── ISwapContract.json
├── ISwapRewards.js
├── ISwapRewards.json
├── ITokenTransferProxy.js
├── ITokenTransferProxy.json
├── IWETH.js
├── IWETH.json
├── LPToken.js
├── LPToken.json
├── Ownable.js
├── Ownable.json
├── Params.js
├── Params.json
├── SwapContract.js
├── SwapContract.json
├── SwapRewards.js
├── SwapRewards.json
├── SwingbyToken.js
├── SwingbyToken.json
├── sbBTCPool.js
└── sbBTCPool.json
├── abigo
├── BurnableToken.go
├── IAugustusSwapper.go
├── IBarn.go
├── IBurnableToken.go
├── IERC20.go
├── IParams.go
├── IParaswap.go
├── ISwapContract.go
├── ISwapRewards.go
├── ITokenTransferProxy.go
├── IWETH.go
├── LPToken.go
├── Ownable.go
├── Params.go
├── SwapContract.go
├── SwapRewards.go
├── SwingbyToken.go
└── sbBTCPool.go
├── args.js
├── contracts
├── BurnableToken.sol
├── LPToken.sol
├── Params.sol
├── SwapContract.sol
├── SwapRewards.sol
├── SwingbyToken.sol
├── interfaces
│ ├── IAugustusSwapper.sol
│ ├── IBarn.sol
│ ├── IBurnableToken.sol
│ ├── IERC20.sol
│ ├── IParams.sol
│ ├── IParaswap.sol
│ ├── ISwapContract.sol
│ ├── ISwapRewards.sol
│ ├── ITokenTransferProxy.sol
│ ├── IWETH.sol
│ └── lib
│ │ ├── Address.sol
│ │ ├── SafeERC20.sol
│ │ └── Utils.sol
└── sbBTCPool.sol
├── docs
├── Diagrams
│ ├── SkyPools Diagram.png
│ ├── SkypoolsDiagram.drawio
│ ├── SkypoolsVisual.drawio
│ ├── SkypoolsVisual_Flow 1.drawio.png
│ ├── SkypoolsVisual_Flow 1.drawio.xml
│ ├── SkypoolsVisual_Flow 2.drawio.png
│ ├── SkypoolsVisual_Flow 2.drawio.xml
│ ├── SwapContractDetailed.png
│ ├── UML_Diagram.dot
│ ├── UML_Image.png
│ └── UML_SVG.svg
├── Skybridge Security Audit Report - Red4Sec.pdf
├── Skybridge Security Audit Report.pdf
├── lp-token-rate-logic.md
├── readme.md
├── support_bsc.md
└── swap_contract_spec.md
├── hardhat.config.js
├── package-lock.json
├── package.json
├── scripts
├── addFloat.js
├── addFloatNew.js
├── addNode.js
├── burnToken.js
├── deploy-goerli.js
├── deploy-mainnet.js
├── deploy-ropsten.js
├── deploy-sbBTCPool.ts
├── deployParams.js
├── deploySwapRewards.js
├── deploySwingbyToken.js
├── erc20ABI.js
├── generateGoBindings.js
├── mintToken.js
├── moveLPTOwner.js
├── moveSCOwner.js
├── paraswap.js
├── removeFloat.js
├── sbBTCchecks.js
├── showNodes.js
├── swapBTC2WBTC.js
├── swapWBTC2BTC.js
├── testnet.js
└── transferOwner.js
├── test
├── old
│ ├── testSkyPools.js
│ └── testSkyPoolsV2.js
├── testAddNode.js
├── testLPToken.js
├── testSkyPoolsV2.js
├── testSwapContract.js
└── testSwapContractFactory.js
├── truffle-config.js
└── web3_test
├── testAddNode.js
├── testLPToken.js
├── testSwapContract.js
└── testSwapContractFactory.js
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | jobs:
3 | build:
4 | docker:
5 | - image: circleci/python:3.8-node
6 | steps:
7 | - checkout
8 | - run:
9 | name: npm install
10 | command: |
11 | node --version
12 | npm install
13 | - persist_to_workspace:
14 | root: .
15 | paths:
16 | - .
17 |
18 | test:
19 | docker:
20 | - image: circleci/python:3.8-node
21 | steps:
22 | - attach_workspace:
23 | at: .
24 | - run:
25 | name: test
26 | command: |
27 | npm run test
28 | - persist_to_workspace:
29 | root: .
30 | paths:
31 | - .
32 |
33 | audit:
34 | docker:
35 | - image: circleci/python:3.8-node
36 | steps:
37 | - attach_workspace:
38 | at: .
39 | - run:
40 | name: Setup virtual environment
41 | command: python -m virtualenv venv
42 | - run:
43 | name: Install MythX CLI
44 | command: |
45 | . venv/bin/activate
46 | pip install mythx-cli
47 | - run:
48 | name: Analyze with MythX
49 | command: |
50 | . venv/bin/activate
51 | mythx --yes analyze --mode standard --async --solc-version 0.8.19 --remap-import @openzeppelin/=$(pwd)/node_modules/@openzeppelin/ contracts/
52 |
53 | workflows:
54 | version: 2
55 | build_test_audit:
56 | jobs:
57 | - build
58 | - test:
59 | requires:
60 | - build
61 | - audit:
62 | requires:
63 | - test
64 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "es2021": true
5 | },
6 | "parserOptions": {
7 | "ecmaVersion": 12,
8 | "sourceType": "module"
9 | },
10 | "rules": {
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/.github/workflows/abigen.yml:
--------------------------------------------------------------------------------
1 | name: Go
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | pull_request:
7 | branches: [ main ]
8 |
9 | jobs:
10 |
11 | build:
12 | name: Build
13 | runs-on: ubuntu-latest
14 | steps:
15 | - uses: actions/checkout@v2
16 | - uses: bahmutov/npm-install@v1
17 |
18 | - name: Use Go 1.x
19 | uses: actions/setup-go@v2
20 | with:
21 | go-version: ^1.13
22 |
23 | - name: Use Node.js ${{ matrix.node-version }}
24 | uses: actions/setup-node@v1
25 | with:
26 | node-version: ${{ matrix.node-version }}
27 |
28 | - name: Download go-ethereum
29 | run: git clone https://github.com/ethereum/go-ethereum /tmp/go-ethereum && cd /tmp/go-ethereum && go install ./cmd/abigen
30 |
31 | - name: Run truffle compile
32 | run: npm install && npm run compile
33 |
34 | - name: Run abigen
35 | run: npm run gen-go
36 |
37 | - name: Commit files
38 | env:
39 | GITHUB_TOKEN: ${{ secrets.github_token }}
40 | run: |
41 | git config --local user.email "action@github.com"
42 | git config --local user.name "GitHub Action"
43 | git remote set-url origin https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git
44 | git checkout main
45 | git add .
46 | git commit -m "Auto build" -a || echo "No files to commit"
47 | git push origin HEAD
48 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | cache
3 | artifacts
4 | build/*
5 | abigenBindings/bin
6 | .DS_Store
7 | .env
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Skybridge-contract-v3
2 |
3 | ## Environment
4 | - hardhat (v2.14.0)
5 | - solidity (v0.8.19)
6 |
7 | ## Deployment Order
8 | 1. Deploy sbBTCPool nodeRewards contracts
9 | 2. Deploy LP token and swap contract (initial liquidiy setup if need)
10 | 3. Initialize sbBTCPool and nodeRewards
11 | 4. Mint LPT to users (if need)
12 | 5. Set old LPT token for convert -- they can convert to new token with burning old token.
13 | 6. Transferring owner of new LPT to swap contract
14 |
15 | ## Build contract
16 | ```
17 | $ npx hardhat compile
18 | ```
19 |
20 | ## Test
21 | ```
22 | $ npx hardhat test ./test/testSwapContract.js
23 | ```
24 |
25 | ## Mainnet contracts
26 | ```
27 | TBA
28 | ```
29 |
30 | ## Testnet contracts (goerli)
31 | ```
32 | SwapContract
33 | https://goerli.etherscan.io/address/0x9e6ba6e811665849f03f56c1f22a8894aebb3993
34 | LPToken
35 | https://goerli.etherscan.io/address/0xb10c6c5a6baf604206867cb229baddab02eea602
36 | SwapRewards
37 | https://goerli.etherscan.io/address/0xf4c381d077272295641f8a53d850d9a8125e0e94
38 | BTCT
39 | https://goerli.etherscan.io/address/0xeb47a21c1fc00d1e863019906df1771b80dbe182
40 | sbBTCPool
41 | https://goerli.etherscan.io/address/0xd60126017fdf906668cfe5327c566c65e7f061ba
42 | Barn
43 | https://goerli.etherscan.io/address/0x009cc14ce70b2e667984c2276490d56ae3234c43
44 | ```
45 |
--------------------------------------------------------------------------------
/abi/IBarn.js:
--------------------------------------------------------------------------------
1 | export default [
2 | {
3 | "inputs": [
4 | {
5 | "internalType": "address",
6 | "name": "user",
7 | "type": "address"
8 | },
9 | {
10 | "internalType": "uint256",
11 | "name": "timestamp",
12 | "type": "uint256"
13 | }
14 | ],
15 | "name": "balanceAtTs",
16 | "outputs": [
17 | {
18 | "internalType": "uint256",
19 | "name": "",
20 | "type": "uint256"
21 | }
22 | ],
23 | "stateMutability": "view",
24 | "type": "function"
25 | },
26 | {
27 | "inputs": [
28 | {
29 | "internalType": "address",
30 | "name": "user",
31 | "type": "address"
32 | }
33 | ],
34 | "name": "balanceOf",
35 | "outputs": [
36 | {
37 | "internalType": "uint256",
38 | "name": "",
39 | "type": "uint256"
40 | }
41 | ],
42 | "stateMutability": "view",
43 | "type": "function"
44 | }
45 | ];
46 |
--------------------------------------------------------------------------------
/abi/IBarn.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "inputs": [
4 | {
5 | "internalType": "address",
6 | "name": "user",
7 | "type": "address"
8 | },
9 | {
10 | "internalType": "uint256",
11 | "name": "timestamp",
12 | "type": "uint256"
13 | }
14 | ],
15 | "name": "balanceAtTs",
16 | "outputs": [
17 | {
18 | "internalType": "uint256",
19 | "name": "",
20 | "type": "uint256"
21 | }
22 | ],
23 | "stateMutability": "view",
24 | "type": "function"
25 | },
26 | {
27 | "inputs": [
28 | {
29 | "internalType": "address",
30 | "name": "user",
31 | "type": "address"
32 | }
33 | ],
34 | "name": "balanceOf",
35 | "outputs": [
36 | {
37 | "internalType": "uint256",
38 | "name": "",
39 | "type": "uint256"
40 | }
41 | ],
42 | "stateMutability": "view",
43 | "type": "function"
44 | }
45 | ]
46 |
--------------------------------------------------------------------------------
/abi/IBurnableToken.js:
--------------------------------------------------------------------------------
1 | export default [
2 | {
3 | "anonymous": false,
4 | "inputs": [
5 | {
6 | "indexed": true,
7 | "internalType": "address",
8 | "name": "owner",
9 | "type": "address"
10 | },
11 | {
12 | "indexed": true,
13 | "internalType": "address",
14 | "name": "spender",
15 | "type": "address"
16 | },
17 | {
18 | "indexed": false,
19 | "internalType": "uint256",
20 | "name": "value",
21 | "type": "uint256"
22 | }
23 | ],
24 | "name": "Approval",
25 | "type": "event"
26 | },
27 | {
28 | "anonymous": false,
29 | "inputs": [
30 | {
31 | "indexed": true,
32 | "internalType": "address",
33 | "name": "from",
34 | "type": "address"
35 | },
36 | {
37 | "indexed": true,
38 | "internalType": "address",
39 | "name": "to",
40 | "type": "address"
41 | },
42 | {
43 | "indexed": false,
44 | "internalType": "uint256",
45 | "name": "value",
46 | "type": "uint256"
47 | }
48 | ],
49 | "name": "Transfer",
50 | "type": "event"
51 | },
52 | {
53 | "inputs": [
54 | {
55 | "internalType": "address",
56 | "name": "_owner",
57 | "type": "address"
58 | },
59 | {
60 | "internalType": "address",
61 | "name": "spender",
62 | "type": "address"
63 | }
64 | ],
65 | "name": "allowance",
66 | "outputs": [
67 | {
68 | "internalType": "uint256",
69 | "name": "",
70 | "type": "uint256"
71 | }
72 | ],
73 | "stateMutability": "view",
74 | "type": "function"
75 | },
76 | {
77 | "inputs": [
78 | {
79 | "internalType": "address",
80 | "name": "spender",
81 | "type": "address"
82 | },
83 | {
84 | "internalType": "uint256",
85 | "name": "amount",
86 | "type": "uint256"
87 | }
88 | ],
89 | "name": "approve",
90 | "outputs": [
91 | {
92 | "internalType": "bool",
93 | "name": "",
94 | "type": "bool"
95 | }
96 | ],
97 | "stateMutability": "nonpayable",
98 | "type": "function"
99 | },
100 | {
101 | "inputs": [
102 | {
103 | "internalType": "address",
104 | "name": "account",
105 | "type": "address"
106 | }
107 | ],
108 | "name": "balanceOf",
109 | "outputs": [
110 | {
111 | "internalType": "uint256",
112 | "name": "",
113 | "type": "uint256"
114 | }
115 | ],
116 | "stateMutability": "view",
117 | "type": "function"
118 | },
119 | {
120 | "inputs": [
121 | {
122 | "internalType": "uint256",
123 | "name": "amount",
124 | "type": "uint256"
125 | }
126 | ],
127 | "name": "burn",
128 | "outputs": [
129 | {
130 | "internalType": "bool",
131 | "name": "",
132 | "type": "bool"
133 | }
134 | ],
135 | "stateMutability": "nonpayable",
136 | "type": "function"
137 | },
138 | {
139 | "inputs": [],
140 | "name": "decimals",
141 | "outputs": [
142 | {
143 | "internalType": "uint8",
144 | "name": "",
145 | "type": "uint8"
146 | }
147 | ],
148 | "stateMutability": "view",
149 | "type": "function"
150 | },
151 | {
152 | "inputs": [],
153 | "name": "getOwner",
154 | "outputs": [
155 | {
156 | "internalType": "address",
157 | "name": "",
158 | "type": "address"
159 | }
160 | ],
161 | "stateMutability": "view",
162 | "type": "function"
163 | },
164 | {
165 | "inputs": [
166 | {
167 | "internalType": "address",
168 | "name": "target",
169 | "type": "address"
170 | },
171 | {
172 | "internalType": "uint256",
173 | "name": "amount",
174 | "type": "uint256"
175 | }
176 | ],
177 | "name": "mint",
178 | "outputs": [
179 | {
180 | "internalType": "bool",
181 | "name": "",
182 | "type": "bool"
183 | }
184 | ],
185 | "stateMutability": "nonpayable",
186 | "type": "function"
187 | },
188 | {
189 | "inputs": [],
190 | "name": "mintable",
191 | "outputs": [
192 | {
193 | "internalType": "bool",
194 | "name": "",
195 | "type": "bool"
196 | }
197 | ],
198 | "stateMutability": "nonpayable",
199 | "type": "function"
200 | },
201 | {
202 | "inputs": [],
203 | "name": "name",
204 | "outputs": [
205 | {
206 | "internalType": "string",
207 | "name": "",
208 | "type": "string"
209 | }
210 | ],
211 | "stateMutability": "view",
212 | "type": "function"
213 | },
214 | {
215 | "inputs": [],
216 | "name": "symbol",
217 | "outputs": [
218 | {
219 | "internalType": "string",
220 | "name": "",
221 | "type": "string"
222 | }
223 | ],
224 | "stateMutability": "view",
225 | "type": "function"
226 | },
227 | {
228 | "inputs": [],
229 | "name": "totalSupply",
230 | "outputs": [
231 | {
232 | "internalType": "uint256",
233 | "name": "",
234 | "type": "uint256"
235 | }
236 | ],
237 | "stateMutability": "view",
238 | "type": "function"
239 | },
240 | {
241 | "inputs": [
242 | {
243 | "internalType": "address",
244 | "name": "recipient",
245 | "type": "address"
246 | },
247 | {
248 | "internalType": "uint256",
249 | "name": "amount",
250 | "type": "uint256"
251 | }
252 | ],
253 | "name": "transfer",
254 | "outputs": [
255 | {
256 | "internalType": "bool",
257 | "name": "",
258 | "type": "bool"
259 | }
260 | ],
261 | "stateMutability": "nonpayable",
262 | "type": "function"
263 | },
264 | {
265 | "inputs": [
266 | {
267 | "internalType": "address",
268 | "name": "sender",
269 | "type": "address"
270 | },
271 | {
272 | "internalType": "address",
273 | "name": "recipient",
274 | "type": "address"
275 | },
276 | {
277 | "internalType": "uint256",
278 | "name": "amount",
279 | "type": "uint256"
280 | }
281 | ],
282 | "name": "transferFrom",
283 | "outputs": [
284 | {
285 | "internalType": "bool",
286 | "name": "",
287 | "type": "bool"
288 | }
289 | ],
290 | "stateMutability": "nonpayable",
291 | "type": "function"
292 | }
293 | ];
294 |
--------------------------------------------------------------------------------
/abi/IBurnableToken.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "anonymous": false,
4 | "inputs": [
5 | {
6 | "indexed": true,
7 | "internalType": "address",
8 | "name": "owner",
9 | "type": "address"
10 | },
11 | {
12 | "indexed": true,
13 | "internalType": "address",
14 | "name": "spender",
15 | "type": "address"
16 | },
17 | {
18 | "indexed": false,
19 | "internalType": "uint256",
20 | "name": "value",
21 | "type": "uint256"
22 | }
23 | ],
24 | "name": "Approval",
25 | "type": "event"
26 | },
27 | {
28 | "anonymous": false,
29 | "inputs": [
30 | {
31 | "indexed": true,
32 | "internalType": "address",
33 | "name": "from",
34 | "type": "address"
35 | },
36 | {
37 | "indexed": true,
38 | "internalType": "address",
39 | "name": "to",
40 | "type": "address"
41 | },
42 | {
43 | "indexed": false,
44 | "internalType": "uint256",
45 | "name": "value",
46 | "type": "uint256"
47 | }
48 | ],
49 | "name": "Transfer",
50 | "type": "event"
51 | },
52 | {
53 | "inputs": [
54 | {
55 | "internalType": "address",
56 | "name": "_owner",
57 | "type": "address"
58 | },
59 | {
60 | "internalType": "address",
61 | "name": "spender",
62 | "type": "address"
63 | }
64 | ],
65 | "name": "allowance",
66 | "outputs": [
67 | {
68 | "internalType": "uint256",
69 | "name": "",
70 | "type": "uint256"
71 | }
72 | ],
73 | "stateMutability": "view",
74 | "type": "function"
75 | },
76 | {
77 | "inputs": [
78 | {
79 | "internalType": "address",
80 | "name": "spender",
81 | "type": "address"
82 | },
83 | {
84 | "internalType": "uint256",
85 | "name": "amount",
86 | "type": "uint256"
87 | }
88 | ],
89 | "name": "approve",
90 | "outputs": [
91 | {
92 | "internalType": "bool",
93 | "name": "",
94 | "type": "bool"
95 | }
96 | ],
97 | "stateMutability": "nonpayable",
98 | "type": "function"
99 | },
100 | {
101 | "inputs": [
102 | {
103 | "internalType": "address",
104 | "name": "account",
105 | "type": "address"
106 | }
107 | ],
108 | "name": "balanceOf",
109 | "outputs": [
110 | {
111 | "internalType": "uint256",
112 | "name": "",
113 | "type": "uint256"
114 | }
115 | ],
116 | "stateMutability": "view",
117 | "type": "function"
118 | },
119 | {
120 | "inputs": [
121 | {
122 | "internalType": "uint256",
123 | "name": "amount",
124 | "type": "uint256"
125 | }
126 | ],
127 | "name": "burn",
128 | "outputs": [
129 | {
130 | "internalType": "bool",
131 | "name": "",
132 | "type": "bool"
133 | }
134 | ],
135 | "stateMutability": "nonpayable",
136 | "type": "function"
137 | },
138 | {
139 | "inputs": [],
140 | "name": "decimals",
141 | "outputs": [
142 | {
143 | "internalType": "uint8",
144 | "name": "",
145 | "type": "uint8"
146 | }
147 | ],
148 | "stateMutability": "view",
149 | "type": "function"
150 | },
151 | {
152 | "inputs": [],
153 | "name": "getOwner",
154 | "outputs": [
155 | {
156 | "internalType": "address",
157 | "name": "",
158 | "type": "address"
159 | }
160 | ],
161 | "stateMutability": "view",
162 | "type": "function"
163 | },
164 | {
165 | "inputs": [
166 | {
167 | "internalType": "address",
168 | "name": "target",
169 | "type": "address"
170 | },
171 | {
172 | "internalType": "uint256",
173 | "name": "amount",
174 | "type": "uint256"
175 | }
176 | ],
177 | "name": "mint",
178 | "outputs": [
179 | {
180 | "internalType": "bool",
181 | "name": "",
182 | "type": "bool"
183 | }
184 | ],
185 | "stateMutability": "nonpayable",
186 | "type": "function"
187 | },
188 | {
189 | "inputs": [],
190 | "name": "mintable",
191 | "outputs": [
192 | {
193 | "internalType": "bool",
194 | "name": "",
195 | "type": "bool"
196 | }
197 | ],
198 | "stateMutability": "nonpayable",
199 | "type": "function"
200 | },
201 | {
202 | "inputs": [],
203 | "name": "name",
204 | "outputs": [
205 | {
206 | "internalType": "string",
207 | "name": "",
208 | "type": "string"
209 | }
210 | ],
211 | "stateMutability": "view",
212 | "type": "function"
213 | },
214 | {
215 | "inputs": [],
216 | "name": "symbol",
217 | "outputs": [
218 | {
219 | "internalType": "string",
220 | "name": "",
221 | "type": "string"
222 | }
223 | ],
224 | "stateMutability": "view",
225 | "type": "function"
226 | },
227 | {
228 | "inputs": [],
229 | "name": "totalSupply",
230 | "outputs": [
231 | {
232 | "internalType": "uint256",
233 | "name": "",
234 | "type": "uint256"
235 | }
236 | ],
237 | "stateMutability": "view",
238 | "type": "function"
239 | },
240 | {
241 | "inputs": [
242 | {
243 | "internalType": "address",
244 | "name": "recipient",
245 | "type": "address"
246 | },
247 | {
248 | "internalType": "uint256",
249 | "name": "amount",
250 | "type": "uint256"
251 | }
252 | ],
253 | "name": "transfer",
254 | "outputs": [
255 | {
256 | "internalType": "bool",
257 | "name": "",
258 | "type": "bool"
259 | }
260 | ],
261 | "stateMutability": "nonpayable",
262 | "type": "function"
263 | },
264 | {
265 | "inputs": [
266 | {
267 | "internalType": "address",
268 | "name": "sender",
269 | "type": "address"
270 | },
271 | {
272 | "internalType": "address",
273 | "name": "recipient",
274 | "type": "address"
275 | },
276 | {
277 | "internalType": "uint256",
278 | "name": "amount",
279 | "type": "uint256"
280 | }
281 | ],
282 | "name": "transferFrom",
283 | "outputs": [
284 | {
285 | "internalType": "bool",
286 | "name": "",
287 | "type": "bool"
288 | }
289 | ],
290 | "stateMutability": "nonpayable",
291 | "type": "function"
292 | }
293 | ]
294 |
--------------------------------------------------------------------------------
/abi/IERC20.js:
--------------------------------------------------------------------------------
1 | export default [
2 | {
3 | "anonymous": false,
4 | "inputs": [
5 | {
6 | "indexed": true,
7 | "internalType": "address",
8 | "name": "owner",
9 | "type": "address"
10 | },
11 | {
12 | "indexed": true,
13 | "internalType": "address",
14 | "name": "spender",
15 | "type": "address"
16 | },
17 | {
18 | "indexed": false,
19 | "internalType": "uint256",
20 | "name": "value",
21 | "type": "uint256"
22 | }
23 | ],
24 | "name": "Approval",
25 | "type": "event"
26 | },
27 | {
28 | "anonymous": false,
29 | "inputs": [
30 | {
31 | "indexed": true,
32 | "internalType": "address",
33 | "name": "from",
34 | "type": "address"
35 | },
36 | {
37 | "indexed": true,
38 | "internalType": "address",
39 | "name": "to",
40 | "type": "address"
41 | },
42 | {
43 | "indexed": false,
44 | "internalType": "uint256",
45 | "name": "value",
46 | "type": "uint256"
47 | }
48 | ],
49 | "name": "Transfer",
50 | "type": "event"
51 | },
52 | {
53 | "inputs": [
54 | {
55 | "internalType": "address",
56 | "name": "_owner",
57 | "type": "address"
58 | },
59 | {
60 | "internalType": "address",
61 | "name": "spender",
62 | "type": "address"
63 | }
64 | ],
65 | "name": "allowance",
66 | "outputs": [
67 | {
68 | "internalType": "uint256",
69 | "name": "",
70 | "type": "uint256"
71 | }
72 | ],
73 | "stateMutability": "view",
74 | "type": "function"
75 | },
76 | {
77 | "inputs": [
78 | {
79 | "internalType": "address",
80 | "name": "spender",
81 | "type": "address"
82 | },
83 | {
84 | "internalType": "uint256",
85 | "name": "amount",
86 | "type": "uint256"
87 | }
88 | ],
89 | "name": "approve",
90 | "outputs": [
91 | {
92 | "internalType": "bool",
93 | "name": "",
94 | "type": "bool"
95 | }
96 | ],
97 | "stateMutability": "nonpayable",
98 | "type": "function"
99 | },
100 | {
101 | "inputs": [
102 | {
103 | "internalType": "address",
104 | "name": "account",
105 | "type": "address"
106 | }
107 | ],
108 | "name": "balanceOf",
109 | "outputs": [
110 | {
111 | "internalType": "uint256",
112 | "name": "",
113 | "type": "uint256"
114 | }
115 | ],
116 | "stateMutability": "view",
117 | "type": "function"
118 | },
119 | {
120 | "inputs": [],
121 | "name": "decimals",
122 | "outputs": [
123 | {
124 | "internalType": "uint8",
125 | "name": "",
126 | "type": "uint8"
127 | }
128 | ],
129 | "stateMutability": "view",
130 | "type": "function"
131 | },
132 | {
133 | "inputs": [],
134 | "name": "getOwner",
135 | "outputs": [
136 | {
137 | "internalType": "address",
138 | "name": "",
139 | "type": "address"
140 | }
141 | ],
142 | "stateMutability": "view",
143 | "type": "function"
144 | },
145 | {
146 | "inputs": [],
147 | "name": "name",
148 | "outputs": [
149 | {
150 | "internalType": "string",
151 | "name": "",
152 | "type": "string"
153 | }
154 | ],
155 | "stateMutability": "view",
156 | "type": "function"
157 | },
158 | {
159 | "inputs": [],
160 | "name": "symbol",
161 | "outputs": [
162 | {
163 | "internalType": "string",
164 | "name": "",
165 | "type": "string"
166 | }
167 | ],
168 | "stateMutability": "view",
169 | "type": "function"
170 | },
171 | {
172 | "inputs": [],
173 | "name": "totalSupply",
174 | "outputs": [
175 | {
176 | "internalType": "uint256",
177 | "name": "",
178 | "type": "uint256"
179 | }
180 | ],
181 | "stateMutability": "view",
182 | "type": "function"
183 | },
184 | {
185 | "inputs": [
186 | {
187 | "internalType": "address",
188 | "name": "recipient",
189 | "type": "address"
190 | },
191 | {
192 | "internalType": "uint256",
193 | "name": "amount",
194 | "type": "uint256"
195 | }
196 | ],
197 | "name": "transfer",
198 | "outputs": [
199 | {
200 | "internalType": "bool",
201 | "name": "",
202 | "type": "bool"
203 | }
204 | ],
205 | "stateMutability": "nonpayable",
206 | "type": "function"
207 | },
208 | {
209 | "inputs": [
210 | {
211 | "internalType": "address",
212 | "name": "sender",
213 | "type": "address"
214 | },
215 | {
216 | "internalType": "address",
217 | "name": "recipient",
218 | "type": "address"
219 | },
220 | {
221 | "internalType": "uint256",
222 | "name": "amount",
223 | "type": "uint256"
224 | }
225 | ],
226 | "name": "transferFrom",
227 | "outputs": [
228 | {
229 | "internalType": "bool",
230 | "name": "",
231 | "type": "bool"
232 | }
233 | ],
234 | "stateMutability": "nonpayable",
235 | "type": "function"
236 | }
237 | ];
238 |
--------------------------------------------------------------------------------
/abi/IERC20.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "anonymous": false,
4 | "inputs": [
5 | {
6 | "indexed": true,
7 | "internalType": "address",
8 | "name": "owner",
9 | "type": "address"
10 | },
11 | {
12 | "indexed": true,
13 | "internalType": "address",
14 | "name": "spender",
15 | "type": "address"
16 | },
17 | {
18 | "indexed": false,
19 | "internalType": "uint256",
20 | "name": "value",
21 | "type": "uint256"
22 | }
23 | ],
24 | "name": "Approval",
25 | "type": "event"
26 | },
27 | {
28 | "anonymous": false,
29 | "inputs": [
30 | {
31 | "indexed": true,
32 | "internalType": "address",
33 | "name": "from",
34 | "type": "address"
35 | },
36 | {
37 | "indexed": true,
38 | "internalType": "address",
39 | "name": "to",
40 | "type": "address"
41 | },
42 | {
43 | "indexed": false,
44 | "internalType": "uint256",
45 | "name": "value",
46 | "type": "uint256"
47 | }
48 | ],
49 | "name": "Transfer",
50 | "type": "event"
51 | },
52 | {
53 | "inputs": [
54 | {
55 | "internalType": "address",
56 | "name": "_owner",
57 | "type": "address"
58 | },
59 | {
60 | "internalType": "address",
61 | "name": "spender",
62 | "type": "address"
63 | }
64 | ],
65 | "name": "allowance",
66 | "outputs": [
67 | {
68 | "internalType": "uint256",
69 | "name": "",
70 | "type": "uint256"
71 | }
72 | ],
73 | "stateMutability": "view",
74 | "type": "function"
75 | },
76 | {
77 | "inputs": [
78 | {
79 | "internalType": "address",
80 | "name": "spender",
81 | "type": "address"
82 | },
83 | {
84 | "internalType": "uint256",
85 | "name": "amount",
86 | "type": "uint256"
87 | }
88 | ],
89 | "name": "approve",
90 | "outputs": [
91 | {
92 | "internalType": "bool",
93 | "name": "",
94 | "type": "bool"
95 | }
96 | ],
97 | "stateMutability": "nonpayable",
98 | "type": "function"
99 | },
100 | {
101 | "inputs": [
102 | {
103 | "internalType": "address",
104 | "name": "account",
105 | "type": "address"
106 | }
107 | ],
108 | "name": "balanceOf",
109 | "outputs": [
110 | {
111 | "internalType": "uint256",
112 | "name": "",
113 | "type": "uint256"
114 | }
115 | ],
116 | "stateMutability": "view",
117 | "type": "function"
118 | },
119 | {
120 | "inputs": [],
121 | "name": "decimals",
122 | "outputs": [
123 | {
124 | "internalType": "uint8",
125 | "name": "",
126 | "type": "uint8"
127 | }
128 | ],
129 | "stateMutability": "view",
130 | "type": "function"
131 | },
132 | {
133 | "inputs": [],
134 | "name": "getOwner",
135 | "outputs": [
136 | {
137 | "internalType": "address",
138 | "name": "",
139 | "type": "address"
140 | }
141 | ],
142 | "stateMutability": "view",
143 | "type": "function"
144 | },
145 | {
146 | "inputs": [],
147 | "name": "name",
148 | "outputs": [
149 | {
150 | "internalType": "string",
151 | "name": "",
152 | "type": "string"
153 | }
154 | ],
155 | "stateMutability": "view",
156 | "type": "function"
157 | },
158 | {
159 | "inputs": [],
160 | "name": "symbol",
161 | "outputs": [
162 | {
163 | "internalType": "string",
164 | "name": "",
165 | "type": "string"
166 | }
167 | ],
168 | "stateMutability": "view",
169 | "type": "function"
170 | },
171 | {
172 | "inputs": [],
173 | "name": "totalSupply",
174 | "outputs": [
175 | {
176 | "internalType": "uint256",
177 | "name": "",
178 | "type": "uint256"
179 | }
180 | ],
181 | "stateMutability": "view",
182 | "type": "function"
183 | },
184 | {
185 | "inputs": [
186 | {
187 | "internalType": "address",
188 | "name": "recipient",
189 | "type": "address"
190 | },
191 | {
192 | "internalType": "uint256",
193 | "name": "amount",
194 | "type": "uint256"
195 | }
196 | ],
197 | "name": "transfer",
198 | "outputs": [
199 | {
200 | "internalType": "bool",
201 | "name": "",
202 | "type": "bool"
203 | }
204 | ],
205 | "stateMutability": "nonpayable",
206 | "type": "function"
207 | },
208 | {
209 | "inputs": [
210 | {
211 | "internalType": "address",
212 | "name": "sender",
213 | "type": "address"
214 | },
215 | {
216 | "internalType": "address",
217 | "name": "recipient",
218 | "type": "address"
219 | },
220 | {
221 | "internalType": "uint256",
222 | "name": "amount",
223 | "type": "uint256"
224 | }
225 | ],
226 | "name": "transferFrom",
227 | "outputs": [
228 | {
229 | "internalType": "bool",
230 | "name": "",
231 | "type": "bool"
232 | }
233 | ],
234 | "stateMutability": "nonpayable",
235 | "type": "function"
236 | }
237 | ]
238 |
--------------------------------------------------------------------------------
/abi/IParams.js:
--------------------------------------------------------------------------------
1 | export default [
2 | {
3 | "inputs": [],
4 | "name": "depositFeesBPS",
5 | "outputs": [
6 | {
7 | "internalType": "uint8",
8 | "name": "",
9 | "type": "uint8"
10 | }
11 | ],
12 | "stateMutability": "view",
13 | "type": "function"
14 | },
15 | {
16 | "inputs": [],
17 | "name": "expirationTime",
18 | "outputs": [
19 | {
20 | "internalType": "uint256",
21 | "name": "",
22 | "type": "uint256"
23 | }
24 | ],
25 | "stateMutability": "view",
26 | "type": "function"
27 | },
28 | {
29 | "inputs": [],
30 | "name": "loopCount",
31 | "outputs": [
32 | {
33 | "internalType": "uint8",
34 | "name": "",
35 | "type": "uint8"
36 | }
37 | ],
38 | "stateMutability": "view",
39 | "type": "function"
40 | },
41 | {
42 | "inputs": [],
43 | "name": "minimumSwapAmountForWBTC",
44 | "outputs": [
45 | {
46 | "internalType": "uint256",
47 | "name": "",
48 | "type": "uint256"
49 | }
50 | ],
51 | "stateMutability": "view",
52 | "type": "function"
53 | },
54 | {
55 | "inputs": [],
56 | "name": "nodeRewardsRatio",
57 | "outputs": [
58 | {
59 | "internalType": "uint8",
60 | "name": "",
61 | "type": "uint8"
62 | }
63 | ],
64 | "stateMutability": "view",
65 | "type": "function"
66 | },
67 | {
68 | "inputs": [],
69 | "name": "paraswapAddress",
70 | "outputs": [
71 | {
72 | "internalType": "address",
73 | "name": "",
74 | "type": "address"
75 | }
76 | ],
77 | "stateMutability": "view",
78 | "type": "function"
79 | },
80 | {
81 | "inputs": [
82 | {
83 | "internalType": "uint8",
84 | "name": "_depositFeesBPS",
85 | "type": "uint8"
86 | }
87 | ],
88 | "name": "setDepositFeesBPS",
89 | "outputs": [],
90 | "stateMutability": "nonpayable",
91 | "type": "function"
92 | },
93 | {
94 | "inputs": [
95 | {
96 | "internalType": "uint256",
97 | "name": "_expirationTime",
98 | "type": "uint256"
99 | }
100 | ],
101 | "name": "setExpirationTime",
102 | "outputs": [],
103 | "stateMutability": "nonpayable",
104 | "type": "function"
105 | },
106 | {
107 | "inputs": [
108 | {
109 | "internalType": "uint8",
110 | "name": "_loopCount",
111 | "type": "uint8"
112 | }
113 | ],
114 | "name": "setLoopCount",
115 | "outputs": [],
116 | "stateMutability": "nonpayable",
117 | "type": "function"
118 | },
119 | {
120 | "inputs": [
121 | {
122 | "internalType": "uint256",
123 | "name": "_minimumSwapAmountForWBTC",
124 | "type": "uint256"
125 | }
126 | ],
127 | "name": "setMinimumSwapAmountForWBTC",
128 | "outputs": [],
129 | "stateMutability": "nonpayable",
130 | "type": "function"
131 | },
132 | {
133 | "inputs": [
134 | {
135 | "internalType": "uint8",
136 | "name": "_nodeRewardsRatio",
137 | "type": "uint8"
138 | }
139 | ],
140 | "name": "setNodeRewardsRatio",
141 | "outputs": [],
142 | "stateMutability": "nonpayable",
143 | "type": "function"
144 | },
145 | {
146 | "inputs": [
147 | {
148 | "internalType": "address",
149 | "name": "_paraswapAddress",
150 | "type": "address"
151 | }
152 | ],
153 | "name": "setParaswapAddress",
154 | "outputs": [],
155 | "stateMutability": "nonpayable",
156 | "type": "function"
157 | },
158 | {
159 | "inputs": [
160 | {
161 | "internalType": "uint8",
162 | "name": "_withdrawalFeeBPS",
163 | "type": "uint8"
164 | }
165 | ],
166 | "name": "setWithdrawalFeeBPS",
167 | "outputs": [],
168 | "stateMutability": "nonpayable",
169 | "type": "function"
170 | },
171 | {
172 | "inputs": [],
173 | "name": "withdrawalFeeBPS",
174 | "outputs": [
175 | {
176 | "internalType": "uint8",
177 | "name": "",
178 | "type": "uint8"
179 | }
180 | ],
181 | "stateMutability": "view",
182 | "type": "function"
183 | }
184 | ];
185 |
--------------------------------------------------------------------------------
/abi/IParams.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "inputs": [],
4 | "name": "depositFeesBPS",
5 | "outputs": [
6 | {
7 | "internalType": "uint8",
8 | "name": "",
9 | "type": "uint8"
10 | }
11 | ],
12 | "stateMutability": "view",
13 | "type": "function"
14 | },
15 | {
16 | "inputs": [],
17 | "name": "expirationTime",
18 | "outputs": [
19 | {
20 | "internalType": "uint256",
21 | "name": "",
22 | "type": "uint256"
23 | }
24 | ],
25 | "stateMutability": "view",
26 | "type": "function"
27 | },
28 | {
29 | "inputs": [],
30 | "name": "loopCount",
31 | "outputs": [
32 | {
33 | "internalType": "uint8",
34 | "name": "",
35 | "type": "uint8"
36 | }
37 | ],
38 | "stateMutability": "view",
39 | "type": "function"
40 | },
41 | {
42 | "inputs": [],
43 | "name": "minimumSwapAmountForWBTC",
44 | "outputs": [
45 | {
46 | "internalType": "uint256",
47 | "name": "",
48 | "type": "uint256"
49 | }
50 | ],
51 | "stateMutability": "view",
52 | "type": "function"
53 | },
54 | {
55 | "inputs": [],
56 | "name": "nodeRewardsRatio",
57 | "outputs": [
58 | {
59 | "internalType": "uint8",
60 | "name": "",
61 | "type": "uint8"
62 | }
63 | ],
64 | "stateMutability": "view",
65 | "type": "function"
66 | },
67 | {
68 | "inputs": [],
69 | "name": "paraswapAddress",
70 | "outputs": [
71 | {
72 | "internalType": "address",
73 | "name": "",
74 | "type": "address"
75 | }
76 | ],
77 | "stateMutability": "view",
78 | "type": "function"
79 | },
80 | {
81 | "inputs": [
82 | {
83 | "internalType": "uint8",
84 | "name": "_depositFeesBPS",
85 | "type": "uint8"
86 | }
87 | ],
88 | "name": "setDepositFeesBPS",
89 | "outputs": [],
90 | "stateMutability": "nonpayable",
91 | "type": "function"
92 | },
93 | {
94 | "inputs": [
95 | {
96 | "internalType": "uint256",
97 | "name": "_expirationTime",
98 | "type": "uint256"
99 | }
100 | ],
101 | "name": "setExpirationTime",
102 | "outputs": [],
103 | "stateMutability": "nonpayable",
104 | "type": "function"
105 | },
106 | {
107 | "inputs": [
108 | {
109 | "internalType": "uint8",
110 | "name": "_loopCount",
111 | "type": "uint8"
112 | }
113 | ],
114 | "name": "setLoopCount",
115 | "outputs": [],
116 | "stateMutability": "nonpayable",
117 | "type": "function"
118 | },
119 | {
120 | "inputs": [
121 | {
122 | "internalType": "uint256",
123 | "name": "_minimumSwapAmountForWBTC",
124 | "type": "uint256"
125 | }
126 | ],
127 | "name": "setMinimumSwapAmountForWBTC",
128 | "outputs": [],
129 | "stateMutability": "nonpayable",
130 | "type": "function"
131 | },
132 | {
133 | "inputs": [
134 | {
135 | "internalType": "uint8",
136 | "name": "_nodeRewardsRatio",
137 | "type": "uint8"
138 | }
139 | ],
140 | "name": "setNodeRewardsRatio",
141 | "outputs": [],
142 | "stateMutability": "nonpayable",
143 | "type": "function"
144 | },
145 | {
146 | "inputs": [
147 | {
148 | "internalType": "address",
149 | "name": "_paraswapAddress",
150 | "type": "address"
151 | }
152 | ],
153 | "name": "setParaswapAddress",
154 | "outputs": [],
155 | "stateMutability": "nonpayable",
156 | "type": "function"
157 | },
158 | {
159 | "inputs": [
160 | {
161 | "internalType": "uint8",
162 | "name": "_withdrawalFeeBPS",
163 | "type": "uint8"
164 | }
165 | ],
166 | "name": "setWithdrawalFeeBPS",
167 | "outputs": [],
168 | "stateMutability": "nonpayable",
169 | "type": "function"
170 | },
171 | {
172 | "inputs": [],
173 | "name": "withdrawalFeeBPS",
174 | "outputs": [
175 | {
176 | "internalType": "uint8",
177 | "name": "",
178 | "type": "uint8"
179 | }
180 | ],
181 | "stateMutability": "view",
182 | "type": "function"
183 | }
184 | ]
185 |
--------------------------------------------------------------------------------
/abi/ISwapRewards.js:
--------------------------------------------------------------------------------
1 | export default [
2 | {
3 | "inputs": [
4 | {
5 | "internalType": "address",
6 | "name": "_dest",
7 | "type": "address"
8 | },
9 | {
10 | "internalType": "address",
11 | "name": "_receiver",
12 | "type": "address"
13 | },
14 | {
15 | "internalType": "uint256",
16 | "name": "_swapped",
17 | "type": "uint256"
18 | }
19 | ],
20 | "name": "pullRewards",
21 | "outputs": [
22 | {
23 | "internalType": "bool",
24 | "name": "",
25 | "type": "bool"
26 | }
27 | ],
28 | "stateMutability": "nonpayable",
29 | "type": "function"
30 | },
31 | {
32 | "inputs": [
33 | {
34 | "internalType": "address",
35 | "name": "_dest",
36 | "type": "address"
37 | },
38 | {
39 | "internalType": "address[]",
40 | "name": "_receiver",
41 | "type": "address[]"
42 | },
43 | {
44 | "internalType": "uint256[]",
45 | "name": "_swapped",
46 | "type": "uint256[]"
47 | }
48 | ],
49 | "name": "pullRewardsMulti",
50 | "outputs": [
51 | {
52 | "internalType": "bool",
53 | "name": "",
54 | "type": "bool"
55 | }
56 | ],
57 | "stateMutability": "nonpayable",
58 | "type": "function"
59 | },
60 | {
61 | "inputs": [
62 | {
63 | "internalType": "uint256",
64 | "name": "_pricePerBTC",
65 | "type": "uint256"
66 | }
67 | ],
68 | "name": "setSWINGBYPrice",
69 | "outputs": [],
70 | "stateMutability": "nonpayable",
71 | "type": "function"
72 | }
73 | ];
74 |
--------------------------------------------------------------------------------
/abi/ISwapRewards.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "inputs": [
4 | {
5 | "internalType": "address",
6 | "name": "_dest",
7 | "type": "address"
8 | },
9 | {
10 | "internalType": "address",
11 | "name": "_receiver",
12 | "type": "address"
13 | },
14 | {
15 | "internalType": "uint256",
16 | "name": "_swapped",
17 | "type": "uint256"
18 | }
19 | ],
20 | "name": "pullRewards",
21 | "outputs": [
22 | {
23 | "internalType": "bool",
24 | "name": "",
25 | "type": "bool"
26 | }
27 | ],
28 | "stateMutability": "nonpayable",
29 | "type": "function"
30 | },
31 | {
32 | "inputs": [
33 | {
34 | "internalType": "address",
35 | "name": "_dest",
36 | "type": "address"
37 | },
38 | {
39 | "internalType": "address[]",
40 | "name": "_receiver",
41 | "type": "address[]"
42 | },
43 | {
44 | "internalType": "uint256[]",
45 | "name": "_swapped",
46 | "type": "uint256[]"
47 | }
48 | ],
49 | "name": "pullRewardsMulti",
50 | "outputs": [
51 | {
52 | "internalType": "bool",
53 | "name": "",
54 | "type": "bool"
55 | }
56 | ],
57 | "stateMutability": "nonpayable",
58 | "type": "function"
59 | },
60 | {
61 | "inputs": [
62 | {
63 | "internalType": "uint256",
64 | "name": "_pricePerBTC",
65 | "type": "uint256"
66 | }
67 | ],
68 | "name": "setSWINGBYPrice",
69 | "outputs": [],
70 | "stateMutability": "nonpayable",
71 | "type": "function"
72 | }
73 | ]
74 |
--------------------------------------------------------------------------------
/abi/ITokenTransferProxy.js:
--------------------------------------------------------------------------------
1 | export default [
2 | {
3 | "inputs": [
4 | {
5 | "internalType": "address",
6 | "name": "user",
7 | "type": "address"
8 | },
9 | {
10 | "internalType": "uint256",
11 | "name": "tokensToFree",
12 | "type": "uint256"
13 | }
14 | ],
15 | "name": "freeReduxTokens",
16 | "outputs": [],
17 | "stateMutability": "nonpayable",
18 | "type": "function"
19 | },
20 | {
21 | "inputs": [
22 | {
23 | "internalType": "address",
24 | "name": "token",
25 | "type": "address"
26 | },
27 | {
28 | "internalType": "address",
29 | "name": "from",
30 | "type": "address"
31 | },
32 | {
33 | "internalType": "address",
34 | "name": "to",
35 | "type": "address"
36 | },
37 | {
38 | "internalType": "uint256",
39 | "name": "amount",
40 | "type": "uint256"
41 | }
42 | ],
43 | "name": "transferFrom",
44 | "outputs": [],
45 | "stateMutability": "nonpayable",
46 | "type": "function"
47 | }
48 | ];
49 |
--------------------------------------------------------------------------------
/abi/ITokenTransferProxy.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "inputs": [
4 | {
5 | "internalType": "address",
6 | "name": "user",
7 | "type": "address"
8 | },
9 | {
10 | "internalType": "uint256",
11 | "name": "tokensToFree",
12 | "type": "uint256"
13 | }
14 | ],
15 | "name": "freeReduxTokens",
16 | "outputs": [],
17 | "stateMutability": "nonpayable",
18 | "type": "function"
19 | },
20 | {
21 | "inputs": [
22 | {
23 | "internalType": "address",
24 | "name": "token",
25 | "type": "address"
26 | },
27 | {
28 | "internalType": "address",
29 | "name": "from",
30 | "type": "address"
31 | },
32 | {
33 | "internalType": "address",
34 | "name": "to",
35 | "type": "address"
36 | },
37 | {
38 | "internalType": "uint256",
39 | "name": "amount",
40 | "type": "uint256"
41 | }
42 | ],
43 | "name": "transferFrom",
44 | "outputs": [],
45 | "stateMutability": "nonpayable",
46 | "type": "function"
47 | }
48 | ]
49 |
--------------------------------------------------------------------------------
/abi/IWETH.js:
--------------------------------------------------------------------------------
1 | export default [
2 | {
3 | "inputs": [
4 | {
5 | "internalType": "address",
6 | "name": "spender",
7 | "type": "address"
8 | },
9 | {
10 | "internalType": "uint256",
11 | "name": "amount",
12 | "type": "uint256"
13 | }
14 | ],
15 | "name": "approve",
16 | "outputs": [
17 | {
18 | "internalType": "bool",
19 | "name": "",
20 | "type": "bool"
21 | }
22 | ],
23 | "stateMutability": "nonpayable",
24 | "type": "function"
25 | },
26 | {
27 | "inputs": [],
28 | "name": "deposit",
29 | "outputs": [],
30 | "stateMutability": "payable",
31 | "type": "function"
32 | },
33 | {
34 | "inputs": [
35 | {
36 | "internalType": "address",
37 | "name": "to",
38 | "type": "address"
39 | },
40 | {
41 | "internalType": "uint256",
42 | "name": "value",
43 | "type": "uint256"
44 | }
45 | ],
46 | "name": "transfer",
47 | "outputs": [
48 | {
49 | "internalType": "bool",
50 | "name": "",
51 | "type": "bool"
52 | }
53 | ],
54 | "stateMutability": "nonpayable",
55 | "type": "function"
56 | },
57 | {
58 | "inputs": [
59 | {
60 | "internalType": "uint256",
61 | "name": "",
62 | "type": "uint256"
63 | }
64 | ],
65 | "name": "withdraw",
66 | "outputs": [],
67 | "stateMutability": "nonpayable",
68 | "type": "function"
69 | }
70 | ];
71 |
--------------------------------------------------------------------------------
/abi/IWETH.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "inputs": [
4 | {
5 | "internalType": "address",
6 | "name": "spender",
7 | "type": "address"
8 | },
9 | {
10 | "internalType": "uint256",
11 | "name": "amount",
12 | "type": "uint256"
13 | }
14 | ],
15 | "name": "approve",
16 | "outputs": [
17 | {
18 | "internalType": "bool",
19 | "name": "",
20 | "type": "bool"
21 | }
22 | ],
23 | "stateMutability": "nonpayable",
24 | "type": "function"
25 | },
26 | {
27 | "inputs": [],
28 | "name": "deposit",
29 | "outputs": [],
30 | "stateMutability": "payable",
31 | "type": "function"
32 | },
33 | {
34 | "inputs": [
35 | {
36 | "internalType": "address",
37 | "name": "to",
38 | "type": "address"
39 | },
40 | {
41 | "internalType": "uint256",
42 | "name": "value",
43 | "type": "uint256"
44 | }
45 | ],
46 | "name": "transfer",
47 | "outputs": [
48 | {
49 | "internalType": "bool",
50 | "name": "",
51 | "type": "bool"
52 | }
53 | ],
54 | "stateMutability": "nonpayable",
55 | "type": "function"
56 | },
57 | {
58 | "inputs": [
59 | {
60 | "internalType": "uint256",
61 | "name": "",
62 | "type": "uint256"
63 | }
64 | ],
65 | "name": "withdraw",
66 | "outputs": [],
67 | "stateMutability": "nonpayable",
68 | "type": "function"
69 | }
70 | ]
71 |
--------------------------------------------------------------------------------
/abi/Ownable.js:
--------------------------------------------------------------------------------
1 | export default [
2 | {
3 | "anonymous": false,
4 | "inputs": [
5 | {
6 | "indexed": true,
7 | "internalType": "address",
8 | "name": "previousOwner",
9 | "type": "address"
10 | },
11 | {
12 | "indexed": true,
13 | "internalType": "address",
14 | "name": "newOwner",
15 | "type": "address"
16 | }
17 | ],
18 | "name": "OwnershipTransferred",
19 | "type": "event"
20 | },
21 | {
22 | "inputs": [],
23 | "name": "owner",
24 | "outputs": [
25 | {
26 | "internalType": "address",
27 | "name": "",
28 | "type": "address"
29 | }
30 | ],
31 | "stateMutability": "view",
32 | "type": "function"
33 | },
34 | {
35 | "inputs": [],
36 | "name": "renounceOwnership",
37 | "outputs": [],
38 | "stateMutability": "nonpayable",
39 | "type": "function"
40 | },
41 | {
42 | "inputs": [
43 | {
44 | "internalType": "address",
45 | "name": "newOwner",
46 | "type": "address"
47 | }
48 | ],
49 | "name": "transferOwnership",
50 | "outputs": [],
51 | "stateMutability": "nonpayable",
52 | "type": "function"
53 | }
54 | ];
55 |
--------------------------------------------------------------------------------
/abi/Ownable.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "anonymous": false,
4 | "inputs": [
5 | {
6 | "indexed": true,
7 | "internalType": "address",
8 | "name": "previousOwner",
9 | "type": "address"
10 | },
11 | {
12 | "indexed": true,
13 | "internalType": "address",
14 | "name": "newOwner",
15 | "type": "address"
16 | }
17 | ],
18 | "name": "OwnershipTransferred",
19 | "type": "event"
20 | },
21 | {
22 | "inputs": [],
23 | "name": "owner",
24 | "outputs": [
25 | {
26 | "internalType": "address",
27 | "name": "",
28 | "type": "address"
29 | }
30 | ],
31 | "stateMutability": "view",
32 | "type": "function"
33 | },
34 | {
35 | "inputs": [],
36 | "name": "renounceOwnership",
37 | "outputs": [],
38 | "stateMutability": "nonpayable",
39 | "type": "function"
40 | },
41 | {
42 | "inputs": [
43 | {
44 | "internalType": "address",
45 | "name": "newOwner",
46 | "type": "address"
47 | }
48 | ],
49 | "name": "transferOwnership",
50 | "outputs": [],
51 | "stateMutability": "nonpayable",
52 | "type": "function"
53 | }
54 | ]
55 |
--------------------------------------------------------------------------------
/abi/Params.js:
--------------------------------------------------------------------------------
1 | export default [
2 | {
3 | "inputs": [],
4 | "stateMutability": "nonpayable",
5 | "type": "constructor"
6 | },
7 | {
8 | "anonymous": false,
9 | "inputs": [
10 | {
11 | "indexed": true,
12 | "internalType": "address",
13 | "name": "previousOwner",
14 | "type": "address"
15 | },
16 | {
17 | "indexed": true,
18 | "internalType": "address",
19 | "name": "newOwner",
20 | "type": "address"
21 | }
22 | ],
23 | "name": "OwnershipTransferred",
24 | "type": "event"
25 | },
26 | {
27 | "inputs": [],
28 | "name": "depositFeesBPS",
29 | "outputs": [
30 | {
31 | "internalType": "uint8",
32 | "name": "",
33 | "type": "uint8"
34 | }
35 | ],
36 | "stateMutability": "view",
37 | "type": "function"
38 | },
39 | {
40 | "inputs": [],
41 | "name": "expirationTime",
42 | "outputs": [
43 | {
44 | "internalType": "uint256",
45 | "name": "",
46 | "type": "uint256"
47 | }
48 | ],
49 | "stateMutability": "view",
50 | "type": "function"
51 | },
52 | {
53 | "inputs": [],
54 | "name": "loopCount",
55 | "outputs": [
56 | {
57 | "internalType": "uint8",
58 | "name": "",
59 | "type": "uint8"
60 | }
61 | ],
62 | "stateMutability": "view",
63 | "type": "function"
64 | },
65 | {
66 | "inputs": [],
67 | "name": "minimumSwapAmountForWBTC",
68 | "outputs": [
69 | {
70 | "internalType": "uint256",
71 | "name": "",
72 | "type": "uint256"
73 | }
74 | ],
75 | "stateMutability": "view",
76 | "type": "function"
77 | },
78 | {
79 | "inputs": [],
80 | "name": "nodeRewardsRatio",
81 | "outputs": [
82 | {
83 | "internalType": "uint8",
84 | "name": "",
85 | "type": "uint8"
86 | }
87 | ],
88 | "stateMutability": "view",
89 | "type": "function"
90 | },
91 | {
92 | "inputs": [],
93 | "name": "owner",
94 | "outputs": [
95 | {
96 | "internalType": "address",
97 | "name": "",
98 | "type": "address"
99 | }
100 | ],
101 | "stateMutability": "view",
102 | "type": "function"
103 | },
104 | {
105 | "inputs": [],
106 | "name": "paraswapAddress",
107 | "outputs": [
108 | {
109 | "internalType": "address",
110 | "name": "",
111 | "type": "address"
112 | }
113 | ],
114 | "stateMutability": "view",
115 | "type": "function"
116 | },
117 | {
118 | "inputs": [],
119 | "name": "renounceOwnership",
120 | "outputs": [],
121 | "stateMutability": "nonpayable",
122 | "type": "function"
123 | },
124 | {
125 | "inputs": [
126 | {
127 | "internalType": "uint8",
128 | "name": "_depositFeesBPS",
129 | "type": "uint8"
130 | }
131 | ],
132 | "name": "setDepositFeesBPS",
133 | "outputs": [],
134 | "stateMutability": "nonpayable",
135 | "type": "function"
136 | },
137 | {
138 | "inputs": [
139 | {
140 | "internalType": "uint256",
141 | "name": "_expirationTime",
142 | "type": "uint256"
143 | }
144 | ],
145 | "name": "setExpirationTime",
146 | "outputs": [],
147 | "stateMutability": "nonpayable",
148 | "type": "function"
149 | },
150 | {
151 | "inputs": [
152 | {
153 | "internalType": "uint8",
154 | "name": "_loopCount",
155 | "type": "uint8"
156 | }
157 | ],
158 | "name": "setLoopCount",
159 | "outputs": [],
160 | "stateMutability": "nonpayable",
161 | "type": "function"
162 | },
163 | {
164 | "inputs": [
165 | {
166 | "internalType": "uint256",
167 | "name": "_minimumSwapAmountForWBTC",
168 | "type": "uint256"
169 | }
170 | ],
171 | "name": "setMinimumSwapAmountForWBTC",
172 | "outputs": [],
173 | "stateMutability": "nonpayable",
174 | "type": "function"
175 | },
176 | {
177 | "inputs": [
178 | {
179 | "internalType": "uint8",
180 | "name": "_nodeRewardsRatio",
181 | "type": "uint8"
182 | }
183 | ],
184 | "name": "setNodeRewardsRatio",
185 | "outputs": [],
186 | "stateMutability": "nonpayable",
187 | "type": "function"
188 | },
189 | {
190 | "inputs": [
191 | {
192 | "internalType": "address",
193 | "name": "_paraswapAddress",
194 | "type": "address"
195 | }
196 | ],
197 | "name": "setParaswapAddress",
198 | "outputs": [],
199 | "stateMutability": "nonpayable",
200 | "type": "function"
201 | },
202 | {
203 | "inputs": [
204 | {
205 | "internalType": "uint8",
206 | "name": "_withdrawalFeeBPS",
207 | "type": "uint8"
208 | }
209 | ],
210 | "name": "setWithdrawalFeeBPS",
211 | "outputs": [],
212 | "stateMutability": "nonpayable",
213 | "type": "function"
214 | },
215 | {
216 | "inputs": [
217 | {
218 | "internalType": "address",
219 | "name": "newOwner",
220 | "type": "address"
221 | }
222 | ],
223 | "name": "transferOwnership",
224 | "outputs": [],
225 | "stateMutability": "nonpayable",
226 | "type": "function"
227 | },
228 | {
229 | "inputs": [],
230 | "name": "withdrawalFeeBPS",
231 | "outputs": [
232 | {
233 | "internalType": "uint8",
234 | "name": "",
235 | "type": "uint8"
236 | }
237 | ],
238 | "stateMutability": "view",
239 | "type": "function"
240 | }
241 | ];
242 |
--------------------------------------------------------------------------------
/abi/Params.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "inputs": [],
4 | "stateMutability": "nonpayable",
5 | "type": "constructor"
6 | },
7 | {
8 | "anonymous": false,
9 | "inputs": [
10 | {
11 | "indexed": true,
12 | "internalType": "address",
13 | "name": "previousOwner",
14 | "type": "address"
15 | },
16 | {
17 | "indexed": true,
18 | "internalType": "address",
19 | "name": "newOwner",
20 | "type": "address"
21 | }
22 | ],
23 | "name": "OwnershipTransferred",
24 | "type": "event"
25 | },
26 | {
27 | "inputs": [],
28 | "name": "depositFeesBPS",
29 | "outputs": [
30 | {
31 | "internalType": "uint8",
32 | "name": "",
33 | "type": "uint8"
34 | }
35 | ],
36 | "stateMutability": "view",
37 | "type": "function"
38 | },
39 | {
40 | "inputs": [],
41 | "name": "expirationTime",
42 | "outputs": [
43 | {
44 | "internalType": "uint256",
45 | "name": "",
46 | "type": "uint256"
47 | }
48 | ],
49 | "stateMutability": "view",
50 | "type": "function"
51 | },
52 | {
53 | "inputs": [],
54 | "name": "loopCount",
55 | "outputs": [
56 | {
57 | "internalType": "uint8",
58 | "name": "",
59 | "type": "uint8"
60 | }
61 | ],
62 | "stateMutability": "view",
63 | "type": "function"
64 | },
65 | {
66 | "inputs": [],
67 | "name": "minimumSwapAmountForWBTC",
68 | "outputs": [
69 | {
70 | "internalType": "uint256",
71 | "name": "",
72 | "type": "uint256"
73 | }
74 | ],
75 | "stateMutability": "view",
76 | "type": "function"
77 | },
78 | {
79 | "inputs": [],
80 | "name": "nodeRewardsRatio",
81 | "outputs": [
82 | {
83 | "internalType": "uint8",
84 | "name": "",
85 | "type": "uint8"
86 | }
87 | ],
88 | "stateMutability": "view",
89 | "type": "function"
90 | },
91 | {
92 | "inputs": [],
93 | "name": "owner",
94 | "outputs": [
95 | {
96 | "internalType": "address",
97 | "name": "",
98 | "type": "address"
99 | }
100 | ],
101 | "stateMutability": "view",
102 | "type": "function"
103 | },
104 | {
105 | "inputs": [],
106 | "name": "paraswapAddress",
107 | "outputs": [
108 | {
109 | "internalType": "address",
110 | "name": "",
111 | "type": "address"
112 | }
113 | ],
114 | "stateMutability": "view",
115 | "type": "function"
116 | },
117 | {
118 | "inputs": [],
119 | "name": "renounceOwnership",
120 | "outputs": [],
121 | "stateMutability": "nonpayable",
122 | "type": "function"
123 | },
124 | {
125 | "inputs": [
126 | {
127 | "internalType": "uint8",
128 | "name": "_depositFeesBPS",
129 | "type": "uint8"
130 | }
131 | ],
132 | "name": "setDepositFeesBPS",
133 | "outputs": [],
134 | "stateMutability": "nonpayable",
135 | "type": "function"
136 | },
137 | {
138 | "inputs": [
139 | {
140 | "internalType": "uint256",
141 | "name": "_expirationTime",
142 | "type": "uint256"
143 | }
144 | ],
145 | "name": "setExpirationTime",
146 | "outputs": [],
147 | "stateMutability": "nonpayable",
148 | "type": "function"
149 | },
150 | {
151 | "inputs": [
152 | {
153 | "internalType": "uint8",
154 | "name": "_loopCount",
155 | "type": "uint8"
156 | }
157 | ],
158 | "name": "setLoopCount",
159 | "outputs": [],
160 | "stateMutability": "nonpayable",
161 | "type": "function"
162 | },
163 | {
164 | "inputs": [
165 | {
166 | "internalType": "uint256",
167 | "name": "_minimumSwapAmountForWBTC",
168 | "type": "uint256"
169 | }
170 | ],
171 | "name": "setMinimumSwapAmountForWBTC",
172 | "outputs": [],
173 | "stateMutability": "nonpayable",
174 | "type": "function"
175 | },
176 | {
177 | "inputs": [
178 | {
179 | "internalType": "uint8",
180 | "name": "_nodeRewardsRatio",
181 | "type": "uint8"
182 | }
183 | ],
184 | "name": "setNodeRewardsRatio",
185 | "outputs": [],
186 | "stateMutability": "nonpayable",
187 | "type": "function"
188 | },
189 | {
190 | "inputs": [
191 | {
192 | "internalType": "address",
193 | "name": "_paraswapAddress",
194 | "type": "address"
195 | }
196 | ],
197 | "name": "setParaswapAddress",
198 | "outputs": [],
199 | "stateMutability": "nonpayable",
200 | "type": "function"
201 | },
202 | {
203 | "inputs": [
204 | {
205 | "internalType": "uint8",
206 | "name": "_withdrawalFeeBPS",
207 | "type": "uint8"
208 | }
209 | ],
210 | "name": "setWithdrawalFeeBPS",
211 | "outputs": [],
212 | "stateMutability": "nonpayable",
213 | "type": "function"
214 | },
215 | {
216 | "inputs": [
217 | {
218 | "internalType": "address",
219 | "name": "newOwner",
220 | "type": "address"
221 | }
222 | ],
223 | "name": "transferOwnership",
224 | "outputs": [],
225 | "stateMutability": "nonpayable",
226 | "type": "function"
227 | },
228 | {
229 | "inputs": [],
230 | "name": "withdrawalFeeBPS",
231 | "outputs": [
232 | {
233 | "internalType": "uint8",
234 | "name": "",
235 | "type": "uint8"
236 | }
237 | ],
238 | "stateMutability": "view",
239 | "type": "function"
240 | }
241 | ]
242 |
--------------------------------------------------------------------------------
/abi/SwapRewards.js:
--------------------------------------------------------------------------------
1 | export default [
2 | {
3 | "inputs": [
4 | {
5 | "internalType": "address",
6 | "name": "_owner",
7 | "type": "address"
8 | },
9 | {
10 | "internalType": "address",
11 | "name": "_swingby",
12 | "type": "address"
13 | },
14 | {
15 | "internalType": "uint256",
16 | "name": "_pricePerBTC",
17 | "type": "uint256"
18 | }
19 | ],
20 | "stateMutability": "nonpayable",
21 | "type": "constructor"
22 | },
23 | {
24 | "anonymous": false,
25 | "inputs": [
26 | {
27 | "indexed": true,
28 | "internalType": "address",
29 | "name": "previousOwner",
30 | "type": "address"
31 | },
32 | {
33 | "indexed": true,
34 | "internalType": "address",
35 | "name": "newOwner",
36 | "type": "address"
37 | }
38 | ],
39 | "name": "OwnershipTransferred",
40 | "type": "event"
41 | },
42 | {
43 | "anonymous": false,
44 | "inputs": [
45 | {
46 | "indexed": false,
47 | "internalType": "address",
48 | "name": "to",
49 | "type": "address"
50 | },
51 | {
52 | "indexed": false,
53 | "internalType": "uint256",
54 | "name": "amount",
55 | "type": "uint256"
56 | },
57 | {
58 | "indexed": false,
59 | "internalType": "uint256",
60 | "name": "rebate",
61 | "type": "uint256"
62 | }
63 | ],
64 | "name": "Paid",
65 | "type": "event"
66 | },
67 | {
68 | "inputs": [],
69 | "name": "owner",
70 | "outputs": [
71 | {
72 | "internalType": "address",
73 | "name": "",
74 | "type": "address"
75 | }
76 | ],
77 | "stateMutability": "view",
78 | "type": "function"
79 | },
80 | {
81 | "inputs": [],
82 | "name": "pricePerBTC",
83 | "outputs": [
84 | {
85 | "internalType": "uint256",
86 | "name": "",
87 | "type": "uint256"
88 | }
89 | ],
90 | "stateMutability": "view",
91 | "type": "function"
92 | },
93 | {
94 | "inputs": [
95 | {
96 | "internalType": "address",
97 | "name": "_dest",
98 | "type": "address"
99 | },
100 | {
101 | "internalType": "address",
102 | "name": "_receiver",
103 | "type": "address"
104 | },
105 | {
106 | "internalType": "uint256",
107 | "name": "_swapped",
108 | "type": "uint256"
109 | }
110 | ],
111 | "name": "pullRewards",
112 | "outputs": [
113 | {
114 | "internalType": "bool",
115 | "name": "",
116 | "type": "bool"
117 | }
118 | ],
119 | "stateMutability": "nonpayable",
120 | "type": "function"
121 | },
122 | {
123 | "inputs": [
124 | {
125 | "internalType": "address",
126 | "name": "_dest",
127 | "type": "address"
128 | },
129 | {
130 | "internalType": "address[]",
131 | "name": "_receiver",
132 | "type": "address[]"
133 | },
134 | {
135 | "internalType": "uint256[]",
136 | "name": "_swapped",
137 | "type": "uint256[]"
138 | }
139 | ],
140 | "name": "pullRewardsMulti",
141 | "outputs": [
142 | {
143 | "internalType": "bool",
144 | "name": "",
145 | "type": "bool"
146 | }
147 | ],
148 | "stateMutability": "nonpayable",
149 | "type": "function"
150 | },
151 | {
152 | "inputs": [],
153 | "name": "rebateRate",
154 | "outputs": [
155 | {
156 | "internalType": "uint256",
157 | "name": "",
158 | "type": "uint256"
159 | }
160 | ],
161 | "stateMutability": "view",
162 | "type": "function"
163 | },
164 | {
165 | "inputs": [],
166 | "name": "renounceOwnership",
167 | "outputs": [],
168 | "stateMutability": "nonpayable",
169 | "type": "function"
170 | },
171 | {
172 | "inputs": [],
173 | "name": "rewardToken",
174 | "outputs": [
175 | {
176 | "internalType": "contract IERC20",
177 | "name": "",
178 | "type": "address"
179 | }
180 | ],
181 | "stateMutability": "view",
182 | "type": "function"
183 | },
184 | {
185 | "inputs": [
186 | {
187 | "internalType": "uint256",
188 | "name": "_pricePerBTC",
189 | "type": "uint256"
190 | }
191 | ],
192 | "name": "setSWINGBYPrice",
193 | "outputs": [],
194 | "stateMutability": "nonpayable",
195 | "type": "function"
196 | },
197 | {
198 | "inputs": [
199 | {
200 | "internalType": "address",
201 | "name": "_swap",
202 | "type": "address"
203 | },
204 | {
205 | "internalType": "uint256",
206 | "name": "_newRebateRate",
207 | "type": "uint256"
208 | },
209 | {
210 | "internalType": "uint256",
211 | "name": "_thresholdRatio",
212 | "type": "uint256"
213 | }
214 | ],
215 | "name": "setSwap",
216 | "outputs": [],
217 | "stateMutability": "nonpayable",
218 | "type": "function"
219 | },
220 | {
221 | "inputs": [],
222 | "name": "swapContract",
223 | "outputs": [
224 | {
225 | "internalType": "contract ISwapContract",
226 | "name": "",
227 | "type": "address"
228 | }
229 | ],
230 | "stateMutability": "view",
231 | "type": "function"
232 | },
233 | {
234 | "inputs": [],
235 | "name": "thresholdRatio",
236 | "outputs": [
237 | {
238 | "internalType": "uint256",
239 | "name": "",
240 | "type": "uint256"
241 | }
242 | ],
243 | "stateMutability": "view",
244 | "type": "function"
245 | },
246 | {
247 | "inputs": [
248 | {
249 | "internalType": "address",
250 | "name": "newOwner",
251 | "type": "address"
252 | }
253 | ],
254 | "name": "transferOwnership",
255 | "outputs": [],
256 | "stateMutability": "nonpayable",
257 | "type": "function"
258 | }
259 | ];
260 |
--------------------------------------------------------------------------------
/abi/SwapRewards.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "inputs": [
4 | {
5 | "internalType": "address",
6 | "name": "_owner",
7 | "type": "address"
8 | },
9 | {
10 | "internalType": "address",
11 | "name": "_swingby",
12 | "type": "address"
13 | },
14 | {
15 | "internalType": "uint256",
16 | "name": "_pricePerBTC",
17 | "type": "uint256"
18 | }
19 | ],
20 | "stateMutability": "nonpayable",
21 | "type": "constructor"
22 | },
23 | {
24 | "anonymous": false,
25 | "inputs": [
26 | {
27 | "indexed": true,
28 | "internalType": "address",
29 | "name": "previousOwner",
30 | "type": "address"
31 | },
32 | {
33 | "indexed": true,
34 | "internalType": "address",
35 | "name": "newOwner",
36 | "type": "address"
37 | }
38 | ],
39 | "name": "OwnershipTransferred",
40 | "type": "event"
41 | },
42 | {
43 | "anonymous": false,
44 | "inputs": [
45 | {
46 | "indexed": false,
47 | "internalType": "address",
48 | "name": "to",
49 | "type": "address"
50 | },
51 | {
52 | "indexed": false,
53 | "internalType": "uint256",
54 | "name": "amount",
55 | "type": "uint256"
56 | },
57 | {
58 | "indexed": false,
59 | "internalType": "uint256",
60 | "name": "rebate",
61 | "type": "uint256"
62 | }
63 | ],
64 | "name": "Paid",
65 | "type": "event"
66 | },
67 | {
68 | "inputs": [],
69 | "name": "owner",
70 | "outputs": [
71 | {
72 | "internalType": "address",
73 | "name": "",
74 | "type": "address"
75 | }
76 | ],
77 | "stateMutability": "view",
78 | "type": "function"
79 | },
80 | {
81 | "inputs": [],
82 | "name": "pricePerBTC",
83 | "outputs": [
84 | {
85 | "internalType": "uint256",
86 | "name": "",
87 | "type": "uint256"
88 | }
89 | ],
90 | "stateMutability": "view",
91 | "type": "function"
92 | },
93 | {
94 | "inputs": [
95 | {
96 | "internalType": "address",
97 | "name": "_dest",
98 | "type": "address"
99 | },
100 | {
101 | "internalType": "address",
102 | "name": "_receiver",
103 | "type": "address"
104 | },
105 | {
106 | "internalType": "uint256",
107 | "name": "_swapped",
108 | "type": "uint256"
109 | }
110 | ],
111 | "name": "pullRewards",
112 | "outputs": [
113 | {
114 | "internalType": "bool",
115 | "name": "",
116 | "type": "bool"
117 | }
118 | ],
119 | "stateMutability": "nonpayable",
120 | "type": "function"
121 | },
122 | {
123 | "inputs": [
124 | {
125 | "internalType": "address",
126 | "name": "_dest",
127 | "type": "address"
128 | },
129 | {
130 | "internalType": "address[]",
131 | "name": "_receiver",
132 | "type": "address[]"
133 | },
134 | {
135 | "internalType": "uint256[]",
136 | "name": "_swapped",
137 | "type": "uint256[]"
138 | }
139 | ],
140 | "name": "pullRewardsMulti",
141 | "outputs": [
142 | {
143 | "internalType": "bool",
144 | "name": "",
145 | "type": "bool"
146 | }
147 | ],
148 | "stateMutability": "nonpayable",
149 | "type": "function"
150 | },
151 | {
152 | "inputs": [],
153 | "name": "rebateRate",
154 | "outputs": [
155 | {
156 | "internalType": "uint256",
157 | "name": "",
158 | "type": "uint256"
159 | }
160 | ],
161 | "stateMutability": "view",
162 | "type": "function"
163 | },
164 | {
165 | "inputs": [],
166 | "name": "renounceOwnership",
167 | "outputs": [],
168 | "stateMutability": "nonpayable",
169 | "type": "function"
170 | },
171 | {
172 | "inputs": [],
173 | "name": "rewardToken",
174 | "outputs": [
175 | {
176 | "internalType": "contract IERC20",
177 | "name": "",
178 | "type": "address"
179 | }
180 | ],
181 | "stateMutability": "view",
182 | "type": "function"
183 | },
184 | {
185 | "inputs": [
186 | {
187 | "internalType": "uint256",
188 | "name": "_pricePerBTC",
189 | "type": "uint256"
190 | }
191 | ],
192 | "name": "setSWINGBYPrice",
193 | "outputs": [],
194 | "stateMutability": "nonpayable",
195 | "type": "function"
196 | },
197 | {
198 | "inputs": [
199 | {
200 | "internalType": "address",
201 | "name": "_swap",
202 | "type": "address"
203 | },
204 | {
205 | "internalType": "uint256",
206 | "name": "_newRebateRate",
207 | "type": "uint256"
208 | },
209 | {
210 | "internalType": "uint256",
211 | "name": "_thresholdRatio",
212 | "type": "uint256"
213 | }
214 | ],
215 | "name": "setSwap",
216 | "outputs": [],
217 | "stateMutability": "nonpayable",
218 | "type": "function"
219 | },
220 | {
221 | "inputs": [],
222 | "name": "swapContract",
223 | "outputs": [
224 | {
225 | "internalType": "contract ISwapContract",
226 | "name": "",
227 | "type": "address"
228 | }
229 | ],
230 | "stateMutability": "view",
231 | "type": "function"
232 | },
233 | {
234 | "inputs": [],
235 | "name": "thresholdRatio",
236 | "outputs": [
237 | {
238 | "internalType": "uint256",
239 | "name": "",
240 | "type": "uint256"
241 | }
242 | ],
243 | "stateMutability": "view",
244 | "type": "function"
245 | },
246 | {
247 | "inputs": [
248 | {
249 | "internalType": "address",
250 | "name": "newOwner",
251 | "type": "address"
252 | }
253 | ],
254 | "name": "transferOwnership",
255 | "outputs": [],
256 | "stateMutability": "nonpayable",
257 | "type": "function"
258 | }
259 | ]
260 |
--------------------------------------------------------------------------------
/abi/sbBTCPool.js:
--------------------------------------------------------------------------------
1 | export default [
2 | {
3 | "anonymous": false,
4 | "inputs": [
5 | {
6 | "indexed": true,
7 | "internalType": "address",
8 | "name": "user",
9 | "type": "address"
10 | },
11 | {
12 | "indexed": false,
13 | "internalType": "uint256",
14 | "name": "amount",
15 | "type": "uint256"
16 | }
17 | ],
18 | "name": "Claim",
19 | "type": "event"
20 | },
21 | {
22 | "anonymous": false,
23 | "inputs": [
24 | {
25 | "indexed": true,
26 | "internalType": "address",
27 | "name": "previousOwner",
28 | "type": "address"
29 | },
30 | {
31 | "indexed": true,
32 | "internalType": "address",
33 | "name": "newOwner",
34 | "type": "address"
35 | }
36 | ],
37 | "name": "OwnershipTransferred",
38 | "type": "event"
39 | },
40 | {
41 | "inputs": [],
42 | "name": "ackFunds",
43 | "outputs": [],
44 | "stateMutability": "nonpayable",
45 | "type": "function"
46 | },
47 | {
48 | "inputs": [],
49 | "name": "balanceBefore",
50 | "outputs": [
51 | {
52 | "internalType": "uint256",
53 | "name": "",
54 | "type": "uint256"
55 | }
56 | ],
57 | "stateMutability": "view",
58 | "type": "function"
59 | },
60 | {
61 | "inputs": [],
62 | "name": "barn",
63 | "outputs": [
64 | {
65 | "internalType": "contract IBarn",
66 | "name": "",
67 | "type": "address"
68 | }
69 | ],
70 | "stateMutability": "view",
71 | "type": "function"
72 | },
73 | {
74 | "inputs": [],
75 | "name": "claim",
76 | "outputs": [
77 | {
78 | "internalType": "uint256",
79 | "name": "",
80 | "type": "uint256"
81 | }
82 | ],
83 | "stateMutability": "nonpayable",
84 | "type": "function"
85 | },
86 | {
87 | "inputs": [],
88 | "name": "currentMultiplier",
89 | "outputs": [
90 | {
91 | "internalType": "uint256",
92 | "name": "",
93 | "type": "uint256"
94 | }
95 | ],
96 | "stateMutability": "view",
97 | "type": "function"
98 | },
99 | {
100 | "inputs": [],
101 | "name": "emergencyWithdraw",
102 | "outputs": [],
103 | "stateMutability": "nonpayable",
104 | "type": "function"
105 | },
106 | {
107 | "inputs": [
108 | {
109 | "internalType": "address",
110 | "name": "",
111 | "type": "address"
112 | }
113 | ],
114 | "name": "owed",
115 | "outputs": [
116 | {
117 | "internalType": "uint256",
118 | "name": "",
119 | "type": "uint256"
120 | }
121 | ],
122 | "stateMutability": "view",
123 | "type": "function"
124 | },
125 | {
126 | "inputs": [],
127 | "name": "owner",
128 | "outputs": [
129 | {
130 | "internalType": "address",
131 | "name": "",
132 | "type": "address"
133 | }
134 | ],
135 | "stateMutability": "view",
136 | "type": "function"
137 | },
138 | {
139 | "inputs": [],
140 | "name": "renounceOwnership",
141 | "outputs": [],
142 | "stateMutability": "nonpayable",
143 | "type": "function"
144 | },
145 | {
146 | "inputs": [
147 | {
148 | "internalType": "address",
149 | "name": "_node",
150 | "type": "address"
151 | }
152 | ],
153 | "name": "resetUnstakedNode",
154 | "outputs": [],
155 | "stateMutability": "nonpayable",
156 | "type": "function"
157 | },
158 | {
159 | "inputs": [],
160 | "name": "rewardToken",
161 | "outputs": [
162 | {
163 | "internalType": "contract IERC20",
164 | "name": "",
165 | "type": "address"
166 | }
167 | ],
168 | "stateMutability": "view",
169 | "type": "function"
170 | },
171 | {
172 | "inputs": [
173 | {
174 | "internalType": "address",
175 | "name": "_barn",
176 | "type": "address"
177 | },
178 | {
179 | "internalType": "address",
180 | "name": "_swap",
181 | "type": "address"
182 | }
183 | ],
184 | "name": "setBarnAndSwap",
185 | "outputs": [],
186 | "stateMutability": "nonpayable",
187 | "type": "function"
188 | },
189 | {
190 | "inputs": [],
191 | "name": "swapContract",
192 | "outputs": [
193 | {
194 | "internalType": "contract ISwapContract",
195 | "name": "",
196 | "type": "address"
197 | }
198 | ],
199 | "stateMutability": "view",
200 | "type": "function"
201 | },
202 | {
203 | "inputs": [],
204 | "name": "totalNodeStaked",
205 | "outputs": [
206 | {
207 | "internalType": "uint256",
208 | "name": "",
209 | "type": "uint256"
210 | }
211 | ],
212 | "stateMutability": "view",
213 | "type": "function"
214 | },
215 | {
216 | "inputs": [
217 | {
218 | "internalType": "address",
219 | "name": "newOwner",
220 | "type": "address"
221 | }
222 | ],
223 | "name": "transferOwnership",
224 | "outputs": [],
225 | "stateMutability": "nonpayable",
226 | "type": "function"
227 | },
228 | {
229 | "inputs": [
230 | {
231 | "internalType": "uint256",
232 | "name": "_timestamp",
233 | "type": "uint256"
234 | }
235 | ],
236 | "name": "updateAll",
237 | "outputs": [],
238 | "stateMutability": "nonpayable",
239 | "type": "function"
240 | },
241 | {
242 | "inputs": [
243 | {
244 | "internalType": "address",
245 | "name": "",
246 | "type": "address"
247 | }
248 | ],
249 | "name": "userMultiplier",
250 | "outputs": [
251 | {
252 | "internalType": "uint256",
253 | "name": "",
254 | "type": "uint256"
255 | }
256 | ],
257 | "stateMutability": "view",
258 | "type": "function"
259 | }
260 | ];
261 |
--------------------------------------------------------------------------------
/abi/sbBTCPool.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "anonymous": false,
4 | "inputs": [
5 | {
6 | "indexed": true,
7 | "internalType": "address",
8 | "name": "user",
9 | "type": "address"
10 | },
11 | {
12 | "indexed": false,
13 | "internalType": "uint256",
14 | "name": "amount",
15 | "type": "uint256"
16 | }
17 | ],
18 | "name": "Claim",
19 | "type": "event"
20 | },
21 | {
22 | "anonymous": false,
23 | "inputs": [
24 | {
25 | "indexed": true,
26 | "internalType": "address",
27 | "name": "previousOwner",
28 | "type": "address"
29 | },
30 | {
31 | "indexed": true,
32 | "internalType": "address",
33 | "name": "newOwner",
34 | "type": "address"
35 | }
36 | ],
37 | "name": "OwnershipTransferred",
38 | "type": "event"
39 | },
40 | {
41 | "inputs": [],
42 | "name": "ackFunds",
43 | "outputs": [],
44 | "stateMutability": "nonpayable",
45 | "type": "function"
46 | },
47 | {
48 | "inputs": [],
49 | "name": "balanceBefore",
50 | "outputs": [
51 | {
52 | "internalType": "uint256",
53 | "name": "",
54 | "type": "uint256"
55 | }
56 | ],
57 | "stateMutability": "view",
58 | "type": "function"
59 | },
60 | {
61 | "inputs": [],
62 | "name": "barn",
63 | "outputs": [
64 | {
65 | "internalType": "contract IBarn",
66 | "name": "",
67 | "type": "address"
68 | }
69 | ],
70 | "stateMutability": "view",
71 | "type": "function"
72 | },
73 | {
74 | "inputs": [],
75 | "name": "claim",
76 | "outputs": [
77 | {
78 | "internalType": "uint256",
79 | "name": "",
80 | "type": "uint256"
81 | }
82 | ],
83 | "stateMutability": "nonpayable",
84 | "type": "function"
85 | },
86 | {
87 | "inputs": [],
88 | "name": "currentMultiplier",
89 | "outputs": [
90 | {
91 | "internalType": "uint256",
92 | "name": "",
93 | "type": "uint256"
94 | }
95 | ],
96 | "stateMutability": "view",
97 | "type": "function"
98 | },
99 | {
100 | "inputs": [],
101 | "name": "emergencyWithdraw",
102 | "outputs": [],
103 | "stateMutability": "nonpayable",
104 | "type": "function"
105 | },
106 | {
107 | "inputs": [
108 | {
109 | "internalType": "address",
110 | "name": "",
111 | "type": "address"
112 | }
113 | ],
114 | "name": "owed",
115 | "outputs": [
116 | {
117 | "internalType": "uint256",
118 | "name": "",
119 | "type": "uint256"
120 | }
121 | ],
122 | "stateMutability": "view",
123 | "type": "function"
124 | },
125 | {
126 | "inputs": [],
127 | "name": "owner",
128 | "outputs": [
129 | {
130 | "internalType": "address",
131 | "name": "",
132 | "type": "address"
133 | }
134 | ],
135 | "stateMutability": "view",
136 | "type": "function"
137 | },
138 | {
139 | "inputs": [],
140 | "name": "renounceOwnership",
141 | "outputs": [],
142 | "stateMutability": "nonpayable",
143 | "type": "function"
144 | },
145 | {
146 | "inputs": [
147 | {
148 | "internalType": "address",
149 | "name": "_node",
150 | "type": "address"
151 | }
152 | ],
153 | "name": "resetUnstakedNode",
154 | "outputs": [],
155 | "stateMutability": "nonpayable",
156 | "type": "function"
157 | },
158 | {
159 | "inputs": [],
160 | "name": "rewardToken",
161 | "outputs": [
162 | {
163 | "internalType": "contract IERC20",
164 | "name": "",
165 | "type": "address"
166 | }
167 | ],
168 | "stateMutability": "view",
169 | "type": "function"
170 | },
171 | {
172 | "inputs": [
173 | {
174 | "internalType": "address",
175 | "name": "_barn",
176 | "type": "address"
177 | },
178 | {
179 | "internalType": "address",
180 | "name": "_swap",
181 | "type": "address"
182 | }
183 | ],
184 | "name": "setBarnAndSwap",
185 | "outputs": [],
186 | "stateMutability": "nonpayable",
187 | "type": "function"
188 | },
189 | {
190 | "inputs": [],
191 | "name": "swapContract",
192 | "outputs": [
193 | {
194 | "internalType": "contract ISwapContract",
195 | "name": "",
196 | "type": "address"
197 | }
198 | ],
199 | "stateMutability": "view",
200 | "type": "function"
201 | },
202 | {
203 | "inputs": [],
204 | "name": "totalNodeStaked",
205 | "outputs": [
206 | {
207 | "internalType": "uint256",
208 | "name": "",
209 | "type": "uint256"
210 | }
211 | ],
212 | "stateMutability": "view",
213 | "type": "function"
214 | },
215 | {
216 | "inputs": [
217 | {
218 | "internalType": "address",
219 | "name": "newOwner",
220 | "type": "address"
221 | }
222 | ],
223 | "name": "transferOwnership",
224 | "outputs": [],
225 | "stateMutability": "nonpayable",
226 | "type": "function"
227 | },
228 | {
229 | "inputs": [
230 | {
231 | "internalType": "uint256",
232 | "name": "_timestamp",
233 | "type": "uint256"
234 | }
235 | ],
236 | "name": "updateAll",
237 | "outputs": [],
238 | "stateMutability": "nonpayable",
239 | "type": "function"
240 | },
241 | {
242 | "inputs": [
243 | {
244 | "internalType": "address",
245 | "name": "",
246 | "type": "address"
247 | }
248 | ],
249 | "name": "userMultiplier",
250 | "outputs": [
251 | {
252 | "internalType": "uint256",
253 | "name": "",
254 | "type": "uint256"
255 | }
256 | ],
257 | "stateMutability": "view",
258 | "type": "function"
259 | }
260 | ]
261 |
--------------------------------------------------------------------------------
/args.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | "0xde6bD5afCDCCA4dD5DA8e3904345Ed02dC735374",
3 | "0xaD6D458402F60fD3Bd25163575031ACDce07538D",
4 | "0xc778417e063141139fce010982780140aa0cd5ab",
5 | 0
6 | ]
--------------------------------------------------------------------------------
/contracts/LPToken.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: AGPL-3.0
2 | pragma solidity ^0.8.0;
3 |
4 | import "./BurnableToken.sol";
5 |
6 | contract LPToken is BurnableToken {
7 | address public old;
8 |
9 | constructor(uint8 _decimals) {
10 | _initialize("Swingby BTC LP Token", "sbBTC", _decimals, 0, true);
11 | }
12 |
13 | function setOld(address _old) public onlyOwner {
14 | old = _old;
15 | }
16 |
17 | /// @dev convertTo allows to convert new LPT when user burnd this tokens at the same time.
18 | /// note: new LPT has to allow minting permission from this contract.
19 | function convertTo(LPToken target, uint256 amount) public {
20 | require(address(target) != address(this), "target != this contract");
21 | _burn(_msgSender(), amount);
22 | target.mintFrom(_msgSender(), amount);
23 | }
24 |
25 | function mintFrom(address target, uint256 amount) public returns (bool) {
26 | require(old != address(this), "target != this contract");
27 | require(msg.sender == old, "caller is not old");
28 | _mint(target, amount);
29 | return true;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/contracts/Params.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: AGPL-3.0
2 | pragma solidity ^0.8.0;
3 | pragma experimental ABIEncoderV2;
4 | import "./interfaces/IParams.sol";
5 | import "@openzeppelin/contracts/access/Ownable.sol";
6 |
7 | contract Params is Ownable, IParams {
8 | uint256 public minimumSwapAmountForWBTC;
9 | uint256 public expirationTime;
10 | address public paraswapAddress;
11 | uint8 public nodeRewardsRatio;
12 | uint8 public depositFeesBPS;
13 | uint8 public withdrawalFeeBPS;
14 | uint8 public loopCount; //max loops when cleaning up expired SkyPools TXs
15 |
16 | constructor() {
17 | //Initialize minimumSwapAmountForWBTC
18 | minimumSwapAmountForWBTC = 24000;
19 | // Initialize expirationTime
20 | expirationTime = 172800; //2 days
21 | // Initialize paraswap address to current address
22 | paraswapAddress = 0xDEF171Fe48CF0115B1d80b88dc8eAB59176FEe57;
23 | // Initialize nodeRewardsRatio
24 | nodeRewardsRatio = 66;
25 | // Initialize withdrawalFeeBPS
26 | withdrawalFeeBPS = 20;
27 | // Initialize depositFeesBPS
28 | depositFeesBPS = 0;
29 | // Initialize loopCount
30 | loopCount = 10;
31 | }
32 |
33 | function setMinimumSwapAmountForWBTC(uint256 _minimumSwapAmountForWBTC)
34 | external
35 | onlyOwner
36 | {
37 | require(
38 | _minimumSwapAmountForWBTC > 0,
39 | "_minimumSwapAmountForWBTC can not be 0"
40 | );
41 | minimumSwapAmountForWBTC = _minimumSwapAmountForWBTC;
42 | }
43 |
44 | function setExpirationTime(uint256 _expirationTime) external onlyOwner {
45 | require(_expirationTime >= 0, "_expirationTime can not be 0");
46 | expirationTime = _expirationTime;
47 | }
48 |
49 | function setParaswapAddress(address _paraswapAddress) external onlyOwner {
50 | paraswapAddress = _paraswapAddress;
51 | }
52 |
53 | function setNodeRewardsRatio(uint8 _nodeRewardsRatio) external onlyOwner {
54 | require(
55 | _nodeRewardsRatio >= 0 && _nodeRewardsRatio <= 100,
56 | "_nodeRewardsRatio is not valid"
57 | );
58 | nodeRewardsRatio = _nodeRewardsRatio;
59 | }
60 |
61 | function setWithdrawalFeeBPS(uint8 _withdrawalFeeBPS) external onlyOwner {
62 | require(
63 | _withdrawalFeeBPS >= 0 && _withdrawalFeeBPS <= 100,
64 | "_withdrawalFeeBPS is invalid"
65 | );
66 | withdrawalFeeBPS = _withdrawalFeeBPS;
67 | }
68 |
69 | function setDepositFeesBPS(uint8 _depositFeesBPS) external onlyOwner {
70 | require(
71 | _depositFeesBPS >= 0 && _depositFeesBPS <= 100,
72 | "_depositFeesBPS is invalid"
73 | );
74 | depositFeesBPS = _depositFeesBPS;
75 | }
76 |
77 | function setLoopCount(uint8 _loopCount) external onlyOwner {
78 | require(_loopCount != 0, "_loopCount can not equal 0");
79 | loopCount = _loopCount;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/contracts/SwapRewards.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 | pragma solidity ^0.8.0;
3 | pragma experimental ABIEncoderV2;
4 |
5 | import "@openzeppelin/contracts/access/Ownable.sol";
6 | import "@openzeppelin/contracts/utils/math/SafeMath.sol";
7 | import "./interfaces/ISwapContract.sol";
8 |
9 | contract SwapRewards is Ownable {
10 | using SafeMath for uint256;
11 |
12 | IERC20 public immutable rewardToken; //swingby
13 | ISwapContract public swapContract;
14 | uint256 public rebateRate = 30; // BPS base
15 | uint256 public thresholdRatio = 55; // diff is over 10%
16 | uint256 public pricePerBTC;
17 |
18 | event Paid(address to, uint256 amount, uint256 rebate);
19 |
20 | constructor(
21 | address _owner,
22 | address _swingby,
23 | uint256 _pricePerBTC
24 | ) {
25 | require(_owner != address(0), "owner address is not be 0x0");
26 | require(_swingby != address(0), "swingby address must not be 0x0");
27 |
28 | transferOwnership(_owner);
29 | rewardToken = IERC20(_swingby);
30 | pricePerBTC = _pricePerBTC;
31 | }
32 |
33 | // expected DAO executes this
34 | function setSWINGBYPrice(uint256 _pricePerBTC) external {
35 | require(msg.sender == owner(), "!owner");
36 | pricePerBTC = _pricePerBTC;
37 | }
38 |
39 | function setSwap(
40 | address _swap,
41 | uint256 _newRebateRate,
42 | uint256 _thresholdRatio
43 | ) external {
44 | require(msg.sender == owner(), "!owner");
45 | require(
46 | _newRebateRate >= 0 && _newRebateRate <= 100,
47 | "_newRebateRate is not valid"
48 | );
49 | require(
50 | _thresholdRatio >= 20 && _thresholdRatio <= 100,
51 | "_thresholdRatio is not valid"
52 | );
53 | swapContract = ISwapContract(_swap);
54 | rebateRate = _newRebateRate;
55 | thresholdRatio = _thresholdRatio;
56 | }
57 |
58 | // pullRewards transfers the funds to the user
59 | function pullRewards(
60 | address _dest,
61 | address _receiver,
62 | uint256 _swapped
63 | ) external returns (bool) {
64 | require(
65 | msg.sender == address(swapContract),
66 | "caller is not swap contact"
67 | );
68 | address tokenB = swapContract.BTCT_ADDR();
69 | (uint256 balA, uint256 balB) = swapContract.getFloatReserve(
70 | address(0),
71 | tokenB
72 | );
73 | uint256 threshold = balA.add(balB).mul(thresholdRatio).div(100);
74 | if (
75 | (_dest == tokenB && balB >= threshold) ||
76 | (_dest == address(0) && balA >= threshold)
77 | ) {
78 | uint256 amount = _swapped.mul(rebateRate).mul(pricePerBTC).mul(1e6);
79 | rewardToken.transfer(_receiver, amount); // decimals == 18 for payout
80 | emit Paid(_receiver, _swapped, amount);
81 | }
82 | return true;
83 | }
84 |
85 | // pullRewardsMulti transfers the funds to the user
86 | function pullRewardsMulti(
87 | address _dest,
88 | address[] memory _receiver,
89 | uint256[] memory _swapped
90 | ) external returns (bool) {
91 | require(
92 | msg.sender == address(swapContract),
93 | "caller is not swap contact"
94 | );
95 | require(_receiver.length == _swapped.length, "array size is not match");
96 | address tokenB = swapContract.BTCT_ADDR();
97 | (uint256 balA, uint256 balB) = swapContract.getFloatReserve(
98 | address(0),
99 | tokenB
100 | );
101 | uint256 threshold = balA.add(balB).mul(thresholdRatio).div(100);
102 | if (
103 | (_dest == tokenB && balB >= threshold) ||
104 | (_dest == address(0) && balA >= threshold)
105 | ) {
106 | for (uint256 i = 0; i < _receiver.length; i++) {
107 | uint256 amount = _swapped[i]
108 | .mul(rebateRate)
109 | .mul(pricePerBTC)
110 | .mul(1e6);
111 | rewardToken.transfer(_receiver[i], amount); // decimals == 18 for payout
112 | emit Paid(_receiver[i], _swapped[i], amount);
113 | }
114 | }
115 | return true;
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/contracts/SwingbyToken.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: AGPL-3.0
2 | pragma solidity ^0.8.0;
3 |
4 | import "./BurnableToken.sol";
5 |
6 | contract SwingbyToken is BurnableToken {
7 | constructor() {
8 | _initialize("SWINGBY token", "SWINGBY", 18, 0, true);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/contracts/interfaces/IAugustusSwapper.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: AGPL-3.0
2 | pragma solidity ^0.8.0;
3 | pragma experimental ABIEncoderV2;
4 |
5 | import "./IERC20.sol";
6 |
7 | interface IAugustusSwapper {
8 |
9 | /**
10 | * @param fromToken Address of the source token
11 | * @param fromAmount Amount of source tokens to be swapped
12 | * @param toAmount Minimum destination token amount expected out of this swap
13 | * @param expectedAmount Expected amount of destination tokens without slippage
14 | * @param beneficiary Beneficiary address
15 | * 0 then 100% will be transferred to beneficiary. Pass 10000 for 100%
16 | * @param referrer referral id
17 | * @param useReduxToken whether to use redux token or not
18 | * @param path Route to be taken for this swap to take place
19 |
20 | */
21 | struct SellData {
22 | address fromToken;
23 | uint256 fromAmount;
24 | uint256 toAmount;
25 | uint256 expectedAmount;
26 | address payable beneficiary;
27 | string referrer;
28 | bool useReduxToken;
29 | Path[] path;
30 |
31 | }
32 |
33 | struct MegaSwapSellData {
34 | address fromToken;
35 | uint256 fromAmount;
36 | uint256 toAmount;
37 | uint256 expectedAmount;
38 | address payable beneficiary;
39 | string referrer;
40 | bool useReduxToken;
41 | MegaSwapPath[] path;
42 | }
43 |
44 | struct BuyData {
45 | address fromToken;
46 | address toToken;
47 | uint256 fromAmount;
48 | uint256 toAmount;
49 | address payable beneficiary;
50 | string referrer;
51 | bool useReduxToken;
52 | BuyRoute[] route;
53 | }
54 |
55 | struct Route {
56 | address payable exchange;
57 | address targetExchange;
58 | uint percent;
59 | bytes payload;
60 | uint256 networkFee;//Network fee is associated with 0xv3 trades
61 | }
62 |
63 | struct MegaSwapPath {
64 | uint256 fromAmountPercent;
65 | Path[] path;
66 | }
67 |
68 | struct Path {
69 | address to;
70 | uint256 totalNetworkFee;//Network fee is associated with 0xv3 trades
71 | Route[] routes;
72 | }
73 |
74 | struct BuyRoute {
75 | address payable exchange;
76 | address targetExchange;
77 | uint256 fromAmount;
78 | uint256 toAmount;
79 | bytes payload;
80 | uint256 networkFee;//Network fee is associated with 0xv3 trades
81 | }
82 |
83 | function getPartnerRegistry() external view returns(address);
84 |
85 | function getWhitelistAddress() external view returns(address);
86 |
87 | function getFeeWallet() external view returns(address);
88 |
89 | function getTokenTransferProxy() external view returns (address);
90 |
91 | function getUniswapProxy() external view returns(address);
92 |
93 | function getVersion() external view returns(string memory);
94 |
95 | /**
96 | * @dev The function which performs the multi path swap.
97 | */
98 | function multiSwap(
99 | SellData calldata data
100 | )
101 | external
102 | payable
103 | returns (uint256);
104 |
105 | /**
106 | * @dev The function which performs the single path buy.
107 | */
108 | function buy(
109 | BuyData calldata data
110 | )
111 | external
112 | payable
113 | returns (uint256);
114 |
115 | function swapOnUniswap(
116 | uint256 amountIn,
117 | uint256 amountOutMin,
118 | address[] calldata path,
119 | uint8 referrer
120 | )
121 | external
122 | payable;
123 |
124 | function buyOnUniswap(
125 | uint256 amountInMax,
126 | uint256 amountOut,
127 | address[] calldata path,
128 | uint8 referrer
129 | )
130 | external
131 | payable;
132 |
133 | function buyOnUniswapFork(
134 | address factory,
135 | bytes32 initCode,
136 | uint256 amountInMax,
137 | uint256 amountOut,
138 | address[] calldata path,
139 | uint8 referrer
140 | )
141 | external
142 | payable;
143 |
144 | function swapOnUniswapFork(
145 | address factory,
146 | bytes32 initCode,
147 | uint256 amountIn,
148 | uint256 amountOutMin,
149 | address[] calldata path,
150 | uint8 referrer
151 | )
152 | external
153 | payable;
154 |
155 |
156 | function simplBuy(
157 | address fromToken,
158 | address toToken,
159 | uint256 fromAmount,
160 | uint256 toAmount,
161 | address[] memory callees,
162 | bytes memory exchangeData,
163 | uint256[] memory startIndexes,
164 | uint256[] memory values,
165 | address payable beneficiary,
166 | string memory referrer,
167 | bool useReduxToken
168 | )
169 | external
170 | payable;
171 |
172 | function simpleSwap(
173 | address fromToken,
174 | address toToken,
175 | uint256 fromAmount,
176 | uint256 toAmount,
177 | uint256 expectedAmount,
178 | address[] memory callees,
179 | bytes memory exchangeData,
180 | uint256[] memory startIndexes,
181 | uint256[] memory values,
182 | address payable beneficiary,
183 | string memory referrer,
184 | bool useReduxToken
185 | )
186 | external
187 | payable
188 | returns (uint256 receivedAmount);
189 |
190 | /**
191 | * @dev The function which performs the mega path swap.
192 | * @param data Data required to perform swap.
193 | */
194 | function megaSwap(
195 | MegaSwapSellData memory data
196 | )
197 | external
198 | payable
199 | returns (uint256);
200 | }
--------------------------------------------------------------------------------
/contracts/interfaces/IBarn.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 | pragma solidity ^0.8.0;
3 | pragma experimental ABIEncoderV2;
4 |
5 | interface IBarn {
6 | // balanceOf returns the current BOND balance of a user (bonus not included)
7 | function balanceOf(address user) external view returns (uint256);
8 |
9 | // balanceAtTs returns the amount of BOND that the user currently staked (bonus NOT included)
10 | function balanceAtTs(
11 | address user,
12 | uint256 timestamp
13 | ) external view returns (uint256);
14 | }
15 |
--------------------------------------------------------------------------------
/contracts/interfaces/IBurnableToken.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: AGPL-3.0
2 | pragma solidity ^0.8.0;
3 |
4 | import "./IERC20.sol";
5 |
6 | interface IBurnableToken is IERC20 {
7 | function mint(address target, uint256 amount) external returns (bool);
8 |
9 | function burn(uint256 amount) external returns (bool);
10 |
11 | function mintable() external returns (bool);
12 | }
13 |
--------------------------------------------------------------------------------
/contracts/interfaces/IERC20.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: AGPL-3.0
2 | pragma solidity ^0.8.0;
3 |
4 | interface IERC20 {
5 | /**
6 | * @dev Returns the amount of tokens in existence.
7 | */
8 | function totalSupply() external view returns (uint256);
9 |
10 | /**
11 | * @dev Returns the token decimals.
12 | */
13 | function decimals() external view returns (uint8);
14 |
15 | /**
16 | * @dev Returns the token symbol.
17 | */
18 | function symbol() external view returns (string memory);
19 |
20 | /**
21 | * @dev Returns the token name.
22 | */
23 | function name() external view returns (string memory);
24 |
25 | /**
26 | * @dev Returns the bep token owner. (This is a BEP-20 token specific.)
27 | */
28 | function getOwner() external view returns (address);
29 |
30 | /**
31 | * @dev Returns the amount of tokens owned by `account`.
32 | */
33 | function balanceOf(address account) external view returns (uint256);
34 |
35 | /**
36 | * @dev Moves `amount` tokens from the caller's account to `recipient`.
37 | *
38 | * Returns a boolean value indicating whether the operation succeeded.
39 | *
40 | * Emits a {Transfer} event.
41 | */
42 | function transfer(address recipient, uint256 amount)
43 | external
44 | returns (bool);
45 |
46 | /**
47 | * @dev Returns the remaining number of tokens that `spender` will be
48 | * allowed to spend on behalf of `owner` through {transferFrom}. This is
49 | * zero by default.
50 | *
51 | * This value changes when {approve} or {transferFrom} are called.
52 | */
53 | function allowance(address _owner, address spender)
54 | external
55 | view
56 | returns (uint256);
57 |
58 | /**
59 | * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
60 | *
61 | * Returns a boolean value indicating whether the operation succeeded.
62 | *
63 | * IMPORTANT: Beware that changing an allowance with this method brings the risk
64 | * that someone may use both the old and the new allowance by unfortunate
65 | * transaction ordering. One possible solution to mitigate this race
66 | * condition is to first reduce the spender's allowance to 0 and set the
67 | * desired value afterwards:
68 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
69 | *
70 | * Emits an {Approval} event.
71 | */
72 | function approve(address spender, uint256 amount) external returns (bool);
73 |
74 | /**
75 | * @dev Moves `amount` tokens from `sender` to `recipient` using the
76 | * allowance mechanism. `amount` is then deducted from the caller's
77 | * allowance.
78 | *
79 | * Returns a boolean value indicating whether the operation succeeded.
80 | *
81 | * Emits a {Transfer} event.
82 | */
83 | function transferFrom(
84 | address sender,
85 | address recipient,
86 | uint256 amount
87 | ) external returns (bool);
88 |
89 | /**
90 | * @dev Emitted when `value` tokens are moved from one account (`from`) to
91 | * another (`to`).
92 | *
93 | * Note that `value` may be zero.
94 | */
95 | event Transfer(address indexed from, address indexed to, uint256 value);
96 |
97 | /**
98 | * @dev Emitted when the allowance of a `spender` for an `owner` is set by
99 | * a call to {approve}. `value` is the new allowance.
100 | */
101 | event Approval(
102 | address indexed owner,
103 | address indexed spender,
104 | uint256 value
105 | );
106 | }
107 |
--------------------------------------------------------------------------------
/contracts/interfaces/IParams.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: AGPL-3.0
2 | pragma solidity ^0.8.0;
3 | pragma experimental ABIEncoderV2;
4 |
5 | interface IParams {
6 |
7 | function minimumSwapAmountForWBTC() external view returns (uint256);
8 | function expirationTime() external view returns (uint256);
9 | function paraswapAddress() external view returns (address);
10 | function nodeRewardsRatio() external view returns (uint8);
11 | function depositFeesBPS() external view returns (uint8);
12 | function withdrawalFeeBPS() external view returns (uint8);
13 | function loopCount() external view returns (uint8);
14 |
15 | function setMinimumSwapAmountForWBTC(uint256 _minimumSwapAmountForWBTC) external;
16 |
17 | function setExpirationTime(uint256 _expirationTime) external;
18 |
19 | function setParaswapAddress(address _paraswapAddress) external;
20 |
21 | function setNodeRewardsRatio(uint8 _nodeRewardsRatio) external;
22 |
23 | function setWithdrawalFeeBPS(uint8 _withdrawalFeeBPS) external;
24 |
25 | function setDepositFeesBPS(uint8 _depositFeesBPS) external;
26 |
27 | function setLoopCount(uint8 _loopCount) external;
28 | }
29 |
30 |
--------------------------------------------------------------------------------
/contracts/interfaces/IParaswap.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: AGPL-3.0
2 |
3 | pragma solidity ^0.8.0;
4 | pragma experimental ABIEncoderV2;
5 |
6 | import "./lib/Utils.sol";
7 | import "./IERC20.sol";
8 |
9 | interface IParaswap {
10 | function multiSwap(
11 | Utils.SellData calldata data
12 | ) external payable returns (uint256);
13 |
14 | function megaSwap(
15 | Utils.MegaSwapSellData calldata data
16 | ) external payable returns (uint256);
17 |
18 | function protectedMultiSwap(
19 | Utils.SellData calldata data
20 | ) external payable returns (uint256);
21 |
22 | function protectedMegaSwap(
23 | Utils.MegaSwapSellData calldata data
24 | ) external payable returns (uint256);
25 |
26 | function protectedSimpleSwap(
27 | Utils.SimpleData calldata data
28 | ) external payable returns (uint256 receivedAmount);
29 |
30 | function protectedSimpleBuy(
31 | Utils.SimpleData calldata data
32 | ) external payable;
33 |
34 | function simpleSwap(
35 | Utils.SimpleData calldata data
36 | ) external payable returns (uint256 receivedAmount);
37 |
38 | function simpleBuy(Utils.SimpleData calldata data) external payable;
39 |
40 | function swapOnUniswap(
41 | uint256 amountIn,
42 | uint256 amountOutMin,
43 | address[] calldata path
44 | ) external payable;
45 |
46 | function swapOnUniswapFork(
47 | address factory,
48 | bytes32 initCode,
49 | uint256 amountIn,
50 | uint256 amountOutMin,
51 | address[] calldata path
52 | ) external payable;
53 |
54 | function buyOnUniswap(
55 | uint256 amountInMax,
56 | uint256 amountOut,
57 | address[] calldata path
58 | ) external payable;
59 |
60 | function buyOnUniswapFork(
61 | address factory,
62 | bytes32 initCode,
63 | uint256 amountInMax,
64 | uint256 amountOut,
65 | address[] calldata path
66 | ) external payable;
67 |
68 | function swapOnUniswapV2Fork(
69 | address tokenIn,
70 | uint256 amountIn,
71 | uint256 amountOutMin,
72 | address weth,
73 | uint256[] calldata pools
74 | ) external payable;
75 |
76 | function buyOnUniswapV2Fork(
77 | address tokenIn,
78 | uint256 amountInMax,
79 | uint256 amountOut,
80 | address weth,
81 | uint256[] calldata pools
82 | ) external payable;
83 |
84 | function swapOnZeroXv2(
85 | IERC20 fromToken,
86 | IERC20 toToken,
87 | uint256 fromAmount,
88 | uint256 amountOutMin,
89 | address exchange,
90 | bytes calldata payload
91 | ) external payable;
92 |
93 | function swapOnZeroXv4(
94 | IERC20 fromToken,
95 | IERC20 toToken,
96 | uint256 fromAmount,
97 | uint256 amountOutMin,
98 | address exchange,
99 | bytes calldata payload
100 | ) external payable;
101 | }
102 |
--------------------------------------------------------------------------------
/contracts/interfaces/ISwapContract.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: AGPL-3.0
2 | pragma solidity ^0.8.0;
3 | pragma experimental ABIEncoderV2;
4 |
5 | import "./IBurnableToken.sol";
6 |
7 | interface ISwapContract {
8 | function BTCT_ADDR() external returns (address);
9 |
10 | function lpToken() external returns (IBurnableToken);
11 |
12 | function singleTransferERC20(
13 | address _destToken,
14 | address _to,
15 | uint256 _amount,
16 | uint256 _totalSwapped,
17 | uint256 _rewardsAmount,
18 | bytes32[] memory _redeemedFloatTxIds
19 | ) external returns (bool);
20 |
21 | function multiTransferERC20TightlyPacked(
22 | address _destToken,
23 | bytes32[] memory _addressesAndAmounts,
24 | uint256 _totalSwapped,
25 | uint256 _rewardsAmount,
26 | bytes32[] memory _redeemedFloatTxIds
27 | ) external returns (bool);
28 |
29 | function collectSwapFeesForBTC(
30 | uint256 _incomingAmount,
31 | uint256 _minerFee,
32 | uint256 _rewardsAmount,
33 | address[] memory _spenders,
34 | uint256[] memory _swapAmounts
35 | ) external returns (bool);
36 |
37 | function recordIncomingFloat(
38 | address _token,
39 | bytes32 _addressesAndAmountOfFloat,
40 | bytes32 _txid
41 | ) external returns (bool);
42 |
43 | function recordOutcomingFloat(
44 | address _token,
45 | bytes32 _addressesAndAmountOfLPtoken,
46 | uint256 _minerFee,
47 | bytes32 _txid
48 | ) external returns (bool);
49 |
50 | function recordUTXOSweepMinerFee(
51 | uint256 _minerFee,
52 | bytes32 _txid
53 | ) external returns (bool);
54 |
55 | function churn(
56 | address _newOwner,
57 | address[] memory _nodes,
58 | bool[] memory _isRemoved,
59 | uint8 _churnedInCount,
60 | uint8 _tssThreshold
61 | ) external returns (bool);
62 |
63 | function updateParams(
64 | address _sbBTCPool,
65 | address _buybackAddress,
66 | uint256 _withdrawalFeeBPS,
67 | uint256 _nodeRewardsRatio,
68 | uint256 _buybackRewardsRatio
69 | ) external returns (bool);
70 |
71 | function isTxUsed(bytes32 _txid) external view returns (bool);
72 |
73 | function getCurrentPriceLP() external view returns (uint256);
74 |
75 | function getFloatReserve(
76 | address _tokenA,
77 | address _tokenB
78 | ) external returns (uint256 reserveA, uint256 reserveB);
79 |
80 | function getActiveNodes() external view returns (address[] memory);
81 |
82 | function isNodeStake(address _user) external returns (bool);
83 | }
84 |
--------------------------------------------------------------------------------
/contracts/interfaces/ISwapRewards.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: AGPL-3.0
2 | pragma solidity ^0.8.0;
3 |
4 | interface ISwapRewards {
5 |
6 | function setSWINGBYPrice(uint256 _pricePerBTC) external;
7 |
8 | function pullRewards(address _dest, address _receiver, uint256 _swapped) external returns (bool);
9 |
10 | function pullRewardsMulti(address _dest, address[] memory _receiver, uint256[] memory _swapped) external returns (bool);
11 | }
12 |
--------------------------------------------------------------------------------
/contracts/interfaces/ITokenTransferProxy.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: AGPL-3.0
2 |
3 | pragma solidity ^0.8.0;
4 |
5 |
6 | interface ITokenTransferProxy {
7 |
8 | function transferFrom(
9 | address token,
10 | address from,
11 | address to,
12 | uint256 amount
13 | )
14 | external;
15 |
16 | function freeReduxTokens(address user, uint256 tokensToFree) external;
17 | }
--------------------------------------------------------------------------------
/contracts/interfaces/IWETH.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: AGPL-3.0
2 |
3 | pragma solidity ^0.8.0;
4 |
5 | interface IWETH {
6 | function deposit() external payable;
7 |
8 | function transfer(address to, uint256 value) external returns (bool);
9 |
10 | function withdraw(uint256) external;
11 |
12 | function approve(address spender, uint256 amount) external returns (bool);
13 | }
14 |
--------------------------------------------------------------------------------
/contracts/interfaces/lib/SafeERC20.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: AGPL-3.0
2 |
3 | pragma solidity ^0.8.0;
4 |
5 | import "../IERC20.sol";
6 | import "./Address.sol";
7 |
8 | /**
9 | * @title SafeERC20
10 | * @dev Wrappers around ERC20 operations that throw on failure (when the token
11 | * contract returns false). Tokens that return no value (and instead revert or
12 | * throw on failure) are also supported, non-reverting calls are assumed to be
13 | * successful.
14 | * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
15 | * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
16 | */
17 | library SafeERC20 {
18 | using Address for address;
19 |
20 | function safeTransfer(
21 | IERC20 token,
22 | address to,
23 | uint256 value
24 | ) internal {
25 | _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
26 | }
27 |
28 | function safeTransferFrom(
29 | IERC20 token,
30 | address from,
31 | address to,
32 | uint256 value
33 | ) internal {
34 | _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
35 | }
36 |
37 | /**
38 | * @dev Deprecated. This function has issues similar to the ones found in
39 | * {IERC20-approve}, and its usage is discouraged.
40 | *
41 | * Whenever possible, use {safeIncreaseAllowance} and
42 | * {safeDecreaseAllowance} instead.
43 | */
44 | function safeApprove(
45 | IERC20 token,
46 | address spender,
47 | uint256 value
48 | ) internal {
49 | // safeApprove should only be called when setting an initial allowance,
50 | // or when resetting it to zero. To increase and decrease it, use
51 | // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
52 | require(
53 | (value == 0) || (token.allowance(address(this), spender) == 0),
54 | "SafeERC20: approve from non-zero to non-zero allowance"
55 | );
56 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
57 | }
58 |
59 | function safeIncreaseAllowance(
60 | IERC20 token,
61 | address spender,
62 | uint256 value
63 | ) internal {
64 | uint256 newAllowance = token.allowance(address(this), spender) + value;
65 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
66 | }
67 |
68 |
69 |
70 | /**
71 | * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
72 | * on the return value: the return value is optional (but if data is returned, it must not be false).
73 | * @param token The token targeted by the call.
74 | * @param data The call data (encoded using abi.encode or one of its variants).
75 | */
76 | function _callOptionalReturn(IERC20 token, bytes memory data) private {
77 | // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
78 | // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
79 | // the target address contains contract code and also asserts for success in the low-level call.
80 |
81 | bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
82 | if (returndata.length > 0) {
83 | // Return data is optional
84 | require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
85 | }
86 | }
87 | }
--------------------------------------------------------------------------------
/contracts/interfaces/lib/Utils.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: AGPL-3.0
2 |
3 | pragma solidity ^0.8.0;
4 |
5 | library Utils {
6 | /**
7 | * @param fromToken Address of the source token
8 | * @param fromAmount Amount of source tokens to be swapped
9 | * @param toAmount Minimum destination token amount expected out of this swap
10 | * @param expectedAmount Expected amount of destination tokens without slippage
11 | * @param beneficiary Beneficiary address
12 | * 0 then 100% will be transferred to beneficiary. Pass 10000 for 100%
13 | * @param path Route to be taken for this swap to take place
14 |
15 | */
16 | struct SellData {
17 | address fromToken;
18 | uint256 fromAmount;
19 | uint256 toAmount;
20 | uint256 expectedAmount;
21 | address payable beneficiary;
22 | Utils.Path[] path;
23 | address payable partner;
24 | uint256 feePercent;
25 | bytes permit;
26 | uint256 deadline;
27 | bytes16 uuid;
28 | }
29 |
30 | struct MegaSwapSellData {
31 | address fromToken;
32 | uint256 fromAmount;
33 | uint256 toAmount;
34 | uint256 expectedAmount;
35 | address payable beneficiary;
36 | Utils.MegaSwapPath[] path;
37 | address payable partner;
38 | uint256 feePercent;
39 | bytes permit;
40 | uint256 deadline;
41 | bytes16 uuid;
42 | }
43 |
44 | struct SimpleData {
45 | address fromToken;
46 | address toToken;
47 | uint256 fromAmount;
48 | uint256 toAmount;
49 | uint256 expectedAmount;
50 | address[] callees;
51 | bytes exchangeData;
52 | uint256[] startIndexes;
53 | uint256[] values;
54 | address payable beneficiary;
55 | address payable partner;
56 | uint256 feePercent;
57 | bytes permit;
58 | uint256 deadline;
59 | bytes16 uuid;
60 | }
61 |
62 | struct Adapter {
63 | address payable adapter;
64 | uint256 percent;
65 | uint256 networkFee;
66 | Route[] route;
67 | }
68 |
69 | struct Route {
70 | uint256 index;//Adapter at which index needs to be used
71 | address targetExchange;
72 | uint percent;
73 | bytes payload;
74 | uint256 networkFee;//Network fee is associated with 0xv3 trades
75 | }
76 |
77 | struct MegaSwapPath {
78 | uint256 fromAmountPercent;
79 | Path[] path;
80 | }
81 |
82 | struct Path {
83 | address to;
84 | uint256 totalNetworkFee;//Network fee is associated with 0xv3 trades
85 | Adapter[] adapters;
86 | }
87 | }
--------------------------------------------------------------------------------
/contracts/sbBTCPool.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 | pragma solidity ^0.8.0;
3 |
4 | import "@openzeppelin/contracts/access/Ownable.sol";
5 | import "@openzeppelin/contracts/utils/math/SafeMath.sol";
6 | import "./interfaces/IBarn.sol";
7 | import "./interfaces/ISwapContract.sol";
8 |
9 | contract sbBTCPool is Ownable {
10 | using SafeMath for uint256;
11 |
12 | uint256 constant divisor = 10 ** 27;
13 |
14 | uint256 public balanceBefore;
15 | uint256 public currentMultiplier;
16 | uint256 public totalNodeStaked;
17 |
18 | mapping(address => uint256) public userMultiplier;
19 | mapping(address => uint256) public owed;
20 |
21 | IBarn public barn;
22 | IERC20 public rewardToken;
23 | ISwapContract public swapContract;
24 |
25 | event Claim(address indexed user, uint256 amount);
26 |
27 | // setBarn sets the address of the BarnBridge Barn into the state variable
28 | function setBarnAndSwap(address _barn, address _swap) public {
29 | require(_barn != address(0), "barn address must not be 0x0");
30 | require(_swap != address(0), "swap contract address must not be 0x0");
31 | require(msg.sender == owner(), "!owner");
32 | swapContract = ISwapContract(_swap);
33 | rewardToken = IERC20(swapContract.lpToken());
34 | barn = IBarn(_barn);
35 | }
36 |
37 | // update all node rewards.
38 | function updateAll(uint256 _timestamp) public onlyOwner {
39 | updateStakes(_timestamp);
40 | // Getting rewards
41 | ackFunds();
42 | // Update all distribution.
43 | address[] memory nodes = swapContract.getActiveNodes();
44 | for (uint256 i = 0; i < nodes.length; i++) {
45 | _updateOwed(nodes[i], _timestamp);
46 | }
47 | }
48 |
49 | // check all active nodes to calculate current stakes.
50 | function updateStakes(uint256 _timestamp) internal {
51 | address[] memory nodes = swapContract.getActiveNodes();
52 | uint256 newTotalNodeStaked;
53 | for (uint256 i = 0; i < nodes.length; i++) {
54 | newTotalNodeStaked = newTotalNodeStaked.add(
55 | barn.balanceAtTs(nodes[i], _timestamp)
56 | );
57 | if (userMultiplier[nodes[i]] == 0) {
58 | userMultiplier[nodes[i]] = currentMultiplier;
59 | }
60 | }
61 | // only change when stakers had actions.
62 | if (totalNodeStaked != newTotalNodeStaked) {
63 | totalNodeStaked = newTotalNodeStaked;
64 | }
65 | }
66 |
67 | function resetUnstakedNode(address _node) public {
68 | require(!swapContract.isNodeStake(_node), "node is staker");
69 | userMultiplier[_node] = 0;
70 | }
71 |
72 | // claim calculates the currently owed reward and transfers the funds to the user
73 | function claim() public returns (uint256) {
74 | require(swapContract.isNodeStake(msg.sender), "caller is not node");
75 |
76 | updateStakes(block.timestamp);
77 |
78 | ackFunds();
79 |
80 | _updateOwed(msg.sender, block.timestamp);
81 |
82 | uint256 amount = owed[msg.sender];
83 | require(amount > 0, "nothing to claim");
84 |
85 | owed[msg.sender] = 0;
86 |
87 | rewardToken.transfer(msg.sender, amount);
88 |
89 | // acknowledge the amount that was transferred to the user
90 | ackFunds();
91 |
92 | emit Claim(msg.sender, amount);
93 |
94 | return amount;
95 | }
96 |
97 | // ackFunds checks the difference between the last known balance of `token` and the current one
98 | // if it goes up, the multiplier is re-calculated
99 | // if it goes down, it only updates the known balance
100 | function ackFunds() public {
101 | uint256 balanceNow = rewardToken.balanceOf(address(this));
102 |
103 | if (balanceNow == 0 || balanceNow <= balanceBefore) {
104 | balanceBefore = balanceNow;
105 | return;
106 | }
107 | if (totalNodeStaked == 0) {
108 | return;
109 | }
110 |
111 | uint256 diff = balanceNow.sub(balanceBefore);
112 | uint256 multiplier = currentMultiplier.add(
113 | diff.mul(divisor).div(totalNodeStaked)
114 | );
115 |
116 | balanceBefore = balanceNow;
117 | currentMultiplier = multiplier;
118 | }
119 |
120 | function emergencyWithdraw() public {
121 | require(msg.sender == owner(), "!owner");
122 | rewardToken.transfer(msg.sender, rewardToken.balanceOf(address(this)));
123 | swapContract = ISwapContract(address(0));
124 | }
125 |
126 | // _updateOwed calculates and updates the total amount that is owed to an user and updates the user's multiplier
127 | // to the current value
128 | // it automatically attempts to pull the token from the source and acknowledge the funds
129 | function _updateOwed(address user, uint256 timestamp) internal {
130 | uint256 reward = _userPendingReward(user, timestamp);
131 | owed[user] = owed[user].add(reward);
132 | userMultiplier[user] = currentMultiplier;
133 | }
134 |
135 | // _userPendingReward calculates the reward that should be based on the current multiplier / anything that's not included in the `owed[user]` value
136 | // it does not represent the entire reward that's due to the user unless added on top of `owed[user]`
137 | function _userPendingReward(
138 | address user,
139 | uint256 timestamp
140 | ) internal view returns (uint256) {
141 | uint256 multiplier = currentMultiplier.sub(userMultiplier[user]);
142 | return barn.balanceAtTs(user, timestamp).mul(multiplier).div(divisor);
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/docs/Diagrams/SkyPools Diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SwingbyProtocol/skybridge-contract/48b50cf9c1bc6abe6d5744c90d7b4f7def1d8f54/docs/Diagrams/SkyPools Diagram.png
--------------------------------------------------------------------------------
/docs/Diagrams/SkypoolsDiagram.drawio:
--------------------------------------------------------------------------------
1 | 7Z3bcuK4FoafJlXTF+nyOeSSQ5hJNR2oQPqwb1LCVsATYzGyCKSffku2bIxlTmmINBPRXRW8LAsjfVpa+iWLC7s9W/2JwXz6FQUwurCMYHVhdy4sy/auHfqHWV4zi+VZ3DLBYZDZzLVhGP6C3Ghw6yIMYLKRkCAUkXC+afRRHEOfbNgAxmi5mewJRZufOgcTKBiGPohE6/cwINPM2nCNtf0vGE6m+SebBj8zA3libkimIEDLksm+ubDbGCGSvZut2jBipZeXS3Zdd8vZ4sYwjMkhF3yb/bp7mT6YgfM/d/krdm8D/8slz+UFRAv+hS8sL6L5tZ4QzZbeNXnlReH9s0D5icskragmTWA25qv1Sfpuwv4Ol2DepgkxoHXCc6S3lmWaJeGlUuRvJctwFoGYHrWmZBZRo8k/bsgTsWMQhZOYvvfp14aYGl4gJiGtsCY/QdCcWv1pGAU98IoWrHASAvzn/Kg1RTj8RbMF+WfQ05hw9qzGRoohu5KaDWrFkH3tQV7iZmHqgYTwND6KIjBPwnFxwzOAJ2HcQoSgGU+Uf9NuGEVtFCGcFoD9lL5YrmgRBzDIU+fgZPnPQp+/j8AYRi16f5P0gjynGKVlmBCMngto06KsfJzL/vEi7oJZGLFG+g3iAMQgL/msUEyryLCUgZe+eMqSPXsVVcwqCK62UmsWbYF6EYhmkOBXmoRfYDV48+EOJD9crhuj63HbtNwQHcPjXoB7gEmR97qR0De8naSHaPw38yGWkZZsdlmnOWpmGe1sSFbpW/CGV492lee3g+odD2pm+gpWGwmPxbcMRmMHV2cCZrsjEynKu53GYdS4ubM+Ahp6yLk5wu/agt8FQUBrI2HfdTGOaBu3jNaoPXpsdjr3gqukxUOEAubtvlwb3JT7zAg+ka0eM5kDP4wnvTRNx1lb7nn5MBOi1z5FqTeahkEA49RbEUBARgzDY47CmKTl57bof1qibeOze+HSG2/TY3N9TP+z5JiyENPvAsK0iiHFcQkTUtNYKtwY9NXtVoj0fosjazdH3mEcWcf7nsO4cQ7hJpoTikWsqVGEGteSTI0rUDMD8zmtpD/W9GQxHo/MjDGNsT+VmVpOQwKjkJavpkoNqq4O7NPORpUnULWghdYoU+NPFziGwW3cpgGqRkcVdEzDkczO1X52SJKMptQ5TdmQXZOjCDn2geOvs5HT2E9OjAJ4D5cAB8k9ICHS9KhCjys7fr7eT08A5ygJSRfCpDUYanZUYachO4rOJeld8CxDMg0wWKKI8qPxUQcfy5AdLpui1s7wsZhPLI3dkf8Mg95gxEbwSRfhO9qZaYpUociWHTib1iEUPdHOSzOkKEOe7BDaFNXnGobCOCQhiG5W/hTEE0gjac2QMgw1ZAfSpqhElxjC4UuKC5uWZ98+m1DX9NTS024zft6RHjvvROTRIyrSdfRE8w70wxmIEs2OKuzY0uNoUXfeN5vB2fq0ARetRECaMyZM9580X6rw5UmPsEVtOudr/EpgYlsCX8VsWQHXIoFatFaGqWvpEbeoWu+dgc1Y28SKKdu6L1SFK8eUHoWLevbBM/sFVGFyG/f0zL5CXDmy43NLlLpznlhpdwSn1KRntWNSBiBPdpBuiWL3Psd0aBC/sSwpXeimwdsBXrv9nuBdy47eLVEf79/1flJL//vdzT392324a49u+3dD+v6P4Zefrfvbzp83DDf6wZYxGg4/CTz9d9dve5UW8ab124bheamDeztXu9dvu86hDi2foDk9WKJontDGH8ERBnHyBPHNfbt41OdjeqI6Iuo81Ik80b5pFtmeSFTIZ4uIhBu8jNiNRK8DwGZ9NTyqwCN9xbYlCuTMtUOfsCfr2NqkLsKtUVsjowoy0pdjW6IujqGPcHAbs4cG40mXCd4aGFWAkb8I2xKV7oyY/oJoZFRERvrqa0sUsjNkHkY/+sMlhPOvYQwx7aA0NcpQI33VtSXK1OmTQZoRZRiRvrraFiXnzLMMn18HCEXJ6IfG5aJG1pMyuJa+mtoWBebBQ6t3295U+LSOd5yOx9cxvh2c3Tre1cFupnE2cESB2E+b3cIntBw+sovZ5UpOT4q9Z8sO2UGLLQq+YTJaPeiVPQpRIl2os0WVdwJJe4HZ9xrg0Ie9gcZFFVyki3S2qOtSXDrFI6f6KQuVcJEv0dmiqEt5SWW5e5hA/KJpUYcW6eqcLQq6lJamT8IXeKeXjioFi3RRzhal3DGgg2MffvDHId5XadnHiXxhThRvAzQAGLCZaA2KKqDIl+QcUcENkHkb+9MRBh/8AXS1UJG+i4EjqrcYBhDOlnpNi0qgSN+qIH8SogTKLdv3Owbs0u4iprEtqlkAroX+nUK/d9VsXZ9T6DeNQx9BKB4oPj07ooD7GCbJApZ2RtELXI4YFZ2AGmfPvKLsQZEjyrmP4wWONTKqIiN9BsARJd1Hfwr9527EfqREg6IIKNK1f0fUch9BEGh/ohQm8jV/R1RxHzGc0YrRqKiFinTB3xE13Mfko8tyajEiXed3RP32MQFPxXOLmhVlWJGu9buihEu7nnQn9Xb2+FmIPvaqbaWAka/5u6KQy2JatkhutNKgKAOKdMU/H6bXgqJHyeqQIl3yd2tkW0qK3sNaKUykb0Ds1ii1yTwKyQh9YybtU5SBRf5+w66o0X65+SkQ8t+aNRR+KbkEgmVUoH+H323dPWPYqOl4rDpIzKuzUSIKtHdwyeaZ2YNBRv4g4mGOZaPYthW0qt6Dewt3izepW6Twdu+RNc5j5gRrucjFuNNjIeqxg3z/uWzPMBrFMkC6ad1pPE67kHYPHjX62jvjIWqwg3xvTE2CuAnm2UioCUnfmQRRaUVx9NpfxoeqrB+EhRPsF7iHBbNma+b3hcETpdSalWsai9OORPZh4UjHQhRMLywvykvrgv1kTl4g3j8LRNLisH0/9Z4lU7Yvbmn/0iwTelNZPvm+uRW+MFrEAQx4BaS/6j2knLCzSwzYkHZKZtGFMHK0jbpmnP/skTh6FgAu/H925juvgN8dPfAL7HzDPF7Rlw1xNOE0airaO1tFi4KnON6cgjl7+xTBVRNj1i5bMA74244fgSShYSYfUIrm+qoya6qqCNPhKiQ/WKLPhuXy45+s5X92bI8fd/JxZ3rwWjoYQBzS4mGjyU7NCLJSx9t7fxhM4LE1XapJ06gbF+ZGDCPAnnjb+IC6+uWfMWAOb41S/hhDTpLT+HztGcUrn07NM0zQAvuQ57FmRsjWNiuEuhXyaBVPIBEySuEriuE3eBRl1Vav3/7S/qt5e7eVTH8xhvv9xDhzKr1xYQD+8yR1Nf0FicI4d/gBwM991i2RlKrPhrtptFJrhWfLrfUaNU7nBI7k0mxU6t+0aoSJWgCds/kSUes8pNPgYVbJVKri3MgyuEzSkm7SBLYxX4ndzF2/U/QwY7zuXLZZ9vVCOV6LWdRMt11Z66s9MIbRgD0Oz8IjuzPmktYWAbZEIcpQo8FIDP1cKat4qCLyFDxUcSaq3EAhn+3S0+yDo9l9+FXcj+2I9JlXdRHLtXsu+kTxtELfG6l6GLIN2VUj5u31f0h4VLbXMHiMWrKbJNOwNknyDPkkiQLrO8VEZ6kflaMYs8go18kald7p0MClYVY6ROuwwIVWDXgtJePjyu13XAU273jXxGVZnjYsEsVdFZDc3j1t69DUR/LS2tK1HR1KV0fn5w6dRYX3nRix3DpG9oYw/15G3E1EnKs3ImJdVTq/9x5tiVKwVGT29mjb+kD1kWlUmGm8taMzjUpPd2W7J4KGHmLEYt91cjqInn5FAWQp/g8=
--------------------------------------------------------------------------------
/docs/Diagrams/SkypoolsVisual.drawio:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SwingbyProtocol/skybridge-contract/48b50cf9c1bc6abe6d5744c90d7b4f7def1d8f54/docs/Diagrams/SkypoolsVisual.drawio
--------------------------------------------------------------------------------
/docs/Diagrams/SkypoolsVisual_Flow 1.drawio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SwingbyProtocol/skybridge-contract/48b50cf9c1bc6abe6d5744c90d7b4f7def1d8f54/docs/Diagrams/SkypoolsVisual_Flow 1.drawio.png
--------------------------------------------------------------------------------
/docs/Diagrams/SkypoolsVisual_Flow 1.drawio.xml:
--------------------------------------------------------------------------------
1 |
2 | 3Zpdc6M2FIZ/DdPuRTJ8m1wmdrLtTHaTSdrZbm86MgijiYwYIa/t/voegfgU1M5ucNxeGR0JGd7z6PAK23Dm691HjrLkE4swNWwz2hnOwrBtywo8+JCRfRnxHRVYcRKpQU3gmfyNVdBU0Q2JcN4ZKBijgmTdYMjSFIeiE0Ocs213WMxo91sztMJa4DlEVI9+IZFIymjgmU38F0xWSfXNlql61qgarAJ5giK2bYWcW8OZc8ZEebTezTGV4lW6lOfdjfTWF8ZxKo45ASef7p7ugh37TK8vPv719Of91r5Qs3xDdKNu+Plln4HAOUSf14gL+JyzVHAE4pb3IfaVOJxt0gjL+S3DudkmRODnDIWydws4QCwRa6q61TdhLvBu9BasWhggCrM1FnwPQ9QJjq+0VDA5M9XeNqmxKr2TdlquVBApHFb13I1icKBEe4WAzpCAS0AZsDo3uWz3SLn8qdRyNbU+M7m8+0rBWsnkYbinBCTjzmG9lqW498s6gMKXVSH5w0bANFjF87LGWN7biFwLWDF5dSyTzlQqe5rKv+eYj4q8WdPrUDAOekglCBS/e7TE9JHlRBCWwpAlE4KtWwOuKVnJDsF6aWCl1vO6HJtvI7Pfl3lo6ZtDMs+mktnSi+cj4ijfAppDxdP8NRWYxxLgc6sMvnUstPZkauqV9O7+4QtE4J6v4ePmN5jYvDBsH62lIitRaGFuxzpun+YX8nLNn1kmOUb0gyY8SCi66iJFdohltgaQX5MokqffcAylBC2LqSTlGSOpKGTxbgxvIefaCFaVG1l5BGcvsDSoXGuLlMmSdBMTSnuhclxlN1w5CCBS3siaVW11F9Yb8FC5tH1VmjwNh3rBtXGYrIRZeg2zRgtYTPHuWno9UAankTpchBTlOQm76W1WmtnV1faKs+Hi/1BDi8bXdmOxU+eVrX01SyuFhu1ECAdxqOUbevwwwMu4XsI40rxnL2FgdhFfYXHIgOiJbWXOG0hcFeOYIkG+dS9jKJvqGx4l462qbHXriGv2gMjZhodYndU2pwcmcvoTlTpoExVw1bf9A7z5Gm/2xLwVHO2IkLiZl55q1bzBcYObbIzR5uEgcodoC+yl4/uvoq1M17nSVlurirZ++TmWttoIVxNZp6Wteoh2qlvxkFvgTLqu+nGH0khOloIRQwLLDJXuQrDmyScSgGyVyM7Rrcc7PufadW+sUrafb29kGD2zm+MBW24HA6xOZnBs3S7aZdJvdzjcjGW3JABRysKSAAHapnk1alM4exNcugRB9odju/X3ZaCuRmP1axIGer5mwOY6QzZ3OghsDQLnEtrlBs0MUVpcnUgijrYNBA9PPThQyiDbvMJBmlyZd5JucDXE/VA74nSZZ7WiZ0NE5C99b4CIOI7tcKqq0PMZ9Sa8TYRzUiL0fY/bLwtZs60czr5kBJwISVctInJcPPMiwmEnTvftivGTrB9bKCr43MrElT9z0AAU2IJCMZsIit67BcsbgGJo+zMdFPqLslPa0cqAfu1Y02E7KhuPmBO4ccnG+1tUJd3BjdMIE/8xK+v2rKwTnNjK6ht194Skmpeu67a3TpemefVqXuttP0zndbb+FyZMODuw/y9aB9ZAXb/GK94broFjXx5YZ7UI/P427HsXgX/itwe2/vbgFItgSsQOouO9Jzlu0Et4v+od/d7JPlCHpyZnppFzenBqwz1u0f+v4Lj9X4e+94Wl2/eCU4MTaOA4GjkyX8VPedP5+T5axpgdV3/QUJMZtXduI/QvS2TUvMMT2rKCqx+joxrC4jjHr8wXNJs/cZTDm7/COLf/AA==
--------------------------------------------------------------------------------
/docs/Diagrams/SkypoolsVisual_Flow 2.drawio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SwingbyProtocol/skybridge-contract/48b50cf9c1bc6abe6d5744c90d7b4f7def1d8f54/docs/Diagrams/SkypoolsVisual_Flow 2.drawio.png
--------------------------------------------------------------------------------
/docs/Diagrams/SkypoolsVisual_Flow 2.drawio.xml:
--------------------------------------------------------------------------------
1 |
2 | 3Zphc6I4GMc/jS/bASKIL1tt926mu+vU3uzuvbmJEDVTJE6Iq96nvyckIITQulVs93xRyEMS5P//5UlI7aHRaveJ4/XyM4tJ0vOceNdD457nuW7ow0FG9irih6EKLDiNdaVDYEr/JTro6OiGxiSrVRSMJYKu68GIpSmJRC2GOWfberU5S+p3XeMFaQSmEU6a0W80FksVDX3nEP+D0MWyuLPr6CsrXFTWgWyJY7athNBdD404Y0KdrXYjkkjxCl1Uu/uWq+UX4yQVxzQgy8/3j/fhjn1Jbq4+/fP498PWu9K9/MTJRj/w9Hm/BoEziE5XmAs4jlgqOAZx1XOIfSEOZ5s0JrJ/t4dut0sqyHSNI3l1CzhAbClWib6s70S4ILvWR3BLYYAowlZE8D1UKRoMBqqJhqlfULI9WOMWei+rtgx1EGscFmXfB8XgRIv2CwIim4AzQBmw+mhyeeGRcgVdqdVvqPWFyeFtKgVjZS1Po31CQTKOXtdrpsR9mJUBHD0vcsm/bgR0Q3Q8UznG9c8jct8zRPaOZRJ1pbLfUPmvjPBWkTer5CYSjIMeUgkKye8Bz0gyYRkVlKVQZcaEYKtKhZuELuQFwQwbmNJ6VKZj50wyoyOGvmOTedCVzG4zeU4wx9kW0LQlT+fPVBA+lwB/tMwQ+MdC63WmZjOT3j98/QYReI4bONw9jq7k3Z2rnhfglRRlIXI5nO3t08h6IY8bWoNqoi4o1jBHRBpkoXxF41g2v+UEsgee5V1JsNeMpiJXwr/t+WPZ10awIsPIZCM4e4bRkMjhNU6ZzEK3c5okRkjVK1YYfVkJuNHLIXdQlPVTuOdAoEg/+6LsNxAoJ4wqAp2lrQKtCgGusn5M1jIXVSF4ArnSj+Rtz0NBFJLZ3DAY4jEm4TwyPD1TXvS9uo1Dy0BGFhc7G8deMysWA3hHoo2A5OdU0qRgh/GL0xj+chIxLk/WJI1pupCLe84yuSCNlpim0vG87YfyPvRmKAgs3vskjM3x3JH3rmVORLYs3p35XsN8pMyf0OgZDpt1zdin76XtpKSjSkaKYQnyk3y8VC6tDWaBb7F8Pp970YWGezm2q1k7uKjlzXm7ryyfktxYw0Llq1jKwMa2LH1fU4fBAGGLqcSFkTy4kKm21Zh/UVOHlqm47f1hnpDdjdxqATXAcn06jhKcZTSqW3lY6Dp1LT1ZJjsqvutr8vyHPL9GxkdfHO8qNcf7SmFCOAUdJCrqNi3TcfsErp6VxI29IcNS0INteERekNK3W1+x1uZsEeMkwfnoqd7TZre+w0QCfyALGW9NvmMQo76+blXdPDI68obG61cwqHckMF8Q0egop6987BO2WWyriv8NkMUaoX1VcSyQ7wWa+XoOoF0H1Q86D3e+416Wu+bsdgJ3GXxbcQqOKTxNzuO1XxR/6JZ54YBgXtp3ztsRCbDYJlFOvVTxVYDtGzzOeRB2DdSC8Ey50jc76prZ5i4r+v2YLVOvalYk3xdzbdtCvH3pfk7Oj8QcvTPmoTGTm/s5R2NudITMjrrGvLnNfQLmb+C5SnMF7jaeZemVhcBZgX0VxP57LhiQU3/nQe4bMUR+vSPv0tk2aGDYvwSG1vTonroULV9z21+Mz5gy35XAfmAQaP6P+FgC+2ZGNV+y3kwgFA+/D1DVD7+yQHf/AQ==
--------------------------------------------------------------------------------
/docs/Diagrams/SwapContractDetailed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SwingbyProtocol/skybridge-contract/48b50cf9c1bc6abe6d5744c90d7b4f7def1d8f54/docs/Diagrams/SwapContractDetailed.png
--------------------------------------------------------------------------------
/docs/Diagrams/UML_Image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SwingbyProtocol/skybridge-contract/48b50cf9c1bc6abe6d5744c90d7b4f7def1d8f54/docs/Diagrams/UML_Image.png
--------------------------------------------------------------------------------
/docs/Skybridge Security Audit Report - Red4Sec.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SwingbyProtocol/skybridge-contract/48b50cf9c1bc6abe6d5744c90d7b4f7def1d8f54/docs/Skybridge Security Audit Report - Red4Sec.pdf
--------------------------------------------------------------------------------
/docs/Skybridge Security Audit Report.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SwingbyProtocol/skybridge-contract/48b50cf9c1bc6abe6d5744c90d7b4f7def1d8f54/docs/Skybridge Security Audit Report.pdf
--------------------------------------------------------------------------------
/docs/lp-token-rate-logic.md:
--------------------------------------------------------------------------------
1 | # LP exchange rate logic
2 |
3 |
4 | In the first iteration of Skybridge v2, LP tokens represent ownership by the underlying assets from the pools, which are composed of **two assets meant to have the same value** (_"the bridged assets"_).
5 |
6 | The first iteration of Skybridge v2 will focus on a **BTC/WBTC pool**. This document explains the process on how LP exchange rate fluctuates, with a focus on the following cases:
7 |
8 | 1. Users swapping assets (WBTC -> BTC and BTC -> WBTC)
9 | 2. Liquidity providers depositing assets (aka minting LP tokens)
10 | 3. Liquidity providers withdrawing assets(aka burning LP tokens)
11 |
12 | Similar to other protocols like Compound or Uniswap, the price of the LP token is bound to increase over time to reflect the transaction fees being incorporated into the pools.
13 |
14 | ## 1. Description of the parameters and other notations
15 |
16 | ```initialExchangeRate```: LP token to BTC/WBTC (defined in the contract constructor). Part of the constructor of the LP contract, an arbitrary value must defined.
17 | ```currentExchangeRate```: 1 LP token to BTC (changes over time)
18 | ```amountReceivedByLP```: amount received owing to swap transaction fees. It is an accounting claim and is incorporated into the pools.
19 |
20 | ## 2. Case studies
21 |
22 | ### 2.1 Swap BTC --> WBTC
23 |
24 | When a swap is handled, part of the transaction fee is allocated to the SC and defined in the contract through the use of a field called ```amountReceivedByLP``` (in BTC).
25 |
26 | The fee calculation is handled at the node configuration scope (not at the smart contract level).
27 |
28 | Once the amount is paid to LPs (recorded as```amountReceivedByLP```), the ```currentExchangeRate``` must be re-calculated such as:
29 |
30 | ```currentExchangeRate = (newQuantityBTC + newQuantityWBTC)/(numberOfLPTokens)```
31 |
32 | with (1) ```newQuantityBTC = initialQuantityBTC + quantityBTCSwapped + amountReceivedByLP```
33 | and (2) ```newQuantityWBTC = initialQuantityWBTC - quantityWBTCSwapped ```
34 |
35 | Since ```newQuantityBTC + newQuantityWBTC > initialQuantityBTC + initialQuantityWBTC```, the new ```currentExchangeRate``` **increases after every new swap**.
36 |
37 | ### 2.2 Swap WBTC --> BTC
38 |
39 | It follows a similar process as described in subsection 2.1.
40 |
41 | Once the fee is allocated and amount is received to the contract (and recorded as```amountReceivedByLP```), the ```currentExchangeRate``` must be re-calculated such as:
42 |
43 | ```currentExchangeRate = (newQuantityBTC + newQuantityWBTC)/(numberOfLPTokens)```
44 |
45 | with (1) ```newQuantityBTC = initialQuantityBTC - quantityBTCSwapped```
46 | and (2) ```newQuantityWBTC = initialQuantityWBTC + quantityWBTCSwapped + amountReceivedByLP```
47 |
48 | Since ```newQuantityBTC + newQuantityWBTC > initialQuantityBTC + initialQuantityWBTC```, the new ```currentExchangeRate``` **increases after every new swap**.
49 |
50 | ### 2.3 Addition of liquidity to one side of the pool
51 |
52 | When a user wishes to add additional liquidity to one side of the pool, he/she must mint the LP token at the ```currentExchangeRate``` while depositing WBTC or BTC to their respective TSS addresses held by the protocol validators.
53 |
54 | #### 2.3.1 BTC deposit
55 |
56 | 1. The user deposits BTC using a special tag placed in the KV store that tells the system it is a float deposit. The swap is processed as normal by the nodes but the destination token becomes BTC-LP.
57 | 3. The parameter```currentExchangeRate``` is read by the contract.
58 | 4. The contract mints a quantity of BTC-LP token (1-1 representation) based on ```currentExchangeRate``` and ```amountDeposited``` (as supplied by the nodes) and sends the minted BTC-LP token to the user on Ethereum.
59 |
60 | **Adding BTC liquidity does not change the LP exchange rate (vs. BTC) since no fee is collected by LP providers**.
61 |
62 | However, ```numberOfLPTokens``` increases accordingly based on the quantity newly minted.
63 |
64 | #### 2.3.2 WBTC deposit
65 |
66 | 1. User sends the WBTC to the contract on Ethereum.
67 | 2. The contract mints a quantity of the BTC-LP token (1-1 representation) based on ```currentExchangeRate``` and ```amountDeposited``` (as supplied by the nodes) and sends the minted BTC-LP token to the user on Ethereum.
68 | 3. The contract credits the swap pool with the deposited WBTC.
69 |
70 | **Adding WBTC liquidity does not change the LP exchange rate (vs. BTC) since no fee is collected by LP providers**.
71 |
72 | However, ```numberOfLPTokens``` increases accordingly based on the quantity newly minted.
73 |
74 | ### 2.4 Removal of liquidity from one side of the pool
75 |
76 | When a user wishes to withdraw liquidity to one side of the pool, he must burn the LP token, indicate the asset he wishes to redeem his LP token to, while the ```currentExchangeRate``` is recorded part of the user's request.
77 |
78 | #### 2.4.1 WBTC redemption
79 |
80 | 1. User sends the BTC-LP token to the swap contract on Ethereum: `redeemFloat()`.
81 | 2. The swap contract sends the WBTC to the user on Ethereum.
82 | 3. Swap contract burns the received BTC-LP token.
83 |
84 | **Removing WBTC does not change the LP exchange rate (to BTC) since no fee is collected to LP providers**.
85 |
86 | #### 2.4.2 BTC redemption
87 |
88 | 1. User sends the BTC-LP token to the swap contract on Ethereum: `redeemFloat()`.
89 | 2. Swap contract burns the received BTC-LP token and sends the WBTC for swapping to BTC.
90 | 3. System sends the BTC to the user on the Bitcoin blockchain.
91 |
92 | **Removing BTC does change the LP exchange rate (to BTC)** since it is effectively a two-step process:
93 | (1) WBTC redemption (no change in the ```currentExchangeRate```)
94 | (2) a swap WBTC -> BTC (change in the ```currentExchangeRate```).
95 |
96 | Similarly, the```numberOfLPTokens``` also decreases accordingly based on the quantity burnt.
--------------------------------------------------------------------------------
/docs/readme.md:
--------------------------------------------------------------------------------
1 | # Contract Design Docs
2 |
3 | ## Table of Contents
4 |
5 | - [LP Exchange Rate Logic](./lp-token-rate-logic.md)
6 | - [Swap Contract Specification](./swap_contract_spec.md)
7 |
--------------------------------------------------------------------------------
/docs/support_bsc.md:
--------------------------------------------------------------------------------
1 | # Swap Contract upgraded for BSC network
2 |
3 | ## TL;DR
4 | * The swap contract has storages for decimal `8` tokens.
5 | * To support decimal `18` BTC pegged tokens, the contract is upgraded.
6 | * The contract supports transfer for [BTCB](https://testnet.bscscan.com/token/0x6ce8da28e2f864420840cf74474eff5fd80e65b8)
7 | * A new function `_safeTransfer()` handles ERC20 token transfer with `boosting` amount.
8 | * LP token decimal is kept `8`.
9 | * The float balance states are still decimal `8` basis.
10 | * All transfer input params are still decimal `8` basis
11 |
12 |
13 | ### Contract interface changed
14 |
15 | The new LP Token contract has a new consturctor `_decimals` which is for set LP token decimals.
16 | ```js
17 | constructor(uint8 _decimals) {
18 | _initialize("Swingby BTC LP Token", "sbBTC", _decimals, 0, true);
19 | }
20 | ```
21 |
22 | ### A new internal function `_safeTransfer()` is added for amount boosting
23 |
24 | A new function added for sending decimals `18` token, `convertScale` is set `10 ** (btct.decimals - lpToken.decimals)`.
25 | thus, it is set `10 ** 10`in transfer `18` decimal tokens case.
26 | ```js
27 | /// @dev _safeTransfer executes tranfer erc20 tokens
28 | /// @param _token The address of target token
29 | /// @param _to The address of receiver.
30 | /// @param _amount The amount of transfer.
31 | function _safeTransfer(
32 | address _token,
33 | address _to,
34 | uint256 _amount
35 | ) internal {
36 | if (_token == BTCT_ADDR) {
37 | _amount = _amount.mul(convertScale);
38 | }
39 | require(IERC20(_token).transfer(_to, _amount));
40 | }
41 | ```
42 |
43 |
44 | ### TIPS: Swingby node has to check ERC20 transfer amount of the refund case.
45 | The swap contract has to refund the amount of the received `BTCT` even decimal is 18.
46 | the tx input params which is for 'transfer are decimal `8` basis, so a tx input should be converted `8` from `18`.
47 | All transfer functions are just supported boosting the transfer of decimal `8` basis amount. thus, the small amount of received tx will be left in the swap contract. (that is not collected into as float balances, it will left forever)
--------------------------------------------------------------------------------
/hardhat.config.js:
--------------------------------------------------------------------------------
1 |
2 | //npx hardhat run scripts/deploy.js --network
3 | //run the tests: npx hardhat test
4 | //Plugins to let hardhat use web3 and truffle libraries
5 | require("@nomiclabs/hardhat-web3");
6 | require("hardhat-watcher");
7 | require('@symblox/hardhat-abi-gen');
8 | require('@nomiclabs/hardhat-etherscan');
9 | require("@nomiclabs/hardhat-waffle");
10 | //const mnemonic = process.env.SEED
11 |
12 | //This requires a private key rather than a memonic, this is a private key to a throw away account so this can compile, but it should be stored in a local secret.json file
13 | //It could then be accessed below using secret.key
14 | // const mnemonic = process.env.KEY || "4d777ee25c2bb753c12597e8f35a2eedb90ece9bc5682f335e0e2c2fdc8d5674"
15 | const accountInfo = {
16 | mnemonic: process.env.MNEMONIC,
17 | path: "m/44'/60'/0'/0",
18 | initialIndex: 1,
19 | count: 20,
20 | passphrase: "",
21 | }
22 |
23 | module.exports = {
24 | //defaultNetwork: "hardhat",
25 | watcher: {
26 | compilation: { //npx hardhat watch compilation -- auto compile on change
27 | tasks: ["compile"],
28 | },
29 | test: {//npx hardhat watch test -- run test when a file is saved
30 | tasks: [{ command: 'test', params: { testFiles: ['./test/testSkyPoolsV2.js'] } }], //test this file
31 | files: ['./test/testSkyPoolsV2.js'] //test when this file is saved
32 | }
33 | },
34 | solidity: {
35 | version: "0.8.19",
36 | settings: {
37 | optimizer: {
38 | enabled: true,
39 | runs: 1000
40 | }
41 | }
42 | },
43 | networks: {
44 | development: {
45 | url: "http://127.0.0.1:8545",
46 | accounts: accountInfo,
47 | confirmations: 2,
48 | skipDryRun: true,
49 | gas: "auto",
50 | gasPrice: "auto",
51 | maxPriorityFeePerGas: 1000000000,
52 | },
53 | hardhat: {
54 | //run tests on fork of mainnet
55 | // forking: {
56 | // url: "https://eth-mainnet.alchemyapi.io/v2/YfblHzLI_PlnIA0pxphS90J3yaA3dDi5",
57 | // blockNumber: 17322134 //13220045 //previous testing block
58 | // }
59 | },
60 | goerli: {
61 | url: "https://goerli.infura.io/v3/f35c2a4f3d0941a38a3edb62ed10c847",
62 | accounts: accountInfo,
63 | network_id: 5, // Ropsten's id
64 | gas: "auto", // Ropsten has a lower block limit than mainnet
65 | confirmations: 2, // # of confs to wait between deployments. (default: 0)
66 | timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
67 | skipDryRun: true, // Skip dry run before migrations? (default: false for public nets )
68 | gasPrice: "auto",
69 | maxPriorityFeePerGas: 1000000000,
70 | },
71 | mainnet: {
72 | url: "https://mainnet.infura.io/v3/f35c2a4f3d0941a38a3edb62ed10c847",
73 | accounts: accountInfo,
74 | network_id: 1, // Ropsten's id
75 | gas: "auto", // Ropsten has a lower block limit than mainnet
76 | confirmations: 2, // # of confs to wait between deployments. (default: 0)
77 | timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
78 | skipDryRun: true, // Skip dry run before migrations? (default: false for public nets )
79 | gasPrice: "auto",
80 | maxPriorityFeePerGas: 1000000000,
81 | },
82 | bsc_testnet: {
83 | url: "https://mainnet.infura.io/v3/f35c2a4f3d0941a38a3edb62ed10c847",
84 | accounts: accountInfo,
85 | network_id: 97, // Ropsten's id
86 | gas: 7500000, // Ropsten has a lower block limit than mainnet
87 | confirmations: 2, // # of confs to wait between deployments. (default: 0)
88 | timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
89 | skipDryRun: true, // Skip dry run before migrations? (default: false for public nets )
90 | gasPrice: 10000000000
91 | },
92 | bsc_mainnet: {
93 | url: "https://mainnet.infura.io/v3/f35c2a4f3d0941a38a3edb62ed10c847",
94 | accounts: accountInfo,
95 | network_id: 56, // Ropsten's id
96 | gas: 3000000, // Ropsten has a lower block limit than mainnet
97 | confirmations: 2, // # of confs to wait between deployments. (default: 0)
98 | timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
99 | skipDryRun: true, // Skip dry run before migrations? (default: false for public nets )
100 | gasPrice: 10000000000
101 | }
102 | // Useful for private networks
103 | // private: {
104 | // provider: () => new HDWalletProvider(mnemonic, `https://network.io`),
105 | // network_id: 2111, // This network is yours, in the cloud.
106 | // production: true // Treats this network as if it was a public net. (default: false)
107 | // }
108 | },
109 | // Set default mocha options here, use special reporters etc.
110 | mocha: {
111 | timeout: 100000
112 | },
113 |
114 | etherscan: {
115 | apiKey: "A7EAG5WB4FRAHIURRGWD8HSTM8CVYXZGZ4"
116 | },
117 |
118 | abiExporter: {
119 | path: './abi',
120 | clear: false,
121 | flat: true,
122 | spacing: 2
123 | },
124 |
125 | plugins: [
126 | "@chainsafe/truffle-plugin-abigen"
127 | ]
128 | };
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "skybridge-contract",
3 | "version": "1.0.0",
4 | "description": "## Environment - testrpc (ganache) - v2.4.0 - truffle - v5.1.54 - solc - v0.7.5 - web3 - v1.2.9",
5 | "main": "truffle-config.js",
6 | "directories": {
7 | "doc": "docs",
8 | "test": "test"
9 | },
10 | "scripts": {
11 | "build": "npm run compile && rm -rf abigenBindings && truffle run abigen && npm run test",
12 | "test": "npx hardhat test ./test/testSwapContract.js",
13 | "lint": "eslint --fix . --ext .js",
14 | "compile": "truffle compile",
15 | "gen-go": "node scripts/generateGoBindings.js"
16 | },
17 | "repository": {
18 | "type": "git",
19 | "url": "git+https://github.com/SwingbyProtocol/skybridge-contract.git"
20 | },
21 | "author": "",
22 | "license": "SEE LICENSE IN LICENSE",
23 | "bugs": {
24 | "url": "https://github.com/SwingbyProtocol/skybridge-contract/issues"
25 | },
26 | "homepage": "https://github.com/SwingbyProtocol/skybridge-contract#readme",
27 | "dependencies": {
28 | "@chainsafe/truffle-plugin-abigen": "0.0.2",
29 | "@nomiclabs/hardhat-etherscan": "^3.0.3",
30 | "@openzeppelin/contracts": "^4.3.2",
31 | "@symblox/hardhat-abi-gen": "^0.2.0",
32 | "@truffle/hdwallet-provider": "^2.0.8",
33 | "axios": "^0.21.1",
34 | "chai-as-promised": "^7.1.1",
35 | "dotenv": "^8.2.0",
36 | "elliptic": ">=6.5.4",
37 | "hardhat-watcher": "^2.1.1",
38 | "install": "^0.13.0",
39 | "json-parser": "^3.1.2",
40 | "node-fetch": ">=2.6.1",
41 | "npm": "^8.12.1",
42 | "sol2uml": "^1.1.6",
43 | "truffle-contract-size": "^2.0.1",
44 | "truffle-hdwallet-provider-privkey": "^0.0.4",
45 | "truffle-plugin-verify": "^0.5.15",
46 | "ts-node": "^10.9.1",
47 | "typescript": "^5.0.4"
48 | },
49 | "devDependencies": {
50 | "@nomiclabs/hardhat-ethers": "^2.0.2",
51 | "@nomiclabs/hardhat-truffle5": "^2.0.0",
52 | "@nomiclabs/hardhat-waffle": "^2.0.1",
53 | "@nomiclabs/hardhat-web3": "^2.0.0",
54 | "@openzeppelin/hardhat-upgrades": "^1.18.1",
55 | "@openzeppelin/test-helpers": "^0.5.10",
56 | "chai": "^4.3.4",
57 | "eslint": "^7.22.0",
58 | "ethereum-waffle": "^3.4.0",
59 | "ethers": "^5.4.1",
60 | "hardhat": "^2.6.7",
61 | "truffle-flattener": "^1.5.0",
62 | "web3": "^1.4.0"
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/scripts/addFloat.js:
--------------------------------------------------------------------------------
1 |
2 | const { BN, constants } = require('@openzeppelin/test-helpers');
3 | const { ZERO_ADDRESS } = constants
4 | const SwapContract = artifacts.require("SwapContract");
5 |
6 | module.exports = async function (done) {
7 | // await deployer.deploy(LPToken)
8 | try {
9 | const swap = await SwapContract.deployed()
10 | // send 0.1 BTC as float
11 | let amount = new BN(131122121817231).mul(new BN(10).pow(new BN(1)))
12 | let to = process.env.TO
13 | let float = "0x" + web3.utils.padLeft(amount.toString('hex') + to.slice(2), 64)
14 | let isZerofees = false
15 | let txid = "0x1c12143203a48f42cdf7b1acee5b1b1c1fedc144cb309a3bf5edbffafb0ad734"
16 | let btct = await swap.BTCT_ADDR()
17 | await swap.recordIncomingFloat(btct.toString(), float, isZerofees, txid)
18 | } catch (err) {
19 | console.log(err)
20 | }
21 | done()
22 | };
23 |
--------------------------------------------------------------------------------
/scripts/addFloatNew.js:
--------------------------------------------------------------------------------
1 | const { ZERO_ADDRESS } = require("@openzeppelin/test-helpers/src/constants");
2 | const { ethers } = require("hardhat");
3 | BN = require('bn.js')
4 | /*********************************************************************
5 | *
6 | * Boiler Plate script to deploy
7 | *
8 | * July 28, 2021
9 | *
10 | * Deploy with:
11 | * npx hardhat run ./scripts/deploy.js --network development || npx hardhat run ./scripts/deploy.js --network hardhat
12 | * There are still some errors with the above
13 | */
14 | async function main() {
15 | const swapContrat = '0x9e6BA6e811665849f03f56C1f22a8894AEbb3993'
16 | const to = '0x63d9f6A25ddD2c586F4441065Ce7C8412fbBB91e'
17 | const SwapContractFactory = await ethers.getContractFactory("SwapContract");
18 | const swap = await SwapContractFactory.attach(swapContrat);
19 |
20 | // send 1 BTC & 1WBTC as float
21 | let amount = new BN(1).mul(new BN(10).pow(new BN(8)))
22 | let float = "0x" + web3.utils.padLeft(amount.toString('hex') + to.slice(2), 64)
23 | let txid_1 = "0x1c12143203a48f42cdf7b1acee5b1b1c1fedc144cb309a3bf5edbffafc0ad734"
24 | let txid_2 = "0x6a167c4b6750c3213320098178f913478fe50d3f75d5f0377ee7cec9a630ad9e"
25 | let btct = await swap.BTCT_ADDR()
26 | await swap.recordIncomingFloat(btct.toString(), float, txid_1)
27 | await swap.recordIncomingFloat(ZERO_ADDRESS, float, txid_2)
28 | }
29 |
30 | main()
31 | .then(() => process.exit(0))
32 | .catch((error) => {
33 | console.error(error);
34 | process.exit(1);
35 | });
--------------------------------------------------------------------------------
/scripts/addNode.js:
--------------------------------------------------------------------------------
1 | const { ZERO_ADDRESS } = require("@openzeppelin/test-helpers/src/constants");
2 | const { ethers } = require("hardhat");
3 | BN = require('bn.js')
4 | /*********************************************************************
5 | *
6 | * Boiler Plate script to deploy
7 | *
8 | * July 28, 2021
9 | *
10 | * Deploy with:
11 | * npx hardhat run ./scripts/deploy.js --network development || npx hardhat run ./scripts/deploy.js --network hardhat
12 | * There are still some errors with the above
13 | */
14 | async function main() {
15 | [sender, receiver, dao, ...addrs] = await ethers.getSigners();
16 | console.log(sender.address)
17 |
18 | const swapContrat = '0x9e6BA6e811665849f03f56C1f22a8894AEbb3993' // goerli
19 | const to = '0x63d9f6A25ddD2c586F4441065Ce7C8412fbBB91e'
20 | const SwapContractFactory = await ethers.getContractFactory("SwapContract");
21 | const swap = await SwapContractFactory.attach(swapContrat);
22 |
23 | let nodes = []
24 | let isRemoved = []
25 | let churnedInCount = 25
26 | let tssThreshold = 16
27 | let nodeRewardsRatio = 66
28 | // for 17 nodes adding
29 | nodes.push(sender.address)
30 | isRemoved.push(false)
31 | nodes.push(receiver.address)
32 | isRemoved.push(false)
33 | nodes.push(dao.address)
34 | isRemoved.push(false)
35 |
36 | for (i = 0; i < 8; i++) {
37 | nodes.push(addrs[i].address)
38 | isRemoved.push(false)
39 | }
40 |
41 | const tx1 = await swap.churn(
42 | sender.address,
43 | nodes,
44 | isRemoved,
45 | churnedInCount,
46 | tssThreshold,
47 | {
48 | value: 0,
49 | gasPrice: 2 * 10 ** 6
50 | })
51 |
52 | const receipt = await tx1.wait()
53 | console.log(receipt)
54 | }
55 |
56 | main()
57 | .then(() => process.exit(0))
58 | .catch((error) => {
59 | console.error(error);
60 | process.exit(1);
61 | });
--------------------------------------------------------------------------------
/scripts/burnToken.js:
--------------------------------------------------------------------------------
1 | const { BN } = require('@openzeppelin/test-helpers');
2 |
3 | const SwingbyToken = artifacts.require("SwingbyToken");
4 |
5 | module.exports = async function (done) {
6 | // await deployer.deploy(LPToken)
7 | try {
8 | const token = await SwingbyToken.at("0x423fa1c32541b3d9fc3690e15392185753d44fad")
9 | console.log("token:", token.address)
10 | let amount = new BN(1000000).mul(new BN(10).pow(new BN(18)))
11 | await token.burn(amount)
12 | } catch (err) {
13 | console.log(err)
14 | }
15 | done()
16 | };
17 |
--------------------------------------------------------------------------------
/scripts/deploy-goerli.js:
--------------------------------------------------------------------------------
1 | const { ethers } = require("hardhat");
2 |
3 | /*********************************************************************
4 | *
5 | * Boiler Plate script to deploy
6 | *
7 | * July 28, 2021
8 | *
9 | * Deploy with:
10 | * npx hardhat run ./scripts/deploy.js --network development || npx hardhat run ./scripts/deploy.js --network hardhat
11 | * There are still some errors with the above
12 | */
13 | const TOKEN_DECIMALS = process.env.TOKEN_DECIMALS || 8
14 | async function main() {
15 | const [deployer] = await ethers.getSigners();
16 | //let BTCT_ADDR = "0x449268b65BAf7251f83fd0a4b182DbC4C20985Fd"
17 | //BTCT_ADDR = "0xbde8bb00a7ef67007a96945b3a3621177b615c44"
18 | //BTCT_ADDR = "0xaD6D458402F60fD3Bd25163575031ACDce07538D"//address for DAI as there is no liquidity for BTCt on Ropsten
19 | const BTCT_ADDR = "0xEb47a21C1fC00D1E863019906df1771b80DBE182"
20 | const sbBTCPool = "0xec2946aD323f0879269910cbBB5420E8CD578a30"
21 | const swapRewards = "0xF4c381d077272295641F8A53D850d9a8125e0e94"
22 | const dao = "0xA740E20712C630d602D5007b618a1d604D3f41e9"
23 | const initialBTC = 1111
24 | const initialWBTC = 1111
25 | console.log("Deploying contracts with the account:", deployer.address);
26 |
27 | console.log("Account balance:", (await deployer.getBalance() / 1e18).toFixed(8));
28 |
29 | const LPTokenFactory = await ethers.getContractFactory("LPToken");
30 | const lpToken = await LPTokenFactory.deploy(TOKEN_DECIMALS);
31 |
32 | await lpToken.deployed();
33 | console.log("LPToken address:", lpToken.address);
34 |
35 | const SwapContractFactory = await ethers.getContractFactory("SwapContract");
36 | const swap = await SwapContractFactory.deploy(
37 | lpToken.address,
38 | BTCT_ADDR,
39 | sbBTCPool,
40 | swapRewards,
41 | dao,
42 | initialBTC,
43 | initialWBTC);
44 |
45 | await swap.deployed();
46 | console.log("SwapContract address:", swap.address);
47 | }
48 |
49 | main()
50 | .then(() => process.exit(0))
51 | .catch((error) => {
52 | console.error(error);
53 | process.exit(1);
54 | });
--------------------------------------------------------------------------------
/scripts/deploy-mainnet.js:
--------------------------------------------------------------------------------
1 | const { ethers } = require("hardhat");
2 |
3 | /*********************************************************************
4 | *
5 | * Boiler Plate script to deploy
6 | *
7 | * July 28, 2021
8 | *
9 | * Deploy with:
10 | * npx hardhat run ./scripts/deploy.js --network development || npx hardhat run ./scripts/deploy.js --network hardhat
11 | * There are still some errors with the above
12 | */
13 | const TOKEN_DECIMALS = process.env.TOKEN_DECIMALS || 8
14 | async function main() {
15 | const [deployer] = await ethers.getSigners();
16 | //let BTCT_ADDR = "0x449268b65BAf7251f83fd0a4b182DbC4C20985Fd"
17 | //BTCT_ADDR = "0xbde8bb00a7ef67007a96945b3a3621177b615c44"
18 | //BTCT_ADDR = "0xaD6D458402F60fD3Bd25163575031ACDce07538D"//address for DAI as there is no liquidity for BTCt on Ropsten
19 | const BTCT_ADDR = "0x7cb2eac36b4bb7c36640f32e806d33e474d1d427"
20 | const wETH_ADDR = "0xc778417e063141139fce010982780140aa0cd5ab"
21 | const sbBTCPool = "0xf5329508Fdb96A1aada673dB6572109a228edB7e"
22 | const params = "0xad2CD8327BFE0E8C059EA5f789d064ba4C261BDb"
23 | const swapRewards = "0x53E79243D27DCd5E1070b4B71FDC42F8944a7848"
24 |
25 | console.log("Deploying contracts with the account:", deployer.address);
26 |
27 | console.log("Account balance:", (await deployer.getBalance()/1e18).toString());
28 |
29 | const LPTokenFactory = await ethers.getContractFactory("LPToken");
30 | const lpToken = await LPTokenFactory.deploy(TOKEN_DECIMALS);
31 |
32 | await lpToken.deployed();
33 | console.log("LPToken address:", lpToken.address);
34 |
35 | const SwapContractFactory = await ethers.getContractFactory("SwapContract");
36 | const swap = await SwapContractFactory.deploy(lpToken.address, BTCT_ADDR, wETH_ADDR, sbBTCPool, params, swapRewards, 0);
37 |
38 | await swap.deployed();
39 | console.log("SwapContract address:", swap.address);
40 | }
41 |
42 | main()
43 | .then(() => process.exit(0))
44 | .catch((error) => {
45 | console.error(error);
46 | process.exit(1);
47 | });
--------------------------------------------------------------------------------
/scripts/deploy-ropsten.js:
--------------------------------------------------------------------------------
1 | const { ethers } = require("hardhat");
2 |
3 | /*********************************************************************
4 | *
5 | * Boiler Plate script to deploy
6 | *
7 | * July 28, 2021
8 | *
9 | * Deploy with:
10 | * npx hardhat run ./scripts/deploy.js --network development || npx hardhat run ./scripts/deploy.js --network hardhat
11 | * There are still some errors with the above
12 | */
13 | const TOKEN_DECIMALS = process.env.TOKEN_DECIMALS || 8
14 | async function main() {
15 | const [deployer] = await ethers.getSigners();
16 | //let BTCT_ADDR = "0x449268b65BAf7251f83fd0a4b182DbC4C20985Fd"
17 | //BTCT_ADDR = "0xbde8bb00a7ef67007a96945b3a3621177b615c44"
18 | //BTCT_ADDR = "0xaD6D458402F60fD3Bd25163575031ACDce07538D"//address for DAI as there is no liquidity for BTCt on Ropsten
19 | const BTCT_ADDR = "0x7cb2eac36b4bb7c36640f32e806d33e474d1d427"
20 | const wETH_ADDR = "0xc778417e063141139fce010982780140aa0cd5ab"
21 | const sbBTCPool = "0xf5329508Fdb96A1aada673dB6572109a228edB7e"
22 | const params = "0xad2CD8327BFE0E8C059EA5f789d064ba4C261BDb"
23 | const swapRewards = "0x53E79243D27DCd5E1070b4B71FDC42F8944a7848"
24 |
25 | console.log("Deploying contracts with the account:", deployer.address);
26 |
27 | console.log("Account balance:", (await deployer.getBalance()).toString());
28 |
29 | const LPTokenFactory = await ethers.getContractFactory("LPToken");
30 | const lpToken = await LPTokenFactory.deploy(TOKEN_DECIMALS);
31 |
32 | await lpToken.deployed();
33 | console.log("LPToken address:", lpToken.address);
34 |
35 | const SwapContractFactory = await ethers.getContractFactory("SwapContract");
36 | const swap = await SwapContractFactory.deploy(lpToken.address, BTCT_ADDR, wETH_ADDR, sbBTCPool, params, swapRewards, 0);
37 |
38 | await swap.deployed();
39 | console.log("SwapContract address:", swap.address);
40 | }
41 |
42 | main()
43 | .then(() => process.exit(0))
44 | .catch((error) => {
45 | console.error(error);
46 | process.exit(1);
47 | });
--------------------------------------------------------------------------------
/scripts/deploy-sbBTCPool.ts:
--------------------------------------------------------------------------------
1 | const { ethers } = require("hardhat");
2 |
3 | const _owner = '0x64496f51779e400C5E955228E56fA41563Fb4dd8';
4 | const _sbBTC = '0x1B5B6dF2C72D7c406df1C30E640df8dBaE57d21d';
5 | const _barn = '0x009cc14ce70b2e667984c2276490d56ae3234c43';
6 | const _swap = '0xe8d45281d7BD836b30F9B371001676d1ed59465D'
7 |
8 | async function main() {
9 | const sbBTCFactory = await ethers.getContractFactory("sbBTCPool");
10 |
11 | const [owner] = await ethers.getSigners();
12 | console.log(owner.address)
13 | const sbBTCPool = await sbBTCFactory.deploy();
14 | console.log(`sbBTCPool deployed at: ${sbBTCPool.address}`);
15 |
16 | // await sbBTCPool.setBarnAndSwap(_barn, _swap);
17 | }
18 |
19 | main()
20 | .then(() => process.exit(0))
21 | .catch((error) => {
22 | console.error(error);
23 | process.exit(1);
24 | });
--------------------------------------------------------------------------------
/scripts/deployParams.js:
--------------------------------------------------------------------------------
1 | const { ethers } = require("hardhat");
2 |
3 | /*********************************************************************
4 | *
5 | * Boiler Plate script to deploy
6 | *
7 | * July 28, 2021
8 | *
9 | * Deploy with:
10 | * npx hardhat run ./scripts/deploy.js --network development || npx hardhat run ./scripts/deploy.js --network hardhat
11 | * There are still some errors with the above
12 | */
13 | async function main() {
14 | const ParamsFactory = await ethers.getContractFactory("Params");
15 | const param = await ParamsFactory.deploy();
16 |
17 | await param.deployed();
18 | console.log("Params address:", param.address);
19 | }
20 |
21 | main()
22 | .then(() => process.exit(0))
23 | .catch((error) => {
24 | console.error(error);
25 | process.exit(1);
26 | });
--------------------------------------------------------------------------------
/scripts/deploySwapRewards.js:
--------------------------------------------------------------------------------
1 | const { ethers } = require("hardhat");
2 |
3 | /*********************************************************************
4 | *
5 | * Boiler Plate script to deploy
6 | *
7 | * July 28, 2021
8 | *
9 | * Deploy with:
10 | * npx hardhat run ./scripts/deploy.js --network development || npx hardhat run ./scripts/deploy.js --network hardhat
11 | * There are still some errors with the above
12 | */
13 | async function main() {
14 | const [deployer] = await ethers.getSigners();
15 | //const SWINGBY = "0x8287C7b963b405b7B8D467DB9d79eEC40625b13A"
16 | const SWINGBY = "0xFCd51B56e65605C33024A9E98a7aaDfF2e1A15b9" // goerli
17 | const SwapRewardsFactory = await ethers.getContractFactory("SwapRewards");
18 | const swapRewards = await SwapRewardsFactory.deploy(deployer.address, SWINGBY, 358520);
19 |
20 | await swapRewards.deployed();
21 | console.log("SwapRewards address:", swapRewards.address);
22 | }
23 |
24 | main()
25 | .then(() => process.exit(0))
26 | .catch((error) => {
27 | console.error(error);
28 | process.exit(1);
29 | });
--------------------------------------------------------------------------------
/scripts/deploySwingbyToken.js:
--------------------------------------------------------------------------------
1 | const SwingbyToken = artifacts.require("SwingbyToken");
2 |
3 | module.exports = async function (done) {
4 | // await deployer.deploy(LPToken)
5 | try {
6 | const st = await SwingbyToken.new()
7 | console.log(st.address)
8 | } catch (err) {
9 | console.log(err)
10 | }
11 | done()
12 | };
13 |
--------------------------------------------------------------------------------
/scripts/erc20ABI.js:
--------------------------------------------------------------------------------
1 |
2 | class ERC20ABI{
3 |
4 | erc20ABI() {
5 | return [
6 | {
7 | "constant": true,
8 | "inputs": [],
9 | "name": "name",
10 | "outputs": [
11 | {
12 | "name": "",
13 | "type": "string"
14 | }
15 | ],
16 | "payable": false,
17 | "stateMutability": "view",
18 | "type": "function"
19 | },
20 | {
21 | "constant": false,
22 | "inputs": [
23 | {
24 | "name": "_spender",
25 | "type": "address"
26 | },
27 | {
28 | "name": "_value",
29 | "type": "uint256"
30 | }
31 | ],
32 | "name": "approve",
33 | "outputs": [
34 | {
35 | "name": "",
36 | "type": "bool"
37 | }
38 | ],
39 | "payable": false,
40 | "stateMutability": "nonpayable",
41 | "type": "function"
42 | },
43 | {
44 | "constant": true,
45 | "inputs": [],
46 | "name": "totalSupply",
47 | "outputs": [
48 | {
49 | "name": "",
50 | "type": "uint256"
51 | }
52 | ],
53 | "payable": false,
54 | "stateMutability": "view",
55 | "type": "function"
56 | },
57 | {
58 | "constant": false,
59 | "inputs": [
60 | {
61 | "name": "_from",
62 | "type": "address"
63 | },
64 | {
65 | "name": "_to",
66 | "type": "address"
67 | },
68 | {
69 | "name": "_value",
70 | "type": "uint256"
71 | }
72 | ],
73 | "name": "transferFrom",
74 | "outputs": [
75 | {
76 | "name": "",
77 | "type": "bool"
78 | }
79 | ],
80 | "payable": false,
81 | "stateMutability": "nonpayable",
82 | "type": "function"
83 | },
84 | {
85 | "constant": true,
86 | "inputs": [],
87 | "name": "decimals",
88 | "outputs": [
89 | {
90 | "name": "",
91 | "type": "uint8"
92 | }
93 | ],
94 | "payable": false,
95 | "stateMutability": "view",
96 | "type": "function"
97 | },
98 | {
99 | "constant": true,
100 | "inputs": [
101 | {
102 | "name": "_owner",
103 | "type": "address"
104 | }
105 | ],
106 | "name": "balanceOf",
107 | "outputs": [
108 | {
109 | "name": "balance",
110 | "type": "uint256"
111 | }
112 | ],
113 | "payable": false,
114 | "stateMutability": "view",
115 | "type": "function"
116 | },
117 | {
118 | "constant": true,
119 | "inputs": [],
120 | "name": "symbol",
121 | "outputs": [
122 | {
123 | "name": "",
124 | "type": "string"
125 | }
126 | ],
127 | "payable": false,
128 | "stateMutability": "view",
129 | "type": "function"
130 | },
131 | {
132 | "constant": false,
133 | "inputs": [
134 | {
135 | "name": "_to",
136 | "type": "address"
137 | },
138 | {
139 | "name": "_value",
140 | "type": "uint256"
141 | }
142 | ],
143 | "name": "transfer",
144 | "outputs": [
145 | {
146 | "name": "",
147 | "type": "bool"
148 | }
149 | ],
150 | "payable": false,
151 | "stateMutability": "nonpayable",
152 | "type": "function"
153 | },
154 | {
155 | "constant": true,
156 | "inputs": [
157 | {
158 | "name": "_owner",
159 | "type": "address"
160 | },
161 | {
162 | "name": "_spender",
163 | "type": "address"
164 | }
165 | ],
166 | "name": "allowance",
167 | "outputs": [
168 | {
169 | "name": "",
170 | "type": "uint256"
171 | }
172 | ],
173 | "payable": false,
174 | "stateMutability": "view",
175 | "type": "function"
176 | },
177 | {
178 | "payable": true,
179 | "stateMutability": "payable",
180 | "type": "fallback"
181 | },
182 | {
183 | "anonymous": false,
184 | "inputs": [
185 | {
186 | "indexed": true,
187 | "name": "owner",
188 | "type": "address"
189 | },
190 | {
191 | "indexed": true,
192 | "name": "spender",
193 | "type": "address"
194 | },
195 | {
196 | "indexed": false,
197 | "name": "value",
198 | "type": "uint256"
199 | }
200 | ],
201 | "name": "Approval",
202 | "type": "event"
203 | },
204 | {
205 | "anonymous": false,
206 | "inputs": [
207 | {
208 | "indexed": true,
209 | "name": "from",
210 | "type": "address"
211 | },
212 | {
213 | "indexed": true,
214 | "name": "to",
215 | "type": "address"
216 | },
217 | {
218 | "indexed": false,
219 | "name": "value",
220 | "type": "uint256"
221 | }
222 | ],
223 | "name": "Transfer",
224 | "type": "event"
225 | }
226 | ]
227 | }
228 | }
229 | module.exports = ERC20ABI;
230 |
--------------------------------------------------------------------------------
/scripts/generateGoBindings.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const path = require('path')
3 | const { exec } = require("child_process")
4 |
5 | const abis = fs.readdirSync(path.resolve(__dirname, '../abi'))
6 |
7 | abis.forEach((abi) => {
8 | if (!abi.match(".json"))
9 | return
10 | const source = path.resolve(__dirname, '../abi', abi)
11 | const goName = abi.replace(".json", "")
12 | const destination = path.resolve(__dirname, '../abigo', goName)
13 |
14 | const cmd = `abigen --abi ${source} --pkg abigo --type ${goName} --out ${destination}.go`
15 | exec(cmd, (error, stdout, stderr) => {
16 | if (error) {
17 | console.log(`error: ${error.message}`);
18 | return;
19 | }
20 | if (stderr) {
21 | console.log(`stderr: ${stderr}`);
22 | return;
23 | }
24 | console.log(`${abi} -> ${goName}.go`);
25 | });
26 | })
27 |
--------------------------------------------------------------------------------
/scripts/mintToken.js:
--------------------------------------------------------------------------------
1 | const { BN } = require('@openzeppelin/test-helpers');
2 |
3 | const SwingbyToken = artifacts.require("SwingbyToken");
4 |
5 | module.exports = async function (done) {
6 | // await deployer.deploy(LPToken)
7 | try {
8 | const token = await SwingbyToken.at("0x423fa1c32541b3d9fc3690e15392185753d44fad")
9 | console.log("token:", token.address)
10 | let amount = new BN(1000000).mul(new BN(10).pow(new BN(18)))
11 | await token.mint(process.env.OWNER, amount)
12 | } catch (err) {
13 | console.log(err)
14 | }
15 | done()
16 | };
17 |
--------------------------------------------------------------------------------
/scripts/moveLPTOwner.js:
--------------------------------------------------------------------------------
1 |
2 | const LPToken = artifacts.require("LPToken");
3 | const SwapContract = artifacts.require("SwapContract");
4 |
5 | module.exports = async function (done) {
6 | // await deployer.deploy(LPToken)
7 | try {
8 | const lpToken = await LPToken.deployed()
9 | const swap = await SwapContract.deployed()
10 | await lpToken.transferOwnership(swap.address)
11 | } catch (err) {
12 | console.log(err)
13 | }
14 | done()
15 | };
16 |
--------------------------------------------------------------------------------
/scripts/moveSCOwner.js:
--------------------------------------------------------------------------------
1 |
2 | const LPToken = artifacts.require("LPToken");
3 | const SwapContract = artifacts.require("SwapContract");
4 |
5 | module.exports = async function (done) {
6 | // await deployer.deploy(LPToken)
7 | try {
8 | const swap = await SwapContract.deployed()
9 | console.log("SwapContract:", swap.address)
10 | await swap.transferOwnership(process.env.TSS)
11 | } catch (err) {
12 | console.log(err)
13 | }
14 | done()
15 | };
16 |
--------------------------------------------------------------------------------
/scripts/paraswap.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios');
2 | const { BigNumber, Ethers } = require('ethers')
3 |
4 | //call the class with this
5 | const paraURL = "https://apiv4.paraswap.io/v2"
6 | const paraV5 = "https://apiv5.paraswap.io/"
7 |
8 | class ParaSwap {
9 |
10 | constructor(apiURL, version) {
11 | this.apiURL = apiURL
12 | this.version = version
13 | this.referrer = 'SkyPools'
14 | }
15 |
16 | async getTokens(networkID){
17 | if(this.version == 5){
18 | const requestURL = `${this.apiURL}/tokens/${networkID}`
19 |
20 | const {data} = await axios.get(requestURL).catch(e => {
21 | if (e.response != undefined) {
22 | console.log("ERROR RESPONSE: ", e.response.data)
23 | } else { console.log("ERROR: ", e) }
24 | })
25 | return {data}
26 | }
27 | }
28 |
29 | async getPrice(from, to, srcAmount, network) {
30 | if (this.version == 4) {
31 | try {
32 | const requestURL =
33 | `${this.apiURL}/prices/?from=${from.address}&to=${to.address}` +
34 | `&amount=${srcAmount}&fromDecimals=${from.decimals}&toDecimals` +
35 | `=${to.decimals}&side=SELL&network=${network}`
36 |
37 | const { data } = await axios.get(requestURL, {
38 | headers: {
39 | 'X-Partner': this.referrer,
40 | },
41 | }).catch(e => {
42 | if (e.response != undefined) {
43 | console.log("ERROR RESPONSE: ", e.response.data)
44 | } else { console.log("ERROR: ", e) }
45 | })
46 | return {
47 | price: data.priceRoute.destAmount,
48 | payload: data.priceRoute,
49 | }
50 | } catch (e) {
51 | throw new Error(
52 | `Paraswap unable to fetch price ${from.address} ${to.address} ${network} ${e.message}`
53 | )
54 | }
55 | } else if (this.version == 5) {
56 | try {
57 | const requestURL =
58 | `${this.apiURL}/prices/?srcToken=${from.address}&destToken=${to.address}` +
59 | `&amount=${srcAmount}&srcDecimals=${from.decimals}&destDecimals` +
60 | `=${to.decimals}&side=SELL&network=${network}&maxImpact=100`
61 | //PICK WHICH CONTRACT METHODS TO INCLUDE
62 | //+ `&includeContractMethods=swapOnUniswapFork`
63 | //+ `&includeContractMethods=swapOnUniswap`
64 | //+ `&includeContractMethods=simpleSwap`
65 | + `&includeContractMethods=swapOnUniswap,swapOnUniswapFork`
66 |
67 | const { data } = await axios.get(requestURL, {
68 | headers: {
69 | 'partner': this.referrer,
70 | },
71 | }).catch(e => {
72 | if (e.response != undefined) {
73 | console.log("ERROR RESPONSE: ", e.response.data)
74 | } else { console.log("ERROR: ", e) }
75 | })
76 | return {
77 | price: data.priceRoute.destAmount,
78 | payload: data.priceRoute,
79 | }
80 | } catch (e) {
81 | throw new Error(
82 | `Paraswap unable to fetch price ${from.address} ${to.address} ${network} ${e.message}`
83 | )
84 | }
85 | }
86 |
87 | }
88 |
89 |
90 | async buildTransaction(
91 | pricePayload,
92 | from,
93 | to,
94 | srcAmount,
95 | minDestAmount,
96 | network,
97 | userAddress,
98 | onlyParams
99 | ) {
100 | if (this.version == 4) {
101 | const requestURL = `${this.apiURL}/transactions/${network}?skipChecks=true&onlyParams=${onlyParams}`;
102 | const requestData = {
103 | toDecimals: to.decimals,
104 | fromDecimals: from.decimals,
105 | referrer: this.referrer,
106 | userAddress: userAddress,
107 | destAmount: minDestAmount,
108 | priceRoute: pricePayload,
109 | srcAmount: srcAmount,
110 | destToken: to.address,
111 | srcToken: from.address,
112 | receiver: userAddress
113 | }
114 | console.log("destAmount", minDestAmount)
115 | let data = "No Response"
116 | await axios.post(
117 | requestURL,
118 | requestData
119 | ).then(response => {
120 | //console.log("RESPONSE: ", response)
121 | data = response
122 | }).catch(e => {
123 | if (e.response != undefined) {
124 | console.log("ERROR RESPONSE: ", e.response)
125 | data = e.response
126 | } else { console.log("ERROR: ", e) }
127 | })
128 | return data
129 | } else if (this.version == 5) {
130 | const requestURL = `${this.apiURL}/transactions/${network}?skipChecks=true&onlyParams=${onlyParams}`;
131 | const requestData = {
132 | destDecimals: to.decimals,
133 | srcDecimals: from.decimals,
134 | partner: this.referrer,
135 | userAddress: userAddress,
136 | //destAmount: minDestAmount,
137 | slippage: 5000, //50% -> prevents issues with EXPECTED_AMOUNT_GREATER_THAN_MAX_IMPACT
138 | priceRoute: pricePayload,
139 | srcAmount: srcAmount,
140 | destToken: to.address,
141 | srcToken: from.address,
142 | receiver: userAddress
143 | }
144 | let data = "No Response"
145 | await axios.post(
146 | requestURL,
147 | requestData
148 | ).then(response => {
149 | //console.log("RESPONSE: ", response)
150 | data = response
151 | }).catch(e => {
152 | if (e.response != undefined) {
153 | console.log("ERROR RESPONSE: ", e.response)
154 | data = e.response
155 | } else { console.log("ERROR: ", e) }
156 | })
157 | return data
158 | }
159 | }
160 |
161 | }
162 |
163 | module.exports = ParaSwap;
--------------------------------------------------------------------------------
/scripts/removeFloat.js:
--------------------------------------------------------------------------------
1 |
2 | const { BN, constants } = require('@openzeppelin/test-helpers');
3 | const { ZERO_ADDRESS } = constants
4 | const SwapContract = artifacts.require("SwapContract");
5 | const LPToken = artifacts.require("LPToken");
6 |
7 | module.exports = async function (done) {
8 | // await deployer.deploy(LPToken)
9 | try {
10 | const swap = await SwapContract.deployed()
11 | // send 0.1 BTC as float
12 | let amount = new BN(3231122121817231).mul(new BN(10).pow(new BN(1)))
13 | //let amount = new BN(3933663654516931)
14 | let to = process.env.TO
15 | let AmountLP2 = "0x" + web3.utils.padLeft(amount.toString('hex') + to.slice(2), 64)
16 | let minerFees = 0
17 | let txid = "0x1c12143203aa1f42cdf1b1acee5b1b1c1fedc144cb309a3bf5edcffafb0ac731"
18 | let btct = await swap.BTCT_ADDR()
19 | let lptAddr = await swap.lpToken()
20 |
21 | const lpt = await LPToken.at(lptAddr)
22 | const deposit = await lpt.transfer(swap.address, amount)
23 | //console.log('max', amountMAXBTCfloatLP.toString())
24 | await swap.recordOutcomingFloat(ZERO_ADDRESS, AmountLP2, minerFees, deposit.tx)
25 | } catch (err) {
26 | console.log(err)
27 | }
28 | done()
29 | };
30 |
--------------------------------------------------------------------------------
/scripts/sbBTCchecks.js:
--------------------------------------------------------------------------------
1 | const { ZERO_ADDRESS } = require("@openzeppelin/test-helpers/src/constants");
2 | const { ethers } = require("hardhat");
3 | BN = require('bn.js')
4 | /*********************************************************************
5 | *
6 | * Boiler Plate script to deploy
7 | *
8 | * July 28, 2021
9 | *
10 | * Deploy with:
11 | * npx hardhat run ./scripts/deploy.js --network development || npx hardhat run ./scripts/deploy.js --network hardhat
12 | * There are still some errors with the above
13 | */
14 | async function main() {
15 | [...addrs] = await ethers.getSigners();
16 | //console.log(addrs.map((s) => s.address))
17 | const swapContrat = '0x9e6BA6e811665849f03f56C1f22a8894AEbb3993'
18 | const sbBTC_Pool = '0xD60126017fDf906668Cfe5327c566C65e7f061bA'
19 | const barnContract = '0x009cc14ce70b2E667984C2276490d56ae3234c43'
20 | const SwapContractFactory = await ethers.getContractFactory("SwapContract");
21 | const sbBTCFactory = await ethers.getContractFactory("sbBTCPool");
22 | const barnFactory = await ethers.getContractFactory("LPToken");
23 | const swap = await SwapContractFactory.attach(swapContrat);
24 | const sbBTCP = await sbBTCFactory.attach(sbBTC_Pool)
25 | const barn = await barnFactory.attach(barnContract)
26 |
27 | nodes = []
28 | var skipped = []
29 |
30 | //console.log(addrs)
31 |
32 | for (i = 0; i < 10; i++) {
33 | nodes.push({
34 | address: addrs[i].address,
35 | claim: sbBTCP.connect(addrs[i]).callStatic.claim(),
36 | barn: barn.balanceOf(addrs[i].address)
37 | })
38 | }
39 | var sum = 0;
40 | const claimed = await Promise.allSettled(nodes.map((s) => s.claim))
41 | const barnBalance = await Promise.allSettled(nodes.map((s) => s.barn))
42 | const nodeList = []
43 | claimed.forEach((s, i) => {
44 | if (s.status == "fulfilled") {
45 | nodeList.push({ address: nodes[i].address, amount: (s.value / 1e8), barnBalance: barnBalance[i].value / 1e18 })
46 | sum += s.value / 1e8
47 | } else {
48 | skipped.push(nodes[i].address)
49 | }
50 | })
51 | const sorted = nodeList.sort(function (a, b) {
52 | return b.amount - a.amount
53 | })
54 | console.log("sum -------------------------------------- ", sum, "time:", new Date(), "contract:", sbBTCP.address)
55 |
56 | sorted.forEach(async (s) => {
57 | console.log(`address: ${s.address} amount: ${s.amount.toFixed(8)}, bal: ${s.barnBalance.toFixed(8)}`)
58 | })
59 | console.log("skipped: ", skipped)
60 | }
61 | main()
62 | .then(() => process.exit(0))
63 | .catch((error) => {
64 | console.error(error);
65 | process.exit(1);
66 | });
67 |
--------------------------------------------------------------------------------
/scripts/showNodes.js:
--------------------------------------------------------------------------------
1 |
2 | const { BN, constants } = require('@openzeppelin/test-helpers');
3 | const { web3 } = require('@openzeppelin/test-helpers/src/setup');
4 | const { ZERO_ADDRESS } = constants
5 | const SwapContract = artifacts.require("SwapContract");
6 |
7 | module.exports = async function (done) {
8 | // await deployer.deploy(LPToken)
9 | try {
10 | const swap = await SwapContract.at(process.env.WALLET)
11 | const res = await swap.getActiveNodes.call({ gas: 500000, gasPrice: 1 * 10 ** 9 })
12 | const val = new BN(1).mul(new BN(10).pow(new BN(8)))
13 | const result = res.map((stake) => {
14 | const amount = web3.utils.hexToNumber(stake.slice(0, 26))
15 | return {
16 | amount: amount / 1e8,
17 | address: "0x" + stake.slice(26, stake.length)
18 | }
19 | }).sort(function (a, b) {
20 | return b.amount - a.amount;
21 | });
22 | console.log(result)
23 | } catch (err) {
24 | console.log(err)
25 | }
26 | done()
27 | };
28 |
--------------------------------------------------------------------------------
/scripts/swapBTC2WBTC.js:
--------------------------------------------------------------------------------
1 | const { ethers } = require("hardhat");
2 | BN = require('bn.js')
3 | const { BigNumber } = require('ethers');
4 |
5 | /*********************************************************************
6 | *
7 | * Boiler Plate script to deploy
8 | *
9 | * July 28, 2021
10 | *
11 | * Deploy with:
12 | * npx hardhat run ./scripts/deploy.js --network development || npx hardhat run ./scripts/deploy.js --network hardhat
13 | * There are still some errors with the above
14 | */
15 | async function main() {
16 | const swapContrat = '0x9e6BA6e811665849f03f56C1f22a8894AEbb3993'
17 | const to = '0x63d9f6A25ddD2c586F4441065Ce7C8412fbBB91e'
18 | const SwapContractFactory = await ethers.getContractFactory("SwapContract");
19 | const swap = await SwapContractFactory.attach(swapContrat);
20 |
21 | // send 0.1 BTC as float
22 | minerFees = new BigNumber.from(30000)
23 |
24 | //prep to collectSwapFeesForBTC
25 | let swapFeesBPS = new BigNumber.from(20);
26 | //let swapAmount = new BigNumber.from(1).mul(new BigNumber.from(10).pow(decimals))
27 |
28 | let swapAmount = new BigNumber.from(10000000) //.1 BTC
29 | let swapFees = swapAmount.mul(swapFeesBPS).div(new BigNumber.from(10000))
30 | //let rewardsAmount = swapFees.sub(minerFees)
31 | let incomingAmount = swapAmount.add(swapFees) //100200000 sats = 1.002 BTC
32 | let spenders = [to]
33 | let amounts = [incomingAmount]
34 |
35 | let btct = await swap.BTCT_ADDR()
36 | const tx = await swap.singleTransferERC20(
37 | btct,
38 | to,
39 | swapAmount,
40 | swapAmount,
41 | swapFees,
42 | [],
43 | )
44 | console.log(tx.hash);
45 | }
46 |
47 | main()
48 | .then(() => process.exit(0))
49 | .catch((error) => {
50 | console.error(error);
51 | process.exit(1);
52 | });
--------------------------------------------------------------------------------
/scripts/swapWBTC2BTC.js:
--------------------------------------------------------------------------------
1 | const { ethers } = require("hardhat");
2 | BN = require('bn.js')
3 | const { BigNumber } = require('ethers');
4 |
5 | /*********************************************************************
6 | *
7 | * Boiler Plate script to deploy
8 | *
9 | * July 28, 2021
10 | *
11 | * Deploy with:
12 | * npx hardhat run ./scripts/deploy.js --network development || npx hardhat run ./scripts/deploy.js --network hardhat
13 | * There are still some errors with the above
14 | */
15 | async function main() {
16 | const swapContrat = '0x9e6BA6e811665849f03f56C1f22a8894AEbb3993'
17 | const to = '0x63d9f6A25ddD2c586F4441065Ce7C8412fbBB91e'
18 | const SwapContractFactory = await ethers.getContractFactory("SwapContract");
19 | const swap = await SwapContractFactory.attach(swapContrat);
20 |
21 | // send 0.1 BTC as float
22 | minerFees = new BigNumber.from(30000)
23 |
24 | //prep to collectSwapFeesForBTC
25 | let swapFeesBPS = new BigNumber.from(20);
26 | //let swapAmount = new BigNumber.from(1).mul(new BigNumber.from(10).pow(decimals))
27 |
28 | let swapAmount = new BigNumber.from(10000000) //.1 BTC
29 | let swapFees = swapAmount.mul(swapFeesBPS).div(new BigNumber.from(10000))
30 | //let rewardsAmount = swapFees.sub(minerFees)
31 | let incomingAmount = swapAmount.add(swapFees) //100200000 sats = 1.002 BTC
32 | let spenders = [to]
33 | let amounts = [incomingAmount]
34 |
35 | const tx = await swap.collectSwapFeesForBTC(
36 | swapAmount,
37 | minerFees,
38 | swapFees,
39 | spenders,
40 | amounts,
41 | )
42 | console.log(tx.hash);
43 | }
44 |
45 | main()
46 | .then(() => process.exit(0))
47 | .catch((error) => {
48 | console.error(error);
49 | process.exit(1);
50 | });
--------------------------------------------------------------------------------
/scripts/testnet.js:
--------------------------------------------------------------------------------
1 | const { BigNumber } = require("@ethersproject/contracts/node_modules/@ethersproject/bignumber")
2 | const hre = require("hardhat")
3 | const { Ethers } = require('ethers')
4 | const ParaSwap = require('../scripts/paraswap.js')
5 | const paraV5 = "https://apiv5.paraswap.io"
6 | const paraswap = new ParaSwap(paraV5, 5)
7 | const ropsten = 3 //ropsten
8 | const mainnet = 1
9 | const swapAddress = '0xf73D63C3eB97389cB5A28C4aD5e8AC428cb16417'
10 | const swapABI = require('../abi/SwapContract.json')
11 | const { default: Web3 } = require('web3');
12 |
13 | //npx hardhat run testnet.js
14 |
15 | const Tokens = {
16 | [ropsten]: {
17 | WETH: {
18 | address: '0xc778417e063141139fce010982780140aa0cd5ab',
19 | decimals: 18
20 | },
21 | WBTC: {
22 | //address: '0x442be68395613bdcd19778e761f03261ec46c06d',
23 | address: '0x7cb2eac36b4bb7c36640f32e806d33e474d1d427',
24 | decimals: 8
25 | },
26 | DAI: {
27 | address: '0xaD6D458402F60fD3Bd25163575031ACDce07538D',
28 | decimals: 18
29 | },
30 | UNI: {
31 | address: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984',
32 | decimals: 18
33 | },
34 | },
35 | [mainnet]: {
36 | ETH: {
37 | address: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
38 | decimals: 18,
39 | },
40 | WETH: {
41 | address: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
42 | decimals: 18
43 | },
44 | USDC: {
45 | address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
46 | decimals: 6,
47 | },
48 | MATIC: {
49 | address: '0x7d1afa7b718fb893db30a3abc0cfc608aacfebb0',
50 | decimals: 18,
51 | },
52 | WBTC: {
53 | address: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599',
54 | decimals: 8
55 | },
56 | UNI: {
57 | address: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984',
58 | decimals: 18
59 | },
60 | COMP: {
61 | address: '0xc00e94cb662c3520282e6f5717214004a7f26888',
62 | decimals: 18
63 | },
64 | MKR: {
65 | address: '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2',
66 | decimals: 18
67 | },
68 | SWINGBY: {
69 | address: '0x8287c7b963b405b7b8d467db9d79eec40625b13a',
70 | decimals: 18
71 | }
72 | },
73 | }
74 |
75 | const srcAmountBTC = "10000000"//0.1 BTC //USE FOR FLOW 1
76 | const srcAmountETH = "1000000000000000000"//1 ETHER //USE FOR FLOW 2
77 | const smallSrcAmountETH = "100000000000000000"//0.1 ETHER //USE FOR FLOW 2
78 |
79 | const giantAmountFlow2 = "15000000000000000000" // 15 ETH
80 |
81 |
82 |
83 | //const srcAmount = "147618252344340533"
84 | //UNI Amount: 147618252344340533
85 | //UNI Address: 0x1f9840a85d5af5bf1d1762f925bdaddc4201f984
86 |
87 |
88 | async function main() {
89 | let data
90 | let getPrice = await paraswap.getPrice(
91 | Tokens[ropsten]['WETH'], // From token - CHANGE THIS
92 | Tokens[ropsten]['WBTC'], // To token - CHANGE THIS
93 | srcAmountETH, //Change this depending on flow 1 vs flow 2
94 | ropsten
95 | )
96 |
97 | //console.log(getPrice)
98 |
99 | const slippage = (decimals) => {
100 | return new BigNumber.from(3).mul(new BigNumber.from(10).pow(decimals - 2)).toString() //Format ERC20 - 0.05
101 | }
102 |
103 | let decimals = Tokens[ropsten]['WETH'].decimals
104 | let minDestAmount = new BigNumber.from(getPrice.price).sub(slippage(decimals))
105 |
106 | //POST request - build TX data to send to contract
107 | const txRequest = await paraswap.buildTransaction(
108 | getPrice.payload, //data from GET request
109 | Tokens[ropsten]['WETH'], // From token - CHANGE THIS
110 | Tokens[ropsten]['WBTC'], // To token - CHANGE THIS
111 | srcAmountETH, //Change this depending on flow 1 vs flow 2
112 | minDestAmount.toString(), //this param is not used for paraswap V5 anymore, redundant
113 | ropsten,
114 | "0x202CCe504e04bEd6fC0521238dDf04Bc9E8E15aB", //SWAP contract - flow 2 simpleSwap - uniswap functions don't care about this param
115 | //"0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC", //user1.address - Flow 1 simpleSwap
116 | true //only params - true for contract -> contract | false for standard transaction object
117 | )
118 | data = txRequest.data //params to execute transaction contract -> contract
119 | const output = txRequest.config.data
120 | const { parse } = require('json-parser')
121 | const parsedOutput = parse(output)
122 | const contractMethod = parsedOutput.priceRoute.contractMethod
123 |
124 |
125 | console.log("Recomended Contract Method:", contractMethod)
126 | //console.log(data)
127 |
128 | if (contractMethod == "simpleSwap") {
129 | console.log(`Getting data for ${contractMethod}`)
130 | const dataArray = [
131 | data[0].fromToken,
132 | data[0].toToken,
133 | data[0].fromAmount,
134 | data[0].toAmount,
135 | data[0].expectedAmount,
136 | data[0].callees,
137 | data[0].exchangeData,
138 | data[0].startIndexes,
139 | data[0].values,
140 | data[0].beneficiary,
141 | data[0].partner,
142 | data[0].feePercent,
143 | data[0].permit,
144 | data[0].deadline,
145 | data[0].uuid
146 | ]
147 | console.log(dataArray)
148 | } else if (contractMethod == "swapOnUniswap") {
149 | console.log(`Getting data for ${contractMethod}`)
150 | console.log(data)
151 | } else if (contractMethod == "swapOnUniswapFork") {
152 | console.log(`Getting data for ${contractMethod}`)
153 | console.log(data)
154 | }
155 |
156 |
157 |
158 | /**
159 | //megaSwap
160 | let routeArray = [
161 | data[0].path[0].path[0].adapters[0].route[0].index,
162 | data[0].path[0].path[0].adapters[0].route[0].targetExchange,
163 | data[0].path[0].path[0].adapters[0].route[0].percent,
164 | data[0].path[0].path[0].adapters[0].route[0].payload,
165 | data[0].path[0].path[0].adapters[0].route[0].networkFee
166 | ]
167 | let pathArray = [
168 | data[0].path[0].fromAmountPercent,
169 | [
170 | data[0].path[0].path[0].to,
171 | data[0].path[0].path[0].totalNetworkFee,
172 | [ //adapters
173 | data[0].path[0].path[0].adapters[0].adapter,
174 | data[0].path[0].path[0].adapters[0].percent,
175 | data[0].path[0].path[0].adapters[0].networkFee,
176 | routeArray
177 | ]
178 | ]
179 | ]
180 | const megaDataArray = [
181 | data[0].fromToken,
182 | data[0].fromAmount,
183 | data[0].toAmount,
184 | data[0].expectedAmount,
185 | data[0].beneficiary,
186 | pathArray,
187 | data[0].partner,
188 | data[0].feePercent,
189 | data[0].permit,
190 | data[0].deadline,
191 | data[0].uuid
192 | ]
193 |
194 | /**
195 | console.log(dataArray)
196 |
197 | console.log("PATH BELOW")
198 | console.log(pathArray)
199 |
200 | console.log("ROUTE BELOW")
201 | console.log(routeArray)
202 | */
203 |
204 |
205 |
206 | //console.log(data[0].path[0].path[0].adapters[0].route[0].targetExchange)
207 |
208 | //console.log(dataArray)
209 | //console.log(data[0].path)
210 | //console.log(data[0].path[0].path)
211 | //console.log(data[0].path[0].path[0].adapters)
212 | //console.log(data[0].path[0].path[0].adapters[0].route)
213 |
214 | }
215 |
216 |
217 | main()
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 | //SWAP: 0xf73D63C3eB97389cB5A28C4aD5e8AC428cb16417
237 |
238 |
239 | //DAI Amount: 548824612259226186639
240 | //DAI Address: 0xaD6D458402F60fD3Bd25163575031ACDce07538D
241 |
242 | //UNI Amount: 147618252344340533
243 | //UNI Address: 0x1f9840a85d5af5bf1d1762f925bdaddc4201f984
--------------------------------------------------------------------------------
/scripts/transferOwner.js:
--------------------------------------------------------------------------------
1 |
2 | const SwingbyToken = artifacts.require("SwingbyToken");
3 |
4 | module.exports = async function (done) {
5 | // await deployer.deploy(LPToken)
6 | try {
7 | const token = await SwingbyToken.at("0xbd6c7cdf51d143b62bb5e5141313a6d41ea3dd54")
8 | console.log("token:", token.address)
9 | await token.transferOwnership(process.env.OWNER)
10 | } catch (err) {
11 | console.log(err)
12 | }
13 | done()
14 | };
15 |
--------------------------------------------------------------------------------
/test/testLPToken.js:
--------------------------------------------------------------------------------
1 | const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers');
2 | const { expect, assert } = require('chai');
3 | const { BigNumber } = require('ethers');
4 | const { ZERO_ADDRESS } = constants;
5 | const TOKEN_DECIMALS = process.env.TOKEN_DECIMALS || 18
6 |
7 |
8 | //Web3 init
9 | //const LPToken = artifacts.require('LPToken');
10 | //const SwapContract = artifacts.require('SwapContract');
11 | describe("Contract: LPToken", () => {
12 |
13 |
14 | let LPTokenFactory, sender, receiver, accounts
15 |
16 | let value, token, mintValue
17 |
18 | const name = "Swingby BTC LP Token";
19 | const symbol = 'sbBTC';
20 |
21 | beforeEach(async () => {
22 | // The bundled BN library is the same one web3 uses under the hood
23 | [sender, receiver, ...addrs] = await ethers.getSigners();
24 | //this contains all of the account objects, access address string -> accounts[n].address
25 | accounts = [sender, receiver, ...addrs]
26 |
27 | LPTokenFactory = await ethers.getContractFactory("LPToken");
28 |
29 | value = new BigNumber.from(1)
30 |
31 | token = await LPTokenFactory.deploy(TOKEN_DECIMALS);
32 |
33 | mintValue = new BigNumber.from(500).mul(new BigNumber.from(10).pow(new BigNumber.from(TOKEN_DECIMALS)))
34 |
35 | await token.mint(sender.address, mintValue)
36 | })
37 |
38 | // You can nest describe calls to create subsections.
39 | describe("LPToken functions", () => {
40 |
41 |
42 | it('has a name', async () => {
43 | expect(await token.name()).to.equal(name)
44 | });
45 | it('has a symbol', async () => {
46 | expect(await token.symbol()).to.equal(symbol);
47 | });
48 | it('has the right decimals', async () => {
49 | decimals = await token.decimals()
50 | expect(new BigNumber.from(decimals)).equal(new BigNumber.from(TOKEN_DECIMALS));
51 | });
52 | it('reverts when minting tokens from not owner', async () => {
53 | // Conditions that trigger a require statement can be precisely tested\
54 | await expectRevert(
55 | token.connect(receiver).mint(receiver.address, value),
56 | 'Ownable: caller is not the owner',
57 | );
58 | });
59 | it('reverts when transferring tokens to the zero address', async () => {
60 | // Conditions that trigger a require statement can be precisely tested
61 | await expectRevert(
62 | token.connect(sender).transfer(constants.ZERO_ADDRESS, value),
63 | 'ERC20: transfer to the zero address',
64 | );
65 | });
66 | it('emits a Transfer event on successful transfers', async () => {
67 | let tx = await token.connect(sender).transfer(receiver.address, value);
68 | let receipt = await tx.wait();
69 | const data = receipt.events[0].args
70 | //console.log(data);//data emitted from Transfer Event
71 |
72 | assert.equal(receipt.events[0].event, 'Transfer', "Emits correct event")
73 | assert.equal(data.from, sender.address)
74 | assert.equal(data.to, receiver.address)
75 | assert.equal(data.value._hex, value._hex)
76 |
77 |
78 | });
79 | it('updates balances on successful transfers', async () => {
80 | await token.connect(sender).transfer(receiver.address, value)
81 |
82 | balanceOfReceiver = await token.balanceOf(receiver.address)
83 | expect(new BigNumber.from(balanceOfReceiver.sub(value))).equal('0')
84 | });
85 | it('emits a Burn event on successful burning', async () => {
86 | let tx = await token.connect(sender).burn(mintValue);
87 | let receipt = await tx.wait();
88 | const data = receipt.events[0].args
89 | //console.log(data);//data emitted from Transfer Event
90 |
91 | assert.equal(receipt.events[0].event, 'Transfer', "Emits correct event")
92 | assert.equal(data.from, sender.address)
93 | assert.equal(data.to, ZERO_ADDRESS)
94 | assert.equal(data.value._hex, mintValue._hex)
95 | });
96 |
97 |
98 |
99 |
100 | });
101 | });
102 |
--------------------------------------------------------------------------------
/test/testSwapContractFactory.js:
--------------------------------------------------------------------------------
1 | const { constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers');
2 | const { expect, assert } = require('chai');
3 | const { BigNumber } = require('ethers');
4 | const { ZERO_ADDRESS } = constants;
5 | const TOKEN_DECIMALS = process.env.TOKEN_DECIMALS || 18
6 |
7 |
8 | //Web3 init
9 | //const LPToken = artifacts.require('LPToken');
10 | //const SwapContract = artifacts.require('SwapContract');
11 | describe("Contract: SwapFactory", () => {
12 |
13 |
14 | let LPTokenFactory, SwapContractFactory, SwapContract, factory, sender, receiver, accounts
15 |
16 | let value, btctTest, mintValue, btctDecimals
17 |
18 |
19 | beforeEach(async () => {
20 | // The bundled BN library is the same one web3 uses under the hood
21 | [sender, receiver, ...addrs] = await ethers.getSigners();
22 | //this contains all of the account objects, access address string -> accounts[n].address
23 | accounts = [sender, receiver, ...addrs]
24 |
25 | LPToken = await ethers.getContractFactory("LPToken");
26 | SwapContractFactory = await ethers.getContractFactory("SwapContractFactory");
27 | SwapContract = await ethers.getContractFactory("SwapContract");
28 |
29 | value = new BigNumber.from(1)
30 |
31 | btctTest = await LPToken.deploy(TOKEN_DECIMALS)
32 |
33 | btctDecimals = await btctTest.decimals()
34 |
35 | mintValue = new BigNumber.from(500).mul(new BigNumber.from(10).pow(new BigNumber.from(TOKEN_DECIMALS)))
36 |
37 | factory = await SwapContractFactory.deploy()
38 |
39 | })
40 |
41 | // You can nest describe calls to create subsections.
42 | describe("Deploy New Contracts", () => {
43 | it('checks the owner after deployment', async () => {
44 | const sc = await factory.connect(receiver).deployNewContracts(receiver.address, btctTest.address, TOKEN_DECIMALS, 0)
45 | const receipt = await sc.wait()
46 |
47 | //get existing contract address -- condensed to separate consts for readability
48 | const lpTokenAddress = receipt.events[receipt.events.length - 1].args.lpToken
49 | const swapContractAddress = receipt.events[receipt.events.length - 1].args.swapContract
50 |
51 | const newLPToken = await LPToken.attach(lpTokenAddress) //equivilant to truffle .at() method
52 | const newSwapContract = await SwapContract.attach(swapContractAddress)
53 |
54 |
55 | expect(await newLPToken.getOwner()).to.equal(newSwapContract.address)
56 | expect(await newSwapContract.owner()).to.equal(receiver.address)
57 |
58 |
59 | });
60 | });
61 | });
62 |
--------------------------------------------------------------------------------
/truffle-config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Use this file to configure your truffle project. It's seeded with some
3 | * common settings for different networks and features like migrations,
4 | * compilation and testing. Uncomment the ones you need or modify
5 | * them to suit your project as necessary.
6 | *
7 | * More information about configuration can be found at:
8 | *
9 | * trufflesuite.com/docs/advanced/configuration
10 | *
11 | * To deploy via Infura you'll need a wallet provider (like @truffle/hdwallet-provider)
12 | * to sign your transactions before they're sent to a remote public node. Infura accounts
13 | * are available for free at: infura.io/register.
14 | *
15 | * You'll also need a mnemonic - the twelve word phrase the wallet uses to generate
16 | * public/private key pairs. If you're publishing your code to GitHub make sure you load this
17 | * phrase from a file you've .gitignored so it doesn't accidentally become public.
18 | *
19 | */
20 | require('dotenv').config();
21 | const mnemonic = [process.env.PRIVATE_KEYS] || "not found"
22 | console.log(mnemonic)
23 | //const HDWalletProvider = require('@truffle/hdwallet-provider');
24 | const HDWalletProvider = require('truffle-hdwallet-provider-privkey');
25 |
26 | // const infuraKey = "fj4jll3k.....";
27 | //
28 | // const fs = require('fs');
29 | //const mnemonic = process.env.SEED
30 |
31 |
32 | module.exports = {
33 | /**
34 | * Networks define how you connect to your ethereum client and let you set the
35 | * defaults web3 uses to send transactions. If you don't specify one truffle
36 | * will spin up a development blockchain for you on port 9545 when you
37 | * run `develop` or `test`. You can ask a truffle command to use a specific
38 | * network from the command line, e.g
39 | *
40 | * $ truffle test --network
41 | */
42 |
43 | networks: {
44 | // Useful for testing. The `development` name is special - truffle uses it by default
45 | // if it's defined here and no other network is specified at the command line.
46 | // You should run a client (like ganache-cli, geth or parity) in a separate terminal
47 | // tab if you use this network and you must also set the `host`, `port` and `network_id`
48 | // options below to some value.
49 | //
50 | development: {
51 | host: "127.0.0.1", // Localhost (default: none)
52 | port: 8545, // Standard Ethereum port (default: none)
53 | network_id: "*", // Any network (default: none)
54 | },
55 | // Another network with more advanced options...
56 | // advanced: {
57 | // port: 8777, // Custom port
58 | // network_id: 1342, // Custom network
59 | // gas: 8500000, // Gas sent with each transaction (default: ~6700000)
60 | // gasPrice: 20000000000, // 20 gwei (in wei) (default: 100 gwei)
61 | // from: , // Account to send txs from (default: accounts[0])
62 | // websockets: true // Enable EventEmitter interface for web3 (default: false)
63 | // },
64 | // Useful for deploying to a public network.
65 | // NB: It's important to wrap the provider as a function.
66 | goerli: {
67 | provider: () => new HDWalletProvider(mnemonic, `https://goerli.infura.io/v3/f35c2a4f3d0941a38a3edb62ed10c847`),
68 | network_id: 5, // Ropsten's id
69 | gas: 5500000, // Ropsten has a lower block limit than mainnet
70 | confirmations: 2, // # of confs to wait between deployments. (default: 0)
71 | timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
72 | skipDryRun: true, // Skip dry run before migrations? (default: false for public nets )
73 | gasPrice: 53000000000
74 | },
75 |
76 | ropsten: {
77 | provider: function () {
78 | return new HDWalletProvider(
79 | mnemonic,
80 | `https://eth-ropsten.alchemyapi.io/v2/5EGdI7OUE9ptMFggrLzsM2dDpBYPMujp`
81 | )
82 | },
83 | network_id: 3, // Ropsten's id
84 | gas: 8000000, // Ropsten has a lower block limit than mainnet
85 | confirmations: 2, // # of confs to wait between deployments. (default: 0)
86 | timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
87 | skipDryRun: true, // Skip dry run before migrations? (default: false for public nets )
88 | gasPrice: 53000000000
89 | },
90 | mainnet: {
91 | provider: () => new HDWalletProvider(mnemonic, `https://mainnet.infura.io/v3/f35c2a4f3d0941a38a3edb62ed10c847`),
92 | network_id: 1, // Ropsten's id
93 | gas: 3000000, // Ropsten has a lower block limit than mainnet
94 | confirmations: 2, // # of confs to wait between deployments. (default: 0)
95 | timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
96 | skipDryRun: true, // Skip dry run before migrations? (default: false for public nets )
97 | gasPrice: 93000000000
98 | },
99 | bsc_testnet: {
100 | provider: () => new HDWalletProvider(mnemonic, `https://data-seed-prebsc-1-s1.binance.org:8545`),
101 | network_id: 97, // Ropsten's id
102 | gas: 7500000, // Ropsten has a lower block limit than mainnet
103 | confirmations: 2, // # of confs to wait between deployments. (default: 0)
104 | timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
105 | skipDryRun: true, // Skip dry run before migrations? (default: false for public nets )
106 | gasPrice: 10000000000
107 | },
108 | bsc_mainnet: {
109 | provider: () => new HDWalletProvider(mnemonic, `https://bsc-dataseed.binance.org`),
110 | network_id: 56, // Ropsten's id
111 | gas: 3000000, // Ropsten has a lower block limit than mainnet
112 | confirmations: 2, // # of confs to wait between deployments. (default: 0)
113 | timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
114 | skipDryRun: true, // Skip dry run before migrations? (default: false for public nets )
115 | gasPrice: 10000000000
116 | }
117 | // Useful for private networks
118 | // private: {
119 | // provider: () => new HDWalletProvider(mnemonic, `https://network.io`),
120 | // network_id: 2111, // This network is yours, in the cloud.
121 | // production: true // Treats this network as if it was a public net. (default: false)
122 | // }
123 | },
124 |
125 | // Set default mocha options here, use special reporters etc.
126 | mocha: {
127 | // timeout: 100000
128 | },
129 |
130 | // Configure your compilers
131 | compilers: {
132 | solc: {
133 | version: "0.8.9", // Fetch exact version from solc-bin (default: truffle's version)
134 | // docker: true, // Use "0.5.1" you've installed locally with docker (default: false)
135 | settings: { // See the solidity docs for advice about optimization and evmVersion
136 | optimizer: {
137 | enabled: true,
138 | runs: 200
139 | },
140 | // evmVersion: "byzantium"
141 | }
142 | },
143 | },
144 | api_keys: {//https://ethereum.stackexchange.com/questions/19437/etherscan-how-can-i-verify-a-contract-with-multiple-imports-deployed-with-truff/20887
145 | etherscan: 'A7EAG5WB4FRAHIURRGWD8HSTM8CVYXZGZ4', //truffle run verify SwapContract LPToken --network ropsten
146 | bscscan: 'VDKSF7XEFIHS9JT8S5B5DH7H3MAIPGMBQ7'
147 | //https://www.npmjs.com/package/truffle-plugin-verify
148 | },
149 | plugins: [
150 | "@chainsafe/truffle-plugin-abigen",
151 | "truffle-contract-size", /*compile first, then run: truffle run contract-size*/
152 | 'truffle-plugin-verify'
153 | ]
154 |
155 | };
156 |
--------------------------------------------------------------------------------
/web3_test/testLPToken.js:
--------------------------------------------------------------------------------
1 | const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers');
2 | const { expect } = require('chai');
3 | const { ZERO_ADDRESS } = constants;
4 |
5 | const LPToken = artifacts.require('LPToken');
6 |
7 | const TOKEN_DECIMALS = process.env.TOKEN_DECIMALS || 18
8 |
9 | contract('LPToken', function (accounts) {
10 | const [sender, receiver] = accounts
11 | const name = "Swingby BTC LP Token";
12 | const symbol = 'sbBTC';
13 |
14 | beforeEach(async function () {
15 | // The bundled BN library is the same one web3 uses under the hood
16 | this.value = new BN(1);
17 |
18 | this.token = await LPToken.new(TOKEN_DECIMALS)
19 |
20 | this.mintValue = new BN(500).mul(new BN(10).pow(new BN(TOKEN_DECIMALS)))
21 |
22 | await this.token.mint(sender, this.mintValue)
23 | });
24 |
25 | it('has a name', async function () {
26 | expect(await this.token.name()).to.equal(name);
27 | });
28 |
29 | it('has a symbol', async function () {
30 | expect(await this.token.symbol()).to.equal(symbol);
31 | });
32 |
33 | it('has right decimals', async function () {
34 | decimals = await this.token.decimals()
35 | expect(decimals).to.bignumber.equal(new BN(TOKEN_DECIMALS));
36 | });
37 |
38 | it('reverts when minting tokens from not owner', async function () {
39 | // Conditions that trigger a require statement can be precisely tested
40 | await expectRevert(
41 | this.token.mint(receiver, this.value, { from: receiver }),
42 | 'Ownable: caller is not the owner',
43 | );
44 | });
45 |
46 | it('reverts when transferring tokens to the zero address', async function () {
47 | // Conditions that trigger a require statement can be precisely tested
48 | await expectRevert(
49 | this.token.transfer(constants.ZERO_ADDRESS, this.value, { from: sender }),
50 | 'ERC20: transfer to the zero address',
51 | );
52 | });
53 |
54 | it('emits a Transfer event on successful transfers', async function () {
55 | const receipt = await this.token.transfer(
56 | receiver, this.value, { from: sender }
57 | );
58 |
59 | // Event assertions can verify that the arguments are the expected ones
60 | expectEvent(receipt, 'Transfer', {
61 | from: sender,
62 | to: receiver,
63 | value: this.value,
64 | });
65 | });
66 |
67 | it('updates balances on successful transfers', async function () {
68 | this.token.transfer(receiver, this.value, { from: sender });
69 |
70 | // BN assertions are automatically available via chai-bn (if using Chai)
71 | balanceOfReceiver = await this.token.balanceOf(receiver)
72 | expect(balanceOfReceiver.sub(this.value)).to.bignumber.equal('0')
73 | });
74 |
75 | it('emits a Burn event on successful burning', async function () {
76 | const burn = await this.token.burn(
77 | this.mintValue, { from: sender }
78 | );
79 |
80 | // Event assertions can verify that the arguments are the expected ones
81 | expectEvent(burn, 'Transfer', {
82 | from: sender,
83 | to: ZERO_ADDRESS,
84 | value: this.mintValue,
85 | });
86 | });
87 | })
--------------------------------------------------------------------------------
/web3_test/testSwapContractFactory.js:
--------------------------------------------------------------------------------
1 | const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers');
2 | const { expect } = require('chai');
3 | const { ZERO_ADDRESS } = constants;
4 | const WBTC_ADDR = "0xEb47a21C1fC00D1E863019906df1771b80DBE182"
5 |
6 | const LPToken = artifacts.require('LPToken');
7 | const SwapContract = artifacts.require('SwapContract');
8 | const SwapContractFactory = artifacts.require('SwapContractFactory');
9 |
10 | const TOKEN_DECIMALS = process.env.TOKEN_DECIMALS || 18
11 |
12 | contract('SwapFactory', function (accounts) {
13 | const [sender, receiver] = accounts;
14 |
15 | beforeEach(async function () {
16 | // The bundled BN library is the same one web3 uses under the hood
17 | this.value = new BN(1);
18 |
19 | this.btctTest = await LPToken.new(TOKEN_DECIMALS)
20 |
21 | this.btctDecimals = await this.btctTest.decimals()
22 |
23 | this.mintValue = new BN(500).mul(new BN(10).pow(this.btctDecimals))
24 |
25 | this.factory = await SwapContractFactory.new();
26 | });
27 |
28 | it('Deploy new contracts and checking the owner', async function () {
29 | const sc = await this.factory.deployNewContracts(receiver, this.btctTest.address, TOKEN_DECIMALS, 0)
30 | const newLPToken = await LPToken.at(sc.receipt.logs[0].args.lpToken)
31 | const newSwapContract = await SwapContract.at(sc.receipt.logs[0].args.swapContract)
32 |
33 | expect(await newLPToken.getOwner()).to.equal(newSwapContract.address)
34 | expect(await newSwapContract.owner()).to.equal(receiver)
35 | })
36 | })
--------------------------------------------------------------------------------