Skip to content
This repository has been archived by the owner on Sep 27, 2022. It is now read-only.

Commit

Permalink
test EthWrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
Brendan Chou committed Jun 14, 2018
1 parent 6c5efee commit 72ec649
Show file tree
Hide file tree
Showing 5 changed files with 245 additions and 21 deletions.
40 changes: 22 additions & 18 deletions contracts/margin/external/BucketLender/BucketLender.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pragma experimental "v0.5.0";
import { ReentrancyGuard } from "zeppelin-solidity/contracts/ReentrancyGuard.sol";
import { Math } from "zeppelin-solidity/contracts/math/Math.sol";
import { SafeMath } from "zeppelin-solidity/contracts/math/SafeMath.sol";
import { HasNoEther } from "zeppelin-solidity/contracts/ownership/HasNoEther.sol";
import { Margin } from "../../Margin.sol";
import { MathHelpers } from "../../../lib/MathHelpers.sol";
import { TokenInteract } from "../../../lib/TokenInteract.sol";
Expand Down Expand Up @@ -58,13 +59,13 @@ import { MarginHelper } from "../lib/MarginHelper.sol";
* - Go into a particular bucket, determined by time since the start of the position
* - If the position has not started: bucket = 0
* - If the position has started: bucket = ceiling(time_since_start / BUCKET_TIME)
* - This is always the highest bucket; that is, all higher buckets have no Weight, AA or OP
* - This is always the highest bucket; no higher bucket yet exists
* - Increase the bucket's AA
* - Increase the bucket's weight and the account's weight in that bucket
*
* - Token Withdrawals:
* - Can be from any bucket with available amount
* - Decrease the bucket's AA (if it has enough, otherwise throw)
* - Decrease the bucket's AA
* - Decrease the bucket's weight and the account's weight in that bucket
*
* - Increasing the Position (Lending):
Expand All @@ -86,6 +87,7 @@ import { MarginHelper } from "../lib/MarginHelper.sol";
* - The highest bucket with OP is always less-than-or-equal-to the lowest bucket with AA
*/
contract BucketLender is
HasNoEther,
OnlyMargin,
LoanOwner,
IncreaseLoanDelegator,
Expand Down Expand Up @@ -268,6 +270,7 @@ contract BucketLender is
external
onlyMargin
nonReentrant
onlyPosition(positionId)
returns (address)
{
MarginCommon.LoanOffering memory loanOffering = parseLoanOffering(
Expand All @@ -277,12 +280,9 @@ contract BucketLender is
signature
);

// CHECK POSITIONID
require(positionId == POSITION_ID);

// CHECK ADDRESSES
require(loanOffering.owedToken == OWED_TOKEN);
require(loanOffering.heldToken == HELD_TOKEN);
assert(loanOffering.owedToken == OWED_TOKEN);
assert(loanOffering.heldToken == HELD_TOKEN);
require(loanOffering.payer == address(this));
require(loanOffering.owner == address(this));

Expand Down Expand Up @@ -321,7 +321,7 @@ contract BucketLender is
* This function initializes this contract and returns this address to indicate to Margin
* that it is willing to take ownership of the loan.
*
* @param from (unused)
* @param from Address of the previous owner
* @param positionId Unique ID of the position
* @return This address on success, throw otherwise
*/
Expand Down Expand Up @@ -359,7 +359,7 @@ contract BucketLender is
* @param payer Address that loaned the additional tokens
* @param positionId Unique ID of the position
* @param principalAdded Amount that was added to the position
* param lentAmount (unused)
* @param lentAmount Amount of owedToken lent
* @return This address to accept, a different address to ask that contract
*/
function increaseLoanOnBehalfOf(
Expand Down Expand Up @@ -422,7 +422,7 @@ contract BucketLender is
"BucketLender#marginCallOnBehalfOf: Margin-caller must be trusted"
);
require(
depositAmount == 0,
depositAmount == 0, // disallows any deposit amount to cancel the margin-call
"BucketLender#marginCallOnBehalfOf: Deposit amount must be zero"
);

Expand Down Expand Up @@ -499,6 +499,10 @@ contract BucketLender is
external
returns (uint256)
{
require(
amount != 0,
"BucketLender#deposit: Cannot deposit zero tokens"
);
require(
!Margin(DYDX_MARGIN).isPositionClosed(POSITION_ID),
"BucketLender#deposit: Cannot deposit after the position is closed"
Expand Down Expand Up @@ -671,12 +675,12 @@ contract BucketLender is

uint256 principalToSub = principalRemoved;
uint256 availableToAdd = newRepaidAmount.sub(cachedRepaidAmount);
uint256 mostRecentlyUsedBucket;
uint256 criticalBucketTemp = criticalBucket;

// loop over buckets in reverse order starting with the critical bucket
for (
uint256 bucket = criticalBucket;
principalToSub > 0 && bucket <= criticalBucket;
uint256 bucket = criticalBucketTemp;
principalToSub > 0 && bucket <= criticalBucketTemp; // prevent underflow on bucket
bucket--
) {
uint256 principalTemp = Math.min256(principalToSub, principalForBucket[bucket]);
Expand All @@ -695,13 +699,13 @@ contract BucketLender is
principalToSub = principalToSub.sub(principalTemp);
availableToAdd = availableToAdd.sub(availableTemp);

mostRecentlyUsedBucket = bucket;
criticalBucketTemp = bucket;
}

assert(principalToSub == 0);
assert(availableToAdd == 0);

setCriticalBucket(mostRecentlyUsedBucket);
setCriticalBucket(criticalBucketTemp);

cachedRepaidAmount = newRepaidAmount;
}
Expand All @@ -723,7 +727,7 @@ contract BucketLender is
{
uint256 principalToAdd = principalAdded;
uint256 availableToSub = lentAmount;
uint256 mostRecentlyUsedBucket;
uint256 criticalBucketTemp;

// loop over buckets in order starting from the critical bucket
uint256 lastBucket = getBucketNumber();
Expand All @@ -748,13 +752,13 @@ contract BucketLender is
principalToAdd = principalToAdd.sub(principalTemp);
availableToSub = availableToSub.sub(availableTemp);

mostRecentlyUsedBucket = bucket;
criticalBucketTemp = bucket;
}

assert(principalToAdd == 0);
assert(availableToSub == 0);

setCriticalBucket(mostRecentlyUsedBucket);
setCriticalBucket(criticalBucketTemp);
}

function withdrawInternal(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,22 @@ contract EthWrapperForBucketLender

// ============ Functions ============

/**
* Do not allow the fallback function to be used
*/
function ()
external
{
revert();
}

/**
* [depositEth description]
*
* @param bucketLender The address of the BucketLender contract to deposit money into
* @param beneficiary The address that will retain rights to the deposit
* @return The bucket number that was deposited into
*/
function depositEth(
address bucketLender,
address beneficiary
Expand All @@ -59,6 +75,11 @@ contract EthWrapperForBucketLender
{
uint256 amount = msg.value;

require(
amount != 0,
"EthWrapperForBucketLender#depositEth: Cannot deposit zero amount"
);

// wrap the eth
WETH9(WETH).deposit.value(amount)();
assert(TokenInteract.balanceOf(WETH, address(this)) >= amount);
Expand All @@ -67,8 +88,6 @@ contract EthWrapperForBucketLender
TokenInteract.approve(WETH, bucketLender, uint256(-1));

// deposit the tokens
uint256 bucket = BucketLender(bucketLender).deposit(beneficiary, amount);

return bucket;
return BucketLender(bucketLender).deposit(beneficiary, amount);
}
}
2 changes: 2 additions & 0 deletions test/margin/TestIncreasePosition.js
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,8 @@ async function setup(accounts, { loanOwner, positionOwner, depositInHeldToken }
createOpenTx(accounts, { salt: ++salt, depositInHeldToken })
]);

increasePosTx.heldToken = increasePosTx.owedToken;

if (loanOwner) {
openTx.loanOffering.owner = loanOwner;
openTx.loanOffering.signature = await signLoanOffering(openTx.loanOffering);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,11 @@ contract('BucketLender', accounts => {
{ from: trader }
);
console.log(" done.");

await bucketLender.rebalanceBuckets();

console.log(" depositing from useless lender...");
await expectThrow(doDeposit(uselessLender, 0));
await doDeposit(uselessLender, OT.times(3));
console.log(" done.");

Expand Down Expand Up @@ -313,14 +316,27 @@ contract('BucketLender', accounts => {

await runAliceBot();

// margin-call
await expectThrow(margin.marginCall(POSITION_ID, 0, { from: lender1 }));
await expectThrow(margin.marginCall(POSITION_ID, 1));
await margin.marginCall(POSITION_ID, 0);

// can't deposit while margin-called
await expectThrow(doDeposit(uselessLender, OT));

await wait(60 * 60 * 24 * 1);

// cancel margin-call
await expectThrow(margin.cancelMarginCall(POSITION_ID, { from: lender1 }));
await margin.cancelMarginCall(POSITION_ID);

// can deposit again
await doDeposit(uselessLender, OT);

await wait(60 * 60 * 24 * 1);

// margin-call again
await expectThrow(margin.marginCall(POSITION_ID, 0, { from: lender2 }));
await margin.marginCall(POSITION_ID, 0);

console.log(" closing position...");
Expand All @@ -334,8 +350,23 @@ contract('BucketLender', accounts => {

await wait(60 * 60 * 24 * 1);

// Force-recover collateral
console.log(" force-recovering collateral...");
await expectThrow(margin.forceRecoverCollateral(POSITION_ID, accounts[0]));
await margin.forceRecoverCollateral(POSITION_ID, bucketLender.address);
console.log(" done.");

// can't deposit after position closed
await expectThrow(doDeposit(uselessLender, OT));

// do bad withdrawals
await expectThrow(bucketLender.withdraw([0], [0], ADDRESSES.ZERO, { from: alice }));
await expectThrow(bucketLender.withdraw([0], [0, 0], alice, { from: alice }));
await expectThrow(bucketLender.withdraw([0, 0], [0], alice, { from: alice }));
await bucketLender.withdraw([0], [0], alice, { from: alice });

// do all remaining withdrawals
console.log(" doing all remaining withdrawals...");
for(let a = 0; a < 10; a++) {
let act = accounts[a];
for(let b = 0; b < 20; b++) {
Expand All @@ -350,6 +381,56 @@ contract('BucketLender', accounts => {
}
}
}
console.log(" done.");

// check constants
console.log(" checking constants...");
const [
c_criticalBucket,
c_cachedRepaidAmount,

c_available,
c_available2,
c_available3,
c_principal,
c_principal2,
c_weight,
c_weight2,

isClosed,

bucketLenderOwedToken,
bucketLenderHeldToken,
] = await Promise.all([
bucketLender.criticalBucket.call(),
bucketLender.cachedRepaidAmount.call(),

bucketLender.availableTotal.call(),
bucketLender.availableForBucket.call(0),
bucketLender.availableForBucket.call(1),
bucketLender.principalTotal.call(),
bucketLender.principalForBucket.call(0),
bucketLender.weightForBucket.call(0),
bucketLender.weightForBucketForAccount.call(0, accounts[0]),

margin.isPositionClosed.call(POSITION_ID),

owedToken.balanceOf.call(bucketLender.address),
heldToken.balanceOf.call(bucketLender.address),
]);
expect(c_criticalBucket).to.be.bignumber.eq(0);
//expect(c_cachedRepaidAmount).to.be.bignumber.eq(0);
expect(c_available).to.be.bignumber.eq(0);
expect(c_available2).to.be.bignumber.eq(0);
expect(c_available3).to.be.bignumber.eq(0);
expect(c_principal).to.be.bignumber.eq(0);
expect(c_principal2).to.be.bignumber.eq(0);
expect(c_weight).to.be.bignumber.eq(0);
expect(c_weight2).to.be.bignumber.eq(0);
expect(isClosed).to.be.true;
expect(bucketLenderOwedToken).to.be.bignumber.eq(0);
expect(bucketLenderHeldToken).to.be.bignumber.eq(0);
console.log(" done.");

});
});
Expand Down
Loading

0 comments on commit 72ec649

Please sign in to comment.