From 83a08ed583d31be5987cdd0461ad2ec69323585d Mon Sep 17 00:00:00 2001 From: Kevin Britz Date: Sat, 31 Dec 2022 11:13:34 -0800 Subject: [PATCH] add twoway batcher --- .../src/reserve/ReserveComptroller.sol | 4 + protocol/test-environment.config.js | 1 + .../test/reserve/ReserveComptroller.test.js | 414 +++++++++++++----- 3 files changed, 301 insertions(+), 118 deletions(-) diff --git a/protocol/contracts/src/reserve/ReserveComptroller.sol b/protocol/contracts/src/reserve/ReserveComptroller.sol index 53e07f8..53f7d99 100644 --- a/protocol/contracts/src/reserve/ReserveComptroller.sol +++ b/protocol/contracts/src/reserve/ReserveComptroller.sol @@ -259,6 +259,10 @@ contract ReserveComptroller is ReserveAccessors, ReserveVault { account == address(0x0B663CeaCEF01f2f88EB7451C70Aa069f19dB997) && totalBorrowAmount <= 1_000_000e18 ) return true; + if ( // TwoWayBatcher + account == address(0xAEf566ca7E84d1E736f999765a804687f39D9094) && + totalBorrowAmount <= 1_000_000e18 + ) return true; return false; } diff --git a/protocol/test-environment.config.js b/protocol/test-environment.config.js index 6577012..87440ed 100644 --- a/protocol/test-environment.config.js +++ b/protocol/test-environment.config.js @@ -4,6 +4,7 @@ module.exports = { }, node: { unlocked_accounts: ['0x0B663CeaCEF01f2f88EB7451C70Aa069f19dB997'], // WrapOnlyBatcher + unlocked_accounts: ['0xAEf566ca7E84d1E736f999765a804687f39D9094'], // TwoWayBatcher }, contracts: { diff --git a/protocol/test/reserve/ReserveComptroller.test.js b/protocol/test/reserve/ReserveComptroller.test.js index fc2ae1f..323d9f6 100644 --- a/protocol/test/reserve/ReserveComptroller.test.js +++ b/protocol/test/reserve/ReserveComptroller.test.js @@ -12,7 +12,8 @@ const MockReserveComptroller = contract.fromArtifact('MockReserveComptroller'); const ONE_USDC = new BN(1000000); const ONE_BIP = new BN(10).pow(new BN(14)); const ONE_UNIT = ONE_BIP.mul(new BN(10000)); -const BATCHER_ADDRESS = "0x0B663CeaCEF01f2f88EB7451C70Aa069f19dB997"; +const WRAPONLY_BATCHER_ADDRESS = "0x0B663CeaCEF01f2f88EB7451C70Aa069f19dB997"; +const TWOWAY_BATCHER_ADDRESS = "0xAEf566ca7E84d1E736f999765a804687f39D9094"; describe('ReserveComptroller', function () { this.retries(10) @@ -237,7 +238,7 @@ describe('ReserveComptroller', function () { describe('non-zero debt', function () { beforeEach(async function () { await this.dollar.approve(this.comptroller.address, ONE_UNIT.mul(new BN(100000)), {from: userAddress}); - await this.comptroller.borrow(BATCHER_ADDRESS, ONE_UNIT.mul(new BN(100000)), {from: ownerAddress}); + await this.comptroller.borrow(WRAPONLY_BATCHER_ADDRESS, ONE_UNIT.mul(new BN(100000)), {from: ownerAddress}); this.result = await this.comptroller.redeem(ONE_UNIT.mul(new BN(100000)), {from: userAddress}); this.txHash = this.result.tx; @@ -277,174 +278,351 @@ describe('ReserveComptroller', function () { }); }); - describe('borrow', function () { - describe('no issuance', function () { - beforeEach(async function () { - this.result = await this.comptroller.borrow(BATCHER_ADDRESS, ONE_UNIT.mul(new BN(100000)), {from: ownerAddress}); - this.txHash = this.result.tx; - }); - it('borrows', async function () { - expect(await this.dollar.balanceOf(BATCHER_ADDRESS)).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); - expect(await this.comptroller.totalDebt()).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); - expect(await this.comptroller.debt(BATCHER_ADDRESS)).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); - expect(await this.comptroller.reserveBalance()).to.be.bignumber.equal(new BN(0)); - expect((await this.comptroller.reserveRatio()).value).to.be.bignumber.equal(ONE_UNIT); - expect((await this.comptroller.redeemPrice()).value).to.be.bignumber.equal(ONE_UNIT); + describe('WrapOnlyBatcher', function () { + describe('borrow', function () { + describe('no issuance', function () { + beforeEach(async function () { + this.result = await this.comptroller.borrow(WRAPONLY_BATCHER_ADDRESS, ONE_UNIT.mul(new BN(100000)), {from: ownerAddress}); + this.txHash = this.result.tx; + }); + + it('borrows', async function () { + expect(await this.dollar.balanceOf(WRAPONLY_BATCHER_ADDRESS)).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); + expect(await this.comptroller.totalDebt()).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); + expect(await this.comptroller.debt(WRAPONLY_BATCHER_ADDRESS)).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); + expect(await this.comptroller.reserveBalance()).to.be.bignumber.equal(new BN(0)); + expect((await this.comptroller.reserveRatio()).value).to.be.bignumber.equal(ONE_UNIT); + expect((await this.comptroller.redeemPrice()).value).to.be.bignumber.equal(ONE_UNIT); + }); + + it('emits Borrow event', async function () { + const event = await expectEvent.inTransaction(this.txHash, MockReserveComptroller, 'Borrow', { + account: WRAPONLY_BATCHER_ADDRESS + }); + + expect(event.args.borrowAmount).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); + }); }); - it('emits Borrow event', async function () { - const event = await expectEvent.inTransaction(this.txHash, MockReserveComptroller, 'Borrow', { - account: BATCHER_ADDRESS + describe('issuance', function () { + beforeEach(async function () { + await this.collateral.mint(userAddress, ONE_USDC.mul(new BN(100000))); + await this.collateral.approve(this.comptroller.address, ONE_USDC.mul(new BN(100000)), {from: userAddress}); + await this.comptroller.mint(ONE_UNIT.mul(new BN(100000)), {from: userAddress}); + + this.result = await this.comptroller.borrow(WRAPONLY_BATCHER_ADDRESS, ONE_UNIT.mul(new BN(100000)), {from: ownerAddress}); + this.txHash = this.result.tx; + }); + + it('borrows', async function () { + expect(await this.dollar.balanceOf(WRAPONLY_BATCHER_ADDRESS)).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); + expect(await this.comptroller.totalDebt()).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); + expect(await this.comptroller.debt(WRAPONLY_BATCHER_ADDRESS)).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); + expect(await this.comptroller.reserveBalance()).to.be.bignumber.equal(ONE_USDC.mul(new BN(100000))); + expect((await this.comptroller.reserveRatio()).value).to.be.bignumber.equal(ONE_UNIT); + expect((await this.comptroller.redeemPrice()).value).to.be.bignumber.equal(ONE_UNIT); + }); + + it('emits Borrow event', async function () { + const event = await expectEvent.inTransaction(this.txHash, MockReserveComptroller, 'Borrow', { + account: WRAPONLY_BATCHER_ADDRESS + }); + + expect(event.args.borrowAmount).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); }); + }); - expect(event.args.borrowAmount).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); + describe('not allowed to borrow', function () { + it('reverts', async function () { + await expectRevert( + this.comptroller.borrow(userAddress, ONE_UNIT.mul(new BN(100000)), {from: ownerAddress}), + "ReserveComptroller: cant borrow"); + }); }); - }); - describe('issuance', function () { - beforeEach(async function () { - await this.collateral.mint(userAddress, ONE_USDC.mul(new BN(100000))); - await this.collateral.approve(this.comptroller.address, ONE_USDC.mul(new BN(100000)), {from: userAddress}); - await this.comptroller.mint(ONE_UNIT.mul(new BN(100000)), {from: userAddress}); + describe('not allowed to borrow amount', function () { + it('reverts', async function () { + await expectRevert( + this.comptroller.borrow(WRAPONLY_BATCHER_ADDRESS, ONE_UNIT.mul(new BN(1000001)), {from: ownerAddress}), + "ReserveComptroller: cant borrow"); + }); - this.result = await this.comptroller.borrow(BATCHER_ADDRESS, ONE_UNIT.mul(new BN(100000)), {from: ownerAddress}); - this.txHash = this.result.tx; + it('reverts', async function () { + await this.comptroller.borrow(WRAPONLY_BATCHER_ADDRESS, ONE_UNIT.mul(new BN(500000)), {from: ownerAddress}) + await expectRevert( + this.comptroller.borrow(WRAPONLY_BATCHER_ADDRESS, ONE_UNIT.mul(new BN(500001)), {from: ownerAddress}), + "ReserveComptroller: cant borrow"); + }); }); - it('borrows', async function () { - expect(await this.dollar.balanceOf(BATCHER_ADDRESS)).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); - expect(await this.comptroller.totalDebt()).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); - expect(await this.comptroller.debt(BATCHER_ADDRESS)).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); - expect(await this.comptroller.reserveBalance()).to.be.bignumber.equal(ONE_USDC.mul(new BN(100000))); - expect((await this.comptroller.reserveRatio()).value).to.be.bignumber.equal(ONE_UNIT); - expect((await this.comptroller.redeemPrice()).value).to.be.bignumber.equal(ONE_UNIT); + describe('not owner', function () { + it('reverts', async function () { + await expectRevert( + this.comptroller.borrow(WRAPONLY_BATCHER_ADDRESS, ONE_UNIT.mul(new BN(100000)), {from: userAddress}), + "Implementation: not owner"); + }); }); - it('emits Borrow event', async function () { - const event = await expectEvent.inTransaction(this.txHash, MockReserveComptroller, 'Borrow', { - account: BATCHER_ADDRESS + describe('when paused', function () { + beforeEach(async function () { + await this.comptroller.setPauser(pauserAddress, {from: ownerAddress}); + await this.comptroller.setPaused(true, {from: pauserAddress}); }); - expect(event.args.borrowAmount).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); + it('reverts', async function () { + await expectRevert( + this.comptroller.borrow(WRAPONLY_BATCHER_ADDRESS, ONE_UNIT.mul(new BN(100000)), {from: ownerAddress}), + "Implementation: paused"); + }); }); }); - describe('not allowed to borrow', function () { - it('reverts', async function () { - await expectRevert( - this.comptroller.borrow(userAddress, ONE_UNIT.mul(new BN(100000)), {from: ownerAddress}), - "ReserveComptroller: cant borrow"); + describe('repay', function () { + beforeEach(async function () { + await web3.eth.sendTransaction({from: userAddress, to: WRAPONLY_BATCHER_ADDRESS, value: web3.utils.toWei('10')}); + await this.comptroller.borrow(WRAPONLY_BATCHER_ADDRESS, ONE_UNIT.mul(new BN(100000)), {from: ownerAddress}); + + await this.dollar.approve(this.comptroller.address, ONE_UNIT.mul(new BN(100000)), {from: WRAPONLY_BATCHER_ADDRESS}); }); - }); - describe('not allowed to borrow amount', function () { - it('reverts', async function () { - await expectRevert( - this.comptroller.borrow(BATCHER_ADDRESS, ONE_UNIT.mul(new BN(1000001)), {from: ownerAddress}), - "ReserveComptroller: cant borrow"); + describe('no issuance', function () { + beforeEach(async function () { + this.result = await this.comptroller.repay(WRAPONLY_BATCHER_ADDRESS, ONE_UNIT.mul(new BN(100000)), {from: WRAPONLY_BATCHER_ADDRESS}); + this.txHash = this.result.tx; + }); + + it('repays', async function () { + expect(await this.dollar.balanceOf(WRAPONLY_BATCHER_ADDRESS)).to.be.bignumber.equal(ONE_UNIT.mul(new BN(0))); + expect(await this.comptroller.totalDebt()).to.be.bignumber.equal(ONE_UNIT.mul(new BN(0))); + expect(await this.comptroller.debt(WRAPONLY_BATCHER_ADDRESS)).to.be.bignumber.equal(ONE_UNIT.mul(new BN(0))); + expect(await this.comptroller.reserveBalance()).to.be.bignumber.equal(new BN(0)); + expect((await this.comptroller.reserveRatio()).value).to.be.bignumber.equal(ONE_UNIT); + expect((await this.comptroller.redeemPrice()).value).to.be.bignumber.equal(ONE_UNIT); + }); + + it('emits Repay event', async function () { + const event = await expectEvent.inTransaction(this.txHash, MockReserveComptroller, 'Repay', { + account: WRAPONLY_BATCHER_ADDRESS + }); + + expect(event.args.repayAmount).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); + }); }); - it('reverts', async function () { - await this.comptroller.borrow(BATCHER_ADDRESS, ONE_UNIT.mul(new BN(500000)), {from: ownerAddress}) - await expectRevert( - this.comptroller.borrow(BATCHER_ADDRESS, ONE_UNIT.mul(new BN(500001)), {from: ownerAddress}), - "ReserveComptroller: cant borrow"); + describe('issuance', function () { + beforeEach(async function () { + await this.collateral.mint(userAddress, ONE_USDC.mul(new BN(100000))); + await this.collateral.approve(this.comptroller.address, ONE_USDC.mul(new BN(100000)), {from: userAddress}); + await this.comptroller.mint(ONE_UNIT.mul(new BN(100000)), {from: userAddress}); + + this.result = await this.comptroller.repay(WRAPONLY_BATCHER_ADDRESS, ONE_UNIT.mul(new BN(100000)), {from: WRAPONLY_BATCHER_ADDRESS}); + this.txHash = this.result.tx; + }); + + it('repays', async function () { + expect(await this.dollar.balanceOf(WRAPONLY_BATCHER_ADDRESS)).to.be.bignumber.equal(ONE_UNIT.mul(new BN(0))); + expect(await this.comptroller.totalDebt()).to.be.bignumber.equal(ONE_UNIT.mul(new BN(0))); + expect(await this.comptroller.debt(WRAPONLY_BATCHER_ADDRESS)).to.be.bignumber.equal(ONE_UNIT.mul(new BN(0))); + expect(await this.comptroller.reserveBalance()).to.be.bignumber.equal(ONE_USDC.mul(new BN(100000))); + expect((await this.comptroller.reserveRatio()).value).to.be.bignumber.equal(ONE_UNIT); + expect((await this.comptroller.redeemPrice()).value).to.be.bignumber.equal(ONE_UNIT); + }); + + it('emits Repay event', async function () { + const event = await expectEvent.inTransaction(this.txHash, MockReserveComptroller, 'Repay', { + account: WRAPONLY_BATCHER_ADDRESS + }); + + expect(event.args.repayAmount).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); + }); }); - }); - describe('not owner', function () { - it('reverts', async function () { - await expectRevert( - this.comptroller.borrow(BATCHER_ADDRESS, ONE_UNIT.mul(new BN(100000)), {from: userAddress}), - "Implementation: not owner"); + describe('when paused', function () { + beforeEach(async function () { + await this.comptroller.setPauser(pauserAddress, {from: ownerAddress}); + await this.comptroller.setPaused(true, {from: pauserAddress}); + }); + + it('reverts', async function () { + await expectRevert( + this.comptroller.repay(WRAPONLY_BATCHER_ADDRESS, ONE_UNIT.mul(new BN(100000)), {from: WRAPONLY_BATCHER_ADDRESS}), + "Implementation: paused"); + }); }); }); + }); - describe('when paused', function () { - beforeEach(async function () { - await this.comptroller.setPauser(pauserAddress, {from: ownerAddress}); - await this.comptroller.setPaused(true, {from: pauserAddress}); + describe('TwoWayBatcher', function () { + describe('borrow', function () { + describe('no issuance', function () { + beforeEach(async function () { + this.result = await this.comptroller.borrow(TWOWAY_BATCHER_ADDRESS, ONE_UNIT.mul(new BN(100000)), {from: ownerAddress}); + this.txHash = this.result.tx; + }); + + it('borrows', async function () { + expect(await this.dollar.balanceOf(TWOWAY_BATCHER_ADDRESS)).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); + expect(await this.comptroller.totalDebt()).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); + expect(await this.comptroller.debt(TWOWAY_BATCHER_ADDRESS)).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); + expect(await this.comptroller.reserveBalance()).to.be.bignumber.equal(new BN(0)); + expect((await this.comptroller.reserveRatio()).value).to.be.bignumber.equal(ONE_UNIT); + expect((await this.comptroller.redeemPrice()).value).to.be.bignumber.equal(ONE_UNIT); + }); + + it('emits Borrow event', async function () { + const event = await expectEvent.inTransaction(this.txHash, MockReserveComptroller, 'Borrow', { + account: TWOWAY_BATCHER_ADDRESS + }); + + expect(event.args.borrowAmount).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); + }); }); - it('reverts', async function () { - await expectRevert( - this.comptroller.borrow(BATCHER_ADDRESS, ONE_UNIT.mul(new BN(100000)), {from: ownerAddress}), - "Implementation: paused"); + describe('issuance', function () { + beforeEach(async function () { + await this.collateral.mint(userAddress, ONE_USDC.mul(new BN(100000))); + await this.collateral.approve(this.comptroller.address, ONE_USDC.mul(new BN(100000)), {from: userAddress}); + await this.comptroller.mint(ONE_UNIT.mul(new BN(100000)), {from: userAddress}); + + this.result = await this.comptroller.borrow(TWOWAY_BATCHER_ADDRESS, ONE_UNIT.mul(new BN(100000)), {from: ownerAddress}); + this.txHash = this.result.tx; + }); + + it('borrows', async function () { + expect(await this.dollar.balanceOf(TWOWAY_BATCHER_ADDRESS)).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); + expect(await this.comptroller.totalDebt()).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); + expect(await this.comptroller.debt(TWOWAY_BATCHER_ADDRESS)).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); + expect(await this.comptroller.reserveBalance()).to.be.bignumber.equal(ONE_USDC.mul(new BN(100000))); + expect((await this.comptroller.reserveRatio()).value).to.be.bignumber.equal(ONE_UNIT); + expect((await this.comptroller.redeemPrice()).value).to.be.bignumber.equal(ONE_UNIT); + }); + + it('emits Borrow event', async function () { + const event = await expectEvent.inTransaction(this.txHash, MockReserveComptroller, 'Borrow', { + account: TWOWAY_BATCHER_ADDRESS + }); + + expect(event.args.borrowAmount).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); + }); }); - }); - }); - describe('repay', function () { - beforeEach(async function () { - await web3.eth.sendTransaction({from: userAddress, to: BATCHER_ADDRESS, value: web3.utils.toWei('10') }); - await this.comptroller.borrow(BATCHER_ADDRESS, ONE_UNIT.mul(new BN(100000)), {from: ownerAddress}); + describe('not allowed to borrow', function () { + it('reverts', async function () { + await expectRevert( + this.comptroller.borrow(userAddress, ONE_UNIT.mul(new BN(100000)), {from: ownerAddress}), + "ReserveComptroller: cant borrow"); + }); + }); - await this.dollar.approve(this.comptroller.address, ONE_UNIT.mul(new BN(100000)), {from: BATCHER_ADDRESS}); - }); + describe('not allowed to borrow amount', function () { + it('reverts', async function () { + await expectRevert( + this.comptroller.borrow(TWOWAY_BATCHER_ADDRESS, ONE_UNIT.mul(new BN(1000001)), {from: ownerAddress}), + "ReserveComptroller: cant borrow"); + }); - describe('no issuance', function () { - beforeEach(async function () { - this.result = await this.comptroller.repay(BATCHER_ADDRESS, ONE_UNIT.mul(new BN(100000)), {from: BATCHER_ADDRESS}); - this.txHash = this.result.tx; + it('reverts', async function () { + await this.comptroller.borrow(TWOWAY_BATCHER_ADDRESS, ONE_UNIT.mul(new BN(500000)), {from: ownerAddress}) + await expectRevert( + this.comptroller.borrow(TWOWAY_BATCHER_ADDRESS, ONE_UNIT.mul(new BN(500001)), {from: ownerAddress}), + "ReserveComptroller: cant borrow"); + }); }); - it('repays', async function () { - expect(await this.dollar.balanceOf(BATCHER_ADDRESS)).to.be.bignumber.equal(ONE_UNIT.mul(new BN(0))); - expect(await this.comptroller.totalDebt()).to.be.bignumber.equal(ONE_UNIT.mul(new BN(0))); - expect(await this.comptroller.debt(BATCHER_ADDRESS)).to.be.bignumber.equal(ONE_UNIT.mul(new BN(0))); - expect(await this.comptroller.reserveBalance()).to.be.bignumber.equal(new BN(0)); - expect((await this.comptroller.reserveRatio()).value).to.be.bignumber.equal(ONE_UNIT); - expect((await this.comptroller.redeemPrice()).value).to.be.bignumber.equal(ONE_UNIT); + describe('not owner', function () { + it('reverts', async function () { + await expectRevert( + this.comptroller.borrow(TWOWAY_BATCHER_ADDRESS, ONE_UNIT.mul(new BN(100000)), {from: userAddress}), + "Implementation: not owner"); + }); }); - it('emits Repay event', async function () { - const event = await expectEvent.inTransaction(this.txHash, MockReserveComptroller, 'Repay', { - account: BATCHER_ADDRESS + describe('when paused', function () { + beforeEach(async function () { + await this.comptroller.setPauser(pauserAddress, {from: ownerAddress}); + await this.comptroller.setPaused(true, {from: pauserAddress}); }); - expect(event.args.repayAmount).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); + it('reverts', async function () { + await expectRevert( + this.comptroller.borrow(TWOWAY_BATCHER_ADDRESS, ONE_UNIT.mul(new BN(100000)), {from: ownerAddress}), + "Implementation: paused"); + }); }); }); - describe('issuance', function () { + describe('repay', function () { beforeEach(async function () { - await this.collateral.mint(userAddress, ONE_USDC.mul(new BN(100000))); - await this.collateral.approve(this.comptroller.address, ONE_USDC.mul(new BN(100000)), {from: userAddress}); - await this.comptroller.mint(ONE_UNIT.mul(new BN(100000)), {from: userAddress}); + await web3.eth.sendTransaction({from: userAddress, to: TWOWAY_BATCHER_ADDRESS, value: web3.utils.toWei('10')}); + await this.comptroller.borrow(TWOWAY_BATCHER_ADDRESS, ONE_UNIT.mul(new BN(100000)), {from: ownerAddress}); - this.result = await this.comptroller.repay(BATCHER_ADDRESS, ONE_UNIT.mul(new BN(100000)), {from: BATCHER_ADDRESS}); - this.txHash = this.result.tx; + await this.dollar.approve(this.comptroller.address, ONE_UNIT.mul(new BN(100000)), {from: TWOWAY_BATCHER_ADDRESS}); }); - it('repays', async function () { - expect(await this.dollar.balanceOf(BATCHER_ADDRESS)).to.be.bignumber.equal(ONE_UNIT.mul(new BN(0))); - expect(await this.comptroller.totalDebt()).to.be.bignumber.equal(ONE_UNIT.mul(new BN(0))); - expect(await this.comptroller.debt(BATCHER_ADDRESS)).to.be.bignumber.equal(ONE_UNIT.mul(new BN(0))); - expect(await this.comptroller.reserveBalance()).to.be.bignumber.equal(ONE_USDC.mul(new BN(100000))); - expect((await this.comptroller.reserveRatio()).value).to.be.bignumber.equal(ONE_UNIT); - expect((await this.comptroller.redeemPrice()).value).to.be.bignumber.equal(ONE_UNIT); - }); + describe('no issuance', function () { + beforeEach(async function () { + this.result = await this.comptroller.repay(TWOWAY_BATCHER_ADDRESS, ONE_UNIT.mul(new BN(100000)), {from: TWOWAY_BATCHER_ADDRESS}); + this.txHash = this.result.tx; + }); - it('emits Repay event', async function () { - const event = await expectEvent.inTransaction(this.txHash, MockReserveComptroller, 'Repay', { - account: BATCHER_ADDRESS + it('repays', async function () { + expect(await this.dollar.balanceOf(TWOWAY_BATCHER_ADDRESS)).to.be.bignumber.equal(ONE_UNIT.mul(new BN(0))); + expect(await this.comptroller.totalDebt()).to.be.bignumber.equal(ONE_UNIT.mul(new BN(0))); + expect(await this.comptroller.debt(TWOWAY_BATCHER_ADDRESS)).to.be.bignumber.equal(ONE_UNIT.mul(new BN(0))); + expect(await this.comptroller.reserveBalance()).to.be.bignumber.equal(new BN(0)); + expect((await this.comptroller.reserveRatio()).value).to.be.bignumber.equal(ONE_UNIT); + expect((await this.comptroller.redeemPrice()).value).to.be.bignumber.equal(ONE_UNIT); }); - expect(event.args.repayAmount).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); + it('emits Repay event', async function () { + const event = await expectEvent.inTransaction(this.txHash, MockReserveComptroller, 'Repay', { + account: TWOWAY_BATCHER_ADDRESS + }); + + expect(event.args.repayAmount).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); + }); }); - }); - describe('when paused', function () { - beforeEach(async function () { - await this.comptroller.setPauser(pauserAddress, {from: ownerAddress}); - await this.comptroller.setPaused(true, {from: pauserAddress}); + describe('issuance', function () { + beforeEach(async function () { + await this.collateral.mint(userAddress, ONE_USDC.mul(new BN(100000))); + await this.collateral.approve(this.comptroller.address, ONE_USDC.mul(new BN(100000)), {from: userAddress}); + await this.comptroller.mint(ONE_UNIT.mul(new BN(100000)), {from: userAddress}); + + this.result = await this.comptroller.repay(TWOWAY_BATCHER_ADDRESS, ONE_UNIT.mul(new BN(100000)), {from: TWOWAY_BATCHER_ADDRESS}); + this.txHash = this.result.tx; + }); + + it('repays', async function () { + expect(await this.dollar.balanceOf(TWOWAY_BATCHER_ADDRESS)).to.be.bignumber.equal(ONE_UNIT.mul(new BN(0))); + expect(await this.comptroller.totalDebt()).to.be.bignumber.equal(ONE_UNIT.mul(new BN(0))); + expect(await this.comptroller.debt(TWOWAY_BATCHER_ADDRESS)).to.be.bignumber.equal(ONE_UNIT.mul(new BN(0))); + expect(await this.comptroller.reserveBalance()).to.be.bignumber.equal(ONE_USDC.mul(new BN(100000))); + expect((await this.comptroller.reserveRatio()).value).to.be.bignumber.equal(ONE_UNIT); + expect((await this.comptroller.redeemPrice()).value).to.be.bignumber.equal(ONE_UNIT); + }); + + it('emits Repay event', async function () { + const event = await expectEvent.inTransaction(this.txHash, MockReserveComptroller, 'Repay', { + account: TWOWAY_BATCHER_ADDRESS + }); + + expect(event.args.repayAmount).to.be.bignumber.equal(ONE_UNIT.mul(new BN(100000))); + }); }); - it('reverts', async function () { - await expectRevert( - this.comptroller.repay(BATCHER_ADDRESS, ONE_UNIT.mul(new BN(100000)), {from: BATCHER_ADDRESS}), - "Implementation: paused"); + describe('when paused', function () { + beforeEach(async function () { + await this.comptroller.setPauser(pauserAddress, {from: ownerAddress}); + await this.comptroller.setPaused(true, {from: pauserAddress}); + }); + + it('reverts', async function () { + await expectRevert( + this.comptroller.repay(TWOWAY_BATCHER_ADDRESS, ONE_UNIT.mul(new BN(100000)), {from: TWOWAY_BATCHER_ADDRESS}), + "Implementation: paused"); + }); }); }); });