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:
commit
2b3448de6b
289
package-lock.json
generated
289
package-lock.json
generated
@ -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",
|
||||
|
@ -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'",
|
||||
|
@ -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
355
src/pools/ssContracts/SideStaking.ts
Normal file
355
src/pools/ssContracts/SideStaking.ts
Normal 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
|
||||
}
|
||||
}
|
1
src/pools/ssContracts/index.ts
Normal file
1
src/pools/ssContracts/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './SideStaking'
|
@ -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 () => {
|
||||
|
761
test/unit/pools/fixedRate/FixedRateExchange.test.ts
Normal file
761
test/unit/pools/fixedRate/FixedRateExchange.test.ts
Normal 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)
|
||||
})
|
||||
})
|
||||
})
|
656
test/unit/pools/ssContracts/SideStaking.test.ts
Normal file
656
test/unit/pools/ssContracts/SideStaking.test.ts
Normal 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)
|
||||
})
|
||||
})
|
||||
})
|
Loading…
x
Reference in New Issue
Block a user