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

Commit

Permalink
Merge pull request #542 from keep-network/contract-types
Browse files Browse the repository at this point in the history
Use specific contract types

Rather than storing addresses and then casting to the known contract
type, it’s better to use the best type available so the compiler can check
for type safety.
  • Loading branch information
Shadowfiend authored Mar 26, 2020
2 parents 08e1426 + 6756361 commit c397657
Show file tree
Hide file tree
Showing 12 changed files with 157 additions and 158 deletions.
6 changes: 3 additions & 3 deletions solidity/contracts/DepositLog.sol
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,13 @@ contract DepositLog {
/// @notice Sets the tbtcDepositToken contract.
/// @dev The contract is used by `approvedToLog` to check if the
/// caller is a Deposit contract. This should only be called once.
/// @param _tbtcDepositTokenAddress The address of the tbtcDepositToken.
function setTbtcDepositToken(address _tbtcDepositTokenAddress) public {
/// @param _tbtcDepositToken tbtcDepositToken contract.
function setTbtcDepositToken(TBTCDepositToken _tbtcDepositToken) public {
require(
address(tbtcDepositToken) == address(0),
"tbtcDepositToken is already set"
);
tbtcDepositToken = TBTCDepositToken(_tbtcDepositTokenAddress);
tbtcDepositToken = _tbtcDepositToken;
}

//
Expand Down
35 changes: 20 additions & 15 deletions solidity/contracts/deposit/Deposit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ import {DepositUtils} from "./DepositUtils.sol";
import {DepositFunding} from "./DepositFunding.sol";
import {DepositRedemption} from "./DepositRedemption.sol";
import {DepositStates} from "./DepositStates.sol";
import {ITBTCSystem} from "../interfaces/ITBTCSystem.sol";
import {IERC721} from "openzeppelin-solidity/contracts/token/ERC721/IERC721.sol";
import {TBTCToken} from "../system/TBTCToken.sol";
import {FeeRebateToken} from "../system/FeeRebateToken.sol";

import "../system/DepositFactoryAuthority.sol";

/// @title Deposit.
Expand Down Expand Up @@ -92,32 +97,32 @@ contract Deposit is DepositFactoryAuthority {
// THIS IS THE INIT FUNCTION
/// @notice The Deposit Factory can spin up a new deposit.
/// @dev Only the Deposit factory can call this.
/// @param _TBTCSystem `TBTCSystem` address. More info in `VendingMachine`.
/// @param _TBTCToken `TBTCToken` address. More info in TBTCToken`.
/// @param _TBTCDepositToken `TBTCDepositToken` (TDT) address. More info in `TBTCDepositToken`.
/// @param _FeeRebateToken `FeeRebateToken` (FRT) address. More info in `FeeRebateToken`.
/// @param _VendingMachine `VendingMachine` address. More info in `VendingMachine`.
/// @param _tbtcSystem `TBTCSystem` contract. More info in `VendingMachine`.
/// @param _tbtcToken `TBTCToken` contract. More info in TBTCToken`.
/// @param _tbtcDepositToken `TBTCDepositToken` (TDT) contract. More info in `TBTCDepositToken`.
/// @param _feeRebateToken `FeeRebateToken` (FRT) contract. More info in `FeeRebateToken`.
/// @param _vendingMachineAddress `VendingMachine` address. More info in `VendingMachine`.
/// @param _m Signing group honesty threshold.
/// @param _n Signing group size.
/// @param _lotSizeSatoshis The minimum amount of satoshi the funder is required to send.
/// This is also the amount of TBTC the TDT holder will receive:
/// (10**7 satoshi == 0.1 BTC == 0.1 TBTC).
/// @return True if successful, otherwise revert.
function createNewDeposit(
address _TBTCSystem,
address _TBTCToken,
address _TBTCDepositToken,
address _FeeRebateToken,
address _VendingMachine,
ITBTCSystem _tbtcSystem,
TBTCToken _tbtcToken,
IERC721 _tbtcDepositToken,
FeeRebateToken _feeRebateToken,
address _vendingMachineAddress,
uint256 _m,
uint256 _n,
uint256 _lotSizeSatoshis
) public onlyFactory payable returns (bool) {
self.TBTCSystem = _TBTCSystem;
self.TBTCToken = _TBTCToken;
self.TBTCDepositToken = _TBTCDepositToken;
self.FeeRebateToken = _FeeRebateToken;
self.VendingMachine = _VendingMachine;
self.tbtcSystem = _tbtcSystem;
self.tbtcToken = _tbtcToken;
self.tbtcDepositToken = _tbtcDepositToken;
self.feeRebateToken = _feeRebateToken;
self.vendingMachineAddress = _vendingMachineAddress;
self.createNewDeposit(_m, _n, _lotSizeSatoshis);
return true;
}
Expand Down
19 changes: 8 additions & 11 deletions solidity/contracts/deposit/DepositFunding.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {BytesLib} from "@summa-tx/bitcoin-spv-sol/contracts/BytesLib.sol";
import {BTCUtils} from "@summa-tx/bitcoin-spv-sol/contracts/BTCUtils.sol";
import {IBondedECDSAKeep} from "@keep-network/keep-ecdsa/contracts/api/IBondedECDSAKeep.sol";
import {TBTCToken} from "../system/TBTCToken.sol";
import {TBTCSystem} from "../system/TBTCSystem.sol";
import {DepositUtils} from "./DepositUtils.sol";
import {DepositLiquidation} from "./DepositLiquidation.sol";
import {DepositStates} from "./DepositStates.sol";
Expand Down Expand Up @@ -55,22 +54,20 @@ library DepositFunding {
uint256 _n,
uint256 _lotSizeSatoshis
) public returns (bool) {
TBTCSystem _system = TBTCSystem(_d.TBTCSystem);

require(_system.getAllowNewDeposits(), "Opening new deposits is currently disabled.");
require(_d.tbtcSystem.getAllowNewDeposits(), "Opening new deposits is currently disabled.");
require(_d.inStart(), "Deposit setup already requested");
require(_system.isAllowedLotSize(_lotSizeSatoshis), "provided lot size not supported");
require(_d.tbtcSystem.isAllowedLotSize(_lotSizeSatoshis), "provided lot size not supported");

_d.lotSizeSatoshis = _lotSizeSatoshis;
uint256 _bondRequirementSatoshi = _lotSizeSatoshis.mul(_system.getInitialCollateralizedPercent()).div(100);
uint256 _bondRequirementSatoshi = _lotSizeSatoshis.mul(_d.tbtcSystem.getInitialCollateralizedPercent()).div(100);
uint256 _bondRequirementWei = _d.fetchBitcoinPrice().mul(_bondRequirementSatoshi);

/* solium-disable-next-line value-in-payable */
_d.keepAddress = _system.requestNewKeep.value(msg.value)(_m, _n, _bondRequirementWei);
_d.signerFeeDivisor = _system.getSignerFeeDivisor();
_d.undercollateralizedThresholdPercent = _system.getUndercollateralizedThresholdPercent();
_d.severelyUndercollateralizedThresholdPercent = _system.getSeverelyUndercollateralizedThresholdPercent();
_d.initialCollateralizedPercent = _system.getInitialCollateralizedPercent();
_d.keepAddress = _d.tbtcSystem.requestNewKeep.value(msg.value)(_m, _n, _bondRequirementWei);
_d.signerFeeDivisor = _d.tbtcSystem.getSignerFeeDivisor();
_d.undercollateralizedThresholdPercent = _d.tbtcSystem.getUndercollateralizedThresholdPercent();
_d.severelyUndercollateralizedThresholdPercent = _d.tbtcSystem.getSeverelyUndercollateralizedThresholdPercent();
_d.initialCollateralizedPercent = _d.tbtcSystem.getInitialCollateralizedPercent();
_d.signingGroupRequestedAt = block.timestamp;

_d.setAwaitingSignerSetup();
Expand Down
10 changes: 4 additions & 6 deletions solidity/contracts/deposit/DepositLiquidation.sol
Original file line number Diff line number Diff line change
Expand Up @@ -167,16 +167,14 @@ library DepositLiquidation {
// send the TBTC to the TDT holder. If the TDT holder is the Vending Machine, burn it to maintain the peg.
address tdtHolder = _d.depositOwner();

TBTCToken _tbtcToken = TBTCToken(_d.TBTCToken);

uint256 lotSizeTbtc = _d.lotSizeTbtc();
require(_tbtcToken.balanceOf(msg.sender) >= lotSizeTbtc, "Not enough TBTC to cover outstanding debt");
require(_d.tbtcToken.balanceOf(msg.sender) >= lotSizeTbtc, "Not enough TBTC to cover outstanding debt");

if(tdtHolder == _d.VendingMachine){
_tbtcToken.burnFrom(msg.sender, lotSizeTbtc); // burn minimal amount to cover size
if(tdtHolder == _d.vendingMachineAddress){
_d.tbtcToken.burnFrom(msg.sender, lotSizeTbtc); // burn minimal amount to cover size
}
else{
_tbtcToken.transferFrom(msg.sender, tdtHolder, lotSizeTbtc);
_d.tbtcToken.transferFrom(msg.sender, tdtHolder, lotSizeTbtc);
}

// Distribute funds to auction buyer
Expand Down
28 changes: 11 additions & 17 deletions solidity/contracts/deposit/DepositRedemption.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,10 @@ library DepositRedemption {
/// @notice Pushes signer fee to the Keep group by transferring it to the Keep address.
/// @dev Approves the keep contract, then expects it to call transferFrom.
function distributeSignerFee(DepositUtils.Deposit storage _d) internal {
address _tbtcTokenAddress = _d.TBTCToken;
TBTCToken _tbtcToken = TBTCToken(_tbtcTokenAddress);

IBondedECDSAKeep _keep = IBondedECDSAKeep(_d.keepAddress);

_tbtcToken.approve(_d.keepAddress, _d.signerFee());
_keep.distributeERC20Reward(_tbtcTokenAddress, _d.signerFee());
_d.tbtcToken.approve(_d.keepAddress, _d.signerFee());
_keep.distributeERC20Reward(address(_d.tbtcToken), _d.signerFee());
}

/// @notice Closes keep associated with the deposit.
Expand All @@ -61,9 +58,8 @@ library DepositRedemption {
/// @notice Handles TBTC requirements for redemption.
/// @dev Burns or transfers depending on term and supply-peg impact.
function performRedemptionTBTCTransfers(DepositUtils.Deposit storage _d) internal {
TBTCToken _tbtc = TBTCToken(_d.TBTCToken);
address tdtHolder = _d.depositOwner();
address vendingMachine = _d.VendingMachine;
address vendingMachineAddress = _d.vendingMachineAddress;

uint256 tbtcLot = _d.lotSizeTbtc();
uint256 signerFee = _d.signerFee();
Expand All @@ -75,7 +71,7 @@ library DepositRedemption {
}
// if we owe > 0 & < signerfee, msg.sender is TDT owner but not FRT holder.
if(tbtcOwed <= signerFee){
_tbtc.transferFrom(msg.sender, address(this), tbtcOwed);
_d.tbtcToken.transferFrom(msg.sender, address(this), tbtcOwed);
return;
}
// Redemmer always owes a full TBTC for at-term redemption.
Expand All @@ -85,17 +81,17 @@ library DepositRedemption {
// As compensation, the TDT owner is reimbursed in TBTC
// Vending Machine-owned TDTs have been used to mint TBTC,
// and we should always burn a full TBTC to redeem the deposit.
if(tdtHolder == vendingMachine){
_tbtc.burnFrom(msg.sender, tbtcLot);
if(tdtHolder == vendingMachineAddress){
_d.tbtcToken.burnFrom(msg.sender, tbtcLot);
}
// if signer fee is not escrowed, escrow and it here and send the rest to TDT owner
else if(_tbtc.balanceOf(address(this)) < signerFee){
_tbtc.transferFrom(msg.sender, address(this), signerFee);
_tbtc.transferFrom(msg.sender, tdtHolder, tbtcLot.sub(signerFee));
else if(_d.tbtcToken.balanceOf(address(this)) < signerFee){
_d.tbtcToken.transferFrom(msg.sender, address(this), signerFee);
_d.tbtcToken.transferFrom(msg.sender, tdtHolder, tbtcLot.sub(signerFee));
}
// tansfer a full TBTC to TDT owner if signerFee is escrowed
else{
_tbtc.transferFrom(msg.sender, tdtHolder, tbtcLot);
_d.tbtcToken.transferFrom(msg.sender, tdtHolder, tbtcLot);
}
return;
}
Expand Down Expand Up @@ -162,9 +158,7 @@ library DepositRedemption {
bytes memory _redeemerOutputScript,
address payable _finalRecipient
) public {
IERC721 _tbtcDepositToken = IERC721(_d.TBTCDepositToken);

_tbtcDepositToken.transferFrom(msg.sender, _finalRecipient, uint256(address(this)));
_d.tbtcDepositToken.transferFrom(msg.sender, _finalRecipient, uint256(address(this)));

_requestRedemption(_d, _outputValueBytes, _redeemerOutputScript, _finalRecipient);
}
Expand Down
35 changes: 14 additions & 21 deletions solidity/contracts/deposit/DepositUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ library DepositUtils {
struct Deposit {

// SET DURING CONSTRUCTION
address TBTCSystem;
address TBTCToken;
address TBTCDepositToken;
address FeeRebateToken;
address VendingMachine;
ITBTCSystem tbtcSystem;
TBTCToken tbtcToken;
IERC721 tbtcDepositToken;
FeeRebateToken feeRebateToken;
address vendingMachineAddress;
uint256 lotSizeSatoshis;
uint8 currentState;
uint256 signerFeeDivisor;
Expand Down Expand Up @@ -74,16 +74,14 @@ library DepositUtils {
/// @dev Calls the light relay and gets the current block difficulty.
/// @return The difficulty.
function currentBlockDifficulty(Deposit storage _d) public view returns (uint256) {
ITBTCSystem _sys = ITBTCSystem(_d.TBTCSystem);
return _sys.fetchRelayCurrentDifficulty();
return _d.tbtcSystem.fetchRelayCurrentDifficulty();
}

/// @notice Gets the previous block difficulty.
/// @dev Calls the light relay and gets the previous block difficulty.
/// @return The difficulty.
function previousBlockDifficulty(Deposit storage _d) public view returns (uint256) {
ITBTCSystem _sys = ITBTCSystem(_d.TBTCSystem);
return _sys.fetchRelayPreviousDifficulty();
return _d.tbtcSystem.fetchRelayPreviousDifficulty();
}

/// @notice Evaluates the header difficulties in a proof.
Expand Down Expand Up @@ -310,8 +308,7 @@ library DepositUtils {
/// @dev Polls the price feed via the system contract.
/// @return The current price of 1 sat in wei.
function fetchBitcoinPrice(Deposit storage _d) public view returns (uint256) {
ITBTCSystem _sys = ITBTCSystem(_d.TBTCSystem);
return _sys.fetchBitcoinPrice();
return _d.tbtcSystem.fetchBitcoinPrice();
}

/// @notice Fetches the Keep's bond amount in wei.
Expand Down Expand Up @@ -342,10 +339,9 @@ library DepositUtils {
/// @return The current token holder if the Token exists.
/// address(0) if the token does not exist.
function feeRebateTokenHolder(Deposit storage _d) public view returns (address payable) {
FeeRebateToken _feeRebateToken = FeeRebateToken(_d.FeeRebateToken);
address tokenHolder;
if(_feeRebateToken.exists(uint256(address(this)))){
tokenHolder = address(uint160(_feeRebateToken.ownerOf(uint256(address(this)))));
if(_d.feeRebateToken.exists(uint256(address(this)))){
tokenHolder = address(uint160(_d.feeRebateToken.ownerOf(uint256(address(this)))));
}
return address(uint160(tokenHolder));
}
Expand All @@ -354,8 +350,7 @@ library DepositUtils {
/// @dev We cast the address to a uint256 to match the 721 standard.
/// @return The current deposit beneficiary.
function depositOwner(Deposit storage _d) public view returns (address payable) {
IERC721 _tbtcDepositToken = IERC721(_d.TBTCDepositToken);
return address(uint160(_tbtcDepositToken.ownerOf(uint256(address(this)))));
return address(uint160(_d.tbtcDepositToken.ownerOf(uint256(address(this)))));
}

/// @notice Deletes state after termination of redemption process.
Expand Down Expand Up @@ -394,16 +389,14 @@ library DepositUtils {
/// @notice Distributes the fee rebate to the Fee Rebate Token owner.
/// @dev Whenever this is called we are shutting down.
function distributeFeeRebate(Deposit storage _d) internal {
TBTCToken _tbtc = TBTCToken(_d.TBTCToken);

address rebateTokenHolder = feeRebateTokenHolder(_d);

// We didn't escrow a rebate if the redeemer is also the Fee Rebate Token holder
if(_d.redeemerAddress == rebateTokenHolder) return;

// pay out the rebate if it is available
if(_tbtc.balanceOf(address(this)) >= signerFee(_d)) {
_tbtc.transfer(rebateTokenHolder, signerFee(_d));
if(_d.tbtcToken.balanceOf(address(this)) >= signerFee(_d)) {
_d.tbtcToken.transfer(rebateTokenHolder, signerFee(_d));
}
}

Expand All @@ -430,7 +423,7 @@ library DepositUtils {
return fee;
}
}
uint256 contractTbtcBalance = TBTCToken(_d.TBTCToken).balanceOf(address(this));
uint256 contractTbtcBalance = _d.tbtcToken.balanceOf(address(this));
if(contractTbtcBalance < fee) {
return fee.sub(contractTbtcBalance);
}
Expand Down
Loading

0 comments on commit c397657

Please sign in to comment.