Skip to content
This repository has been archived by the owner on Mar 28, 2023. It is now read-only.

Dynamic base liquidation percentage #539

Merged
merged 8 commits into from
Mar 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions implementation/contracts/deposit/DepositFunding.sol
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ library DepositFunding {
_d.signerFeeDivisor = _system.getSignerFeeDivisor();
_d.undercollateralizedThresholdPercent = _system.getUndercollateralizedThresholdPercent();
_d.severelyUndercollateralizedThresholdPercent = _system.getSeverelyUndercollateralizedThresholdPercent();
_d.initialCollateralizedPercent = _system.getInitialCollateralizedPercent();
_d.signingGroupRequestedAt = block.timestamp;

_d.setAwaitingSignerSetup();
Expand Down
12 changes: 11 additions & 1 deletion implementation/contracts/deposit/DepositUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ library DepositUtils {
uint256 lotSizeSatoshis;
uint8 currentState;
uint256 signerFeeDivisor;
uint128 initialCollateralizedPercent;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and the two below seem like they can be smaller than uint128, perhaps? Could even be a uint8? Maybe a uint16 if we want to allow ourselves maximum flexibility, but our percentages are expressed as percentages, so uint8 gives us up to 250% as a representation 🤔

Not sure if the Solidity compiler is good enough to pack things together and save us gas in that case though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uint16 for some peace of mind. Also, the enforced initialCollateralizedPercent max is 300, which is over the 255 uint8 limit.
Solidity will automatically pack where possible, given the variables fit into a single 32-byte increment. two uint128s should be packed

uint128 undercollateralizedThresholdPercent;
uint128 severelyUndercollateralizedThresholdPercent;

Expand Down Expand Up @@ -230,7 +231,7 @@ library DepositUtils {
}

// This should make a smooth flow from base% to 100%
uint256 _basePercentage = TBTCConstants.getAuctionBasePercentage();
uint256 _basePercentage = getAuctionBasePercentage(_d);
uint256 _elapsedPercentage = uint256(100).sub(_basePercentage).mul(_elapsed).div(TBTCConstants.getAuctionDuration());
uint256 _percentage = _basePercentage.add(_elapsedPercentage);

Expand Down Expand Up @@ -367,6 +368,15 @@ library DepositUtils {
_d.lastRequestedDigest = bytes32(0);
}


/// @notice Get the starting percentage of the bond at auction.
/// @dev This will return the same value regardless of collateral price.
/// @return The percentage of the InitialCollateralizationPercent that will result
/// in a 100% bond value base auction given perfect collateralization.
function getAuctionBasePercentage(Deposit storage _d) internal view returns (uint256) {
return uint256(10000).div(_d.initialCollateralizedPercent);
}

/// @notice Seize the signer bond from the keep contract.
/// @dev we check our balance before and after.
/// @return The amount seized in wei.
Expand Down
2 changes: 0 additions & 2 deletions implementation/contracts/deposit/TBTCConstants.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ library TBTCConstants {
// Liquidation Flow
uint256 public constant COURTESY_CALL_DURATION = 6 * 60 * 60; // seconds
uint256 public constant AUCTION_DURATION = 24 * 60 * 60; // seconds
uint256 public constant AUCTION_BASE_PERCENTAGE = 90; // percents
uint256 public constant PERMITTED_FEE_BUMPS = 5; // number of times the fee can be increased

// Getters for easy access
Expand All @@ -47,6 +46,5 @@ library TBTCConstants {

function getCourtesyCallTimeout() public pure returns (uint256) { return COURTESY_CALL_DURATION; }
function getAuctionDuration() public pure returns (uint256) { return AUCTION_DURATION; }
function getAuctionBasePercentage() public pure returns (uint256) { return AUCTION_BASE_PERCENTAGE; }
function getPermittedFeeBumps() public pure returns (uint256) {return PERMITTED_FEE_BUMPS; }
}
2 changes: 2 additions & 0 deletions implementation/contracts/interfaces/ITBTCSystem.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ interface ITBTCSystem {
// passthrough requests for the oracle
function fetchRelayCurrentDifficulty() external view returns (uint256);
function fetchRelayPreviousDifficulty() external view returns (uint256);

function getInitialCollateralizedPercent() external view returns (uint128);
}
8 changes: 8 additions & 0 deletions implementation/contracts/test/deposit/TestDeposit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ contract TestDeposit is Deposit {
self.undercollateralizedThresholdPercent = _undercollateralizedThresholdPercent;
}

function setInitialCollateralizedPercent(uint128 _initialCollateralizedPercent) public {
self.initialCollateralizedPercent = _initialCollateralizedPercent;
}

function getUndercollateralizedThresholdPercent() public view returns (uint128) { return self.undercollateralizedThresholdPercent; }

function setSeverelyUndercollateralizedThresholdPercent(uint128 _severelyUndercollateralizedThresholdPercent) public {
Expand Down Expand Up @@ -238,4 +242,8 @@ contract TestDeposit is Deposit {
function pushFundsToKeepGroup(uint256 _ethValue) public returns (bool) {
return self.pushFundsToKeepGroup(_ethValue);
}

function getAuctionBasePercentage() public view returns (uint256) {
return self.getAuctionBasePercentage();
}
}
2 changes: 0 additions & 2 deletions implementation/contracts/test/deposit/TestTBTCConstants.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ library TestTBTCConstants {
// Liquidation Flow
uint256 public constant COURTESY_CALL_DURATION = 6 * 60 * 60; // seconds
uint256 public constant AUCTION_DURATION = 24 * 60 * 60; // seconds
uint256 public constant AUCTION_BASE_PERCENTAGE = 90; // percents
uint256 public constant PERMITTED_FEE_BUMPS = 5; // number of times the fee can be increased

function getBeneficiaryRewardDivisor() public pure returns (uint256) { return BENEFICIARY_FEE_DIVISOR; }
Expand All @@ -46,6 +45,5 @@ library TestTBTCConstants {

function getCourtesyCallTimeout() public pure returns (uint256) { return COURTESY_CALL_DURATION; }
function getAuctionDuration() public pure returns (uint256) { return AUCTION_DURATION; }
function getAuctionBasePercentage() public pure returns (uint256) { return AUCTION_BASE_PERCENTAGE; }
function getPermittedFeeBumps() public pure returns (uint256) {return PERMITTED_FEE_BUMPS; }
}
5 changes: 3 additions & 2 deletions implementation/test/DepositLiquidationTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ describe("DepositLiquidation", async function() {

before(async () => {
lotSize = await testDeposit.lotSizeTbtc.call()
await testDeposit.setInitialCollateralizedPercent(new BN(150))
buyer = accounts[1]
})

Expand Down Expand Up @@ -186,7 +187,7 @@ describe("DepositLiquidation", async function() {
const block = await web3.eth.getBlock("latest")
const notifiedTime = block.timestamp
const value = 1000000000000
const basePercentage = await tbtcConstants.getAuctionBasePercentage.call()
const basePercentage = await testDeposit.getAuctionBasePercentage.call()

await ecdsaKeepStub.pushFundsFromKeep(testDeposit.address, {value: value})

Expand Down Expand Up @@ -228,7 +229,7 @@ describe("DepositLiquidation", async function() {
const notifiedTime = block.timestamp
const liquidationInitiator = accounts[2]
const value = 1000000000000
const basePercentage = await tbtcConstants.getAuctionBasePercentage.call()
const basePercentage = await testDeposit.getAuctionBasePercentage.call()

await ecdsaKeepStub.pushFundsFromKeep(testDeposit.address, {value: value})

Expand Down
14 changes: 13 additions & 1 deletion implementation/test/DepositUtilsTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -386,12 +386,24 @@ describe("DepositUtils", async function() {
})
})

describe("getAuctionBasePercentage()", async () => {
it("returns correct base percentage", async () => {
const basePercentage = await testDeposit.getAuctionBasePercentage.call()

const initialCollateralization = await tbtcSystemStub.getInitialCollateralizedPercent()

// 10000 to avoid losing value to truncating in solidity.
const expected = new BN(10000).div(initialCollateralization)
expect(basePercentage).to.eq.BN(expected) // 66 for 150
})
})

describe("auctionValue()", async () => {
let duration
let basePercentage
before(async () => {
duration = await tbtcConstants.getAuctionDuration.call()
basePercentage = await tbtcConstants.getAuctionBasePercentage.call()
basePercentage = await testDeposit.getAuctionBasePercentage.call()
auctionValue = new BN(100000000)
})
beforeEach(async () => {
Expand Down