1
0
mirror of https://github.com/oceanprotocol/ocean.js.git synced 2024-11-26 20:39:05 +01:00

merged v4 main

This commit is contained in:
Bogdan Fazakas 2021-11-11 10:52:21 +02:00
commit 2b3448de6b
9 changed files with 3183 additions and 261 deletions

289
package-lock.json generated
View File

@ -2047,15 +2047,15 @@
}
},
"node_modules/@ethereumjs/block": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/@ethereumjs/block/-/block-3.5.1.tgz",
"integrity": "sha512-MoY9bHKABOBK6BW0v1N1Oc0Cve4x/giX67M3TtrVBUsKQTj2eznLGKpydoitxWSZ+WgKKSVhfRMzbCGRwk7T5w==",
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/@ethereumjs/block/-/block-3.6.0.tgz",
"integrity": "sha512-dqLo1LtsLG+Oelu5S5tWUDG0pah3QUwV5TJZy2cm19BXDr4ka/S9XBSgao0i09gTcuPlovlHgcs6d7EZ37urjQ==",
"peer": true,
"dependencies": {
"@ethereumjs/common": "^2.5.0",
"@ethereumjs/tx": "^3.3.1",
"ethereumjs-util": "^7.1.1",
"merkle-patricia-tree": "^4.2.1"
"@ethereumjs/common": "^2.6.0",
"@ethereumjs/tx": "^3.4.0",
"ethereumjs-util": "^7.1.3",
"merkle-patricia-tree": "^4.2.2"
}
},
"node_modules/@ethereumjs/block/node_modules/level-ws": {
@ -2102,19 +2102,18 @@
}
},
"node_modules/@ethereumjs/blockchain": {
"version": "5.4.2",
"resolved": "https://registry.npmjs.org/@ethereumjs/blockchain/-/blockchain-5.4.2.tgz",
"integrity": "sha512-AOAAwz/lw2lciG9gf5wHi7M/qknraXXnLR66lYgbQ04qfyFC3ZE5x/5rLVm1Vu+kfJLlKrYZTmA0IbOkc7kvgw==",
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@ethereumjs/blockchain/-/blockchain-5.5.0.tgz",
"integrity": "sha512-879YVmWbM8OUKLVj+OuEZ+sZFkQOnXYGeak5oi7O1hOjaRv//je+fK2axGP04cbttu7sPCp41zy7O6xw4cut8A==",
"peer": true,
"dependencies": {
"@ethereumjs/block": "^3.5.1",
"@ethereumjs/common": "^2.5.0",
"@ethereumjs/block": "^3.6.0",
"@ethereumjs/common": "^2.6.0",
"@ethereumjs/ethash": "^1.1.0",
"debug": "^2.2.0",
"ethereumjs-util": "^7.1.1",
"ethereumjs-util": "^7.1.3",
"level-mem": "^5.0.1",
"lru-cache": "^5.1.1",
"rlp": "^2.2.4",
"semaphore-async-await": "^1.5.1"
}
},
@ -2134,12 +2133,12 @@
"peer": true
},
"node_modules/@ethereumjs/common": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.5.0.tgz",
"integrity": "sha512-DEHjW6e38o+JmB/NO3GZBpW4lpaiBpkFgXF6jLcJ6gETBYpEyaA5nTimsWBUJR3Vmtm/didUEbNjajskugZORg==",
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.0.tgz",
"integrity": "sha512-Cq2qS0FTu6O2VU1sgg+WyU9Ps0M6j/BEMHN+hRaECXCV/r0aI78u4N6p52QW/BDVhwWZpCdrvG8X7NJdzlpNUA==",
"dependencies": {
"crc-32": "^1.2.0",
"ethereumjs-util": "^7.1.1"
"ethereumjs-util": "^7.1.3"
}
},
"node_modules/@ethereumjs/ethash": {
@ -2165,33 +2164,32 @@
}
},
"node_modules/@ethereumjs/tx": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.3.2.tgz",
"integrity": "sha512-6AaJhwg4ucmwTvw/1qLaZUX5miWrwZ4nLOUsKyb/HtzS3BMw/CasKhdi1ims9mBKeK9sOJCH4qGKOBGyJCeeog==",
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.4.0.tgz",
"integrity": "sha512-WWUwg1PdjHKZZxPPo274ZuPsJCWV3SqATrEKQP1n2DrVYVP1aZIYpo/mFaA0BDoE0tIQmBeimRCEA0Lgil+yYw==",
"dependencies": {
"@ethereumjs/common": "^2.5.0",
"ethereumjs-util": "^7.1.2"
"@ethereumjs/common": "^2.6.0",
"ethereumjs-util": "^7.1.3"
}
},
"node_modules/@ethereumjs/vm": {
"version": "5.5.3",
"resolved": "https://registry.npmjs.org/@ethereumjs/vm/-/vm-5.5.3.tgz",
"integrity": "sha512-0k5OreWnlgXYs54wohgO11jtGI05GDasj2EYxzuaStxTi15CS3vow5wGYELC1pG9xngE1F/mFmKi/f14XRuDow==",
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/@ethereumjs/vm/-/vm-5.6.0.tgz",
"integrity": "sha512-J2m/OgjjiGdWF2P9bj/4LnZQ1zRoZhY8mRNVw/N3tXliGI8ai1sI1mlDPkLpeUUM4vq54gH6n0ZlSpz8U/qlYQ==",
"peer": true,
"dependencies": {
"@ethereumjs/block": "^3.5.0",
"@ethereumjs/blockchain": "^5.4.1",
"@ethereumjs/common": "^2.5.0",
"@ethereumjs/tx": "^3.3.1",
"@ethereumjs/block": "^3.6.0",
"@ethereumjs/blockchain": "^5.5.0",
"@ethereumjs/common": "^2.6.0",
"@ethereumjs/tx": "^3.4.0",
"async-eventemitter": "^0.2.4",
"core-js-pure": "^3.0.1",
"debug": "^2.2.0",
"ethereumjs-util": "^7.1.1",
"ethereumjs-util": "^7.1.3",
"functional-red-black-tree": "^1.0.1",
"mcl-wasm": "^0.7.1",
"merkle-patricia-tree": "^4.2.1",
"rustbn.js": "~0.2.0",
"util.promisify": "^1.0.1"
"merkle-patricia-tree": "^4.2.2",
"rustbn.js": "~0.2.0"
}
},
"node_modules/@ethereumjs/vm/node_modules/debug": {
@ -3053,7 +3051,7 @@
"node_modules/@oceanprotocol/contracts": {
"name": "hardhat-project",
"version": "v1.0.0-alpha.1",
"resolved": "git+ssh://git@github.com/oceanprotocol/contracts.git#a8292971264794219e86c46c4f5d8eb9d5ce9d37",
"resolved": "git+ssh://git@github.com/oceanprotocol/contracts.git#c1bea5033dfc9071105a11b63ce86d8e8f612b7b",
"dependencies": {
"@balancer-labs/v2-pool-utils": "^1.0.0",
"@openzeppelin/contracts": "^4.2.0",
@ -3552,9 +3550,9 @@
"integrity": "sha512-BFo/nyxwhoHqPrqBQA1EAmSxeNnspGLiOCMa9pAL7WYSjyNBlrHaqCMO/F2O87G+NUK/u06E70DiSP2BFP0ZZw=="
},
"node_modules/@truffle/codec": {
"version": "0.11.17",
"resolved": "https://registry.npmjs.org/@truffle/codec/-/codec-0.11.17.tgz",
"integrity": "sha512-WO9D5TVyTf9czqdsfK/qqYeSS//zWcHBgQgSNKPlCDb6koCNLxG5yGbb4P+0bZvTUNS2e2iIdN92QHg00wMbSQ==",
"version": "0.11.18",
"resolved": "https://registry.npmjs.org/@truffle/codec/-/codec-0.11.18.tgz",
"integrity": "sha512-OCsKQHOBAmjr+9DypTkTxWYqHmCd388astUvC+ycwlmAqGKIYy2GzpOIX4pX7YX0q/g2iuixEMCTlF440YiNMA==",
"dependencies": {
"@truffle/abi-utils": "^0.2.4",
"@truffle/compile-common": "^0.7.22",
@ -3653,17 +3651,18 @@
}
},
"node_modules/@truffle/contract": {
"version": "4.3.38",
"resolved": "https://registry.npmjs.org/@truffle/contract/-/contract-4.3.38.tgz",
"integrity": "sha512-11HL9IJTmd45pVXJvEaRYeyuhf8GmAgRD7bTYBZj2CiMBnt0337Fg7Zz/GuTpUUW2h3fbyTYO4hgOntxdQjZ5A==",
"version": "4.3.39",
"resolved": "https://registry.npmjs.org/@truffle/contract/-/contract-4.3.39.tgz",
"integrity": "sha512-ZBCrFUWaTtOvKlJw2J2bDwaBghGDvb5AeVU1WxHvwLnzGqCHzIE6dhZixItdFQgbuZ2gJAxzFQVT38miiK7ufA==",
"dependencies": {
"@ensdomains/ensjs": "^2.0.1",
"@truffle/blockchain-utils": "^0.0.31",
"@truffle/contract-schema": "^3.4.3",
"@truffle/debug-utils": "^5.1.18",
"@truffle/debug-utils": "^5.1.19",
"@truffle/error": "^0.0.14",
"@truffle/interface-adapter": "^0.5.8",
"bignumber.js": "^7.2.1",
"debug": "^4.3.1",
"ethers": "^4.0.32",
"web3": "1.5.3",
"web3-core-helpers": "1.5.3",
@ -3709,9 +3708,9 @@
}
},
"node_modules/@truffle/contract/node_modules/@types/node": {
"version": "12.20.36",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.36.tgz",
"integrity": "sha512-+5haRZ9uzI7rYqzDznXgkuacqb6LJhAti8mzZKWxIXn/WEtvB+GHVJ7AuMwcN1HMvXOSJcrvA6PPoYHYOYYebA=="
"version": "12.20.37",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.37.tgz",
"integrity": "sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA=="
},
"node_modules/@truffle/contract/node_modules/cacheable-request": {
"version": "6.1.0",
@ -4147,11 +4146,11 @@
}
},
"node_modules/@truffle/debug-utils": {
"version": "5.1.18",
"resolved": "https://registry.npmjs.org/@truffle/debug-utils/-/debug-utils-5.1.18.tgz",
"integrity": "sha512-QBq1vA/YozksQZGjyA7o482AuT8KW5gvO8VmYM/PIDllCIqDruEZuz4DZ+zpVUPXyVoJycFo+RKnM/TLE1AZRQ==",
"version": "5.1.19",
"resolved": "https://registry.npmjs.org/@truffle/debug-utils/-/debug-utils-5.1.19.tgz",
"integrity": "sha512-MWk2DszA6Alme1r4SrWu7BZgz7RNf1TsxdJuSToSltGiJE7DDwV+qsfQ+AGY/PoLKPTQ2xW/sd23BQheA+W9qA==",
"dependencies": {
"@truffle/codec": "^0.11.17",
"@truffle/codec": "^0.11.18",
"@trufflesuite/chromafi": "^2.2.2",
"bn.js": "^5.1.3",
"chalk": "^2.4.2",
@ -4244,9 +4243,9 @@
}
},
"node_modules/@truffle/interface-adapter/node_modules/@types/node": {
"version": "12.20.36",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.36.tgz",
"integrity": "sha512-+5haRZ9uzI7rYqzDznXgkuacqb6LJhAti8mzZKWxIXn/WEtvB+GHVJ7AuMwcN1HMvXOSJcrvA6PPoYHYOYYebA=="
"version": "12.20.37",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.37.tgz",
"integrity": "sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA=="
},
"node_modules/@truffle/interface-adapter/node_modules/bignumber.js": {
"version": "9.0.1",
@ -7469,9 +7468,9 @@
}
},
"node_modules/core-js-pure": {
"version": "3.19.0",
"resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.19.0.tgz",
"integrity": "sha512-UEQk8AxyCYvNAs6baNoPqDADv7BX0AmBLGxVsrAifPPx/C8EAzV4Q+2ZUJqVzfI2TQQEZITnwUkWcHpgc/IubQ==",
"version": "3.19.1",
"resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.19.1.tgz",
"integrity": "sha512-Q0Knr8Es84vtv62ei6/6jXH/7izKmOrtrxH9WJTHLCMAVeU+8TF8z8Nr08CsH4Ot0oJKzBzJJL9SJBYIv7WlfQ==",
"hasInstallScript": true,
"peer": true,
"funding": {
@ -11108,15 +11107,6 @@
}
}
},
"node_modules/for-each": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
"integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
"peer": true,
"dependencies": {
"is-callable": "^1.1.3"
}
},
"node_modules/for-in": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
@ -12662,9 +12652,9 @@
}
},
"node_modules/hardhat": {
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.6.7.tgz",
"integrity": "sha512-Mua01f6ZN1feQLktHSH2p5A5LCdA+Wf7+O2lJDH6wClvWPtI2eqKNNY2gxBwYXoQ28GZrT3K6mqQOZeRWAca6Q==",
"version": "2.6.8",
"resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.6.8.tgz",
"integrity": "sha512-iRVd5DgcIVV3rNXMlogOfwlXAhHp7Wy/OjjFiUhTey8Unvo6oq5+Is5ANiKVN+Iw07Pcb/HpkGt7jCB6a4ITgg==",
"peer": true,
"dependencies": {
"@ethereumjs/block": "^3.4.0",
@ -13779,9 +13769,9 @@
}
},
"node_modules/highlightjs-solidity": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/highlightjs-solidity/-/highlightjs-solidity-2.0.1.tgz",
"integrity": "sha512-9YY+HQpXMTrF8HgRByjeQhd21GXAz2ktMPTcs6oWSj5HJR52fgsNoelMOmgigwcpt9j4tu4IVSaWaJB2n2TbvQ=="
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/highlightjs-solidity/-/highlightjs-solidity-2.0.2.tgz",
"integrity": "sha512-q0aYUKiZ9MPQg41qx/KpXKaCpqql50qTvmwGYyLFfcjt9AE/+C9CwjVIdJZc7EYj6NGgJuFJ4im1gfgrzUU1fQ=="
},
"node_modules/hmac-drbg": {
"version": "1.0.1",
@ -23186,22 +23176,6 @@
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
},
"node_modules/util.promisify": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.1.1.tgz",
"integrity": "sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw==",
"peer": true,
"dependencies": {
"call-bind": "^1.0.0",
"define-properties": "^1.1.3",
"for-each": "^0.3.3",
"has-symbols": "^1.0.1",
"object.getownpropertydescriptors": "^2.1.1"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/utils-merge": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
@ -27215,15 +27189,15 @@
}
},
"@ethereumjs/block": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/@ethereumjs/block/-/block-3.5.1.tgz",
"integrity": "sha512-MoY9bHKABOBK6BW0v1N1Oc0Cve4x/giX67M3TtrVBUsKQTj2eznLGKpydoitxWSZ+WgKKSVhfRMzbCGRwk7T5w==",
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/@ethereumjs/block/-/block-3.6.0.tgz",
"integrity": "sha512-dqLo1LtsLG+Oelu5S5tWUDG0pah3QUwV5TJZy2cm19BXDr4ka/S9XBSgao0i09gTcuPlovlHgcs6d7EZ37urjQ==",
"peer": true,
"requires": {
"@ethereumjs/common": "^2.5.0",
"@ethereumjs/tx": "^3.3.1",
"ethereumjs-util": "^7.1.1",
"merkle-patricia-tree": "^4.2.1"
"@ethereumjs/common": "^2.6.0",
"@ethereumjs/tx": "^3.4.0",
"ethereumjs-util": "^7.1.3",
"merkle-patricia-tree": "^4.2.2"
},
"dependencies": {
"level-ws": {
@ -27266,19 +27240,18 @@
}
},
"@ethereumjs/blockchain": {
"version": "5.4.2",
"resolved": "https://registry.npmjs.org/@ethereumjs/blockchain/-/blockchain-5.4.2.tgz",
"integrity": "sha512-AOAAwz/lw2lciG9gf5wHi7M/qknraXXnLR66lYgbQ04qfyFC3ZE5x/5rLVm1Vu+kfJLlKrYZTmA0IbOkc7kvgw==",
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@ethereumjs/blockchain/-/blockchain-5.5.0.tgz",
"integrity": "sha512-879YVmWbM8OUKLVj+OuEZ+sZFkQOnXYGeak5oi7O1hOjaRv//je+fK2axGP04cbttu7sPCp41zy7O6xw4cut8A==",
"peer": true,
"requires": {
"@ethereumjs/block": "^3.5.1",
"@ethereumjs/common": "^2.5.0",
"@ethereumjs/block": "^3.6.0",
"@ethereumjs/common": "^2.6.0",
"@ethereumjs/ethash": "^1.1.0",
"debug": "^2.2.0",
"ethereumjs-util": "^7.1.1",
"ethereumjs-util": "^7.1.3",
"level-mem": "^5.0.1",
"lru-cache": "^5.1.1",
"rlp": "^2.2.4",
"semaphore-async-await": "^1.5.1"
},
"dependencies": {
@ -27300,12 +27273,12 @@
}
},
"@ethereumjs/common": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.5.0.tgz",
"integrity": "sha512-DEHjW6e38o+JmB/NO3GZBpW4lpaiBpkFgXF6jLcJ6gETBYpEyaA5nTimsWBUJR3Vmtm/didUEbNjajskugZORg==",
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.0.tgz",
"integrity": "sha512-Cq2qS0FTu6O2VU1sgg+WyU9Ps0M6j/BEMHN+hRaECXCV/r0aI78u4N6p52QW/BDVhwWZpCdrvG8X7NJdzlpNUA==",
"requires": {
"crc-32": "^1.2.0",
"ethereumjs-util": "^7.1.1"
"ethereumjs-util": "^7.1.3"
}
},
"@ethereumjs/ethash": {
@ -27333,33 +27306,32 @@
}
},
"@ethereumjs/tx": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.3.2.tgz",
"integrity": "sha512-6AaJhwg4ucmwTvw/1qLaZUX5miWrwZ4nLOUsKyb/HtzS3BMw/CasKhdi1ims9mBKeK9sOJCH4qGKOBGyJCeeog==",
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.4.0.tgz",
"integrity": "sha512-WWUwg1PdjHKZZxPPo274ZuPsJCWV3SqATrEKQP1n2DrVYVP1aZIYpo/mFaA0BDoE0tIQmBeimRCEA0Lgil+yYw==",
"requires": {
"@ethereumjs/common": "^2.5.0",
"ethereumjs-util": "^7.1.2"
"@ethereumjs/common": "^2.6.0",
"ethereumjs-util": "^7.1.3"
}
},
"@ethereumjs/vm": {
"version": "5.5.3",
"resolved": "https://registry.npmjs.org/@ethereumjs/vm/-/vm-5.5.3.tgz",
"integrity": "sha512-0k5OreWnlgXYs54wohgO11jtGI05GDasj2EYxzuaStxTi15CS3vow5wGYELC1pG9xngE1F/mFmKi/f14XRuDow==",
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/@ethereumjs/vm/-/vm-5.6.0.tgz",
"integrity": "sha512-J2m/OgjjiGdWF2P9bj/4LnZQ1zRoZhY8mRNVw/N3tXliGI8ai1sI1mlDPkLpeUUM4vq54gH6n0ZlSpz8U/qlYQ==",
"peer": true,
"requires": {
"@ethereumjs/block": "^3.5.0",
"@ethereumjs/blockchain": "^5.4.1",
"@ethereumjs/common": "^2.5.0",
"@ethereumjs/tx": "^3.3.1",
"@ethereumjs/block": "^3.6.0",
"@ethereumjs/blockchain": "^5.5.0",
"@ethereumjs/common": "^2.6.0",
"@ethereumjs/tx": "^3.4.0",
"async-eventemitter": "^0.2.4",
"core-js-pure": "^3.0.1",
"debug": "^2.2.0",
"ethereumjs-util": "^7.1.1",
"ethereumjs-util": "^7.1.3",
"functional-red-black-tree": "^1.0.1",
"mcl-wasm": "^0.7.1",
"merkle-patricia-tree": "^4.2.1",
"rustbn.js": "~0.2.0",
"util.promisify": "^1.0.1"
"merkle-patricia-tree": "^4.2.2",
"rustbn.js": "~0.2.0"
},
"dependencies": {
"debug": {
@ -27883,7 +27855,7 @@
}
},
"@oceanprotocol/contracts": {
"version": "git+ssh://git@github.com/oceanprotocol/contracts.git#a8292971264794219e86c46c4f5d8eb9d5ce9d37",
"version": "git+ssh://git@github.com/oceanprotocol/contracts.git#c1bea5033dfc9071105a11b63ce86d8e8f612b7b",
"from": "@oceanprotocol/contracts@github:oceanprotocol/contracts#v4main",
"requires": {
"@balancer-labs/v2-pool-utils": "^1.0.0",
@ -28318,9 +28290,9 @@
"integrity": "sha512-BFo/nyxwhoHqPrqBQA1EAmSxeNnspGLiOCMa9pAL7WYSjyNBlrHaqCMO/F2O87G+NUK/u06E70DiSP2BFP0ZZw=="
},
"@truffle/codec": {
"version": "0.11.17",
"resolved": "https://registry.npmjs.org/@truffle/codec/-/codec-0.11.17.tgz",
"integrity": "sha512-WO9D5TVyTf9czqdsfK/qqYeSS//zWcHBgQgSNKPlCDb6koCNLxG5yGbb4P+0bZvTUNS2e2iIdN92QHg00wMbSQ==",
"version": "0.11.18",
"resolved": "https://registry.npmjs.org/@truffle/codec/-/codec-0.11.18.tgz",
"integrity": "sha512-OCsKQHOBAmjr+9DypTkTxWYqHmCd388astUvC+ycwlmAqGKIYy2GzpOIX4pX7YX0q/g2iuixEMCTlF440YiNMA==",
"requires": {
"@truffle/abi-utils": "^0.2.4",
"@truffle/compile-common": "^0.7.22",
@ -28413,17 +28385,18 @@
}
},
"@truffle/contract": {
"version": "4.3.38",
"resolved": "https://registry.npmjs.org/@truffle/contract/-/contract-4.3.38.tgz",
"integrity": "sha512-11HL9IJTmd45pVXJvEaRYeyuhf8GmAgRD7bTYBZj2CiMBnt0337Fg7Zz/GuTpUUW2h3fbyTYO4hgOntxdQjZ5A==",
"version": "4.3.39",
"resolved": "https://registry.npmjs.org/@truffle/contract/-/contract-4.3.39.tgz",
"integrity": "sha512-ZBCrFUWaTtOvKlJw2J2bDwaBghGDvb5AeVU1WxHvwLnzGqCHzIE6dhZixItdFQgbuZ2gJAxzFQVT38miiK7ufA==",
"requires": {
"@ensdomains/ensjs": "^2.0.1",
"@truffle/blockchain-utils": "^0.0.31",
"@truffle/contract-schema": "^3.4.3",
"@truffle/debug-utils": "^5.1.18",
"@truffle/debug-utils": "^5.1.19",
"@truffle/error": "^0.0.14",
"@truffle/interface-adapter": "^0.5.8",
"bignumber.js": "^7.2.1",
"debug": "^4.3.1",
"ethers": "^4.0.32",
"web3": "1.5.3",
"web3-core-helpers": "1.5.3",
@ -28454,9 +28427,9 @@
}
},
"@types/node": {
"version": "12.20.36",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.36.tgz",
"integrity": "sha512-+5haRZ9uzI7rYqzDznXgkuacqb6LJhAti8mzZKWxIXn/WEtvB+GHVJ7AuMwcN1HMvXOSJcrvA6PPoYHYOYYebA=="
"version": "12.20.37",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.37.tgz",
"integrity": "sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA=="
},
"cacheable-request": {
"version": "6.1.0",
@ -28820,11 +28793,11 @@
}
},
"@truffle/debug-utils": {
"version": "5.1.18",
"resolved": "https://registry.npmjs.org/@truffle/debug-utils/-/debug-utils-5.1.18.tgz",
"integrity": "sha512-QBq1vA/YozksQZGjyA7o482AuT8KW5gvO8VmYM/PIDllCIqDruEZuz4DZ+zpVUPXyVoJycFo+RKnM/TLE1AZRQ==",
"version": "5.1.19",
"resolved": "https://registry.npmjs.org/@truffle/debug-utils/-/debug-utils-5.1.19.tgz",
"integrity": "sha512-MWk2DszA6Alme1r4SrWu7BZgz7RNf1TsxdJuSToSltGiJE7DDwV+qsfQ+AGY/PoLKPTQ2xW/sd23BQheA+W9qA==",
"requires": {
"@truffle/codec": "^0.11.17",
"@truffle/codec": "^0.11.18",
"@trufflesuite/chromafi": "^2.2.2",
"bn.js": "^5.1.3",
"chalk": "^2.4.2",
@ -28915,9 +28888,9 @@
}
},
"@types/node": {
"version": "12.20.36",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.36.tgz",
"integrity": "sha512-+5haRZ9uzI7rYqzDznXgkuacqb6LJhAti8mzZKWxIXn/WEtvB+GHVJ7AuMwcN1HMvXOSJcrvA6PPoYHYOYYebA=="
"version": "12.20.37",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.37.tgz",
"integrity": "sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA=="
},
"bignumber.js": {
"version": "9.0.1",
@ -31528,9 +31501,9 @@
}
},
"core-js-pure": {
"version": "3.19.0",
"resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.19.0.tgz",
"integrity": "sha512-UEQk8AxyCYvNAs6baNoPqDADv7BX0AmBLGxVsrAifPPx/C8EAzV4Q+2ZUJqVzfI2TQQEZITnwUkWcHpgc/IubQ==",
"version": "3.19.1",
"resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.19.1.tgz",
"integrity": "sha512-Q0Knr8Es84vtv62ei6/6jXH/7izKmOrtrxH9WJTHLCMAVeU+8TF8z8Nr08CsH4Ot0oJKzBzJJL9SJBYIv7WlfQ==",
"peer": true
},
"core-util-is": {
@ -34462,15 +34435,6 @@
"integrity": "sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==",
"peer": true
},
"for-each": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
"integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
"peer": true,
"requires": {
"is-callable": "^1.1.3"
}
},
"for-in": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
@ -35507,9 +35471,9 @@
}
},
"hardhat": {
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.6.7.tgz",
"integrity": "sha512-Mua01f6ZN1feQLktHSH2p5A5LCdA+Wf7+O2lJDH6wClvWPtI2eqKNNY2gxBwYXoQ28GZrT3K6mqQOZeRWAca6Q==",
"version": "2.6.8",
"resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.6.8.tgz",
"integrity": "sha512-iRVd5DgcIVV3rNXMlogOfwlXAhHp7Wy/OjjFiUhTey8Unvo6oq5+Is5ANiKVN+Iw07Pcb/HpkGt7jCB6a4ITgg==",
"peer": true,
"requires": {
"@ethereumjs/block": "^3.4.0",
@ -36376,9 +36340,9 @@
"integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A=="
},
"highlightjs-solidity": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/highlightjs-solidity/-/highlightjs-solidity-2.0.1.tgz",
"integrity": "sha512-9YY+HQpXMTrF8HgRByjeQhd21GXAz2ktMPTcs6oWSj5HJR52fgsNoelMOmgigwcpt9j4tu4IVSaWaJB2n2TbvQ=="
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/highlightjs-solidity/-/highlightjs-solidity-2.0.2.tgz",
"integrity": "sha512-q0aYUKiZ9MPQg41qx/KpXKaCpqql50qTvmwGYyLFfcjt9AE/+C9CwjVIdJZc7EYj6NGgJuFJ4im1gfgrzUU1fQ=="
},
"hmac-drbg": {
"version": "1.0.1",
@ -43650,19 +43614,6 @@
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
},
"util.promisify": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.1.1.tgz",
"integrity": "sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw==",
"peer": true,
"requires": {
"call-bind": "^1.0.0",
"define-properties": "^1.1.3",
"for-each": "^0.3.3",
"has-symbols": "^1.0.1",
"object.getownpropertydescriptors": "^2.1.1"
}
},
"utils-merge": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",

View File

@ -24,6 +24,8 @@
"release": "release-it --non-interactive",
"changelog": "auto-changelog -p",
"prepublishOnly": "npm run build",
"test:ss": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/pools/ssContracts/SideStaking.test.ts'",
"test:fixed": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/pools/fixedRate/FixedRateExchange.test.ts'",
"test:pool": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/pools/balancer/Pool.test.ts'",
"test:dt": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/Datatoken.test.ts'",
"test:nftDt": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/NFTDatatoken.test.ts'",

View File

@ -2,12 +2,13 @@ import Web3 from 'web3'
import { AbiItem } from 'web3-utils/types'
import { TransactionReceipt } from 'web3-core'
import { Contract } from 'web3-eth-contract'
import { Logger, getFairGasPrice } from '../../utils'
import { Logger, getFairGasPrice, LoggerInstance } from '../../utils'
import BigNumber from 'bignumber.js'
import PoolTemplate from '@oceanprotocol/contracts/artifacts/contracts/pools/balancer/BPool.sol/BPool.json'
import defaultPool from '@oceanprotocol/contracts/artifacts/contracts/pools/FactoryRouter.sol/FactoryRouter.json'
import defaultERC20ABI from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json'
import Decimal from 'decimal.js'
const BN = require('bn.js')
const MaxUint256 =
'115792089237316195423570985008687907853269984665640564039457584007913129639934'
@ -29,7 +30,7 @@ export class Pool {
}
/**
* Estimate gas cost for collectMarketFee
* Estimate gas cost for approval function
* @param {String} account
* @param {String} tokenAddress
* @param {String} spender
@ -53,10 +54,11 @@ export class Pool {
let estGas
try {
estGas = await tokenContract.methods
.approve(spender, amount)
.approve(spender, new BigNumber(amount))
.estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
LoggerInstance.error('estimage gas failed for approve!', e)
}
return estGas
}
@ -162,6 +164,38 @@ export class Pool {
return result
}
/**
* Estimate gas cost for setSwapFee
* @param {String} account
* @param {String} tokenAddress
* @param {String} spender
* @param {String} amount
* @param {String} force
* @param {Contract} contractInstance optional contract instance
* @return {Promise<number>}
*/
public async estSetSwapFee(
account: string,
poolAddress: string,
fee: string,
contractInstance?: Contract
): Promise<number> {
const poolContract =
contractInstance ||
new this.web3.eth.Contract(defaultERC20ABI.abi as AbiItem[], poolAddress)
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas
try {
estGas = await poolContract.methods
.setSwapFee(fee)
.estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
}
return estGas
}
/**
* Set pool fee
* @param {String} account
@ -177,10 +211,12 @@ export class Pool {
from: account
})
let result = null
const estGas = await this.estSetSwapFee(account, poolAddress, fee)
try {
result = await pool.methods.setSwapFee(this.web3.utils.toWei(fee)).send({
from: account,
gas: this.GASLIMIT_DEFAULT,
gas: estGas,
gasPrice: await getFairGasPrice(this.web3)
})
} catch (e) {
@ -705,7 +741,7 @@ export class Pool {
tokenAmountIn,
tokenOut,
minAmountOut,
maxPrice ? this.web3.utils.toWei(maxPrice) : MaxUint256
maxPrice || MaxUint256
)
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
@ -715,37 +751,38 @@ export class Pool {
}
async amountToUnits(token: string, amount: string): Promise<string> {
let decimals = 18
const tokenContract = new this.web3.eth.Contract(
defaultERC20ABI.abi as AbiItem[],
token
)
try {
decimals = await tokenContract.methods.decimals().call()
const tokenContract = new this.web3.eth.Contract(
defaultERC20ABI.abi as AbiItem[],
token
)
let decimals = await tokenContract.methods.decimals().call()
if (decimals === '0') {
decimals = 18
}
const amountFormatted = new BigNumber(parseInt(amount) * 10 ** decimals)
return amountFormatted.toString()
} catch (e) {
this.logger.error('ERROR: FAILED TO CALL DECIMALS(), USING 18')
}
const amountFormatted = new BigNumber(parseInt(amount) * 10 ** decimals)
return amountFormatted.toString()
}
async unitsToAmount(token: string, amount: string): Promise<string> {
let decimals = 18
const tokenContract = new this.web3.eth.Contract(
defaultERC20ABI.abi as AbiItem[],
token
)
try {
decimals = await tokenContract.methods.decimals().call()
const tokenContract = new this.web3.eth.Contract(
defaultERC20ABI.abi as AbiItem[],
token
)
let decimals = await tokenContract.methods.decimals().call()
if (decimals === '0') {
decimals = 18
}
const amountFormatted = new BigNumber(parseInt(amount) / 10 ** decimals)
return amountFormatted.toString()
} catch (e) {
this.logger.error('ERROR: FAILED TO CALL DECIMALS(), USING 18')
}
const amountFormatted = new BigNumber(parseInt(amount) / 10 ** decimals)
return amountFormatted.toString()
}
/**
@ -785,7 +822,8 @@ export class Pool {
minAmountOutFormatted.toString(),
maxPrice ? this.web3.utils.toWei(maxPrice) : MaxUint256
)
console.log(minAmountOutFormatted, 'minamoutnoutformatted')
// console.log(minAmountOutFormatted, 'minamoutnoutformatted')
try {
result = await pool.methods
.swapExactAmountIn(
@ -842,7 +880,7 @@ export class Pool {
maxAmountIn,
tokenOut,
amountOut,
maxPrice ? this.web3.utils.toWei(maxPrice) : MaxUint256
maxPrice || MaxUint256
)
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
@ -930,7 +968,7 @@ export class Pool {
let estGas
try {
estGas = await poolContract.methods
.joinPool(this.web3.utils.toWei(poolAmountOut), maxAmountsIn)
.joinPool(poolAmountOut, maxAmountsIn)
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
@ -1009,7 +1047,7 @@ export class Pool {
let estGas
try {
estGas = await poolContract.methods
.exitPool(this.web3.utils.toWei(poolAmountIn), minAmountsOut)
.exitPool(poolAmountIn, minAmountsOut)
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
@ -1046,6 +1084,7 @@ export class Pool {
this.web3.utils.toWei(poolAmountIn),
weiMinAmountsOut
)
try {
result = await pool.methods
.exitPool(this.web3.utils.toWei(poolAmountIn), weiMinAmountsOut)
@ -1198,6 +1237,7 @@ export class Pool {
this.web3.utils.toWei(poolAmountOut),
maxAmountInFormatted
)
try {
result = await pool.methods
.joinswapPoolAmountOut(
@ -1277,6 +1317,7 @@ export class Pool {
this.web3.utils.toWei(poolAmountIn),
minTokenOutFormatted
)
try {
result = await pool.methods
.exitswapPoolAmountIn(
@ -1355,6 +1396,7 @@ export class Pool {
this.web3.utils.toWei(tokenAmountOut),
this.web3.utils.toWei(maxPoolAmountIn)
)
try {
result = await pool.methods
.exitswapExternAmountOut(
@ -1472,6 +1514,7 @@ export class Pool {
const result = await pool.methods
.getAmountOutExactIn(tokenIn, tokenOut, amountInFormatted)
.call()
amount = await this.unitsToAmount(tokenOut, result)
} catch (e) {
this.logger.error('ERROR: Failed to calcOutGivenIn')
@ -1481,27 +1524,18 @@ export class Pool {
public async calcPoolOutGivenSingleIn(
poolAddress: string,
tokenBalanceIn: string,
tokenWeightIn: string,
poolSupply: string,
totalWeight: string,
tokenAmountIn: string,
swapFee: string
tokenIn: string,
tokenAmountIn: string
): Promise<string> {
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
let amount = null
try {
const result = await pool.methods
.calcPoolOutGivenSingleIn(
this.web3.utils.toWei(tokenBalanceIn),
this.web3.utils.toWei(tokenWeightIn),
this.web3.utils.toWei(poolSupply),
this.web3.utils.toWei(totalWeight),
this.web3.utils.toWei(tokenAmountIn),
this.web3.utils.toWei(swapFee)
)
.calcPoolOutSingleIn(tokenIn, await this.amountToUnits(tokenIn, tokenAmountIn))
.call()
amount = this.web3.utils.fromWei(result)
amount = await this.unitsToAmount(poolAddress, result)
} catch (e) {
this.logger.error(`ERROR: Failed to calculate PoolOutGivenSingleIn : ${e.message}`)
}
@ -1510,27 +1544,19 @@ export class Pool {
public async calcSingleInGivenPoolOut(
poolAddress: string,
tokenBalanceIn: string,
tokenWeightIn: string,
poolSupply: string,
totalWeight: string,
poolAmountOut: string,
swapFee: string
tokenIn: string,
poolAmountOut: string
): Promise<string> {
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
let amount = null
const amountFormatted = await this.amountToUnits(poolAddress, poolAmountOut)
try {
const result = await pool.methods
.calcSingleInGivenPoolOut(
this.web3.utils.toWei(tokenBalanceIn),
this.web3.utils.toWei(tokenWeightIn),
this.web3.utils.toWei(poolSupply),
this.web3.utils.toWei(totalWeight),
this.web3.utils.toWei(poolAmountOut),
this.web3.utils.toWei(swapFee)
)
.calcSingleInPoolOut(tokenIn, amountFormatted)
.call()
amount = this.web3.utils.fromWei(result)
amount = await this.unitsToAmount(tokenIn, result)
} catch (e) {
this.logger.error(`ERROR: Failed to calculate SingleInGivenPoolOut : ${e.message}`)
}
@ -1539,56 +1565,40 @@ export class Pool {
public async calcSingleOutGivenPoolIn(
poolAddress: string,
tokenBalanceOut: string,
tokenWeightOut: string,
poolSupply: string,
totalWeight: string,
poolAmountIn: string,
swapFee: string
tokenOut: string,
poolAmountIn: string
): Promise<string> {
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
let amount = null
try {
const result = await pool.methods
.calcSingleOutGivenPoolIn(
this.web3.utils.toWei(tokenBalanceOut),
this.web3.utils.toWei(tokenWeightOut),
this.web3.utils.toWei(poolSupply),
this.web3.utils.toWei(totalWeight),
this.web3.utils.toWei(poolAmountIn),
this.web3.utils.toWei(swapFee)
.calcSingleOutPoolIn(
tokenOut,
await this.amountToUnits(poolAddress, poolAmountIn)
)
.call()
amount = this.web3.utils.fromWei(result)
amount = await this.unitsToAmount(tokenOut, result)
} catch (e) {
this.logger.error(`ERROR: Failed to calculate SingleOutGivenPoolIn : ${e.message}`)
this.logger.error(`ERROR: Failed to calculate SingleOutGivenPoolIn : ${e}`)
}
return amount
}
public async calcPoolInGivenSingleOut(
poolAddress: string,
tokenBalanceOut: string,
tokenWeightOut: string,
poolSupply: string,
totalWeight: string,
tokenAmountOut: string,
swapFee: string
tokenOut: string,
tokenAmountOut: string
): Promise<string> {
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
let amount = null
try {
const result = await pool.methods
.calcPoolInGivenSingleOut(
this.web3.utils.toWei(tokenBalanceOut),
this.web3.utils.toWei(tokenWeightOut),
this.web3.utils.toWei(poolSupply),
this.web3.utils.toWei(totalWeight),
this.web3.utils.toWei(tokenAmountOut),
this.web3.utils.toWei(swapFee)
)
.calcPoolInSingleOut(tokenOut, await this.amountToUnits(tokenOut, tokenAmountOut))
.call()
amount = this.web3.utils.fromWei(result)
amount = await this.unitsToAmount(poolAddress, result)
} catch (e) {
this.logger.error(`ERROR: Failed to calculate PoolInGivenSingleOut : ${e.message}`)
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,355 @@
import Web3 from 'web3'
import { AbiItem } from 'web3-utils/types'
import { TransactionReceipt } from 'web3-core'
import { Contract } from 'web3-eth-contract'
import { LoggerInstance, getFairGasPrice } from '../../utils'
import BigNumber from 'bignumber.js'
import SideStakingTemplate from '@oceanprotocol/contracts/artifacts/contracts/pools/ssContracts/SideStaking.sol/SideStaking.json'
import defaultPool from '@oceanprotocol/contracts/artifacts/contracts/pools/FactoryRouter.sol/FactoryRouter.json'
import defaultERC20ABI from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json'
const MaxUint256 =
'115792089237316195423570985008687907853269984665640564039457584007913129639934'
/**
* Provides an interface to Ocean friendly fork from Balancer BPool
*/
export class SideStaking {
public ssABI: AbiItem | AbiItem[]
public web3: Web3
public GASLIMIT_DEFAULT = 1000000
constructor(web3: Web3, ssABI: AbiItem | AbiItem[] = null) {
if (ssABI) this.ssABI = ssABI
else this.ssABI = SideStakingTemplate.abi as AbiItem[]
this.web3 = web3
}
async amountToUnits(token: string, amount: string): Promise<string> {
let decimals = 18
const tokenContract = new this.web3.eth.Contract(
defaultERC20ABI.abi as AbiItem[],
token
)
try {
decimals = await tokenContract.methods.decimals().call()
} catch (e) {
LoggerInstance.error('ERROR: FAILED TO CALL DECIMALS(), USING 18')
}
const amountFormatted = new BigNumber(parseInt(amount) * 10 ** decimals)
return amountFormatted.toString()
}
async unitsToAmount(token: string, amount: string): Promise<string> {
let decimals = 18
const tokenContract = new this.web3.eth.Contract(
defaultERC20ABI.abi as AbiItem[],
token
)
try {
decimals = await tokenContract.methods.decimals().call()
} catch (e) {
LoggerInstance.error('ERROR: FAILED TO CALL DECIMALS(), USING 18')
}
const amountFormatted = new BigNumber(parseInt(amount) / 10 ** decimals)
return amountFormatted.toString()
}
/**
* Get (total vesting amount + token released from the contract when adding liquidity)
* @param {String} ssAddress side staking contract address
* @param {String} datatokenAddress datatoken address
* @return {String}
*/
async getDataTokenCirculatingSupply(
ssAddress: string,
datatokenAddress: string
): Promise<string> {
const sideStaking = new this.web3.eth.Contract(this.ssABI, ssAddress)
let result = null
try {
result = await sideStaking.methods
.getDataTokenCirculatingSupply(datatokenAddress)
.call()
} catch (e) {
LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)
}
return result.toString()
}
/**
* Get actual dts in circulation (vested token withdrawn from the contract +
token released from the contract when adding liquidity)
* @param {String} ssAddress side staking contract address
* @param {String} datatokenAddress datatoken address
* @return {String}
*/
async getDataTokenCurrentCirculatingSupply(
ssAddress: string,
datatokenAddress: string
): Promise<string> {
try {
const sideStaking = new this.web3.eth.Contract(this.ssABI, ssAddress)
let result = null
result = await sideStaking.methods
.getDataTokenCurrentCirculatingSupply(datatokenAddress)
.call()
return result.toString()
} catch (e) {
LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)
}
}
/**
* Get Publisher address
* @param {String} ssAddress side staking contract address
* @param {String} datatokenAddress datatoken address
* @return {String}
*/
async getPublisherAddress(
ssAddress: string,
datatokenAddress: string
): Promise<string> {
const sideStaking = new this.web3.eth.Contract(this.ssABI, ssAddress)
let result = null
try {
result = await sideStaking.methods.getPublisherAddress(datatokenAddress).call()
} catch (e) {
LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)
}
return result
}
/**
* Get
* @param {String} ssAddress side staking contract address
* @param {String} datatokenAddress datatokenAddress
* @return {String}
*/
async getBasetoken(ssAddress: string, datatokenAddress: string): Promise<string> {
const sideStaking = new this.web3.eth.Contract(this.ssABI, ssAddress)
let result = null
try {
result = await sideStaking.methods.getBaseTokenAddress(datatokenAddress).call()
} catch (e) {
LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)
}
return result
}
/**
* Get Pool Address
* @param {String} ssAddress side staking contract address
* @param {String} datatokenAddress datatokenAddress
* @return {String}
*/
async getPoolAddress(ssAddress: string, datatokenAddress: string): Promise<string> {
const sideStaking = new this.web3.eth.Contract(this.ssABI, ssAddress)
let result = null
try {
result = await sideStaking.methods.getPoolAddress(datatokenAddress).call()
} catch (e) {
LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)
}
return result
}
/**
* Get basetoken balance in the contract
* @param {String} ssAddress side staking contract address
* @param {String} datatokenAddress datatokenAddress
* @return {String}
*/
async getBasetokenBalance(
ssAddress: string,
datatokenAddress: string
): Promise<string> {
const sideStaking = new this.web3.eth.Contract(this.ssABI, ssAddress)
let result = null
try {
result = await sideStaking.methods.getBaseTokenBalance(datatokenAddress).call()
} catch (e) {
LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)
}
return result
}
/**
* Get dt balance in the staking contract available for being added as liquidity
* @param {String} ssAddress side staking contract address
* @param {String} datatokenAddress datatokenAddress
* @return {String}
*/
async getDatatokenBalance(
ssAddress: string,
datatokenAddress: string
): Promise<string> {
const sideStaking = new this.web3.eth.Contract(this.ssABI, ssAddress)
let result = null
try {
result = await sideStaking.methods.getDataTokenBalance(datatokenAddress).call()
} catch (e) {
LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)
}
result = await this.unitsToAmount(datatokenAddress, result)
return result
}
/**
* Get block when vesting ends
* @param {String} ssAddress side staking contract address
* @param {String} datatokenAddress datatokenAddress
* @return {String} end block for vesting amount
*/
async getvestingEndBlock(ssAddress: string, datatokenAddress: string): Promise<string> {
const sideStaking = new this.web3.eth.Contract(this.ssABI, ssAddress)
let result = null
try {
result = await sideStaking.methods.getvestingEndBlock(datatokenAddress).call()
} catch (e) {
LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)
}
return result
}
/**
* Get total amount vesting
* @param {String} ssAddress side staking contract address
* @param {String} datatokenAddress datatokenAddress
* @return {String}
*/
async getvestingAmount(ssAddress: string, datatokenAddress: string): Promise<string> {
const sideStaking = new this.web3.eth.Contract(this.ssABI, ssAddress)
let result = null
try {
result = await sideStaking.methods.getvestingAmount(datatokenAddress).call()
} catch (e) {
LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)
}
result = await this.unitsToAmount(datatokenAddress, result)
return result
}
/**
* Get last block publisher got some vested tokens
* @param {String} ssAddress side staking contract address
* @param {String} datatokenAddress datatokenAddress
* @return {String}
*/
async getvestingLastBlock(
ssAddress: string,
datatokenAddress: string
): Promise<string> {
const sideStaking = new this.web3.eth.Contract(this.ssABI, ssAddress)
let result = null
try {
result = await sideStaking.methods.getvestingLastBlock(datatokenAddress).call()
} catch (e) {
LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)
}
return result
}
/**
* Get how much has been taken from the vesting amount
* @param {String} ssAddress side staking contract address
* @param {String} datatokenAddress datatokenAddress
* @return {String}
*/
async getvestingAmountSoFar(
ssAddress: string,
datatokenAddress: string
): Promise<string> {
const sideStaking = new this.web3.eth.Contract(this.ssABI, ssAddress)
let result = null
try {
result = await sideStaking.methods.getvestingAmountSoFar(datatokenAddress).call()
} catch (e) {
LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)
}
result = await this.unitsToAmount(datatokenAddress, result)
return result
}
/**
* Estimate gas cost for getVesting
* @param {String} account
* @param {String} ssAddress side staking contract address
* @param {String} datatokenAddress datatokenAddress
* @param {Contract} contractInstance optional contract instance
* @return {Promise<number>}
*/
public async estGetVesting(
account: string,
ssAddress: string,
datatokenAddress: string,
contractInstance?: Contract
): Promise<number> {
const sideStaking =
contractInstance || new this.web3.eth.Contract(this.ssABI as AbiItem[], ssAddress)
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas
try {
estGas = await sideStaking.methods
.getVesting(datatokenAddress)
.estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
}
return estGas
}
/** Send vested tokens available to the publisher address, can be called by anyone
*
* @param {String} account
* @param {String} ssAddress side staking contract address
* @param {String} datatokenAddress datatokenAddress
* @return {TransactionReceipt}
*/
async getVesting(
account: string,
ssAddress: string,
datatokenAddress: string
): Promise<TransactionReceipt> {
const sideStaking = new this.web3.eth.Contract(this.ssABI, ssAddress)
let result = null
const estGas = await this.estGetVesting(
account,
ssAddress,
datatokenAddress,
sideStaking
)
try {
result = await sideStaking.methods.getVesting(datatokenAddress).send({
from: account,
gas: estGas + 1,
gasPrice: await getFairGasPrice(this.web3)
})
} catch (e) {
LoggerInstance.error('ERROR: Failed to join swap pool amount out')
}
return result
}
/**
* Get Router address set in side staking contract
* @param {String} ssAddress side staking contract address
* @return {String}
*/
async getRouter(ssAddress: string): Promise<string> {
const sideStaking = new this.web3.eth.Contract(this.ssABI, ssAddress)
let result = null
try {
result = await sideStaking.methods.router().call()
} catch (e) {
LoggerInstance.error(`ERROR: Failed to get Router address: ${e.message}`)
}
return result
}
}

View File

@ -0,0 +1 @@
export * from './SideStaking'

View File

@ -124,6 +124,8 @@ describe('Pool unit test', () => {
await usdcContract.methods.decimals().call(),
'USDC DECIMALS IN THIS TEST'
)
await pool.amountToUnits(contracts.usdcAddress, '20')
})
describe('Test a pool with DAI (18 Decimals)', () => {
@ -241,7 +243,6 @@ describe('Pool unit test', () => {
it('#isFinalized - should return true if pool is finalized', async () => {
expect(await pool.isFinalized(poolAddress)).to.equal(true)
expect(await pool.isFinalized(contracts.oceanAddress)).to.equal(null)
})
it('#getSwapFee - should return the swap fee', async () => {
@ -632,6 +633,77 @@ describe('Pool unit test', () => {
expect(await erc20Contract.methods.balanceOf(user2).call()).to.equal('0')
})
it('#calcPoolOutGivenSingleIn - should get the amount of pool OUT for exact token IN', async () => {
// since rate is 1 and the pool is just created
// amount of pool out received for same amount of different token In is equal
const tokenInAmount = '10' // 10 USDC or 10 DTs
expect(
await pool.calcPoolOutGivenSingleIn(poolAddress, erc20Token, tokenInAmount)
).to.equal(
await pool.calcPoolOutGivenSingleIn(
poolAddress,
contracts.usdcAddress,
tokenInAmount
)
)
// console.log(await pool.calcPoolOutGivenSingleIn(poolAddress, erc20Token, tokenInAmount))
})
it('#calcSingleInGivenPoolOut - should get the amount of token IN for exact pool token OUT', async () => {
// since rate is 1 and the pool is just created
// amount of different token In for getting same pool amount out is equal
const poolAmountOut = '1'
expect(
parseInt(
await pool.calcSingleInGivenPoolOut(poolAddress, erc20Token, poolAmountOut)
)
).to.be.closeTo(
parseInt(
await pool.calcSingleInGivenPoolOut(
poolAddress,
contracts.usdcAddress,
poolAmountOut
)
),
1e9
)
})
it('#calcSingleOutGivenPoolIn - should get the amount of token OUT for exact pool token IN', async () => {
// since rate is 1 and the pool is just created
// amount amount of different token Out for rediming the same pool In is equal
const poolAmountIn = '10'
expect(
await pool.calcSingleOutGivenPoolIn(poolAddress, erc20Token, poolAmountIn)
).to.equal(
await pool.calcSingleOutGivenPoolIn(
poolAddress,
contracts.usdcAddress,
poolAmountIn
)
)
})
it('#calcPoolInGivenSingleOut - should get the amount of pool IN for exact token OUT', async () => {
// since rate is 1 and the pool is just created
// amount of pool In for getting the same amount of different token Out is equal
const tokenAmountOut = '10'
expect(
parseInt(
await pool.calcPoolInGivenSingleOut(poolAddress, erc20Token, tokenAmountOut)
)
).to.be.closeTo(
parseInt(
await pool.calcPoolInGivenSingleOut(
poolAddress,
contracts.usdcAddress,
tokenAmountOut
)
),
1e11
)
})
it('#sharesBalance - should return user shares balance (datatoken balance, LPT balance, etc) ', async () => {
expect(await usdcContract.methods.balanceOf(user2).call()).to.equal(
await pool.sharesBalance(user2, contracts.usdcAddress)
@ -685,7 +757,6 @@ describe('Pool unit test', () => {
it('#isFinalized - should return true if pool is finalized', async () => {
expect(await pool.isFinalized(poolAddress)).to.equal(true)
expect(await pool.isFinalized(contracts.oceanAddress)).to.equal(null)
})
it('#getSwapFee - should return the swap fee', async () => {

View File

@ -0,0 +1,761 @@
import { assert, expect } from 'chai'
import { AbiItem } from 'web3-utils/types'
import { TestContractHandler } from '../../../TestContractHandler'
import { Contract } from 'web3-eth-contract'
import Web3 from 'web3'
import BigNumber from 'bignumber.js'
import BN from 'bn.js'
import ERC721Factory from '@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json'
import ERC721Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC721Template.sol/ERC721Template.json'
import SSContract from '@oceanprotocol/contracts/artifacts/contracts/pools/ssContracts/SideStaking.sol/SideStaking.json'
import FactoryRouter from '@oceanprotocol/contracts/artifacts/contracts/pools/FactoryRouter.sol/FactoryRouter.json'
import ERC20Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json'
import Dispenser from '@oceanprotocol/contracts/artifacts/contracts/pools/dispenser/Dispenser.sol/Dispenser.json'
import FixedRate from '@oceanprotocol/contracts/artifacts/contracts/pools/fixedRate/FixedRateExchange.sol/FixedRateExchange.json'
import MockERC20 from '@oceanprotocol/contracts/artifacts/contracts/utils/mock/MockERC20Decimals.sol/MockERC20Decimals.json'
import PoolTemplate from '@oceanprotocol/contracts/artifacts/contracts/pools/balancer/BPool.sol/BPool.json'
import OPFCollector from '@oceanprotocol/contracts/artifacts/contracts/communityFee/OPFCommunityFeeCollector.sol/OPFCommunityFeeCollector.json'
import { LoggerInstance } from '../../../../src/utils'
import { NFTFactory, NFTCreateData } from '../../../../src/factories/NFTFactory'
import { Pool } from '../../../../src/pools/balancer/Pool'
import { FixedRateExchange } from '../../../../src/pools/fixedRate/FixedRateExchange'
import { BADFAMILY } from 'dns'
import { FreCreationParams, Erc20CreateParams } from '../../../../src/interfaces'
const { keccak256 } = require('@ethersproject/keccak256')
const web3 = new Web3('http://127.0.0.1:8545')
const communityCollector = '0xeE9300b7961e0a01d9f0adb863C7A227A07AaD75'
describe('Fixed Rate unit test', () => {
let factoryOwner: string
let nftOwner: string
let exchangeOwner: string
let user1: string
let user2: string
let user3: string
let user4: string
let initialBlock: number
let fixedRateAddress: string
let daiAddress: string
let usdcAddress: string
let exchangeId: string
let contracts: TestContractHandler
let fixedRate: FixedRateExchange
let dtAddress: string
let dtAddress2: string
let dtContract: Contract
let daiContract: Contract
let usdcContract: Contract
const vestedBlocks = 2500000
const ADDRESS_ZERO = '0x0000000000000000000000000000000000000000'
it('should deploy contracts', async () => {
contracts = new TestContractHandler(
web3,
ERC721Template.abi as AbiItem[],
ERC20Template.abi as AbiItem[],
PoolTemplate.abi as AbiItem[],
ERC721Factory.abi as AbiItem[],
FactoryRouter.abi as AbiItem[],
SSContract.abi as AbiItem[],
FixedRate.abi as AbiItem[],
Dispenser.abi as AbiItem[],
OPFCollector.abi as AbiItem[],
ERC721Template.bytecode,
ERC20Template.bytecode,
PoolTemplate.bytecode,
ERC721Factory.bytecode,
FactoryRouter.bytecode,
SSContract.bytecode,
FixedRate.bytecode,
Dispenser.bytecode,
OPFCollector.bytecode
)
await contracts.getAccounts()
factoryOwner = contracts.accounts[0]
nftOwner = contracts.accounts[1]
user1 = contracts.accounts[2]
user2 = contracts.accounts[3]
user3 = contracts.accounts[4]
user4 = contracts.accounts[5]
exchangeOwner = contracts.accounts[0]
await contracts.deployContracts(factoryOwner, FactoryRouter.abi as AbiItem[])
// initialize fixed rate
//
daiContract = new web3.eth.Contract(
contracts.MockERC20.options.jsonInterface,
contracts.daiAddress
)
usdcContract = new web3.eth.Contract(
contracts.MockERC20.options.jsonInterface,
contracts.usdcAddress
)
console.log(
await usdcContract.methods.decimals().call(),
'USDC DECIMALS IN THIS TEST'
)
})
describe('Test a Fixed Rate Exchange with DAI (18 Decimals)', () => {
it('#create an exchange', async () => {
// CREATE AN Exchange
// we prepare transaction parameters objects
const nftFactory = new NFTFactory(contracts.factory721Address, web3)
const nftData: NFTCreateData = {
name: '72120Bundle',
symbol: '72Bundle',
templateIndex: 1,
baseURI: 'https://oceanprotocol.com/nft/'
}
const ercParams: Erc20CreateParams = {
templateIndex: 1,
minter: contracts.accounts[0],
feeManager: user3,
mpFeeAddress: contracts.accounts[0],
feeToken: ADDRESS_ZERO,
cap: '1000000',
feeAmount: '0',
name: 'ERC20B1',
symbol: 'ERC20DT1Symbol'
}
const freParams: FreCreationParams = {
fixedRateAddress: contracts.fixedRateAddress,
baseTokenAddress: contracts.daiAddress,
owner: exchangeOwner,
marketFeeCollector: user3,
baseTokenDecimals: 18,
dataTokenDecimals: 18,
fixedRate: web3.utils.toWei('1'),
marketFee: 1e15,
allowedConsumer: ADDRESS_ZERO,
withMint: false
}
const txReceipt = await nftFactory.createNftErcWithFixedRate(
exchangeOwner,
nftData,
ercParams,
freParams
)
initialBlock = await web3.eth.getBlockNumber()
dtAddress = txReceipt.events.TokenCreated.returnValues.newTokenAddress
exchangeId = txReceipt.events.NewFixedRate.returnValues.exchangeId
dtContract = new web3.eth.Contract(ERC20Template.abi as AbiItem[], dtAddress)
// user2 has no dt1
expect(await dtContract.methods.balanceOf(user2).call()).to.equal('0')
fixedRateAddress = contracts.fixedRateAddress
fixedRate = new FixedRateExchange(
web3,
fixedRateAddress,
FixedRate.abi as AbiItem[],
contracts.oceanAddress
)
assert(fixedRate != null)
})
it('#isActive - should return true if exchange is active', async () => {
expect(await fixedRate.isActive(exchangeId)).to.equal(true)
expect(await fixedRate.isActive('0x00')).to.equal(false)
})
it('#getOwner - should get exchange owner given an id', async () => {
expect(await fixedRate.getExchangeOwner(exchangeId)).to.equal(exchangeOwner)
})
it('#getOPFCollector - should get OPF collector', async () => {
expect(await fixedRate.getOPFCollector()).to.equal(contracts.opfCollectorAddress)
})
it('#getRouter - should get Router address', async () => {
expect(await fixedRate.getRouter()).to.equal(contracts.routerAddress)
})
it('#deactivate - should deactivate an exchange if exchangeOwner', async () => {
expect(await fixedRate.isActive(exchangeId)).to.equal(true)
await fixedRate.deactivate(exchangeOwner, exchangeId)
expect(await fixedRate.isActive(exchangeId)).to.equal(false)
})
it('#activate - should activate an exchange if exchangeOwner', async () => {
expect(await fixedRate.isActive(exchangeId)).to.equal(false)
await fixedRate.activate(exchangeOwner, exchangeId)
expect(await fixedRate.isActive(exchangeId)).to.equal(true)
})
it('#activateMint - should activate Mint(allows fixed rate contract to mint dts if required), if exchangeOwner', async () => {
expect((await fixedRate.getExchange(exchangeId)).withMint).to.equal(false)
await fixedRate.activateMint(exchangeOwner, exchangeId)
expect((await fixedRate.getExchange(exchangeId)).withMint).to.equal(true)
})
it('#dectivateMint - should deactivate Mint if exchangeOwner', async () => {
expect((await fixedRate.getExchange(exchangeId)).withMint).to.equal(true)
await fixedRate.deactivateMint(exchangeOwner, exchangeId)
expect((await fixedRate.getExchange(exchangeId)).withMint).to.equal(false)
})
it('#generate exchangeId - should generate a specific exchangeId', async () => {
expect(
await fixedRate.generateExchangeId(contracts.daiAddress, dtAddress, exchangeOwner)
).to.equal(exchangeId)
})
it('#getNumberOfExchanges - should return total number of exchanges', async () => {
expect(await fixedRate.getNumberOfExchanges()).to.equal('1')
})
it('#getExchanges - should return all exchanges ids', async () => {
const exchangeIds = await fixedRate.getExchanges()
expect(exchangeIds[0]).to.equal(exchangeId)
})
it('#getRate - should return rate', async () => {
expect(await fixedRate.getRate(exchangeId)).to.equal('1')
})
it('#setRate - set new rate if exchangeOwner', async () => {
await fixedRate.setRate(exchangeOwner, exchangeId, '2')
expect(await fixedRate.getRate(exchangeId)).to.equal('2')
await fixedRate.setRate(exchangeOwner, exchangeId, '1')
expect(await fixedRate.getRate(exchangeId)).to.equal('1')
})
it('#getDTSupply - should get the dt supply in the exchange', async () => {
// exchange owner hasn't approved any DT for sell
expect(await fixedRate.getDTSupply(exchangeId)).to.equal('0')
})
it('#getBTSupply - should get the bt supply in the exchange', async () => {
// no basetoken at the beginning
expect(await fixedRate.getBTSupply(exchangeId)).to.equal('0')
})
it('#getAmountBTIn - should get bt amount in for a specific dt amount', async () => {
// 100.2 DAI for 100 DT (0.1% market fee and 0.1% ocean fee)
expect(await fixedRate.getAmountBTIn(exchangeId, '100')).to.equal('100.2')
})
it('#getAmountBTOut - should get bt amount out for a specific dt amount', async () => {
// 99.8 DAI for 100 DT (0.1% market fee and 0.1% ocean fee)
expect(await fixedRate.getAmountBTOut(exchangeId, '100')).to.equal('99.8')
})
it('#buyDT - user2 should buy some dt', async () => {
// total supply is ZERO right now so dt owner mints 1000 DT and approves the fixed rate contract
await dtContract.methods
.mint(exchangeOwner, web3.utils.toWei('1000'))
.send({ from: exchangeOwner })
await dtContract.methods
.approve(fixedRateAddress, web3.utils.toWei('1000'))
.send({ from: exchangeOwner })
// user2 gets 100 DAI so he can buy DTs
await daiContract.methods
.transfer(user2, web3.utils.toWei('100'))
.send({ from: exchangeOwner })
await daiContract.methods
.approve(fixedRateAddress, web3.utils.toWei('100'))
.send({ from: user2 })
// user2 has no dts but has 100 DAI
expect(await dtContract.methods.balanceOf(user2).call()).to.equal('0')
const daiBalanceBefore = new BN(await daiContract.methods.balanceOf(user2).call())
expect(daiBalanceBefore.toString()).to.equal(web3.utils.toWei('100'))
// user2 buys 10 DT
const tx = await fixedRate.buyDT(user2, exchangeId, '10', '11')
// console.log(tx.events.Swapped.returnValues)
assert(tx.events.Swapped != null)
const args = tx.events.Swapped.returnValues
expect(args.exchangeId).to.equal(exchangeId)
expect(args.by).to.equal(user2)
expect(args.dataTokenSwappedAmount).to.equal(web3.utils.toWei('10'))
expect(args.tokenOutAddress).to.equal(dtAddress)
expect(await dtContract.methods.balanceOf(user2).call()).to.equal(
args.dataTokenSwappedAmount
)
expect(
daiBalanceBefore.sub(new BN(args.baseTokenSwappedAmount)).toString()
).to.equal(await daiContract.methods.balanceOf(user2).call())
// basetoken stays in the contract
expect((await fixedRate.getExchange(exchangeId)).btBalance).to.equal('10')
// no dt in the contract
expect((await fixedRate.getExchange(exchangeId)).dtBalance).to.equal('0')
})
it('#sellDT - user2 should sell some dt', async () => {
await dtContract.methods
.approve(fixedRateAddress, web3.utils.toWei('10'))
.send({ from: user2 })
const daiBalanceBefore = new BN(await daiContract.methods.balanceOf(user2).call())
const tx = await fixedRate.sellDT(user2, exchangeId, '10', '9')
// console.log(tx.events.Swapped.returnValues)
assert(tx.events.Swapped != null)
const args = tx.events.Swapped.returnValues
expect(args.exchangeId).to.equal(exchangeId)
expect(args.by).to.equal(user2)
expect(args.dataTokenSwappedAmount).to.equal(web3.utils.toWei('10'))
expect(args.tokenOutAddress).to.equal(contracts.daiAddress)
expect(await dtContract.methods.balanceOf(user2).call()).to.equal('0')
expect(
daiBalanceBefore.add(new BN(args.baseTokenSwappedAmount)).toString()
).to.equal(await daiContract.methods.balanceOf(user2).call())
// DTs stay in the contract
expect((await fixedRate.getExchange(exchangeId)).dtBalance).to.equal('10')
// no BTs in the contract (except for the fees, but not accounted here)
expect((await fixedRate.getExchange(exchangeId)).btBalance).to.equal('0')
// DT supply is back at 1000 (exchange Owner allowance + dt balance in the fixed rate)
expect(await fixedRate.getDTSupply(exchangeId)).to.equal('1000')
})
it('#getExchange - should return exchange details', async () => {
const result = await fixedRate.getExchange(exchangeId)
expect(result.active).to.equal(true)
expect(result.btDecimals).to.equal('18')
expect(result.dtDecimals).to.equal('18')
expect(result.baseToken).to.equal(contracts.daiAddress)
expect(result.dataToken).to.equal(dtAddress)
expect(result.exchangeOwner).to.equal(exchangeOwner)
expect(result.withMint).to.equal(false)
expect(result.dtBalance).to.equal('10') // balance in the fixedRate
expect(result.btBalance).to.equal('0') // balance in the fixedRate
expect(result.dtSupply).to.equal('1000') // total supply available (owner allowance + dtBalance)
expect(result.btSupply).to.equal('0') // total supply available of basetoken in the contract
expect(result.fixedRate).to.equal('1')
})
it('#getFeesInfo - should return exchange fee details', async () => {
const result = await fixedRate.getFeesInfo(exchangeId)
expect(result.marketFee).to.equal('0.001')
// we made 2 swaps for 10 DT at rate 1, the fee is 0.1% for market and always in basetoken so it's 0.01 DAI
// we made 2 swaps for 10 DT at rate 1, the fee is 0.1% for ocean community and always in basetoken so it's 0.01 DAI
expect(result.marketFeeAvailable).to.equal('0.02') // formatted for basetoken decimals
expect(result.oceanFeeAvailable).to.equal('0.02') // formatted for basetoken decimals
expect(result.marketFeeCollector).to.equal(user3)
expect(result.opfFee).to.equal('0.001')
})
it('#getAllowedSwapper- should return address(0) if not set, if exchangeOwner', async () => {
expect(await fixedRate.getAllowedSwapper(exchangeId)).to.equal(ADDRESS_ZERO)
})
it('#setAllowedSwapper- should set an allowed swapper, if exchangeOwner', async () => {
await fixedRate.setAllowedSwapper(exchangeOwner, exchangeId, user2)
expect(await fixedRate.getAllowedSwapper(exchangeId)).to.equal(user2)
})
it('#setAllowedSwapper- should disable allowed swapper(return address(0)), if exchangeOwner', async () => {
await fixedRate.setAllowedSwapper(exchangeOwner, exchangeId, ADDRESS_ZERO)
expect(await fixedRate.getAllowedSwapper(exchangeId)).to.equal(ADDRESS_ZERO)
})
it('#collectBT- should collect BT in the contract, if exchangeOwner', async () => {
// there are no bt in the contract
expect((await fixedRate.getExchange(exchangeId)).btBalance).to.equal('0')
// user2 buys 1 DT
await fixedRate.buyDT(user2, exchangeId, '1', '2')
// 1 DAI in the contract
expect((await fixedRate.getExchange(exchangeId)).btBalance).to.equal('1')
// owner collects BTs
await fixedRate.collectBT(exchangeOwner, exchangeId)
// btBalance is zero
expect((await fixedRate.getExchange(exchangeId)).btBalance).to.equal('0')
})
it('#collectDT- should collect DT in the contract, if exchangeOwner', async () => {
const result = await fixedRate.getExchange(exchangeId)
// 9 dts left
expect(result.dtBalance).to.equal('9')
// owner collects DTs
await fixedRate.collectDT(exchangeOwner, exchangeId)
// no more dts in the contract
const result2 = await fixedRate.getExchange(exchangeId)
expect(result2.dtBalance).to.equal('0')
// Only allowance left since dt is ZERO
expect(result2.dtSupply).to.equal('990')
})
it('#collectMarketFee- should collect marketFee and send it to marketFeeCollector, anyone can call it', async () => {
let result = await fixedRate.getFeesInfo(exchangeId)
// we made 2 swaps for 10 DT at rate 1, the fee is 0.1% for market and always in basetoken so it's 0.01 DAI
// plus another swap for 1 DT
expect(result.marketFeeAvailable).to.equal('0.021') // formatted for basetoken decimals
// same for ocean fee
expect(result.oceanFeeAvailable).to.equal('0.021') // formatted for basetoken decimals
expect(result.marketFeeCollector).to.equal(user3)
// user4 calls collectMarketFee
await fixedRate.collectMarketFee(user4, exchangeId)
result = await fixedRate.getFeesInfo(exchangeId)
expect(result.marketFeeAvailable).to.equal('0')
// ocean fee still available
expect(result.oceanFeeAvailable).to.equal('0.021')
// user3 is the marketFeeCollector
expect(await daiContract.methods.balanceOf(user3).call()).to.equal(
web3.utils.toWei('0.021')
)
})
it('#collectOceanFee- should collect oceanFee and send it to OPF Collector, anyone can call it', async () => {
let result = await fixedRate.getFeesInfo(exchangeId)
// we made 2 swaps for 10 DT at rate 1, the fee is 0.1% for market and always in basetoken so it's 0.01 DAI
// plus another swap for 1 DT
expect(result.oceanFeeAvailable).to.equal('0.021') // formatted for basetoken decimals
// user4 calls collectOceanFee
await fixedRate.collectOceanFee(user4, exchangeId)
result = await fixedRate.getFeesInfo(exchangeId)
// fee has been reset
expect(result.oceanFeeAvailable).to.equal('0')
// OPF collector got the fee
expect(
await daiContract.methods.balanceOf(await fixedRate.getOPFCollector()).call()
).to.equal(web3.utils.toWei('0.021'))
})
it('#updateMarketFee- should update Market fee if market fee collector', async () => {
expect((await fixedRate.getFeesInfo(exchangeId)).marketFee).to.equal('0.001')
// user3 is marketFeeCollector
await fixedRate.updateMarketFee(user3, exchangeId, '0.01')
expect((await fixedRate.getFeesInfo(exchangeId)).marketFee).to.equal('0.01')
})
it('#updateMarketFeeCollector - should update Market fee collector if market fee collector', async () => {
expect((await fixedRate.getFeesInfo(exchangeId)).marketFeeCollector).to.equal(user3)
await fixedRate.updateMarketFeeCollector(user3, exchangeId, user2)
expect((await fixedRate.getFeesInfo(exchangeId)).marketFeeCollector).to.equal(user2)
})
})
describe('Test a Fixed Rate Exchange with USDC (6 Decimals)', () => {
it('#create an exchange', async () => {
// CREATE AN Exchange
// we prepare transaction parameters objects
const nftFactory = new NFTFactory(contracts.factory721Address, web3)
const nftData: NFTCreateData = {
name: '72120Bundle',
symbol: '72Bundle',
templateIndex: 1,
baseURI: 'https://oceanprotocol.com/nft/'
}
const ercParams: Erc20CreateParams = {
templateIndex: 1,
minter: contracts.accounts[0],
feeManager: user3,
mpFeeAddress: contracts.accounts[0],
feeToken: ADDRESS_ZERO,
cap: '1000000',
feeAmount: '0',
name: 'ERC20B1',
symbol: 'ERC20DT1Symbol'
}
const freParams: FreCreationParams = {
fixedRateAddress: contracts.fixedRateAddress,
baseTokenAddress: contracts.usdcAddress,
owner: exchangeOwner,
marketFeeCollector: user3,
baseTokenDecimals: 6,
dataTokenDecimals: 18,
fixedRate: web3.utils.toWei('1'),
marketFee: 1e15,
allowedConsumer: ADDRESS_ZERO,
withMint: false
}
const txReceipt = await nftFactory.createNftErcWithFixedRate(
exchangeOwner,
nftData,
ercParams,
freParams
)
initialBlock = await web3.eth.getBlockNumber()
dtAddress = txReceipt.events.TokenCreated.returnValues.newTokenAddress
exchangeId = txReceipt.events.NewFixedRate.returnValues.exchangeId
dtContract = new web3.eth.Contract(ERC20Template.abi as AbiItem[], dtAddress)
// user2 has no dt1
expect(await dtContract.methods.balanceOf(user2).call()).to.equal('0')
fixedRateAddress = contracts.fixedRateAddress
fixedRate = new FixedRateExchange(
web3,
fixedRateAddress,
FixedRate.abi as AbiItem[],
contracts.oceanAddress
)
assert(fixedRate != null)
})
it('#isActive - should return true if exchange is active', async () => {
expect(await fixedRate.isActive(exchangeId)).to.equal(true)
expect(await fixedRate.isActive('0x00')).to.equal(false)
})
it('#getOwner - should get exchange owner given an id', async () => {
expect(await fixedRate.getExchangeOwner(exchangeId)).to.equal(exchangeOwner)
})
it('#getOPFCollector - should get OPF collector', async () => {
expect(await fixedRate.getOPFCollector()).to.equal(contracts.opfCollectorAddress)
})
it('#getRouter - should get Router address', async () => {
expect(await fixedRate.getRouter()).to.equal(contracts.routerAddress)
})
it('#deactivate - should deactivate an exchange if exchangeOwner', async () => {
expect(await fixedRate.isActive(exchangeId)).to.equal(true)
await fixedRate.deactivate(exchangeOwner, exchangeId)
expect(await fixedRate.isActive(exchangeId)).to.equal(false)
})
it('#activate - should activate an exchange if exchangeOwner', async () => {
expect(await fixedRate.isActive(exchangeId)).to.equal(false)
await fixedRate.activate(exchangeOwner, exchangeId)
expect(await fixedRate.isActive(exchangeId)).to.equal(true)
})
it('#activateMint - should activate Mint(allows fixed rate contract to mint dts if required), if exchangeOwner', async () => {
expect((await fixedRate.getExchange(exchangeId)).withMint).to.equal(false)
await fixedRate.activateMint(exchangeOwner, exchangeId)
expect((await fixedRate.getExchange(exchangeId)).withMint).to.equal(true)
})
it('#dectivateMint - should deactivate Mint if exchangeOwner', async () => {
expect((await fixedRate.getExchange(exchangeId)).withMint).to.equal(true)
await fixedRate.deactivateMint(exchangeOwner, exchangeId)
expect((await fixedRate.getExchange(exchangeId)).withMint).to.equal(false)
})
it('#generate exchangeId - should generate a specific exchangeId', async () => {
expect(
await fixedRate.generateExchangeId(
contracts.usdcAddress,
dtAddress,
exchangeOwner
)
).to.equal(exchangeId)
})
it('#getNumberOfExchanges - should return total number of exchanges', async () => {
expect(await fixedRate.getNumberOfExchanges()).to.equal('2')
})
it('#getExchanges - should return all exchanges ids', async () => {
const exchangeIds = await fixedRate.getExchanges()
expect(exchangeIds[1]).to.equal(exchangeId)
})
it('#getRate - should return rate', async () => {
expect(await fixedRate.getRate(exchangeId)).to.equal('1')
})
it('#setRate - set new rate if exchangeOwner', async () => {
await fixedRate.setRate(exchangeOwner, exchangeId, '2')
expect(await fixedRate.getRate(exchangeId)).to.equal('2')
await fixedRate.setRate(exchangeOwner, exchangeId, '1')
expect(await fixedRate.getRate(exchangeId)).to.equal('1')
})
it('#getDTSupply - should get the dt supply in the exchange', async () => {
// exchange owner hasn't approved any DT for sell
expect(await fixedRate.getDTSupply(exchangeId)).to.equal('0')
})
it('#getBTSupply - should get the bt supply in the exchange', async () => {
// no basetoken at the beginning
expect(await fixedRate.getBTSupply(exchangeId)).to.equal('0')
})
it('#getAmountBTIn - should get bt amount in for a specific dt amount', async () => {
// 100.2 USDC for 100 DT (0.1% market fee and 0.1% ocean fee)
expect(await fixedRate.getAmountBTIn(exchangeId, '100')).to.equal('100.2')
})
it('#getAmountBTOut - should get bt amount out for a specific dt amount', async () => {
// 99.8 USDC for 100 DT (0.1% market fee and 0.1% ocean fee)
expect(await fixedRate.getAmountBTOut(exchangeId, '100')).to.equal('99.8')
})
it('#buyDT - user2 should buy some dt', async () => {
// total supply is ZERO right now so dt owner mints 1000 DT and approves the fixed rate contract
await dtContract.methods
.mint(exchangeOwner, web3.utils.toWei('1000'))
.send({ from: exchangeOwner })
await dtContract.methods
.approve(fixedRateAddress, web3.utils.toWei('1000'))
.send({ from: exchangeOwner })
// user2 gets 100 USDC so he can buy DTs
await usdcContract.methods.transfer(user2, 100 * 1e6).send({ from: exchangeOwner })
await usdcContract.methods
.approve(fixedRateAddress, 100 * 1e6)
.send({ from: user2 })
// user2 has no dts but has 100 USDC
expect(await dtContract.methods.balanceOf(user2).call()).to.equal('0')
const usdcBalanceBefore = new BN(await usdcContract.methods.balanceOf(user2).call())
expect(usdcBalanceBefore.toString()).to.equal(new BN(100 * 1e6).toString())
// user2 buys 10 DT
const tx = await fixedRate.buyDT(user2, exchangeId, '10', '11')
// console.log(tx.events.Swapped.returnValues)
assert(tx.events.Swapped != null)
const args = tx.events.Swapped.returnValues
expect(args.exchangeId).to.equal(exchangeId)
expect(args.by).to.equal(user2)
expect(args.dataTokenSwappedAmount).to.equal(web3.utils.toWei('10'))
expect(args.tokenOutAddress).to.equal(dtAddress)
expect(await dtContract.methods.balanceOf(user2).call()).to.equal(
args.dataTokenSwappedAmount
)
expect(
usdcBalanceBefore.sub(new BN(args.baseTokenSwappedAmount)).toString()
).to.equal(await usdcContract.methods.balanceOf(user2).call())
// basetoken stays in the contract
expect((await fixedRate.getExchange(exchangeId)).btBalance).to.equal('10')
// no dt in the contract
expect((await fixedRate.getExchange(exchangeId)).dtBalance).to.equal('0')
})
it('#sellDT - user2 should sell some dt', async () => {
await dtContract.methods
.approve(fixedRateAddress, web3.utils.toWei('10'))
.send({ from: user2 })
const usdcBalanceBefore = new BN(await usdcContract.methods.balanceOf(user2).call())
const tx = await fixedRate.sellDT(user2, exchangeId, '10', '9')
// console.log(tx.events.Swapped.returnValues)
assert(tx.events.Swapped != null)
const args = tx.events.Swapped.returnValues
expect(args.exchangeId).to.equal(exchangeId)
expect(args.by).to.equal(user2)
expect(args.dataTokenSwappedAmount).to.equal(web3.utils.toWei('10'))
expect(args.tokenOutAddress).to.equal(contracts.usdcAddress)
expect(await dtContract.methods.balanceOf(user2).call()).to.equal('0')
expect(
usdcBalanceBefore.add(new BN(args.baseTokenSwappedAmount)).toString()
).to.equal(await usdcContract.methods.balanceOf(user2).call())
// DTs stay in the contract
expect((await fixedRate.getExchange(exchangeId)).dtBalance).to.equal('10')
// no BTs in the contract (except for the fees, but not accounted here)
expect((await fixedRate.getExchange(exchangeId)).btBalance).to.equal('0')
// DT supply is back at 1000 (exchange Owner allowance + dt balance in the fixed rate)
expect(await fixedRate.getDTSupply(exchangeId)).to.equal('1000')
})
it('#getExchange - should return exchange details', async () => {
const result = await fixedRate.getExchange(exchangeId)
expect(result.active).to.equal(true)
expect(result.btDecimals).to.equal('6')
expect(result.dtDecimals).to.equal('18')
expect(result.baseToken).to.equal(contracts.usdcAddress)
expect(result.dataToken).to.equal(dtAddress)
expect(result.exchangeOwner).to.equal(exchangeOwner)
expect(result.withMint).to.equal(false)
expect(result.dtBalance).to.equal('10') // balance in the fixedRate
expect(result.btBalance).to.equal('0') // balance in the fixedRate
expect(result.dtSupply).to.equal('1000') // total supply available (owner allowance + dtBalance)
expect(result.btSupply).to.equal('0') // total supply available of basetoken in the contract
expect(result.fixedRate).to.equal('1')
})
it('#getFeesInfo - should return exchange fee details', async () => {
const result = await fixedRate.getFeesInfo(exchangeId)
expect(result.marketFee).to.equal('0.001')
// we made 2 swaps for 10 DT at rate 1, the fee is 0.1% for market and always in basetoken so it's 0.01 USDC
// we made 2 swaps for 10 DT at rate 1, the fee is 0.1% for ocean community and always in basetoken so it's 0.01 USDC
expect(result.marketFeeAvailable).to.equal('0.02') // formatted for basetoken decimals
expect(result.oceanFeeAvailable).to.equal('0.02') // formatted for basetoken decimals
expect(result.marketFeeCollector).to.equal(user3)
expect(result.opfFee).to.equal('0.001')
})
it('#getAllowedSwapper- should return address(0) if not set, if exchangeOwner', async () => {
expect(await fixedRate.getAllowedSwapper(exchangeId)).to.equal(ADDRESS_ZERO)
})
it('#setAllowedSwapper- should set an allowed swapper, if exchangeOwner', async () => {
await fixedRate.setAllowedSwapper(exchangeOwner, exchangeId, user2)
expect(await fixedRate.getAllowedSwapper(exchangeId)).to.equal(user2)
})
it('#setAllowedSwapper- should disable allowed swapper(return address(0)), if exchangeOwner', async () => {
await fixedRate.setAllowedSwapper(exchangeOwner, exchangeId, ADDRESS_ZERO)
expect(await fixedRate.getAllowedSwapper(exchangeId)).to.equal(ADDRESS_ZERO)
})
it('#collectBT- should collect BT in the contract, if exchangeOwner', async () => {
// there are no bt in the contract
expect((await fixedRate.getExchange(exchangeId)).btBalance).to.equal('0')
// user2 buys 1 DT
await fixedRate.buyDT(user2, exchangeId, '1', '2')
// 1 DAI in the contract
expect((await fixedRate.getExchange(exchangeId)).btBalance).to.equal('1')
// owner collects BTs
await fixedRate.collectBT(exchangeOwner, exchangeId)
// btBalance is zero
expect((await fixedRate.getExchange(exchangeId)).btBalance).to.equal('0')
})
it('#collectDT- should collect DT in the contract, if exchangeOwner', async () => {
const result = await fixedRate.getExchange(exchangeId)
// 9 dts left
expect(result.dtBalance).to.equal('9')
// owner collects DTs
await fixedRate.collectDT(exchangeOwner, exchangeId)
// no more dts in the contract
const result2 = await fixedRate.getExchange(exchangeId)
expect(result2.dtBalance).to.equal('0')
// Only allowance left since dt is ZERO
expect(result2.dtSupply).to.equal('990')
})
it('#collectMarketFee- should collect marketFee and send it to marketFeeCollector, anyone can call it', async () => {
let result = await fixedRate.getFeesInfo(exchangeId)
// we made 2 swaps for 10 DT at rate 1, the fee is 0.1% for market and always in basetoken so it's 0.01 USDC
// plus another swap for 1 DT
expect(result.marketFeeAvailable).to.equal('0.021') // formatted for basetoken decimals
// same for ocean fee
expect(result.oceanFeeAvailable).to.equal('0.021') // formatted for basetoken decimals
expect(result.marketFeeCollector).to.equal(user3)
// user4 calls collectMarketFee
await fixedRate.collectMarketFee(user4, exchangeId)
result = await fixedRate.getFeesInfo(exchangeId)
expect(result.marketFeeAvailable).to.equal('0')
// ocean fee still available
expect(result.oceanFeeAvailable).to.equal('0.021')
// user3 is the marketFeeCollector
expect(await usdcContract.methods.balanceOf(user3).call()).to.equal(
(0.021 * 1e6).toString()
)
})
it('#collectOceanFee- should collect oceanFee and send it to OPF Collector, anyone can call it', async () => {
let result = await fixedRate.getFeesInfo(exchangeId)
// we made 2 swaps for 10 DT at rate 1, the fee is 0.1% for market and always in basetoken so it's 0.01 DAI
// plus another swap for 1 DT
expect(result.oceanFeeAvailable).to.equal('0.021') // formatted for basetoken decimals
// user4 calls collectOceanFee
await fixedRate.collectOceanFee(user4, exchangeId)
result = await fixedRate.getFeesInfo(exchangeId)
// fee has been reset
expect(result.oceanFeeAvailable).to.equal('0')
// OPF collector got the fee
expect(
await usdcContract.methods.balanceOf(await fixedRate.getOPFCollector()).call()
).to.equal((0.021 * 1e6).toString())
})
it('#updateMarketFee- should update Market fee if market fee collector', async () => {
expect((await fixedRate.getFeesInfo(exchangeId)).marketFee).to.equal('0.001')
// user3 is marketFeeCollector
await fixedRate.updateMarketFee(user3, exchangeId, '0.01')
expect((await fixedRate.getFeesInfo(exchangeId)).marketFee).to.equal('0.01')
})
it('#updateMarketFeeCollector - should update Market fee collector if market fee collector', async () => {
expect((await fixedRate.getFeesInfo(exchangeId)).marketFeeCollector).to.equal(user3)
await fixedRate.updateMarketFeeCollector(user3, exchangeId, user2)
expect((await fixedRate.getFeesInfo(exchangeId)).marketFeeCollector).to.equal(user2)
})
})
})

View File

@ -0,0 +1,656 @@
import { assert, expect } from 'chai'
import { AbiItem } from 'web3-utils/types'
import { TestContractHandler } from '../../../TestContractHandler'
import { Contract } from 'web3-eth-contract'
import Web3 from 'web3'
import BigNumber from 'bignumber.js'
import BN from 'bn.js'
import ERC721Factory from '@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json'
import ERC721Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC721Template.sol/ERC721Template.json'
import SSContract from '@oceanprotocol/contracts/artifacts/contracts/pools/ssContracts/SideStaking.sol/SideStaking.json'
import FactoryRouter from '@oceanprotocol/contracts/artifacts/contracts/pools/FactoryRouter.sol/FactoryRouter.json'
import ERC20Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json'
import Dispenser from '@oceanprotocol/contracts/artifacts/contracts/pools/dispenser/Dispenser.sol/Dispenser.json'
import FixedRate from '@oceanprotocol/contracts/artifacts/contracts/pools/fixedRate/FixedRateExchange.sol/FixedRateExchange.json'
import MockERC20 from '@oceanprotocol/contracts/artifacts/contracts/utils/mock/MockERC20Decimals.sol/MockERC20Decimals.json'
import PoolTemplate from '@oceanprotocol/contracts/artifacts/contracts/pools/balancer/BPool.sol/BPool.json'
import OPFCollector from '@oceanprotocol/contracts/artifacts/contracts/communityFee/OPFCommunityFeeCollector.sol/OPFCommunityFeeCollector.json'
import { LoggerInstance } from '../../../../src/utils'
import { NFTFactory, NFTCreateData } from '../../../../src/factories/NFTFactory'
import { Pool } from '../../../../src/pools/balancer/Pool'
import { SideStaking } from '../../../../src/pools/ssContracts/SideStaking'
import { Erc20CreateParams, PoolCreationParams } from '../../../../src/interfaces'
const { keccak256 } = require('@ethersproject/keccak256')
const web3 = new Web3('http://127.0.0.1:8545')
const communityCollector = '0xeE9300b7961e0a01d9f0adb863C7A227A07AaD75'
describe('SideStaking unit test', () => {
let factoryOwner: string
let nftOwner: string
let user1: string
let user2: string
let user3: string
let initialBlock: number
let sideStakingAddress: string
let contracts: TestContractHandler
let pool: Pool
let sideStaking: SideStaking
let dtAddress: string
let dtAddress2: string
let poolAddress: string
let erc20Token: string
let erc20Contract: Contract
let daiContract: Contract
let usdcContract: Contract
const vestedBlocks = 2500000
it('should deploy contracts', async () => {
contracts = new TestContractHandler(
web3,
ERC721Template.abi as AbiItem[],
ERC20Template.abi as AbiItem[],
PoolTemplate.abi as AbiItem[],
ERC721Factory.abi as AbiItem[],
FactoryRouter.abi as AbiItem[],
SSContract.abi as AbiItem[],
FixedRate.abi as AbiItem[],
Dispenser.abi as AbiItem[],
OPFCollector.abi as AbiItem[],
ERC721Template.bytecode,
ERC20Template.bytecode,
PoolTemplate.bytecode,
ERC721Factory.bytecode,
FactoryRouter.bytecode,
SSContract.bytecode,
FixedRate.bytecode,
Dispenser.bytecode,
OPFCollector.bytecode
)
await contracts.getAccounts()
factoryOwner = contracts.accounts[0]
nftOwner = contracts.accounts[1]
user1 = contracts.accounts[2]
user2 = contracts.accounts[3]
user3 = contracts.accounts[4]
sideStakingAddress = contracts.sideStakingAddress
await contracts.deployContracts(factoryOwner, FactoryRouter.abi as AbiItem[])
// initialize Pool instance
pool = new Pool(web3, LoggerInstance, PoolTemplate.abi as AbiItem[])
assert(pool != null)
//
sideStaking = new SideStaking(web3, SSContract.abi as AbiItem[])
assert(sideStaking != null)
daiContract = new web3.eth.Contract(
contracts.MockERC20.options.jsonInterface,
contracts.daiAddress
)
usdcContract = new web3.eth.Contract(
contracts.MockERC20.options.jsonInterface,
contracts.usdcAddress
)
await pool.approve(
contracts.accounts[0],
contracts.daiAddress,
contracts.factory721Address,
'2000'
)
await pool.approve(
contracts.accounts[0],
contracts.usdcAddress,
contracts.factory721Address,
'10000'
)
expect(
await pool.allowance(
contracts.daiAddress,
contracts.accounts[0],
contracts.factory721Address
)
).to.equal('2000')
expect(
await pool.allowance(
contracts.usdcAddress,
contracts.accounts[0],
contracts.factory721Address
)
).to.equal('10000')
expect(await daiContract.methods.balanceOf(contracts.accounts[0]).call()).to.equal(
web3.utils.toWei('100000')
)
console.log(
await usdcContract.methods.decimals().call(),
'USDC DECIMALS IN THIS TEST'
)
await pool.amountToUnits(contracts.usdcAddress, '20')
})
describe('Test a pool with DAI (18 Decimals)', () => {
it('#create a pool', async () => {
// CREATE A POOL
// we prepare transaction parameters objects
const nftFactory = new NFTFactory(contracts.factory721Address, web3)
const nftData: NFTCreateData = {
name: '72120Bundle',
symbol: '72Bundle',
templateIndex: 1,
baseURI: 'https://oceanprotocol.com/nft/'
}
const ercParams: Erc20CreateParams = {
templateIndex: 1,
minter: contracts.accounts[0],
feeManager: user3,
mpFeeAddress: contracts.accounts[0],
feeToken: '0x0000000000000000000000000000000000000000',
cap: '1000000',
feeAmount: '0',
name: 'ERC20B1',
symbol: 'ERC20DT1Symbol'
}
const poolParams: PoolCreationParams = {
ssContract: contracts.sideStakingAddress,
basetokenAddress: contracts.daiAddress,
basetokenSender: contracts.factory721Address,
publisherAddress: contracts.accounts[0],
marketFeeCollector: contracts.accounts[0],
poolTemplateAddress: contracts.poolTemplateAddress,
rate: '1',
basetokenDecimals: 18,
vestingAmount: '10000',
vestedBlocks: vestedBlocks,
initialBasetokenLiquidity: '2000',
swapFeeLiquidityProvider: 1e15,
swapFeeMarketPlaceRunner: 1e15
}
const txReceipt = await nftFactory.createNftErcWithPool(
contracts.accounts[0],
nftData,
ercParams,
poolParams
)
initialBlock = await web3.eth.getBlockNumber()
erc20Token = txReceipt.events.TokenCreated.returnValues.newTokenAddress
poolAddress = txReceipt.events.NewPool.returnValues.poolAddress
erc20Contract = new web3.eth.Contract(ERC20Template.abi as AbiItem[], erc20Token)
// user2 has no dt1
expect(await erc20Contract.methods.balanceOf(user2).call()).to.equal('0')
sideStakingAddress = contracts.sideStakingAddress
})
it('#getRouter - should get Router address', async () => {
expect(await sideStaking.getRouter(sideStakingAddress)).to.equal(
contracts.routerAddress
)
})
it('#getDataTokenCirculatingSupply - should get datatoken supply in circulation (vesting amount excluded)', async () => {
expect(
await sideStaking.getDataTokenCirculatingSupply(
contracts.sideStakingAddress,
erc20Token
)
).to.equal(web3.utils.toWei('12000'))
})
it('#getDataTokenCurrentCirculatingSupply - should get datatoken supply in circulation ', async () => {
expect(
await sideStaking.getDataTokenCurrentCirculatingSupply(
contracts.sideStakingAddress,
erc20Token
)
).to.equal(web3.utils.toWei('2000'))
})
it('#getBasetoken - should get basetoken address', async () => {
expect(await sideStaking.getBasetoken(sideStakingAddress, erc20Token)).to.equal(
contracts.daiAddress
)
})
it('#getPoolAddress - should get pool address', async () => {
expect(await sideStaking.getPoolAddress(sideStakingAddress, erc20Token)).to.equal(
poolAddress
)
})
it('#getPublisherAddress - should get publisher address', async () => {
expect(
await sideStaking.getPublisherAddress(sideStakingAddress, erc20Token)
).to.equal(contracts.accounts[0])
})
it('#getBasetokenBalance ', async () => {
expect(
await sideStaking.getBasetokenBalance(sideStakingAddress, erc20Token)
).to.equal('0')
})
it('#getDatatokenBalance ', async () => {
expect(
await sideStaking.getDatatokenBalance(sideStakingAddress, erc20Token)
).to.equal('988000')
})
it('#getvestingAmount ', async () => {
expect(await sideStaking.getvestingAmount(sideStakingAddress, erc20Token)).to.equal(
'10000'
)
})
it('#getvestingLastBlock ', async () => {
expect(
await sideStaking.getvestingLastBlock(sideStakingAddress, erc20Token)
).to.equal(initialBlock.toString())
})
it('#getvestingEndBlock ', async () => {
expect(
await sideStaking.getvestingEndBlock(sideStakingAddress, erc20Token)
).to.equal((initialBlock + vestedBlocks).toString())
})
it('#getvestingAmountSoFar ', async () => {
expect(
await sideStaking.getvestingAmountSoFar(sideStakingAddress, erc20Token)
).to.equal('0')
})
it('#getVesting ', async () => {
expect(
await erc20Contract.methods.balanceOf(contracts.accounts[0]).call()
).to.equal('0')
const tx = await sideStaking.getVesting(
contracts.accounts[0],
sideStakingAddress,
erc20Token
)
expect(
await sideStaking.unitsToAmount(
erc20Token,
await erc20Contract.methods.balanceOf(contracts.accounts[0]).call()
)
).to.equal(await sideStaking.getvestingAmountSoFar(sideStakingAddress, erc20Token))
expect(
await sideStaking.getvestingLastBlock(sideStakingAddress, erc20Token)
).to.equal((await web3.eth.getBlockNumber()).toString())
})
it('#swapExactAmountIn - should swap', async () => {
await daiContract.methods
.transfer(user2, web3.utils.toWei('1000'))
.send({ from: contracts.accounts[0] })
expect(await daiContract.methods.balanceOf(user2).call()).to.equal(
web3.utils.toWei('1000')
)
expect(await erc20Contract.methods.balanceOf(user2).call()).to.equal('0')
await pool.approve(user2, contracts.daiAddress, poolAddress, '10')
const tx = await pool.swapExactAmountIn(
user2,
poolAddress,
contracts.daiAddress,
'10',
erc20Token,
'1'
)
expect(await erc20Contract.methods.balanceOf(user2).call()).to.equal(
tx.events.LOG_SWAP.returnValues.tokenAmountOut
)
})
it('#swapExactAmountOut - should swap', async () => {
await pool.approve(user2, contracts.daiAddress, poolAddress, '100')
expect(await daiContract.methods.balanceOf(user2).call()).to.equal(
web3.utils.toWei('990')
)
const tx = await pool.swapExactAmountOut(
user2,
poolAddress,
contracts.daiAddress,
'100',
erc20Token,
'50'
)
assert(tx != null)
})
it('#joinswapExternAmountIn- user2 should add liquidity, receiving LP tokens', async () => {
const daiAmountIn = '100'
const minBPTOut = '0.1'
await pool.approve(user2, contracts.daiAddress, poolAddress, '100', true)
expect(await pool.allowance(contracts.daiAddress, user2, poolAddress)).to.equal(
'100'
)
const tx = await pool.joinswapExternAmountIn(
user2,
poolAddress,
contracts.daiAddress,
daiAmountIn,
minBPTOut
)
assert(tx != null)
expect(tx.events.LOG_JOIN[0].event === 'LOG_JOIN')
expect(tx.events.LOG_BPT.event === 'LOG_BPT')
// 2 JOIN EVENTS BECAUSE SIDE STAKING ALSO STAKED DTs, TODO: we should add to whom has been sent in the LOG_BPT event
expect(tx.events.LOG_JOIN[0].returnValues.bptAmount).to.equal(
tx.events.LOG_JOIN[1].returnValues.bptAmount
)
})
it('#joinswapPoolAmountOut- user2 should add liquidity, receiving LP tokens', async () => {
const BPTAmountOut = '0.1'
const maxDAIIn = '100'
await pool.approve(user2, contracts.daiAddress, poolAddress, '100')
const tx = await pool.joinswapPoolAmountOut(
user2,
poolAddress,
contracts.daiAddress,
BPTAmountOut,
maxDAIIn
)
assert(tx != null)
expect(tx.events.LOG_JOIN[0].event === 'LOG_JOIN')
expect(tx.events.LOG_BPT.event === 'LOG_BPT')
// 2 JOIN EVENTS BECAUSE SIDE STAKING ALSO STAKED DTs, TODO: we should add to whom has been sent in the LOG_BPT event
expect(tx.events.LOG_JOIN[0].returnValues.bptAmount).to.equal(
tx.events.LOG_JOIN[1].returnValues.bptAmount
)
})
it('#exitswapPoolAmountIn- user2 exit the pool receiving only DAI', async () => {
const BPTAmountIn = '0.5'
const minDAIOut = '0.5'
const tx = await pool.exitswapPoolAmountIn(
user2,
poolAddress,
contracts.daiAddress,
BPTAmountIn,
minDAIOut
)
assert(tx != null)
expect(tx.events.LOG_EXIT[0].returnValues.tokenOut).to.equal(contracts.daiAddress)
// DTs were also unstaked in the same transaction (went to the staking contract)
expect(tx.events.LOG_EXIT[1].returnValues.tokenOut).to.equal(erc20Token)
})
it('#exitswapExternAmountOut- user2 exit the pool receiving only DAI', async () => {
const maxBTPIn = '0.5'
const exactDAIOut = '1'
const tx = await pool.exitswapPoolAmountIn(
user2,
poolAddress,
contracts.daiAddress,
maxBTPIn,
exactDAIOut
)
assert(tx != null)
expect(tx.events.LOG_EXIT[0].returnValues.tokenOut).to.equal(contracts.daiAddress)
// DTs were also unstaked in the same transaction (went to the staking contract)
expect(tx.events.LOG_EXIT[1].returnValues.tokenOut).to.equal(erc20Token)
})
})
describe('Test a pool with USDC (6 Decimals)', () => {
it('#create a pool', async () => {
// CREATE A POOL
// we prepare transaction parameters objects
const nftFactory = new NFTFactory(contracts.factory721Address, web3)
const nftData: NFTCreateData = {
name: '72120Bundle',
symbol: '72Bundle',
templateIndex: 1,
baseURI: 'https://oceanprotocol.com/nft/'
}
const ercParams: Erc20CreateParams = {
templateIndex: 1,
minter: contracts.accounts[0],
feeManager: user3,
mpFeeAddress: contracts.accounts[0],
feeToken: '0x0000000000000000000000000000000000000000',
cap: '1000000',
feeAmount: '0',
name: 'ERC20B1',
symbol: 'ERC20DT1Symbol'
}
const poolParams: PoolCreationParams = {
ssContract: contracts.sideStakingAddress,
basetokenAddress: contracts.usdcAddress,
basetokenSender: contracts.factory721Address,
publisherAddress: contracts.accounts[0],
marketFeeCollector: contracts.accounts[0],
poolTemplateAddress: contracts.poolTemplateAddress,
rate: '1',
basetokenDecimals: await usdcContract.methods.decimals().call(),
vestingAmount: '10000',
vestedBlocks: 2500000,
initialBasetokenLiquidity: web3.utils.fromWei(
await pool.amountToUnits(contracts.usdcAddress, '2000')
),
swapFeeLiquidityProvider: 1e15,
swapFeeMarketPlaceRunner: 1e15
}
const txReceipt = await nftFactory.createNftErcWithPool(
contracts.accounts[0],
nftData,
ercParams,
poolParams
)
initialBlock = await web3.eth.getBlockNumber()
erc20Token = txReceipt.events.TokenCreated.returnValues.newTokenAddress
poolAddress = txReceipt.events.NewPool.returnValues.poolAddress
erc20Contract = new web3.eth.Contract(ERC20Template.abi as AbiItem[], erc20Token)
// user2 has no dt1
expect(await erc20Contract.methods.balanceOf(user2).call()).to.equal('0')
})
it('#getBasetokenBalance ', async () => {
expect(
await sideStaking.getBasetokenBalance(sideStakingAddress, erc20Token)
).to.equal('0')
})
it('#getDatatokenBalance ', async () => {
expect(
await sideStaking.getDatatokenBalance(sideStakingAddress, erc20Token)
).to.equal('988000')
})
it('#getvestingAmount ', async () => {
expect(await sideStaking.getvestingAmount(sideStakingAddress, erc20Token)).to.equal(
'10000'
)
})
it('#getvestingLastBlock ', async () => {
expect(
await sideStaking.getvestingLastBlock(sideStakingAddress, erc20Token)
).to.equal(initialBlock.toString())
})
it('#getvestingEndBlock ', async () => {
expect(
await sideStaking.getvestingEndBlock(sideStakingAddress, erc20Token)
).to.equal((initialBlock + vestedBlocks).toString())
})
it('#getvestingAmountSoFar ', async () => {
expect(
await sideStaking.getvestingAmountSoFar(sideStakingAddress, erc20Token)
).to.equal('0')
})
it('#getVesting ', async () => {
expect(
await erc20Contract.methods.balanceOf(contracts.accounts[0]).call()
).to.equal('0')
const tx = await sideStaking.getVesting(
contracts.accounts[0],
sideStakingAddress,
erc20Token
)
expect(
await sideStaking.unitsToAmount(
erc20Token,
await erc20Contract.methods.balanceOf(contracts.accounts[0]).call()
)
).to.equal(await sideStaking.getvestingAmountSoFar(sideStakingAddress, erc20Token))
expect(
await sideStaking.getvestingLastBlock(sideStakingAddress, erc20Token)
).to.equal((await web3.eth.getBlockNumber()).toString())
})
it('#swapExactAmountIn - should swap', async () => {
const transferAmount = await pool.amountToUnits(contracts.usdcAddress, '1000') // 1000 USDC
await usdcContract.methods
.transfer(user2, transferAmount)
.send({ from: contracts.accounts[0] })
expect(await usdcContract.methods.balanceOf(user2).call()).to.equal(
transferAmount.toString()
)
expect(await erc20Contract.methods.balanceOf(user2).call()).to.equal('0')
await pool.approve(user2, contracts.usdcAddress, poolAddress, '10')
const tx = await pool.swapExactAmountIn(
user2,
poolAddress,
contracts.usdcAddress,
'10',
erc20Token,
'1'
)
expect(await erc20Contract.methods.balanceOf(user2).call()).to.equal(
tx.events.LOG_SWAP.returnValues.tokenAmountOut
)
})
it('#swapExactAmountOut - should swap', async () => {
expect(await usdcContract.methods.balanceOf(user2).call()).to.equal(
(await pool.amountToUnits(contracts.usdcAddress, '990')).toString()
)
await pool.approve(user2, contracts.usdcAddress, poolAddress, '100')
const tx = await pool.swapExactAmountOut(
user2,
poolAddress,
contracts.usdcAddress,
'100',
erc20Token,
'50'
)
assert(tx != null)
// console.log(tx.events)
})
it('#joinswapExternAmountIn- user2 should add liquidity, receiving LP tokens', async () => {
const usdcAmountIn = '100'
const minBPTOut = '0.1'
await pool.approve(user2, contracts.usdcAddress, poolAddress, '100', true)
const tx = await pool.joinswapExternAmountIn(
user2,
poolAddress,
contracts.usdcAddress,
usdcAmountIn,
minBPTOut
)
assert(tx != null)
expect(tx.events.LOG_JOIN[0].event === 'LOG_JOIN')
expect(tx.events.LOG_BPT.event === 'LOG_BPT')
// 2 JOIN EVENTS BECAUSE SIDE STAKING ALSO STAKED DTs, TODO: we should add to whom has been sent in the LOG_BPT event
expect(tx.events.LOG_JOIN[0].returnValues.bptAmount).to.equal(
tx.events.LOG_JOIN[1].returnValues.bptAmount
)
})
it('#joinswapPoolAmountOut- user2 should add liquidity, receiving LP tokens', async () => {
const BPTAmountOut = '0.1'
const maxUSDCIn = '100'
await pool.approve(user2, contracts.usdcAddress, poolAddress, '100')
const tx = await pool.joinswapPoolAmountOut(
user2,
poolAddress,
contracts.usdcAddress,
BPTAmountOut,
maxUSDCIn
)
assert(tx != null)
expect(tx.events.LOG_JOIN[0].event === 'LOG_JOIN')
expect(tx.events.LOG_BPT.event === 'LOG_BPT')
// 2 JOIN EVENTS BECAUSE SIDE STAKING ALSO STAKED DTs, TODO: we should add to whom has been sent in the LOG_BPT event
expect(tx.events.LOG_JOIN[0].returnValues.bptAmount).to.equal(
tx.events.LOG_JOIN[1].returnValues.bptAmount
)
})
it('#exitswapPoolAmountIn- user2 exit the pool receiving only USDC', async () => {
const BPTAmountIn = '0.5'
const minUSDCOut = '0.5'
const tx = await pool.exitswapPoolAmountIn(
user2,
poolAddress,
contracts.usdcAddress,
BPTAmountIn,
minUSDCOut
)
assert(tx != null)
expect(tx.events.LOG_EXIT[0].returnValues.tokenOut).to.equal(contracts.usdcAddress)
// DTs were also unstaked in the same transaction (went to the staking contract)
expect(tx.events.LOG_EXIT[1].returnValues.tokenOut).to.equal(erc20Token)
})
it('#exitswapExternAmountOut- user2 exit the pool receiving only USDC', async () => {
const maxBTPIn = '0.5'
const exactUSDCOut = '1'
const tx = await pool.exitswapPoolAmountIn(
user2,
poolAddress,
contracts.usdcAddress,
maxBTPIn,
exactUSDCOut
)
assert(tx != null)
expect(tx.events.LOG_EXIT[0].returnValues.tokenOut).to.equal(contracts.usdcAddress)
// DTs were also unstaked in the same transaction (went to the staking contract)
expect(tx.events.LOG_EXIT[1].returnValues.tokenOut).to.equal(erc20Token)
})
})
})