From 7ae6295161404b2d091b1a23e319d66b38b7cf07 Mon Sep 17 00:00:00 2001 From: Nick Freyaldenhoven Date: Tue, 23 Jul 2019 13:20:33 -0500 Subject: [PATCH 1/2] Adding functions and tests for new bonding curve contract methods. --- packages/kosu.js/src/KosuToken.ts | 56 +++++++++++++++++ packages/kosu.js/src/PosterRegistry.ts | 11 ++++ packages/kosu.js/src/Treasury.ts | 11 ++++ packages/kosu.js/test/kosu_token_test.js | 63 +++++++++++++++++-- packages/kosu.js/test/poster_registry_test.js | 20 ++++++ packages/kosu.js/test/treasury_test.js | 14 +++++ 6 files changed, 170 insertions(+), 5 deletions(-) create mode 100644 packages/kosu.js/test/poster_registry_test.js create mode 100644 packages/kosu.js/test/treasury_test.js diff --git a/packages/kosu.js/src/KosuToken.ts b/packages/kosu.js/src/KosuToken.ts index 3f70efb8..ff17b887 100644 --- a/packages/kosu.js/src/KosuToken.ts +++ b/packages/kosu.js/src/KosuToken.ts @@ -157,4 +157,60 @@ export class KosuToken { const contract = await this.getContract(); return contract.allowance.callAsync(owner, spender); } + + /** + * Calculated tokens to be minted from deposited ether. + * + * @param etherInput Amount of ether to be submitted to generate tokens. + * @returns Estimation of tokens to be minted. + */ + public async estimateEtherToToken(etherInput: BigNumber): Promise { + const contract = await this.getContract(); + return contract.estimateEtherToToken.callAsync(etherInput); + } + + /** + * Calculates ether to be returned for burning tokens. + * + * @param tokensToBurn Amount of tokens to burn for returned ether. + * @returns Estimation of ether to be returned. + */ + public async estimateTokenToEther(tokensToBurn: BigNumber): Promise { + const contract = await this.getContract(); + return contract.estimateTokenToEther.callAsync(tokensToBurn); + } + + /** + * Sends ether to the contract to bond tokens. + * + * @param value Amount of wei to deposit + * @param minPayout Minimum amount of tokens required to be minted to prevent transaction from reverting. + * @returns Logs from the transaction block. + */ + public async bondTokens(value: BigNumber, minPayout: BigNumber): Promise { + const contract = await this.getContract(); + return contract.bondTokens.awaitTransactionSuccessAsync(minPayout, { value }); + } + + /** + * Releases tokens to be burned and return bonded ether. + * + * @param tokensToBurn Amount of tokens to burn for returned ether. + * @returns Logs from the transaction block. + */ + public async releaseTokens(tokensToBurn: BigNumber): Promise { + const contract = await this.getContract(); + return contract.releaseTokens.awaitTransactionSuccessAsync(tokensToBurn); + } + + /** + * Sends ether to the contract to bond tokens. + * + * @param value Amount of wei to deposit + * @returns Logs from the transaction block. + */ + public async pay(value: BigNumber): Promise { + const contract = await this.getContract(); + return this.web3Wrapper.sendTransactionAsync({ from: await this.web3.eth.getCoinbase(), to: contract.address, value, gas: 70000 }).then(async txHash => this.web3Wrapper.awaitTransactionSuccessAsync(txHash)); + } } diff --git a/packages/kosu.js/src/PosterRegistry.ts b/packages/kosu.js/src/PosterRegistry.ts index 8c7d7c5d..c02dc3e4 100644 --- a/packages/kosu.js/src/PosterRegistry.ts +++ b/packages/kosu.js/src/PosterRegistry.ts @@ -142,4 +142,15 @@ export class PosterRegistry { const contract = await this.getContract(); return contract.releaseTokens.awaitTransactionSuccessAsync(amount); } + + /** + * Sends ether to the contract to bond and register tokens for posting. + * + * @param value Amount of wei to deposit + * @returns Logs from the transaction block. + */ + public async pay(value: BigNumber): Promise { + const contract = await this.getContract(); + return this.web3Wrapper.sendTransactionAsync({ from: await this.web3.eth.getCoinbase(), to: contract.address, value, gas: 220000 }).then(async txHash => this.web3Wrapper.awaitTransactionSuccessAsync(txHash)); + } } diff --git a/packages/kosu.js/src/Treasury.ts b/packages/kosu.js/src/Treasury.ts index 6612ff80..8d2e66a7 100644 --- a/packages/kosu.js/src/Treasury.ts +++ b/packages/kosu.js/src/Treasury.ts @@ -216,4 +216,15 @@ export class Treasury { const contract = await this.getContract(); return this.kosuToken.approve(contract.address, value); } + + /** + * Sends ether to the contract to bond and deposit tokens. + * + * @param value Amount of wei to deposit + * @returns Logs from the transaction block. + */ + public async pay(value: BigNumber): Promise { + const contract = await this.getContract(); + return this.web3Wrapper.sendTransactionAsync({ from: await this.web3.eth.getCoinbase(), to: contract.address, value, gas: 120000 }).then(async txHash => this.web3Wrapper.awaitTransactionSuccessAsync(txHash)); +} } diff --git a/packages/kosu.js/test/kosu_token_test.js b/packages/kosu.js/test/kosu_token_test.js index f9f0cd09..2c8a9c32 100644 --- a/packages/kosu.js/test/kosu_token_test.js +++ b/packages/kosu.js/test/kosu_token_test.js @@ -17,7 +17,7 @@ describe("KosuToken", () => { describe("transfer", () => { it("should succeed with the expected log", async () => { - await kosu.kosuToken.transfer(accounts[0], 1, { from: accounts[0] }).then(({ logs }) => { + await kosu.kosuToken.transfer(accounts[0], 1).then(({ logs }) => { logs.length.should.eq(1); }); }); @@ -25,8 +25,8 @@ describe("KosuToken", () => { describe("transferFrom", () => { it("should succeed with the expected log", async () => { - await kosu.kosuToken.approve(accounts[0], 1, { from: accounts[0] }); - await kosu.kosuToken.transferFrom(accounts[0], accounts[0], 1, { from: accounts[0] }).then(({ logs }) => { + await kosu.kosuToken.approve(accounts[0], 1); + await kosu.kosuToken.transferFrom(accounts[0], accounts[0], 1).then(({ logs }) => { logs.length.should.eq(2); }); }); @@ -34,7 +34,7 @@ describe("KosuToken", () => { describe("approve", () => { it("should succeed with the expected log", async () => { - await kosu.kosuToken.approve(accounts[0], 1, { from: accounts[0] }).then(({ logs }) => { + await kosu.kosuToken.approve(accounts[0], 1).then(({ logs }) => { logs.length.should.eq(1); }); }); @@ -42,10 +42,63 @@ describe("KosuToken", () => { describe("allowance", () => { it("should report the allowance", async () => { - await kosu.kosuToken.approve(accounts[0], 1, { from: accounts[0] }); + await kosu.kosuToken.approve(accounts[0], 1); await kosu.kosuToken.allowance(accounts[0], accounts[0]).then(allowance => { allowance.eq(1).should.eq(true); }); }); }); + + describe("bondTokens", () => { + it("should bond ether for tokens", async () => { + const initialBalance = await kosu.kosuToken.balanceOf(accounts[0]); + await kosu.kosuToken.pay(TestValues.oneEther); + const finalBalance = await kosu.kosuToken.balanceOf(accounts[0]); + const difference = finalBalance.minus(initialBalance); + difference.toNumber().should.be.gt(0); + + await kosu.kosuToken.releaseTokens(difference); + }); + }); + + describe("releaseTokens", () => { + it("should burn tokens for ether", async () => { + const initialBalance = await kosu.kosuToken.balanceOf(accounts[0]); + await kosu.kosuToken.pay(TestValues.oneEther); + const finalBalance = await kosu.kosuToken.balanceOf(accounts[0]); + const difference = finalBalance.minus(initialBalance); + difference.toNumber().should.be.gt(0); + + const initialEth = await web3Wrapper.getBalanceInWeiAsync(accounts[0]); + await kosu.kosuToken.releaseTokens(difference); + const finalEth = await web3Wrapper.getBalanceInWeiAsync(accounts[0]); + finalEth.minus(initialEth).toNumber().should.be.gt(0); + }); + }); + + + describe("estimateEtherToToken", () => { + it("should estimate tokens generated from ether", async () => { + await kosu.kosuToken.estimateEtherToToken(TestValues.oneEther).then(val => val.toNumber().should.be.gt(0)); + }); + }); + + describe("estimateTokenToEther", () => { + it("should estimate ether returned from tokens", async () => { + await kosu.kosuToken.estimateTokenToEther(TestValues.oneEther).then(val => val.toNumber().should.be.gt(0)); + }); + }); + + + describe("pay", () => { + it("should generate tokens", async () => { + const initialBalance = await kosu.kosuToken.balanceOf(accounts[0]); + await kosu.kosuToken.pay(TestValues.oneEther); + const finalBalance = await kosu.kosuToken.balanceOf(accounts[0]); + const difference = finalBalance.minus(initialBalance); + difference.toNumber().should.be.gt(0); + + await kosu.kosuToken.releaseTokens(difference); + }); + }); }); diff --git a/packages/kosu.js/test/poster_registry_test.js b/packages/kosu.js/test/poster_registry_test.js new file mode 100644 index 00000000..50c70f31 --- /dev/null +++ b/packages/kosu.js/test/poster_registry_test.js @@ -0,0 +1,20 @@ +describe("PosterRegistry", () => { + describe("pay", () => { + it("should generate treasury balance", async () => { + const initialSystemBalance = await kosu.treasury.systemBalance(accounts[0]); + const initialPosterBalance = await kosu.posterRegistry.tokensRegisteredFor(accounts[0]); + await kosu.posterRegistry.pay(TestValues.oneEther); + const finalSystemBalance = await kosu.treasury.systemBalance(accounts[0]); + const finalPosterBalance = await kosu.posterRegistry.tokensRegisteredFor(accounts[0]); + + const difference = finalSystemBalance.minus(initialSystemBalance); + const posterDifference = finalPosterBalance.minus(initialPosterBalance); + + difference.toString().should.eq(posterDifference.toString()); + + await kosu.posterRegistry.releaseTokens(difference); + await kosu.treasury.withdraw(difference); + await kosu.kosuToken.releaseTokens(difference); + }); + }); +}); diff --git a/packages/kosu.js/test/treasury_test.js b/packages/kosu.js/test/treasury_test.js new file mode 100644 index 00000000..1e8ff4ca --- /dev/null +++ b/packages/kosu.js/test/treasury_test.js @@ -0,0 +1,14 @@ +describe("Treasury", () => { + describe("pay", () => { + it("should generate treasury balance", async () => { + const initialSystemBalance = await kosu.treasury.systemBalance(accounts[0]); + await kosu.treasury.pay(TestValues.oneEther); + const finalSystemBalance = await kosu.treasury.systemBalance(accounts[0]); + const difference = finalSystemBalance.minus(initialSystemBalance); + difference.toNumber().should.be.gt(0); + + await kosu.treasury.withdraw(difference); + await kosu.kosuToken.releaseTokens(difference); + }); + }); +}); From baed8a3f90b1888ffe20ec1523b640fccea49deb Mon Sep 17 00:00:00 2001 From: Nick Freyaldenhoven Date: Tue, 23 Jul 2019 13:23:35 -0500 Subject: [PATCH 2/2] Running prettier. --- packages/kosu.js/src/KosuToken.ts | 4 +++- packages/kosu.js/src/PosterRegistry.ts | 4 +++- packages/kosu.js/src/Treasury.ts | 6 ++++-- packages/kosu.js/test/kosu_token_test.js | 7 ++++--- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/packages/kosu.js/src/KosuToken.ts b/packages/kosu.js/src/KosuToken.ts index ff17b887..e4653dac 100644 --- a/packages/kosu.js/src/KosuToken.ts +++ b/packages/kosu.js/src/KosuToken.ts @@ -211,6 +211,8 @@ export class KosuToken { */ public async pay(value: BigNumber): Promise { const contract = await this.getContract(); - return this.web3Wrapper.sendTransactionAsync({ from: await this.web3.eth.getCoinbase(), to: contract.address, value, gas: 70000 }).then(async txHash => this.web3Wrapper.awaitTransactionSuccessAsync(txHash)); + return this.web3Wrapper + .sendTransactionAsync({ from: await this.web3.eth.getCoinbase(), to: contract.address, value, gas: 70000 }) + .then(async txHash => this.web3Wrapper.awaitTransactionSuccessAsync(txHash)); } } diff --git a/packages/kosu.js/src/PosterRegistry.ts b/packages/kosu.js/src/PosterRegistry.ts index c02dc3e4..bcdc445e 100644 --- a/packages/kosu.js/src/PosterRegistry.ts +++ b/packages/kosu.js/src/PosterRegistry.ts @@ -151,6 +151,8 @@ export class PosterRegistry { */ public async pay(value: BigNumber): Promise { const contract = await this.getContract(); - return this.web3Wrapper.sendTransactionAsync({ from: await this.web3.eth.getCoinbase(), to: contract.address, value, gas: 220000 }).then(async txHash => this.web3Wrapper.awaitTransactionSuccessAsync(txHash)); + return this.web3Wrapper + .sendTransactionAsync({ from: await this.web3.eth.getCoinbase(), to: contract.address, value, gas: 220000 }) + .then(async txHash => this.web3Wrapper.awaitTransactionSuccessAsync(txHash)); } } diff --git a/packages/kosu.js/src/Treasury.ts b/packages/kosu.js/src/Treasury.ts index 8d2e66a7..9ca9ba17 100644 --- a/packages/kosu.js/src/Treasury.ts +++ b/packages/kosu.js/src/Treasury.ts @@ -225,6 +225,8 @@ export class Treasury { */ public async pay(value: BigNumber): Promise { const contract = await this.getContract(); - return this.web3Wrapper.sendTransactionAsync({ from: await this.web3.eth.getCoinbase(), to: contract.address, value, gas: 120000 }).then(async txHash => this.web3Wrapper.awaitTransactionSuccessAsync(txHash)); -} + return this.web3Wrapper + .sendTransactionAsync({ from: await this.web3.eth.getCoinbase(), to: contract.address, value, gas: 120000 }) + .then(async txHash => this.web3Wrapper.awaitTransactionSuccessAsync(txHash)); + } } diff --git a/packages/kosu.js/test/kosu_token_test.js b/packages/kosu.js/test/kosu_token_test.js index 2c8a9c32..9de8e67d 100644 --- a/packages/kosu.js/test/kosu_token_test.js +++ b/packages/kosu.js/test/kosu_token_test.js @@ -72,11 +72,13 @@ describe("KosuToken", () => { const initialEth = await web3Wrapper.getBalanceInWeiAsync(accounts[0]); await kosu.kosuToken.releaseTokens(difference); const finalEth = await web3Wrapper.getBalanceInWeiAsync(accounts[0]); - finalEth.minus(initialEth).toNumber().should.be.gt(0); + finalEth + .minus(initialEth) + .toNumber() + .should.be.gt(0); }); }); - describe("estimateEtherToToken", () => { it("should estimate tokens generated from ether", async () => { await kosu.kosuToken.estimateEtherToToken(TestValues.oneEther).then(val => val.toNumber().should.be.gt(0)); @@ -89,7 +91,6 @@ describe("KosuToken", () => { }); }); - describe("pay", () => { it("should generate tokens", async () => { const initialBalance = await kosu.kosuToken.balanceOf(accounts[0]);