diff --git a/contracts/ChainlinkOracleView.sol b/contracts/ChainlinkOracleView.sol new file mode 100644 index 000000000..1099c0a40 --- /dev/null +++ b/contracts/ChainlinkOracleView.sol @@ -0,0 +1,257 @@ +pragma solidity ^0.5.16; + +import "./SafeMath.sol"; + +// Source: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/GSN/Context.sol +/* + * @dev Provides information about the current execution context, including the + * sender of the transaction and its data. While these are generally available + * via msg.sender and msg.data, they should not be accessed in such a direct + * manner, since when dealing with GSN meta-transactions the account sending and + * paying for execution may not be the actual sender (as far as an application + * is concerned). + * + * This contract is only required for intermediate, library-like contracts. + */ +contract Context { + function _msgSender() internal view returns (address payable) { + return msg.sender; + } + + function _msgData() internal view returns (bytes memory) { + this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 + return msg.data; + } +} + +// Source: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol +/** + * @dev Contract module which provides a basic access control mechanism, where + * there is an account (an owner) that can be granted exclusive access to + * specific functions. + * + * By default, the owner account will be the one that deploys the contract. This + * can later be changed with {transferOwnership}. + * + * This module is used through inheritance. It will make available the modifier + * `onlyOwner`, which can be applied to your functions to restrict their use to + * the owner. + */ +contract Ownable is Context { + address private _owner; + + event OwnershipTransferred( + address indexed previousOwner, + address indexed newOwner + ); + + /** + * @dev Initializes the contract setting the deployer as the initial owner. + */ + constructor() internal { + address msgSender = _msgSender(); + _owner = msgSender; + emit OwnershipTransferred(address(0), msgSender); + } + + /** + * @dev Returns the address of the current owner. + */ + function owner() public view returns (address) { + return _owner; + } + + /** + * @dev Throws if called by any account other than the owner. + */ + modifier onlyOwner() { + require(_owner == _msgSender(), "Ownable: caller is not the owner"); + _; + } + + /** + * @dev Leaves the contract without owner. It will not be possible to call + * `onlyOwner` functions anymore. Can only be called by the current owner. + * + * NOTE: Renouncing ownership will leave the contract without an owner, + * thereby removing any functionality that is only available to the owner. + */ + function renounceOwnership() public onlyOwner { + emit OwnershipTransferred(_owner, address(0)); + _owner = address(0); + } + + /** + * @dev Transfers ownership of the contract to a new account (`newOwner`). + * Can only be called by the current owner. + */ + function transferOwnership(address newOwner) public onlyOwner { + require( + newOwner != address(0), + "Ownable: new owner is the zero address" + ); + emit OwnershipTransferred(_owner, newOwner); + _owner = newOwner; + } +} + +// Source: https://github.com/smartcontractkit/chainlink/blob/develop/evm-contracts/src/v0.6/interfaces/AggregatorV3Interface.sol +interface AggregatorV3Interface { + function decimals() external view returns (uint8); + + function description() external view returns (string memory); + + function version() external view returns (uint256); + + // getRoundData and latestRoundData should both raise "No data present" + // if they do not have data to report, instead of returning unset values + // which could be misinterpreted as actual reported values. + function getRoundData(uint80 _roundId) + external + view + returns ( + uint80 roundId, + int256 answer, + uint256 startedAt, + uint256 updatedAt, + uint80 answeredInRound + ); + + function latestRoundData() + external + view + returns ( + uint80 roundId, + int256 answer, + uint256 startedAt, + uint256 updatedAt, + uint80 answeredInRound + ); +} + +contract PriceOracle { + /// @notice Indicator that this is a PriceOracle contract (for inspection) + bool public constant isPriceOracle = true; + + /** + * @notice Get the underlying price of a slToken asset + * @param slToken The slToken to get the underlying price of + * @return The underlying asset price mantissa (scaled by 1e18). + * Zero means the price is unavailable. + */ + function getUnderlyingPrice(address slToken) + external + view + returns (uint256); +} + +contract ChainlinkOracleView is Ownable, PriceOracle { + using SafeMath for uint256; + + /// @notice Indicator that this is a PriceOracle contract (for inspection) + bool public constant isPriceOracle = true; + + address public ethUsdChainlinkAggregatorAddress; + + struct TokenConfig { + address chainlinkAggregatorAddress; + uint256 chainlinkPriceBase; // 0: Invalid, 1: USD, 2: ETH + uint256 underlyingTokenDecimals; + } + + mapping(address => TokenConfig) public tokenConfig; + + constructor(address ethUsdChainlinkAggregatorAddress_) public { + ethUsdChainlinkAggregatorAddress = ethUsdChainlinkAggregatorAddress_; + } + + /** + * @notice Get the underlying price of a slToken + * @dev Implements the PriceOracle interface for Compound v2. + * @param slToken The slToken address for price retrieval + * @return Price denominated in USD, with 18 decimals, for the given slToken address. Comptroller needs prices in the format: ${raw price} * 1e(36 - baseUnit) + */ + function getUnderlyingPrice(address slToken) + public + view + returns (uint256) + { + TokenConfig memory config = tokenConfig[address(slToken)]; + + (, int256 chainlinkPrice, , , ) = AggregatorV3Interface( + config + .chainlinkAggregatorAddress + ) + .latestRoundData(); + + require(chainlinkPrice > 0, "Chainlink price feed invalid"); + + uint256 underlyingPrice; + + if (config.chainlinkPriceBase == 1) { + underlyingPrice = uint256(chainlinkPrice).mul(1e28).div( + 10**config.underlyingTokenDecimals + ); + } else if (config.chainlinkPriceBase == 2) { + (, int256 ethPriceInUsd, , , ) = AggregatorV3Interface( + ethUsdChainlinkAggregatorAddress + ) + .latestRoundData(); + + require(ethPriceInUsd > 0, "ETH price invalid"); + + underlyingPrice = uint256(chainlinkPrice) + .mul(uint256(ethPriceInUsd)) + .mul(1e10) + .div(10**config.underlyingTokenDecimals); + } else { + revert("Token config invalid"); + } + + require(underlyingPrice > 0, "Underlying price invalid"); + + return underlyingPrice; + } + + function setEthUsdChainlinkAggregatorAddress(address addr) + external + onlyOwner + { + ethUsdChainlinkAggregatorAddress = addr; + } + + function setTokenConfigs( + address[] calldata slTokenAddress, + address[] calldata chainlinkAggregatorAddress, + uint256[] calldata chainlinkPriceBase, + uint256[] calldata underlyingTokenDecimals + ) external onlyOwner { + require( + slTokenAddress.length == chainlinkAggregatorAddress.length && + slTokenAddress.length == chainlinkPriceBase.length && + slTokenAddress.length == underlyingTokenDecimals.length, + "Arguments must have same length" + ); + + for (uint256 i = 0; i < slTokenAddress.length; i++) { + tokenConfig[slTokenAddress[i]] = TokenConfig({ + chainlinkAggregatorAddress: chainlinkAggregatorAddress[i], + chainlinkPriceBase: chainlinkPriceBase[i], + underlyingTokenDecimals: underlyingTokenDecimals[i] + }); + emit TokenConfigUpdated( + slTokenAddress[i], + chainlinkAggregatorAddress[i], + chainlinkPriceBase[i], + underlyingTokenDecimals[i] + ); + } + } + + event TokenConfigUpdated( + address slTokenAddress, + address chainlinkAggregatorAddress, + uint256 chainlinkPriceBase, + uint256 underlyingTokenDecimals + ); +} \ No newline at end of file diff --git a/contracts/Comptroller.sol b/contracts/Comptroller.sol index e829108b6..9e2f4a816 100644 --- a/contracts/Comptroller.sol +++ b/contracts/Comptroller.sol @@ -1,33 +1,32 @@ pragma solidity ^0.5.16; -import "./CToken.sol"; +import "./SLToken.sol"; import "./ErrorReporter.sol"; import "./Exponential.sol"; import "./PriceOracle.sol"; import "./ComptrollerInterface.sol"; import "./ComptrollerStorage.sol"; import "./Unitroller.sol"; -import "./Governance/Comp.sol"; +import "./EIP20Interface.sol"; /** - * @title Compound's Comptroller Contract - * @author Compound + * @title SashimiLending's Comptroller Contract */ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerErrorReporter, Exponential { /// @notice Emitted when an admin supports a market - event MarketListed(CToken cToken); + event MarketListed(SLToken slToken); /// @notice Emitted when an account enters a market - event MarketEntered(CToken cToken, address account); + event MarketEntered(SLToken slToken, address account); /// @notice Emitted when an account exits a market - event MarketExited(CToken cToken, address account); + event MarketExited(SLToken slToken, address account); /// @notice Emitted when close factor is changed by admin event NewCloseFactor(uint oldCloseFactorMantissa, uint newCloseFactorMantissa); /// @notice Emitted when a collateral factor is changed by admin - event NewCollateralFactor(CToken cToken, uint oldCollateralFactorMantissa, uint newCollateralFactorMantissa); + event NewCollateralFactor(SLToken slToken, uint oldCollateralFactorMantissa, uint newCollateralFactorMantissa); /// @notice Emitted when liquidation incentive is changed by admin event NewLiquidationIncentive(uint oldLiquidationIncentiveMantissa, uint newLiquidationIncentiveMantissa); @@ -45,34 +44,34 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE event ActionPaused(string action, bool pauseState); /// @notice Emitted when an action is paused on a market - event ActionPaused(CToken cToken, string action, bool pauseState); + event ActionPaused(SLToken slToken, string action, bool pauseState); - /// @notice Emitted when market comped status is changed - event MarketComped(CToken cToken, bool isComped); + /// @notice Emitted when market sashimied status is changed + event MarketSashimied(SLToken slToken, bool isSashimied); - /// @notice Emitted when COMP rate is changed - event NewCompRate(uint oldCompRate, uint newCompRate); + /// @notice Emitted when SASHIMI rate is changed + event NewSashimiRate(uint oldSashimiRate, uint newSashimiRate); - /// @notice Emitted when a new COMP speed is calculated for a market - event CompSpeedUpdated(CToken indexed cToken, uint newSpeed); + /// @notice Emitted when a new SASHIMI speed is calculated for a market + event SashimiSpeedUpdated(SLToken indexed slToken, uint newSpeed); - /// @notice Emitted when COMP is distributed to a supplier - event DistributedSupplierComp(CToken indexed cToken, address indexed supplier, uint compDelta, uint compSupplyIndex); + /// @notice Emitted when SASHIMI is distributed to a supplier + event DistributedSupplierSashimi(SLToken indexed slToken, address indexed supplier, uint sashimiDelta, uint sashimiSupplyIndex); - /// @notice Emitted when COMP is distributed to a borrower - event DistributedBorrowerComp(CToken indexed cToken, address indexed borrower, uint compDelta, uint compBorrowIndex); + /// @notice Emitted when SASHIMI is distributed to a borrower + event DistributedBorrowerSashimi(SLToken indexed slToken, address indexed borrower, uint sashimiDelta, uint sashimiBorrowIndex); - /// @notice Emitted when borrow cap for a cToken is changed - event NewBorrowCap(CToken indexed cToken, uint newBorrowCap); + /// @notice Emitted when borrow cap for a slToken is changed + event NewBorrowCap(SLToken indexed slToken, uint newBorrowCap); /// @notice Emitted when borrow cap guardian is changed event NewBorrowCapGuardian(address oldBorrowCapGuardian, address newBorrowCapGuardian); - /// @notice The threshold above which the flywheel transfers COMP, in wei - uint public constant compClaimThreshold = 0.001e18; + /// @notice The threshold above which the flywheel transfers SASHIMI, in wei + uint public constant sashimiClaimThreshold = 0.001e18; - /// @notice The initial COMP index for a market - uint224 public constant compInitialIndex = 1e36; + /// @notice The initial SASHIMI index for a market + uint224 public constant sashimiInitialIndex = 1e36; // closeFactorMantissa must be strictly greater than this value uint internal constant closeFactorMinMantissa = 0.05e18; // 0.05 @@ -100,8 +99,8 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE * @param account The address of the account to pull assets for * @return A dynamic list with the assets the account has entered */ - function getAssetsIn(address account) external view returns (CToken[] memory) { - CToken[] memory assetsIn = accountAssets[account]; + function getAssetsIn(address account) external view returns (SLToken[] memory) { + SLToken[] memory assetsIn = accountAssets[account]; return assetsIn; } @@ -109,26 +108,26 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE /** * @notice Returns whether the given account is entered in the given asset * @param account The address of the account to check - * @param cToken The cToken to check + * @param slToken The slToken to check * @return True if the account is in the asset, otherwise false. */ - function checkMembership(address account, CToken cToken) external view returns (bool) { - return markets[address(cToken)].accountMembership[account]; + function checkMembership(address account, SLToken slToken) external view returns (bool) { + return markets[address(slToken)].accountMembership[account]; } /** * @notice Add assets to be included in account liquidity calculation - * @param cTokens The list of addresses of the cToken markets to be enabled + * @param slTokens The list of addresses of the slToken markets to be enabled * @return Success indicator for whether each corresponding market was entered */ - function enterMarkets(address[] memory cTokens) public returns (uint[] memory) { - uint len = cTokens.length; + function enterMarkets(address[] memory slTokens) public returns (uint[] memory) { + uint len = slTokens.length; uint[] memory results = new uint[](len); for (uint i = 0; i < len; i++) { - CToken cToken = CToken(cTokens[i]); + SLToken slToken = SLToken(slTokens[i]); - results[i] = uint(addToMarketInternal(cToken, msg.sender)); + results[i] = uint(addToMarketInternal(slToken, msg.sender)); } return results; @@ -136,12 +135,12 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE /** * @notice Add the market to the borrower's "assets in" for liquidity calculations - * @param cToken The market to enter + * @param slToken The market to enter * @param borrower The address of the account to modify * @return Success indicator for whether the market was entered */ - function addToMarketInternal(CToken cToken, address borrower) internal returns (Error) { - Market storage marketToJoin = markets[address(cToken)]; + function addToMarketInternal(SLToken slToken, address borrower) internal returns (Error) { + Market storage marketToJoin = markets[address(slToken)]; if (!marketToJoin.isListed) { // market is not listed, cannot join @@ -164,9 +163,9 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE // that is, only when we need to perform liquidity checks // and not whenever we want to check if an account is in a particular market marketToJoin.accountMembership[borrower] = true; - accountAssets[borrower].push(cToken); + accountAssets[borrower].push(slToken); - emit MarketEntered(cToken, borrower); + emit MarketEntered(slToken, borrower); return Error.NO_ERROR; } @@ -175,13 +174,13 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE * @notice Removes asset from sender's account liquidity calculation * @dev Sender must not have an outstanding borrow balance in the asset, * or be providing necessary collateral for an outstanding borrow. - * @param cTokenAddress The address of the asset to be removed + * @param slTokenAddress The address of the asset to be removed * @return Whether or not the account successfully exited the market */ - function exitMarket(address cTokenAddress) external returns (uint) { - CToken cToken = CToken(cTokenAddress); - /* Get sender tokensHeld and amountOwed underlying from the cToken */ - (uint oErr, uint tokensHeld, uint amountOwed, ) = cToken.getAccountSnapshot(msg.sender); + function exitMarket(address slTokenAddress) external returns (uint) { + SLToken slToken = SLToken(slTokenAddress); + /* Get sender tokensHeld and amountOwed underlying from the slToken */ + (uint oErr, uint tokensHeld, uint amountOwed, ) = slToken.getAccountSnapshot(msg.sender); require(oErr == 0, "exitMarket: getAccountSnapshot failed"); // semi-opaque error code /* Fail if the sender has a borrow balance */ @@ -190,28 +189,28 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE } /* Fail if the sender is not permitted to redeem all of their tokens */ - uint allowed = redeemAllowedInternal(cTokenAddress, msg.sender, tokensHeld); + uint allowed = redeemAllowedInternal(slTokenAddress, msg.sender, tokensHeld); if (allowed != 0) { return failOpaque(Error.REJECTION, FailureInfo.EXIT_MARKET_REJECTION, allowed); } - Market storage marketToExit = markets[address(cToken)]; + Market storage marketToExit = markets[address(slToken)]; /* Return true if the sender is not already ‘in’ the market */ if (!marketToExit.accountMembership[msg.sender]) { return uint(Error.NO_ERROR); } - /* Set cToken account membership to false */ + /* Set slToken account membership to false */ delete marketToExit.accountMembership[msg.sender]; - /* Delete cToken from the account’s list of assets */ + /* Delete slToken from the account’s list of assets */ // load into memory for faster iteration - CToken[] memory userAssetList = accountAssets[msg.sender]; + SLToken[] memory userAssetList = accountAssets[msg.sender]; uint len = userAssetList.length; uint assetIndex = len; for (uint i = 0; i < len; i++) { - if (userAssetList[i] == cToken) { + if (userAssetList[i] == slToken) { assetIndex = i; break; } @@ -221,11 +220,11 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE assert(assetIndex < len); // copy last item in list to location of item to be removed, reduce length by 1 - CToken[] storage storedList = accountAssets[msg.sender]; + SLToken[] storage storedList = accountAssets[msg.sender]; storedList[assetIndex] = storedList[storedList.length - 1]; storedList.length--; - emit MarketExited(cToken, msg.sender); + emit MarketExited(slToken, msg.sender); return uint(Error.NO_ERROR); } @@ -234,40 +233,40 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE /** * @notice Checks if the account should be allowed to mint tokens in the given market - * @param cToken The market to verify the mint against + * @param slToken The market to verify the mint against * @param minter The account which would get the minted tokens * @param mintAmount The amount of underlying being supplied to the market in exchange for tokens * @return 0 if the mint is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) */ - function mintAllowed(address cToken, address minter, uint mintAmount) external returns (uint) { + function mintAllowed(address slToken, address minter, uint mintAmount) external returns (uint) { // Pausing is a very serious situation - we revert to sound the alarms - require(!mintGuardianPaused[cToken], "mint is paused"); + require(!mintGuardianPaused[slToken], "mint is paused"); // Shh - currently unused minter; mintAmount; - if (!markets[cToken].isListed) { + if (!markets[slToken].isListed) { return uint(Error.MARKET_NOT_LISTED); } // Keep the flywheel moving - updateCompSupplyIndex(cToken); - distributeSupplierComp(cToken, minter, false); + updateSashimiSupplyIndex(slToken); + distributeSupplierSashimi(slToken, minter, false); return uint(Error.NO_ERROR); } /** * @notice Validates mint and reverts on rejection. May emit logs. - * @param cToken Asset being minted + * @param slToken Asset being minted * @param minter The address minting the tokens * @param actualMintAmount The amount of the underlying asset being minted * @param mintTokens The number of tokens being minted */ - function mintVerify(address cToken, address minter, uint actualMintAmount, uint mintTokens) external { + function mintVerify(address slToken, address minter, uint actualMintAmount, uint mintTokens) external { // Shh - currently unused - cToken; + slToken; minter; actualMintAmount; mintTokens; @@ -280,36 +279,36 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE /** * @notice Checks if the account should be allowed to redeem tokens in the given market - * @param cToken The market to verify the redeem against + * @param slToken The market to verify the redeem against * @param redeemer The account which would redeem the tokens - * @param redeemTokens The number of cTokens to exchange for the underlying asset in the market + * @param redeemTokens The number of slTokens to exchange for the underlying asset in the market * @return 0 if the redeem is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) */ - function redeemAllowed(address cToken, address redeemer, uint redeemTokens) external returns (uint) { - uint allowed = redeemAllowedInternal(cToken, redeemer, redeemTokens); + function redeemAllowed(address slToken, address redeemer, uint redeemTokens) external returns (uint) { + uint allowed = redeemAllowedInternal(slToken, redeemer, redeemTokens); if (allowed != uint(Error.NO_ERROR)) { return allowed; } // Keep the flywheel moving - updateCompSupplyIndex(cToken); - distributeSupplierComp(cToken, redeemer, false); + updateSashimiSupplyIndex(slToken); + distributeSupplierSashimi(slToken, redeemer, false); return uint(Error.NO_ERROR); } - function redeemAllowedInternal(address cToken, address redeemer, uint redeemTokens) internal view returns (uint) { - if (!markets[cToken].isListed) { + function redeemAllowedInternal(address slToken, address redeemer, uint redeemTokens) internal view returns (uint) { + if (!markets[slToken].isListed) { return uint(Error.MARKET_NOT_LISTED); } /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */ - if (!markets[cToken].accountMembership[redeemer]) { + if (!markets[slToken].accountMembership[redeemer]) { return uint(Error.NO_ERROR); } /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */ - (Error err, , uint shortfall) = getHypotheticalAccountLiquidityInternal(redeemer, CToken(cToken), redeemTokens, 0); + (Error err, , uint shortfall) = getHypotheticalAccountLiquidityInternal(redeemer, SLToken(slToken), redeemTokens, 0); if (err != Error.NO_ERROR) { return uint(err); } @@ -322,14 +321,14 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE /** * @notice Validates redeem and reverts on rejection. May emit logs. - * @param cToken Asset being redeemed + * @param slToken Asset being redeemed * @param redeemer The address redeeming the tokens * @param redeemAmount The amount of the underlying asset being redeemed * @param redeemTokens The number of tokens being redeemed */ - function redeemVerify(address cToken, address redeemer, uint redeemAmount, uint redeemTokens) external { + function redeemVerify(address slToken, address redeemer, uint redeemAmount, uint redeemTokens) external { // Shh - currently unused - cToken; + slToken; redeemer; // Require tokens is zero or amount is also zero @@ -340,48 +339,48 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE /** * @notice Checks if the account should be allowed to borrow the underlying asset of the given market - * @param cToken The market to verify the borrow against + * @param slToken The market to verify the borrow against * @param borrower The account which would borrow the asset * @param borrowAmount The amount of underlying the account would borrow * @return 0 if the borrow is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) */ - function borrowAllowed(address cToken, address borrower, uint borrowAmount) external returns (uint) { + function borrowAllowed(address slToken, address borrower, uint borrowAmount) external returns (uint) { // Pausing is a very serious situation - we revert to sound the alarms - require(!borrowGuardianPaused[cToken], "borrow is paused"); + require(!borrowGuardianPaused[slToken], "borrow is paused"); - if (!markets[cToken].isListed) { + if (!markets[slToken].isListed) { return uint(Error.MARKET_NOT_LISTED); } - if (!markets[cToken].accountMembership[borrower]) { - // only cTokens may call borrowAllowed if borrower not in market - require(msg.sender == cToken, "sender must be cToken"); + if (!markets[slToken].accountMembership[borrower]) { + // only slTokens may call borrowAllowed if borrower not in market + require(msg.sender == slToken, "sender must be slToken"); // attempt to add borrower to the market - Error err = addToMarketInternal(CToken(msg.sender), borrower); + Error err = addToMarketInternal(SLToken(msg.sender), borrower); if (err != Error.NO_ERROR) { return uint(err); } // it should be impossible to break the important invariant - assert(markets[cToken].accountMembership[borrower]); + assert(markets[slToken].accountMembership[borrower]); } - if (oracle.getUnderlyingPrice(CToken(cToken)) == 0) { + if (oracle.getUnderlyingPrice(SLToken(slToken)) == 0) { return uint(Error.PRICE_ERROR); } - uint borrowCap = borrowCaps[cToken]; + uint borrowCap = borrowCaps[slToken]; // Borrow cap of 0 corresponds to unlimited borrowing if (borrowCap != 0) { - uint totalBorrows = CToken(cToken).totalBorrows(); + uint totalBorrows = SLToken(slToken).totalBorrows(); (MathError mathErr, uint nextTotalBorrows) = addUInt(totalBorrows, borrowAmount); require(mathErr == MathError.NO_ERROR, "total borrows overflow"); require(nextTotalBorrows < borrowCap, "market borrow cap reached"); } - (Error err, , uint shortfall) = getHypotheticalAccountLiquidityInternal(borrower, CToken(cToken), 0, borrowAmount); + (Error err, , uint shortfall) = getHypotheticalAccountLiquidityInternal(borrower, SLToken(slToken), 0, borrowAmount); if (err != Error.NO_ERROR) { return uint(err); } @@ -390,22 +389,22 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE } // Keep the flywheel moving - Exp memory borrowIndex = Exp({mantissa: CToken(cToken).borrowIndex()}); - updateCompBorrowIndex(cToken, borrowIndex); - distributeBorrowerComp(cToken, borrower, borrowIndex, false); + Exp memory borrowIndex = Exp({mantissa: SLToken(slToken).borrowIndex()}); + updateSashimiBorrowIndex(slToken, borrowIndex); + distributeBorrowerSashimi(slToken, borrower, borrowIndex, false); return uint(Error.NO_ERROR); } /** * @notice Validates borrow and reverts on rejection. May emit logs. - * @param cToken Asset whose underlying is being borrowed + * @param slToken Asset whose underlying is being borrowed * @param borrower The address borrowing the underlying * @param borrowAmount The amount of the underlying asset requested to borrow */ - function borrowVerify(address cToken, address borrower, uint borrowAmount) external { + function borrowVerify(address slToken, address borrower, uint borrowAmount) external { // Shh - currently unused - cToken; + slToken; borrower; borrowAmount; @@ -417,14 +416,14 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE /** * @notice Checks if the account should be allowed to repay a borrow in the given market - * @param cToken The market to verify the repay against + * @param slToken The market to verify the repay against * @param payer The account which would repay the asset * @param borrower The account which would borrowed the asset * @param repayAmount The amount of the underlying asset the account would repay * @return 0 if the repay is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) */ function repayBorrowAllowed( - address cToken, + address slToken, address payer, address borrower, uint repayAmount) external returns (uint) { @@ -433,33 +432,33 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE borrower; repayAmount; - if (!markets[cToken].isListed) { + if (!markets[slToken].isListed) { return uint(Error.MARKET_NOT_LISTED); } // Keep the flywheel moving - Exp memory borrowIndex = Exp({mantissa: CToken(cToken).borrowIndex()}); - updateCompBorrowIndex(cToken, borrowIndex); - distributeBorrowerComp(cToken, borrower, borrowIndex, false); + Exp memory borrowIndex = Exp({mantissa: SLToken(slToken).borrowIndex()}); + updateSashimiBorrowIndex(slToken, borrowIndex); + distributeBorrowerSashimi(slToken, borrower, borrowIndex, false); return uint(Error.NO_ERROR); } /** * @notice Validates repayBorrow and reverts on rejection. May emit logs. - * @param cToken Asset being repaid + * @param slToken Asset being repaid * @param payer The address repaying the borrow * @param borrower The address of the borrower * @param actualRepayAmount The amount of underlying being repaid */ function repayBorrowVerify( - address cToken, + address slToken, address payer, address borrower, uint actualRepayAmount, uint borrowerIndex) external { // Shh - currently unused - cToken; + slToken; payer; borrower; actualRepayAmount; @@ -473,22 +472,22 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE /** * @notice Checks if the liquidation should be allowed to occur - * @param cTokenBorrowed Asset which was borrowed by the borrower - * @param cTokenCollateral Asset which was used as collateral and will be seized + * @param slTokenBorrowed Asset which was borrowed by the borrower + * @param slTokenCollateral Asset which was used as collateral and will be seized * @param liquidator The address repaying the borrow and seizing the collateral * @param borrower The address of the borrower * @param repayAmount The amount of underlying being repaid */ function liquidateBorrowAllowed( - address cTokenBorrowed, - address cTokenCollateral, + address slTokenBorrowed, + address slTokenCollateral, address liquidator, address borrower, uint repayAmount) external returns (uint) { // Shh - currently unused liquidator; - if (!markets[cTokenBorrowed].isListed || !markets[cTokenCollateral].isListed) { + if (!markets[slTokenBorrowed].isListed || !markets[slTokenCollateral].isListed) { return uint(Error.MARKET_NOT_LISTED); } @@ -502,7 +501,7 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE } /* The liquidator may not repay more than what is allowed by the closeFactor */ - uint borrowBalance = CToken(cTokenBorrowed).borrowBalanceStored(borrower); + uint borrowBalance = SLToken(slTokenBorrowed).borrowBalanceStored(borrower); (MathError mathErr, uint maxClose) = mulScalarTruncate(Exp({mantissa: closeFactorMantissa}), borrowBalance); if (mathErr != MathError.NO_ERROR) { return uint(Error.MATH_ERROR); @@ -516,22 +515,22 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE /** * @notice Validates liquidateBorrow and reverts on rejection. May emit logs. - * @param cTokenBorrowed Asset which was borrowed by the borrower - * @param cTokenCollateral Asset which was used as collateral and will be seized + * @param slTokenBorrowed Asset which was borrowed by the borrower + * @param slTokenCollateral Asset which was used as collateral and will be seized * @param liquidator The address repaying the borrow and seizing the collateral * @param borrower The address of the borrower * @param actualRepayAmount The amount of underlying being repaid */ function liquidateBorrowVerify( - address cTokenBorrowed, - address cTokenCollateral, + address slTokenBorrowed, + address slTokenCollateral, address liquidator, address borrower, uint actualRepayAmount, uint seizeTokens) external { // Shh - currently unused - cTokenBorrowed; - cTokenCollateral; + slTokenBorrowed; + slTokenCollateral; liquidator; borrower; actualRepayAmount; @@ -545,15 +544,15 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE /** * @notice Checks if the seizing of assets should be allowed to occur - * @param cTokenCollateral Asset which was used as collateral and will be seized - * @param cTokenBorrowed Asset which was borrowed by the borrower + * @param slTokenCollateral Asset which was used as collateral and will be seized + * @param slTokenBorrowed Asset which was borrowed by the borrower * @param liquidator The address repaying the borrow and seizing the collateral * @param borrower The address of the borrower * @param seizeTokens The number of collateral tokens to seize */ function seizeAllowed( - address cTokenCollateral, - address cTokenBorrowed, + address slTokenCollateral, + address slTokenBorrowed, address liquidator, address borrower, uint seizeTokens) external returns (uint) { @@ -563,39 +562,39 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE // Shh - currently unused seizeTokens; - if (!markets[cTokenCollateral].isListed || !markets[cTokenBorrowed].isListed) { + if (!markets[slTokenCollateral].isListed || !markets[slTokenBorrowed].isListed) { return uint(Error.MARKET_NOT_LISTED); } - if (CToken(cTokenCollateral).comptroller() != CToken(cTokenBorrowed).comptroller()) { + if (SLToken(slTokenCollateral).comptroller() != SLToken(slTokenBorrowed).comptroller()) { return uint(Error.COMPTROLLER_MISMATCH); } // Keep the flywheel moving - updateCompSupplyIndex(cTokenCollateral); - distributeSupplierComp(cTokenCollateral, borrower, false); - distributeSupplierComp(cTokenCollateral, liquidator, false); + updateSashimiSupplyIndex(slTokenCollateral); + distributeSupplierSashimi(slTokenCollateral, borrower, false); + distributeSupplierSashimi(slTokenCollateral, liquidator, false); return uint(Error.NO_ERROR); } /** * @notice Validates seize and reverts on rejection. May emit logs. - * @param cTokenCollateral Asset which was used as collateral and will be seized - * @param cTokenBorrowed Asset which was borrowed by the borrower + * @param slTokenCollateral Asset which was used as collateral and will be seized + * @param slTokenBorrowed Asset which was borrowed by the borrower * @param liquidator The address repaying the borrow and seizing the collateral * @param borrower The address of the borrower * @param seizeTokens The number of collateral tokens to seize */ function seizeVerify( - address cTokenCollateral, - address cTokenBorrowed, + address slTokenCollateral, + address slTokenBorrowed, address liquidator, address borrower, uint seizeTokens) external { // Shh - currently unused - cTokenCollateral; - cTokenBorrowed; + slTokenCollateral; + slTokenBorrowed; liquidator; borrower; seizeTokens; @@ -608,41 +607,41 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE /** * @notice Checks if the account should be allowed to transfer tokens in the given market - * @param cToken The market to verify the transfer against + * @param slToken The market to verify the transfer against * @param src The account which sources the tokens * @param dst The account which receives the tokens - * @param transferTokens The number of cTokens to transfer + * @param transferTokens The number of slTokens to transfer * @return 0 if the transfer is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) */ - function transferAllowed(address cToken, address src, address dst, uint transferTokens) external returns (uint) { + function transferAllowed(address slToken, address src, address dst, uint transferTokens) external returns (uint) { // Pausing is a very serious situation - we revert to sound the alarms require(!transferGuardianPaused, "transfer is paused"); // Currently the only consideration is whether or not // the src is allowed to redeem this many tokens - uint allowed = redeemAllowedInternal(cToken, src, transferTokens); + uint allowed = redeemAllowedInternal(slToken, src, transferTokens); if (allowed != uint(Error.NO_ERROR)) { return allowed; } // Keep the flywheel moving - updateCompSupplyIndex(cToken); - distributeSupplierComp(cToken, src, false); - distributeSupplierComp(cToken, dst, false); + updateSashimiSupplyIndex(slToken); + distributeSupplierSashimi(slToken, src, false); + distributeSupplierSashimi(slToken, dst, false); return uint(Error.NO_ERROR); } /** * @notice Validates transfer and reverts on rejection. May emit logs. - * @param cToken Asset being transferred + * @param slToken Asset being transferred * @param src The account which sources the tokens * @param dst The account which receives the tokens - * @param transferTokens The number of cTokens to transfer + * @param transferTokens The number of slTokens to transfer */ - function transferVerify(address cToken, address src, address dst, uint transferTokens) external { + function transferVerify(address slToken, address src, address dst, uint transferTokens) external { // Shh - currently unused - cToken; + slToken; src; dst; transferTokens; @@ -657,13 +656,13 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE /** * @dev Local vars for avoiding stack-depth limits in calculating account liquidity. - * Note that `cTokenBalance` is the number of cTokens the account owns in the market, + * Note that `slTokenBalance` is the number of slTokens the account owns in the market, * whereas `borrowBalance` is the amount of underlying that the account has borrowed. */ struct AccountLiquidityLocalVars { uint sumCollateral; uint sumBorrowPlusEffects; - uint cTokenBalance; + uint slTokenBalance; uint borrowBalance; uint exchangeRateMantissa; uint oraclePriceMantissa; @@ -680,7 +679,7 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE * account shortfall below collateral requirements) */ function getAccountLiquidity(address account) public view returns (uint, uint, uint) { - (Error err, uint liquidity, uint shortfall) = getHypotheticalAccountLiquidityInternal(account, CToken(0), 0, 0); + (Error err, uint liquidity, uint shortfall) = getHypotheticalAccountLiquidityInternal(account, SLToken(0), 0, 0); return (uint(err), liquidity, shortfall); } @@ -692,12 +691,12 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE * account shortfall below collateral requirements) */ function getAccountLiquidityInternal(address account) internal view returns (Error, uint, uint) { - return getHypotheticalAccountLiquidityInternal(account, CToken(0), 0, 0); + return getHypotheticalAccountLiquidityInternal(account, SLToken(0), 0, 0); } /** * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed - * @param cTokenModify The market to hypothetically redeem/borrow in + * @param slTokenModify The market to hypothetically redeem/borrow in * @param account The account to determine liquidity for * @param redeemTokens The number of tokens to hypothetically redeem * @param borrowAmount The amount of underlying to hypothetically borrow @@ -707,20 +706,20 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE */ function getHypotheticalAccountLiquidity( address account, - address cTokenModify, + address slTokenModify, uint redeemTokens, uint borrowAmount) public view returns (uint, uint, uint) { - (Error err, uint liquidity, uint shortfall) = getHypotheticalAccountLiquidityInternal(account, CToken(cTokenModify), redeemTokens, borrowAmount); + (Error err, uint liquidity, uint shortfall) = getHypotheticalAccountLiquidityInternal(account, SLToken(slTokenModify), redeemTokens, borrowAmount); return (uint(err), liquidity, shortfall); } /** * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed - * @param cTokenModify The market to hypothetically redeem/borrow in + * @param slTokenModify The market to hypothetically redeem/borrow in * @param account The account to determine liquidity for * @param redeemTokens The number of tokens to hypothetically redeem * @param borrowAmount The amount of underlying to hypothetically borrow - * @dev Note that we calculate the exchangeRateStored for each collateral cToken using stored data, + * @dev Note that we calculate the exchangeRateStored for each collateral slToken using stored data, * without calculating accumulated interest. * @return (possible error code, hypothetical account liquidity in excess of collateral requirements, @@ -728,7 +727,7 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE */ function getHypotheticalAccountLiquidityInternal( address account, - CToken cTokenModify, + SLToken slTokenModify, uint redeemTokens, uint borrowAmount) internal view returns (Error, uint, uint) { @@ -737,12 +736,12 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE MathError mErr; // For each asset the account is in - CToken[] memory assets = accountAssets[account]; + SLToken[] memory assets = accountAssets[account]; for (uint i = 0; i < assets.length; i++) { - CToken asset = assets[i]; + SLToken asset = assets[i]; - // Read the balances and exchange rate from the cToken - (oErr, vars.cTokenBalance, vars.borrowBalance, vars.exchangeRateMantissa) = asset.getAccountSnapshot(account); + // Read the balances and exchange rate from the slToken + (oErr, vars.slTokenBalance, vars.borrowBalance, vars.exchangeRateMantissa) = asset.getAccountSnapshot(account); if (oErr != 0) { // semi-opaque error code, we assume NO_ERROR == 0 is invariant between upgrades return (Error.SNAPSHOT_ERROR, 0, 0); } @@ -762,8 +761,8 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE return (Error.MATH_ERROR, 0, 0); } - // sumCollateral += tokensToDenom * cTokenBalance - (mErr, vars.sumCollateral) = mulScalarTruncateAddUInt(vars.tokensToDenom, vars.cTokenBalance, vars.sumCollateral); + // sumCollateral += tokensToDenom * slTokenBalance + (mErr, vars.sumCollateral) = mulScalarTruncateAddUInt(vars.tokensToDenom, vars.slTokenBalance, vars.sumCollateral); if (mErr != MathError.NO_ERROR) { return (Error.MATH_ERROR, 0, 0); } @@ -774,8 +773,8 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE return (Error.MATH_ERROR, 0, 0); } - // Calculate effects of interacting with cTokenModify - if (asset == cTokenModify) { + // Calculate effects of interacting with slTokenModify + if (asset == slTokenModify) { // redeem effect // sumBorrowPlusEffects += tokensToDenom * redeemTokens (mErr, vars.sumBorrowPlusEffects) = mulScalarTruncateAddUInt(vars.tokensToDenom, redeemTokens, vars.sumBorrowPlusEffects); @@ -802,16 +801,16 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE /** * @notice Calculate number of tokens of collateral asset to seize given an underlying amount - * @dev Used in liquidation (called in cToken.liquidateBorrowFresh) - * @param cTokenBorrowed The address of the borrowed cToken - * @param cTokenCollateral The address of the collateral cToken - * @param actualRepayAmount The amount of cTokenBorrowed underlying to convert into cTokenCollateral tokens - * @return (errorCode, number of cTokenCollateral tokens to be seized in a liquidation) + * @dev Used in liquidation (called in slToken.liquidateBorrowFresh) + * @param slTokenBorrowed The address of the borrowed slToken + * @param slTokenCollateral The address of the collateral slToken + * @param actualRepayAmount The amount of slTokenBorrowed underlying to convert into slTokenCollateral tokens + * @return (errorCode, number of slTokenCollateral tokens to be seized in a liquidation) */ - function liquidateCalculateSeizeTokens(address cTokenBorrowed, address cTokenCollateral, uint actualRepayAmount) external view returns (uint, uint) { + function liquidateCalculateSeizeTokens(address slTokenBorrowed, address slTokenCollateral, uint actualRepayAmount) external view returns (uint, uint) { /* Read oracle prices for borrowed and collateral markets */ - uint priceBorrowedMantissa = oracle.getUnderlyingPrice(CToken(cTokenBorrowed)); - uint priceCollateralMantissa = oracle.getUnderlyingPrice(CToken(cTokenCollateral)); + uint priceBorrowedMantissa = oracle.getUnderlyingPrice(SLToken(slTokenBorrowed)); + uint priceCollateralMantissa = oracle.getUnderlyingPrice(SLToken(slTokenCollateral)); if (priceBorrowedMantissa == 0 || priceCollateralMantissa == 0) { return (uint(Error.PRICE_ERROR), 0); } @@ -822,7 +821,7 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE * seizeTokens = seizeAmount / exchangeRate * = actualRepayAmount * (liquidationIncentive * priceBorrowed) / (priceCollateral * exchangeRate) */ - uint exchangeRateMantissa = CToken(cTokenCollateral).exchangeRateStored(); // Note: reverts on error + uint exchangeRateMantissa = SLToken(slTokenCollateral).exchangeRateStored(); // Note: reverts on error uint seizeTokens; Exp memory numerator; Exp memory denominator; @@ -910,18 +909,18 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE /** * @notice Sets the collateralFactor for a market * @dev Admin function to set per-market collateralFactor - * @param cToken The market to set the factor on + * @param slToken The market to set the factor on * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18 * @return uint 0=success, otherwise a failure. (See ErrorReporter for details) */ - function _setCollateralFactor(CToken cToken, uint newCollateralFactorMantissa) external returns (uint) { + function _setCollateralFactor(SLToken slToken, uint newCollateralFactorMantissa) external returns (uint) { // Check caller is admin if (msg.sender != admin) { return fail(Error.UNAUTHORIZED, FailureInfo.SET_COLLATERAL_FACTOR_OWNER_CHECK); } // Verify market is listed - Market storage market = markets[address(cToken)]; + Market storage market = markets[address(slToken)]; if (!market.isListed) { return fail(Error.MARKET_NOT_LISTED, FailureInfo.SET_COLLATERAL_FACTOR_NO_EXISTS); } @@ -935,7 +934,7 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE } // If collateral factor != 0, fail if price == 0 - if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(cToken) == 0) { + if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(slToken) == 0) { return fail(Error.PRICE_ERROR, FailureInfo.SET_COLLATERAL_FACTOR_WITHOUT_PRICE); } @@ -944,7 +943,7 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE market.collateralFactorMantissa = newCollateralFactorMantissa; // Emit event with asset, old collateral factor, and new collateral factor - emit NewCollateralFactor(cToken, oldCollateralFactorMantissa, newCollateralFactorMantissa); + emit NewCollateralFactor(slToken, oldCollateralFactorMantissa, newCollateralFactorMantissa); return uint(Error.NO_ERROR); } @@ -1007,54 +1006,54 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE /** * @notice Add the market to the markets mapping and set it as listed * @dev Admin function to set isListed and add support for the market - * @param cToken The address of the market (token) to list + * @param slToken The address of the market (token) to list * @return uint 0=success, otherwise a failure. (See enum Error for details) */ - function _supportMarket(CToken cToken) external returns (uint) { + function _supportMarket(SLToken slToken) external returns (uint) { if (msg.sender != admin) { return fail(Error.UNAUTHORIZED, FailureInfo.SUPPORT_MARKET_OWNER_CHECK); } - if (markets[address(cToken)].isListed) { + if (markets[address(slToken)].isListed) { return fail(Error.MARKET_ALREADY_LISTED, FailureInfo.SUPPORT_MARKET_EXISTS); } - cToken.isCToken(); // Sanity check to make sure its really a CToken + slToken.isSLToken(); // Sanity check to make sure its really a SLToken - markets[address(cToken)] = Market({isListed: true, isComped: false, collateralFactorMantissa: 0}); + markets[address(slToken)] = Market({isListed: true, isSashimied: false, collateralFactorMantissa: 0}); - _addMarketInternal(address(cToken)); + _addMarketInternal(address(slToken)); - emit MarketListed(cToken); + emit MarketListed(slToken); return uint(Error.NO_ERROR); } - function _addMarketInternal(address cToken) internal { + function _addMarketInternal(address slToken) internal { for (uint i = 0; i < allMarkets.length; i ++) { - require(allMarkets[i] != CToken(cToken), "market already added"); + require(allMarkets[i] != SLToken(slToken), "market already added"); } - allMarkets.push(CToken(cToken)); + allMarkets.push(SLToken(slToken)); } /** - * @notice Set the given borrow caps for the given cToken markets. Borrowing that brings total borrows to or above borrow cap will revert. + * @notice Set the given borrow caps for the given slToken markets. Borrowing that brings total borrows to or above borrow cap will revert. * @dev Admin or borrowCapGuardian function to set the borrow caps. A borrow cap of 0 corresponds to unlimited borrowing. - * @param cTokens The addresses of the markets (tokens) to change the borrow caps for + * @param slTokens The addresses of the markets (tokens) to change the borrow caps for * @param newBorrowCaps The new borrow cap values in underlying to be set. A value of 0 corresponds to unlimited borrowing. */ - function _setMarketBorrowCaps(CToken[] calldata cTokens, uint[] calldata newBorrowCaps) external { + function _setMarketBorrowCaps(SLToken[] calldata slTokens, uint[] calldata newBorrowCaps) external { require(msg.sender == admin || msg.sender == borrowCapGuardian, "only admin or borrow cap guardian can set borrow caps"); - uint numMarkets = cTokens.length; + uint numMarkets = slTokens.length; uint numBorrowCaps = newBorrowCaps.length; require(numMarkets != 0 && numMarkets == numBorrowCaps, "invalid input"); for(uint i = 0; i < numMarkets; i++) { - borrowCaps[address(cTokens[i])] = newBorrowCaps[i]; - emit NewBorrowCap(cTokens[i], newBorrowCaps[i]); + borrowCaps[address(slTokens[i])] = newBorrowCaps[i]; + emit NewBorrowCap(slTokens[i], newBorrowCaps[i]); } } @@ -1097,23 +1096,23 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE return uint(Error.NO_ERROR); } - function _setMintPaused(CToken cToken, bool state) public returns (bool) { - require(markets[address(cToken)].isListed, "cannot pause a market that is not listed"); + function _setMintPaused(SLToken slToken, bool state) public returns (bool) { + require(markets[address(slToken)].isListed, "cannot pause a market that is not listed"); require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause"); require(msg.sender == admin || state == true, "only admin can unpause"); - mintGuardianPaused[address(cToken)] = state; - emit ActionPaused(cToken, "Mint", state); + mintGuardianPaused[address(slToken)] = state; + emit ActionPaused(slToken, "Mint", state); return state; } - function _setBorrowPaused(CToken cToken, bool state) public returns (bool) { - require(markets[address(cToken)].isListed, "cannot pause a market that is not listed"); + function _setBorrowPaused(SLToken slToken, bool state) public returns (bool) { + require(markets[address(slToken)].isListed, "cannot pause a market that is not listed"); require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause"); require(msg.sender == admin || state == true, "only admin can unpause"); - borrowGuardianPaused[address(cToken)] = state; - emit ActionPaused(cToken, "Borrow", state); + borrowGuardianPaused[address(slToken)] = state; + emit ActionPaused(slToken, "Borrow", state); return state; } @@ -1147,61 +1146,61 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE return msg.sender == admin || msg.sender == comptrollerImplementation; } - /*** Comp Distribution ***/ + /*** Sashimi Distribution ***/ /** - * @notice Recalculate and update COMP speeds for all COMP markets + * @notice Recalculate and update SASHIMI speeds for all SASHIMI markets */ - function refreshCompSpeeds() public { + function refreshSashimiSpeeds() public { require(msg.sender == tx.origin, "only externally owned accounts may refresh speeds"); - refreshCompSpeedsInternal(); + refreshSashimiSpeedsInternal(); } - function refreshCompSpeedsInternal() internal { - CToken[] memory allMarkets_ = allMarkets; + function refreshSashimiSpeedsInternal() internal { + SLToken[] memory allMarkets_ = allMarkets; for (uint i = 0; i < allMarkets_.length; i++) { - CToken cToken = allMarkets_[i]; - Exp memory borrowIndex = Exp({mantissa: cToken.borrowIndex()}); - updateCompSupplyIndex(address(cToken)); - updateCompBorrowIndex(address(cToken), borrowIndex); + SLToken slToken = allMarkets_[i]; + Exp memory borrowIndex = Exp({mantissa: slToken.borrowIndex()}); + updateSashimiSupplyIndex(address(slToken)); + updateSashimiBorrowIndex(address(slToken), borrowIndex); } Exp memory totalUtility = Exp({mantissa: 0}); Exp[] memory utilities = new Exp[](allMarkets_.length); for (uint i = 0; i < allMarkets_.length; i++) { - CToken cToken = allMarkets_[i]; - if (markets[address(cToken)].isComped) { - Exp memory assetPrice = Exp({mantissa: oracle.getUnderlyingPrice(cToken)}); - Exp memory utility = mul_(assetPrice, cToken.totalBorrows()); + SLToken slToken = allMarkets_[i]; + if (markets[address(slToken)].isSashimied) { + Exp memory assetPrice = Exp({mantissa: oracle.getUnderlyingPrice(slToken)}); + Exp memory utility = mul_(assetPrice, slToken.totalBorrows()); utilities[i] = utility; totalUtility = add_(totalUtility, utility); } } for (uint i = 0; i < allMarkets_.length; i++) { - CToken cToken = allMarkets[i]; - uint newSpeed = totalUtility.mantissa > 0 ? mul_(compRate, div_(utilities[i], totalUtility)) : 0; - compSpeeds[address(cToken)] = newSpeed; - emit CompSpeedUpdated(cToken, newSpeed); + SLToken slToken = allMarkets[i]; + uint newSpeed = totalUtility.mantissa > 0 ? mul_(sashimiRate, div_(utilities[i], totalUtility)) : 0; + sashimiSpeeds[address(slToken)] = newSpeed; + emit SashimiSpeedUpdated(slToken, newSpeed); } } /** - * @notice Accrue COMP to the market by updating the supply index - * @param cToken The market whose supply index to update + * @notice Accrue SASHIMI to the market by updating the supply index + * @param slToken The market whose supply index to update */ - function updateCompSupplyIndex(address cToken) internal { - CompMarketState storage supplyState = compSupplyState[cToken]; - uint supplySpeed = compSpeeds[cToken]; + function updateSashimiSupplyIndex(address slToken) internal { + SashimiMarketState storage supplyState = sashimiSupplyState[slToken]; + uint supplySpeed = sashimiSpeeds[slToken]; uint blockNumber = getBlockNumber(); uint deltaBlocks = sub_(blockNumber, uint(supplyState.block)); if (deltaBlocks > 0 && supplySpeed > 0) { - uint supplyTokens = CToken(cToken).totalSupply(); - uint compAccrued = mul_(deltaBlocks, supplySpeed); - Double memory ratio = supplyTokens > 0 ? fraction(compAccrued, supplyTokens) : Double({mantissa: 0}); + uint supplyTokens = SLToken(slToken).totalSupply(); + uint sashimiAccrued = mul_(deltaBlocks, supplySpeed); + Double memory ratio = supplyTokens > 0 ? fraction(sashimiAccrued, supplyTokens) : Double({mantissa: 0}); Double memory index = add_(Double({mantissa: supplyState.index}), ratio); - compSupplyState[cToken] = CompMarketState({ + sashimiSupplyState[slToken] = SashimiMarketState({ index: safe224(index.mantissa, "new index exceeds 224 bits"), block: safe32(blockNumber, "block number exceeds 32 bits") }); @@ -1211,20 +1210,20 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE } /** - * @notice Accrue COMP to the market by updating the borrow index - * @param cToken The market whose borrow index to update + * @notice Accrue SASHIMI to the market by updating the borrow index + * @param slToken The market whose borrow index to update */ - function updateCompBorrowIndex(address cToken, Exp memory marketBorrowIndex) internal { - CompMarketState storage borrowState = compBorrowState[cToken]; - uint borrowSpeed = compSpeeds[cToken]; + function updateSashimiBorrowIndex(address slToken, Exp memory marketBorrowIndex) internal { + SashimiMarketState storage borrowState = sashimiBorrowState[slToken]; + uint borrowSpeed = sashimiSpeeds[slToken]; uint blockNumber = getBlockNumber(); uint deltaBlocks = sub_(blockNumber, uint(borrowState.block)); if (deltaBlocks > 0 && borrowSpeed > 0) { - uint borrowAmount = div_(CToken(cToken).totalBorrows(), marketBorrowIndex); - uint compAccrued = mul_(deltaBlocks, borrowSpeed); - Double memory ratio = borrowAmount > 0 ? fraction(compAccrued, borrowAmount) : Double({mantissa: 0}); + uint borrowAmount = div_(SLToken(slToken).totalBorrows(), marketBorrowIndex); + uint sashimiAccrued = mul_(deltaBlocks, borrowSpeed); + Double memory ratio = borrowAmount > 0 ? fraction(sashimiAccrued, borrowAmount) : Double({mantissa: 0}); Double memory index = add_(Double({mantissa: borrowState.index}), ratio); - compBorrowState[cToken] = CompMarketState({ + sashimiBorrowState[slToken] = SashimiMarketState({ index: safe224(index.mantissa, "new index exceeds 224 bits"), block: safe32(blockNumber, "block number exceeds 32 bits") }); @@ -1234,63 +1233,63 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE } /** - * @notice Calculate COMP accrued by a supplier and possibly transfer it to them - * @param cToken The market in which the supplier is interacting - * @param supplier The address of the supplier to distribute COMP to + * @notice Calculate SASHIMI accrued by a supplier and possibly transfer it to them + * @param slToken The market in which the supplier is interacting + * @param supplier The address of the supplier to distribute SASHIMI to */ - function distributeSupplierComp(address cToken, address supplier, bool distributeAll) internal { - CompMarketState storage supplyState = compSupplyState[cToken]; + function distributeSupplierSashimi(address slToken, address supplier, bool distributeAll) internal { + SashimiMarketState storage supplyState = sashimiSupplyState[slToken]; Double memory supplyIndex = Double({mantissa: supplyState.index}); - Double memory supplierIndex = Double({mantissa: compSupplierIndex[cToken][supplier]}); - compSupplierIndex[cToken][supplier] = supplyIndex.mantissa; + Double memory supplierIndex = Double({mantissa: sashimiSupplierIndex[slToken][supplier]}); + sashimiSupplierIndex[slToken][supplier] = supplyIndex.mantissa; if (supplierIndex.mantissa == 0 && supplyIndex.mantissa > 0) { - supplierIndex.mantissa = compInitialIndex; + supplierIndex.mantissa = sashimiInitialIndex; } Double memory deltaIndex = sub_(supplyIndex, supplierIndex); - uint supplierTokens = CToken(cToken).balanceOf(supplier); + uint supplierTokens = SLToken(slToken).balanceOf(supplier); uint supplierDelta = mul_(supplierTokens, deltaIndex); - uint supplierAccrued = add_(compAccrued[supplier], supplierDelta); - compAccrued[supplier] = transferComp(supplier, supplierAccrued, distributeAll ? 0 : compClaimThreshold); - emit DistributedSupplierComp(CToken(cToken), supplier, supplierDelta, supplyIndex.mantissa); + uint supplierAccrued = add_(sashimiAccrued[supplier], supplierDelta); + sashimiAccrued[supplier] = transferSashimi(supplier, supplierAccrued, distributeAll ? 0 : sashimiClaimThreshold); + emit DistributedSupplierSashimi(SLToken(slToken), supplier, supplierDelta, supplyIndex.mantissa); } /** - * @notice Calculate COMP accrued by a borrower and possibly transfer it to them + * @notice Calculate SASHIMI accrued by a borrower and possibly transfer it to them * @dev Borrowers will not begin to accrue until after the first interaction with the protocol. - * @param cToken The market in which the borrower is interacting - * @param borrower The address of the borrower to distribute COMP to + * @param slToken The market in which the borrower is interacting + * @param borrower The address of the borrower to distribute SASHIMI to */ - function distributeBorrowerComp(address cToken, address borrower, Exp memory marketBorrowIndex, bool distributeAll) internal { - CompMarketState storage borrowState = compBorrowState[cToken]; + function distributeBorrowerSashimi(address slToken, address borrower, Exp memory marketBorrowIndex, bool distributeAll) internal { + SashimiMarketState storage borrowState = sashimiBorrowState[slToken]; Double memory borrowIndex = Double({mantissa: borrowState.index}); - Double memory borrowerIndex = Double({mantissa: compBorrowerIndex[cToken][borrower]}); - compBorrowerIndex[cToken][borrower] = borrowIndex.mantissa; + Double memory borrowerIndex = Double({mantissa: sashimiBorrowerIndex[slToken][borrower]}); + sashimiBorrowerIndex[slToken][borrower] = borrowIndex.mantissa; if (borrowerIndex.mantissa > 0) { Double memory deltaIndex = sub_(borrowIndex, borrowerIndex); - uint borrowerAmount = div_(CToken(cToken).borrowBalanceStored(borrower), marketBorrowIndex); + uint borrowerAmount = div_(SLToken(slToken).borrowBalanceStored(borrower), marketBorrowIndex); uint borrowerDelta = mul_(borrowerAmount, deltaIndex); - uint borrowerAccrued = add_(compAccrued[borrower], borrowerDelta); - compAccrued[borrower] = transferComp(borrower, borrowerAccrued, distributeAll ? 0 : compClaimThreshold); - emit DistributedBorrowerComp(CToken(cToken), borrower, borrowerDelta, borrowIndex.mantissa); + uint borrowerAccrued = add_(sashimiAccrued[borrower], borrowerDelta); + sashimiAccrued[borrower] = transferSashimi(borrower, borrowerAccrued, distributeAll ? 0 : sashimiClaimThreshold); + emit DistributedBorrowerSashimi(SLToken(slToken), borrower, borrowerDelta, borrowIndex.mantissa); } } /** - * @notice Transfer COMP to the user, if they are above the threshold - * @dev Note: If there is not enough COMP, we do not perform the transfer all. - * @param user The address of the user to transfer COMP to - * @param userAccrued The amount of COMP to (possibly) transfer - * @return The amount of COMP which was NOT transferred to the user + * @notice Transfer SASHIMI to the user, if they are above the threshold + * @dev Note: If there is not enough SASHIMI, we do not perform the transfer all. + * @param user The address of the user to transfer SASHIMI to + * @param userAccrued The amount of SASHIMI to (possibly) transfer + * @return The amount of SASHIMI which was NOT transferred to the user */ - function transferComp(address user, uint userAccrued, uint threshold) internal returns (uint) { + function transferSashimi(address user, uint userAccrued, uint threshold) internal returns (uint) { if (userAccrued >= threshold && userAccrued > 0) { - Comp comp = Comp(getCompAddress()); - uint compRemaining = comp.balanceOf(address(this)); - if (userAccrued <= compRemaining) { - comp.transfer(user, userAccrued); + EIP20Interface sashimi = EIP20Interface(getSashimiAddress()); + uint sashimiRemaining = sashimi.balanceOf(address(this)); + if (userAccrued <= sashimiRemaining) { + sashimi.transfer(user, userAccrued); return 0; } } @@ -1298,118 +1297,118 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE } /** - * @notice Claim all the comp accrued by holder in all markets - * @param holder The address to claim COMP for + * @notice Claim all the sashimi accrued by holder in all markets + * @param holder The address to claim SASHIMI for */ - function claimComp(address holder) public { - return claimComp(holder, allMarkets); + function claimSashimi(address holder) public { + return claimSashimi(holder, allMarkets); } /** - * @notice Claim all the comp accrued by holder in the specified markets - * @param holder The address to claim COMP for - * @param cTokens The list of markets to claim COMP in + * @notice Claim all the sashimi accrued by holder in the specified markets + * @param holder The address to claim SASHIMI for + * @param slTokens The list of markets to claim SASHIMI in */ - function claimComp(address holder, CToken[] memory cTokens) public { + function claimSashimi(address holder, SLToken[] memory slTokens) public { address[] memory holders = new address[](1); holders[0] = holder; - claimComp(holders, cTokens, true, true); + claimSashimi(holders, slTokens, true, true); } /** - * @notice Claim all comp accrued by the holders - * @param holders The addresses to claim COMP for - * @param cTokens The list of markets to claim COMP in - * @param borrowers Whether or not to claim COMP earned by borrowing - * @param suppliers Whether or not to claim COMP earned by supplying + * @notice Claim all sashimi accrued by the holders + * @param holders The addresses to claim SASHIMI for + * @param slTokens The list of markets to claim SASHIMI in + * @param borrowers Whether or not to claim SASHIMI earned by borrowing + * @param suppliers Whether or not to claim SASHIMI earned by supplying */ - function claimComp(address[] memory holders, CToken[] memory cTokens, bool borrowers, bool suppliers) public { - for (uint i = 0; i < cTokens.length; i++) { - CToken cToken = cTokens[i]; - require(markets[address(cToken)].isListed, "market must be listed"); + function claimSashimi(address[] memory holders, SLToken[] memory slTokens, bool borrowers, bool suppliers) public { + for (uint i = 0; i < slTokens.length; i++) { + SLToken slToken = slTokens[i]; + require(markets[address(slToken)].isListed, "market must be listed"); if (borrowers == true) { - Exp memory borrowIndex = Exp({mantissa: cToken.borrowIndex()}); - updateCompBorrowIndex(address(cToken), borrowIndex); + Exp memory borrowIndex = Exp({mantissa: slToken.borrowIndex()}); + updateSashimiBorrowIndex(address(slToken), borrowIndex); for (uint j = 0; j < holders.length; j++) { - distributeBorrowerComp(address(cToken), holders[j], borrowIndex, true); + distributeBorrowerSashimi(address(slToken), holders[j], borrowIndex, true); } } if (suppliers == true) { - updateCompSupplyIndex(address(cToken)); + updateSashimiSupplyIndex(address(slToken)); for (uint j = 0; j < holders.length; j++) { - distributeSupplierComp(address(cToken), holders[j], true); + distributeSupplierSashimi(address(slToken), holders[j], true); } } } } - /*** Comp Distribution Admin ***/ + /*** Sashimi Distribution Admin ***/ /** - * @notice Set the amount of COMP distributed per block - * @param compRate_ The amount of COMP wei per block to distribute + * @notice Set the amount of SASHIMI distributed per block + * @param sashimiRate_ The amount of SASHIMI wei per block to distribute */ - function _setCompRate(uint compRate_) public { - require(adminOrInitializing(), "only admin can change comp rate"); + function _setSashimiRate(uint sashimiRate_) public { + require(adminOrInitializing(), "only admin can change sashimi rate"); - uint oldRate = compRate; - compRate = compRate_; - emit NewCompRate(oldRate, compRate_); + uint oldRate = sashimiRate; + sashimiRate = sashimiRate_; + emit NewSashimiRate(oldRate, sashimiRate_); - refreshCompSpeedsInternal(); + refreshSashimiSpeedsInternal(); } /** - * @notice Add markets to compMarkets, allowing them to earn COMP in the flywheel - * @param cTokens The addresses of the markets to add + * @notice Add markets to sashimiMarkets, allowing them to earn SASHIMI in the flywheel + * @param slTokens The addresses of the markets to add */ - function _addCompMarkets(address[] memory cTokens) public { - require(adminOrInitializing(), "only admin can add comp market"); + function _addSashimiMarkets(address[] memory slTokens) public { + require(adminOrInitializing(), "only admin can add sashimi market"); - for (uint i = 0; i < cTokens.length; i++) { - _addCompMarketInternal(cTokens[i]); + for (uint i = 0; i < slTokens.length; i++) { + _addSashimiMarketInternal(slTokens[i]); } - refreshCompSpeedsInternal(); + refreshSashimiSpeedsInternal(); } - function _addCompMarketInternal(address cToken) internal { - Market storage market = markets[cToken]; - require(market.isListed == true, "comp market is not listed"); - require(market.isComped == false, "comp market already added"); + function _addSashimiMarketInternal(address slToken) internal { + Market storage market = markets[slToken]; + require(market.isListed == true, "sashimi market is not listed"); + require(market.isSashimied == false, "sashimi market already added"); - market.isComped = true; - emit MarketComped(CToken(cToken), true); + market.isSashimied = true; + emit MarketSashimied(SLToken(slToken), true); - if (compSupplyState[cToken].index == 0 && compSupplyState[cToken].block == 0) { - compSupplyState[cToken] = CompMarketState({ - index: compInitialIndex, + if (sashimiSupplyState[slToken].index == 0 && sashimiSupplyState[slToken].block == 0) { + sashimiSupplyState[slToken] = SashimiMarketState({ + index: sashimiInitialIndex, block: safe32(getBlockNumber(), "block number exceeds 32 bits") }); } - if (compBorrowState[cToken].index == 0 && compBorrowState[cToken].block == 0) { - compBorrowState[cToken] = CompMarketState({ - index: compInitialIndex, + if (sashimiBorrowState[slToken].index == 0 && sashimiBorrowState[slToken].block == 0) { + sashimiBorrowState[slToken] = SashimiMarketState({ + index: sashimiInitialIndex, block: safe32(getBlockNumber(), "block number exceeds 32 bits") }); } } /** - * @notice Remove a market from compMarkets, preventing it from earning COMP in the flywheel - * @param cToken The address of the market to drop + * @notice Remove a market from sashimiMarkets, preventing it from earning SASHIMI in the flywheel + * @param slToken The address of the market to drop */ - function _dropCompMarket(address cToken) public { - require(msg.sender == admin, "only admin can drop comp market"); + function _dropSashimiMarket(address slToken) public { + require(msg.sender == admin, "only admin can drop sashimi market"); - Market storage market = markets[cToken]; - require(market.isComped == true, "market is not a comp market"); + Market storage market = markets[slToken]; + require(market.isSashimied == true, "market is not a sashimi market"); - market.isComped = false; - emit MarketComped(CToken(cToken), false); + market.isSashimied = false; + emit MarketSashimied(SLToken(slToken), false); - refreshCompSpeedsInternal(); + refreshSashimiSpeedsInternal(); } /** @@ -1417,7 +1416,7 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE * @dev The automatic getter may be used to access an individual market. * @return The list of market addresses */ - function getAllMarkets() public view returns (CToken[] memory) { + function getAllMarkets() public view returns (SLToken[] memory) { return allMarkets; } @@ -1426,10 +1425,10 @@ contract Comptroller is ComptrollerV4Storage, ComptrollerInterface, ComptrollerE } /** - * @notice Return the address of the COMP token - * @return The address of COMP + * @notice Return the address of the SASHIMI token + * @return The address of SASHIMI */ - function getCompAddress() public view returns (address) { - return 0xc00e94Cb662C3520282E6f5717214004A7f26888; + function getSashimiAddress() public view returns (address) { + return 0xC28E27870558cF22ADD83540d2126da2e4b464c2; } } diff --git a/contracts/ComptrollerG1.sol b/contracts/ComptrollerG1.sol index 9e243f660..47bb9e8e6 100644 --- a/contracts/ComptrollerG1.sol +++ b/contracts/ComptrollerG1.sol @@ -1,6 +1,6 @@ pragma solidity ^0.5.16; -import "./CToken.sol"; +import "./SLToken.sol"; import "./ErrorReporter.sol"; import "./Exponential.sol"; import "./PriceOracle.sol"; @@ -9,8 +9,8 @@ import "./ComptrollerStorage.sol"; import "./Unitroller.sol"; /** - * @title Compound's Comptroller Contract - * @author Compound + * @title SashimiLending's Comptroller Contract + * @author SashimiLending * @dev This was the first version of the Comptroller brains. * We keep it so our tests can continue to do the real-life behavior of upgrading from this logic forward. */ @@ -35,7 +35,7 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle } /** - * @notice Official mapping of cTokens -> Market metadata + * @notice Official mapping of slTokens -> Market metadata * @dev Used e.g. to determine if a market is supported */ mapping(address => Market) public markets; @@ -43,17 +43,17 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle /** * @notice Emitted when an admin supports a market */ - event MarketListed(CToken cToken); + event MarketListed(SLToken slToken); /** * @notice Emitted when an account enters a market */ - event MarketEntered(CToken cToken, address account); + event MarketEntered(SLToken slToken, address account); /** * @notice Emitted when an account exits a market */ - event MarketExited(CToken cToken, address account); + event MarketExited(SLToken slToken, address account); /** * @notice Emitted when close factor is changed by admin @@ -63,7 +63,7 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle /** * @notice Emitted when a collateral factor is changed by admin */ - event NewCollateralFactor(CToken cToken, uint oldCollateralFactorMantissa, uint newCollateralFactorMantissa); + event NewCollateralFactor(SLToken slToken, uint oldCollateralFactorMantissa, uint newCollateralFactorMantissa); /** * @notice Emitted when liquidation incentive is changed by admin @@ -106,8 +106,8 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle * @param account The address of the account to pull assets for * @return A dynamic list with the assets the account has entered */ - function getAssetsIn(address account) external view returns (CToken[] memory) { - CToken[] memory assetsIn = accountAssets[account]; + function getAssetsIn(address account) external view returns (SLToken[] memory) { + SLToken[] memory assetsIn = accountAssets[account]; return assetsIn; } @@ -115,25 +115,25 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle /** * @notice Returns whether the given account is entered in the given asset * @param account The address of the account to check - * @param cToken The cToken to check + * @param slToken The slToken to check * @return True if the account is in the asset, otherwise false. */ - function checkMembership(address account, CToken cToken) external view returns (bool) { - return markets[address(cToken)].accountMembership[account]; + function checkMembership(address account, SLToken slToken) external view returns (bool) { + return markets[address(slToken)].accountMembership[account]; } /** * @notice Add assets to be included in account liquidity calculation - * @param cTokens The list of addresses of the cToken markets to be enabled + * @param slTokens The list of addresses of the slToken markets to be enabled * @return Success indicator for whether each corresponding market was entered */ - function enterMarkets(address[] memory cTokens) public returns (uint[] memory) { - uint len = cTokens.length; + function enterMarkets(address[] memory slTokens) public returns (uint[] memory) { + uint len = slTokens.length; uint[] memory results = new uint[](len); for (uint i = 0; i < len; i++) { - CToken cToken = CToken(cTokens[i]); - Market storage marketToJoin = markets[address(cToken)]; + SLToken slToken = SLToken(slTokens[i]); + Market storage marketToJoin = markets[address(slToken)]; if (!marketToJoin.isListed) { // if market is not listed, cannot join move along @@ -159,9 +159,9 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle // that is, only when we need to perform liquidity checks // and not whenever we want to check if an account is in a particular market marketToJoin.accountMembership[msg.sender] = true; - accountAssets[msg.sender].push(cToken); + accountAssets[msg.sender].push(slToken); - emit MarketEntered(cToken, msg.sender); + emit MarketEntered(slToken, msg.sender); results[i] = uint(Error.NO_ERROR); } @@ -173,13 +173,13 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle * @notice Removes asset from sender's account liquidity calculation * @dev Sender must not have an outstanding borrow balance in the asset, * or be providing neccessary collateral for an outstanding borrow. - * @param cTokenAddress The address of the asset to be removed + * @param slTokenAddress The address of the asset to be removed * @return Whether or not the account successfully exited the market */ - function exitMarket(address cTokenAddress) external returns (uint) { - CToken cToken = CToken(cTokenAddress); - /* Get sender tokensHeld and amountOwed underlying from the cToken */ - (uint oErr, uint tokensHeld, uint amountOwed, ) = cToken.getAccountSnapshot(msg.sender); + function exitMarket(address slTokenAddress) external returns (uint) { + SLToken slToken = SLToken(slTokenAddress); + /* Get sender tokensHeld and amountOwed underlying from the slToken */ + (uint oErr, uint tokensHeld, uint amountOwed, ) = slToken.getAccountSnapshot(msg.sender); require(oErr == 0, "exitMarket: getAccountSnapshot failed"); // semi-opaque error code /* Fail if the sender has a borrow balance */ @@ -188,28 +188,28 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle } /* Fail if the sender is not permitted to redeem all of their tokens */ - uint allowed = redeemAllowedInternal(cTokenAddress, msg.sender, tokensHeld); + uint allowed = redeemAllowedInternal(slTokenAddress, msg.sender, tokensHeld); if (allowed != 0) { return failOpaque(Error.REJECTION, FailureInfo.EXIT_MARKET_REJECTION, allowed); } - Market storage marketToExit = markets[address(cToken)]; + Market storage marketToExit = markets[address(slToken)]; /* Return true if the sender is not already ‘in’ the market */ if (!marketToExit.accountMembership[msg.sender]) { return uint(Error.NO_ERROR); } - /* Set cToken account membership to false */ + /* Set slToken account membership to false */ delete marketToExit.accountMembership[msg.sender]; - /* Delete cToken from the account’s list of assets */ + /* Delete slToken from the account’s list of assets */ // load into memory for faster iteration - CToken[] memory userAssetList = accountAssets[msg.sender]; + SLToken[] memory userAssetList = accountAssets[msg.sender]; uint len = userAssetList.length; uint assetIndex = len; for (uint i = 0; i < len; i++) { - if (userAssetList[i] == cToken) { + if (userAssetList[i] == slToken) { assetIndex = i; break; } @@ -219,11 +219,11 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle assert(assetIndex < len); // copy last item in list to location of item to be removed, reduce length by 1 - CToken[] storage storedList = accountAssets[msg.sender]; + SLToken[] storage storedList = accountAssets[msg.sender]; storedList[assetIndex] = storedList[storedList.length - 1]; storedList.length--; - emit MarketExited(cToken, msg.sender); + emit MarketExited(slToken, msg.sender); return uint(Error.NO_ERROR); } @@ -232,16 +232,16 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the account should be allowed to mint tokens in the given market - * @param cToken The market to verify the mint against + * @param slToken The market to verify the mint against * @param minter The account which would get the minted tokens * @param mintAmount The amount of underlying being supplied to the market in exchange for tokens * @return 0 if the mint is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) */ - function mintAllowed(address cToken, address minter, uint mintAmount) external returns (uint) { + function mintAllowed(address slToken, address minter, uint mintAmount) external returns (uint) { minter; // currently unused mintAmount; // currently unused - if (!markets[cToken].isListed) { + if (!markets[slToken].isListed) { return uint(Error.MARKET_NOT_LISTED); } @@ -252,13 +252,13 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle /** * @notice Validates mint and reverts on rejection. May emit logs. - * @param cToken Asset being minted + * @param slToken Asset being minted * @param minter The address minting the tokens * @param mintAmount The amount of the underlying asset being minted * @param mintTokens The number of tokens being minted */ - function mintVerify(address cToken, address minter, uint mintAmount, uint mintTokens) external { - cToken; // currently unused + function mintVerify(address slToken, address minter, uint mintAmount, uint mintTokens) external { + slToken; // currently unused minter; // currently unused mintAmount; // currently unused mintTokens; // currently unused @@ -270,29 +270,29 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the account should be allowed to redeem tokens in the given market - * @param cToken The market to verify the redeem against + * @param slToken The market to verify the redeem against * @param redeemer The account which would redeem the tokens - * @param redeemTokens The number of cTokens to exchange for the underlying asset in the market + * @param redeemTokens The number of slTokens to exchange for the underlying asset in the market * @return 0 if the redeem is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) */ - function redeemAllowed(address cToken, address redeemer, uint redeemTokens) external returns (uint) { - return redeemAllowedInternal(cToken, redeemer, redeemTokens); + function redeemAllowed(address slToken, address redeemer, uint redeemTokens) external returns (uint) { + return redeemAllowedInternal(slToken, redeemer, redeemTokens); } - function redeemAllowedInternal(address cToken, address redeemer, uint redeemTokens) internal view returns (uint) { - if (!markets[cToken].isListed) { + function redeemAllowedInternal(address slToken, address redeemer, uint redeemTokens) internal view returns (uint) { + if (!markets[slToken].isListed) { return uint(Error.MARKET_NOT_LISTED); } // *may include Policy Hook-type checks /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */ - if (!markets[cToken].accountMembership[redeemer]) { + if (!markets[slToken].accountMembership[redeemer]) { return uint(Error.NO_ERROR); } /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */ - (Error err, , uint shortfall) = getHypotheticalAccountLiquidityInternal(redeemer, CToken(cToken), redeemTokens, 0); + (Error err, , uint shortfall) = getHypotheticalAccountLiquidityInternal(redeemer, SLToken(slToken), redeemTokens, 0); if (err != Error.NO_ERROR) { return uint(err); } @@ -305,13 +305,13 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle /** * @notice Validates redeem and reverts on rejection. May emit logs. - * @param cToken Asset being redeemed + * @param slToken Asset being redeemed * @param redeemer The address redeeming the tokens * @param redeemAmount The amount of the underlying asset being redeemed * @param redeemTokens The number of tokens being redeemed */ - function redeemVerify(address cToken, address redeemer, uint redeemAmount, uint redeemTokens) external { - cToken; // currently unused + function redeemVerify(address slToken, address redeemer, uint redeemAmount, uint redeemTokens) external { + slToken; // currently unused redeemer; // currently unused redeemAmount; // currently unused redeemTokens; // currently unused @@ -324,27 +324,27 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the account should be allowed to borrow the underlying asset of the given market - * @param cToken The market to verify the borrow against + * @param slToken The market to verify the borrow against * @param borrower The account which would borrow the asset * @param borrowAmount The amount of underlying the account would borrow * @return 0 if the borrow is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) */ - function borrowAllowed(address cToken, address borrower, uint borrowAmount) external returns (uint) { - if (!markets[cToken].isListed) { + function borrowAllowed(address slToken, address borrower, uint borrowAmount) external returns (uint) { + if (!markets[slToken].isListed) { return uint(Error.MARKET_NOT_LISTED); } // *may include Policy Hook-type checks - if (!markets[cToken].accountMembership[borrower]) { + if (!markets[slToken].accountMembership[borrower]) { return uint(Error.MARKET_NOT_ENTERED); } - if (oracle.getUnderlyingPrice(CToken(cToken)) == 0) { + if (oracle.getUnderlyingPrice(SLToken(slToken)) == 0) { return uint(Error.PRICE_ERROR); } - (Error err, , uint shortfall) = getHypotheticalAccountLiquidityInternal(borrower, CToken(cToken), 0, borrowAmount); + (Error err, , uint shortfall) = getHypotheticalAccountLiquidityInternal(borrower, SLToken(slToken), 0, borrowAmount); if (err != Error.NO_ERROR) { return uint(err); } @@ -357,12 +357,12 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle /** * @notice Validates borrow and reverts on rejection. May emit logs. - * @param cToken Asset whose underlying is being borrowed + * @param slToken Asset whose underlying is being borrowed * @param borrower The address borrowing the underlying * @param borrowAmount The amount of the underlying asset requested to borrow */ - function borrowVerify(address cToken, address borrower, uint borrowAmount) external { - cToken; // currently unused + function borrowVerify(address slToken, address borrower, uint borrowAmount) external { + slToken; // currently unused borrower; // currently unused borrowAmount; // currently unused @@ -373,14 +373,14 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the account should be allowed to repay a borrow in the given market - * @param cToken The market to verify the repay against + * @param slToken The market to verify the repay against * @param payer The account which would repay the asset * @param borrower The account which would borrowed the asset * @param repayAmount The amount of the underlying asset the account would repay * @return 0 if the repay is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) */ function repayBorrowAllowed( - address cToken, + address slToken, address payer, address borrower, uint repayAmount) external returns (uint) { @@ -388,7 +388,7 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle borrower; // currently unused repayAmount; // currently unused - if (!markets[cToken].isListed) { + if (!markets[slToken].isListed) { return uint(Error.MARKET_NOT_LISTED); } @@ -399,18 +399,18 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle /** * @notice Validates repayBorrow and reverts on rejection. May emit logs. - * @param cToken Asset being repaid + * @param slToken Asset being repaid * @param payer The address repaying the borrow * @param borrower The address of the borrower * @param repayAmount The amount of underlying being repaid */ function repayBorrowVerify( - address cToken, + address slToken, address payer, address borrower, uint repayAmount, uint borrowerIndex) external { - cToken; // currently unused + slToken; // currently unused payer; // currently unused borrower; // currently unused repayAmount; // currently unused @@ -423,15 +423,15 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the liquidation should be allowed to occur - * @param cTokenBorrowed Asset which was borrowed by the borrower - * @param cTokenCollateral Asset which was used as collateral and will be seized + * @param slTokenBorrowed Asset which was borrowed by the borrower + * @param slTokenCollateral Asset which was used as collateral and will be seized * @param liquidator The address repaying the borrow and seizing the collateral * @param borrower The address of the borrower * @param repayAmount The amount of underlying being repaid */ function liquidateBorrowAllowed( - address cTokenBorrowed, - address cTokenCollateral, + address slTokenBorrowed, + address slTokenCollateral, address liquidator, address borrower, uint repayAmount) external returns (uint) { @@ -439,7 +439,7 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle borrower; // currently unused repayAmount; // currently unused - if (!markets[cTokenBorrowed].isListed || !markets[cTokenCollateral].isListed) { + if (!markets[slTokenBorrowed].isListed || !markets[slTokenCollateral].isListed) { return uint(Error.MARKET_NOT_LISTED); } @@ -455,7 +455,7 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle } /* The liquidator may not repay more than what is allowed by the closeFactor */ - uint borrowBalance = CToken(cTokenBorrowed).borrowBalanceStored(borrower); + uint borrowBalance = SLToken(slTokenBorrowed).borrowBalanceStored(borrower); (MathError mathErr, uint maxClose) = mulScalarTruncate(Exp({mantissa: closeFactorMantissa}), borrowBalance); if (mathErr != MathError.NO_ERROR) { return uint(Error.MATH_ERROR); @@ -469,21 +469,21 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle /** * @notice Validates liquidateBorrow and reverts on rejection. May emit logs. - * @param cTokenBorrowed Asset which was borrowed by the borrower - * @param cTokenCollateral Asset which was used as collateral and will be seized + * @param slTokenBorrowed Asset which was borrowed by the borrower + * @param slTokenCollateral Asset which was used as collateral and will be seized * @param liquidator The address repaying the borrow and seizing the collateral * @param borrower The address of the borrower * @param repayAmount The amount of underlying being repaid */ function liquidateBorrowVerify( - address cTokenBorrowed, - address cTokenCollateral, + address slTokenBorrowed, + address slTokenCollateral, address liquidator, address borrower, uint repayAmount, uint seizeTokens) external { - cTokenBorrowed; // currently unused - cTokenCollateral; // currently unused + slTokenBorrowed; // currently unused + slTokenCollateral; // currently unused liquidator; // currently unused borrower; // currently unused repayAmount; // currently unused @@ -496,15 +496,15 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the seizing of assets should be allowed to occur - * @param cTokenCollateral Asset which was used as collateral and will be seized - * @param cTokenBorrowed Asset which was borrowed by the borrower + * @param slTokenCollateral Asset which was used as collateral and will be seized + * @param slTokenBorrowed Asset which was borrowed by the borrower * @param liquidator The address repaying the borrow and seizing the collateral * @param borrower The address of the borrower * @param seizeTokens The number of collateral tokens to seize */ function seizeAllowed( - address cTokenCollateral, - address cTokenBorrowed, + address slTokenCollateral, + address slTokenBorrowed, address liquidator, address borrower, uint seizeTokens) external returns (uint) { @@ -512,11 +512,11 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle borrower; // currently unused seizeTokens; // currently unused - if (!markets[cTokenCollateral].isListed || !markets[cTokenBorrowed].isListed) { + if (!markets[slTokenCollateral].isListed || !markets[slTokenBorrowed].isListed) { return uint(Error.MARKET_NOT_LISTED); } - if (CToken(cTokenCollateral).comptroller() != CToken(cTokenBorrowed).comptroller()) { + if (SLToken(slTokenCollateral).comptroller() != SLToken(slTokenBorrowed).comptroller()) { return uint(Error.COMPTROLLER_MISMATCH); } @@ -527,20 +527,20 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle /** * @notice Validates seize and reverts on rejection. May emit logs. - * @param cTokenCollateral Asset which was used as collateral and will be seized - * @param cTokenBorrowed Asset which was borrowed by the borrower + * @param slTokenCollateral Asset which was used as collateral and will be seized + * @param slTokenBorrowed Asset which was borrowed by the borrower * @param liquidator The address repaying the borrow and seizing the collateral * @param borrower The address of the borrower * @param seizeTokens The number of collateral tokens to seize */ function seizeVerify( - address cTokenCollateral, - address cTokenBorrowed, + address slTokenCollateral, + address slTokenBorrowed, address liquidator, address borrower, uint seizeTokens) external { - cTokenCollateral; // currently unused - cTokenBorrowed; // currently unused + slTokenCollateral; // currently unused + slTokenBorrowed; // currently unused liquidator; // currently unused borrower; // currently unused seizeTokens; // currently unused @@ -552,14 +552,14 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the account should be allowed to transfer tokens in the given market - * @param cToken The market to verify the transfer against + * @param slToken The market to verify the transfer against * @param src The account which sources the tokens * @param dst The account which receives the tokens - * @param transferTokens The number of cTokens to transfer + * @param transferTokens The number of slTokens to transfer * @return 0 if the transfer is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) */ - function transferAllowed(address cToken, address src, address dst, uint transferTokens) external returns (uint) { - cToken; // currently unused + function transferAllowed(address slToken, address src, address dst, uint transferTokens) external returns (uint) { + slToken; // currently unused src; // currently unused dst; // currently unused transferTokens; // currently unused @@ -568,18 +568,18 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle // Currently the only consideration is whether or not // the src is allowed to redeem this many tokens - return redeemAllowedInternal(cToken, src, transferTokens); + return redeemAllowedInternal(slToken, src, transferTokens); } /** * @notice Validates transfer and reverts on rejection. May emit logs. - * @param cToken Asset being transferred + * @param slToken Asset being transferred * @param src The account which sources the tokens * @param dst The account which receives the tokens - * @param transferTokens The number of cTokens to transfer + * @param transferTokens The number of slTokens to transfer */ - function transferVerify(address cToken, address src, address dst, uint transferTokens) external { - cToken; // currently unused + function transferVerify(address slToken, address src, address dst, uint transferTokens) external { + slToken; // currently unused src; // currently unused dst; // currently unused transferTokens; // currently unused @@ -593,13 +593,13 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle /** * @dev Local vars for avoiding stack-depth limits in calculating account liquidity. - * Note that `cTokenBalance` is the number of cTokens the account owns in the market, + * Note that `slTokenBalance` is the number of slTokens the account owns in the market, * whereas `borrowBalance` is the amount of underlying that the account has borrowed. */ struct AccountLiquidityLocalVars { uint sumCollateral; uint sumBorrowPlusEffects; - uint cTokenBalance; + uint slTokenBalance; uint borrowBalance; uint exchangeRateMantissa; uint oraclePriceMantissa; @@ -616,7 +616,7 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle * account shortfall below collateral requirements) */ function getAccountLiquidity(address account) public view returns (uint, uint, uint) { - (Error err, uint liquidity, uint shortfall) = getHypotheticalAccountLiquidityInternal(account, CToken(0), 0, 0); + (Error err, uint liquidity, uint shortfall) = getHypotheticalAccountLiquidityInternal(account, SLToken(0), 0, 0); return (uint(err), liquidity, shortfall); } @@ -628,16 +628,16 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle * account shortfall below collateral requirements) */ function getAccountLiquidityInternal(address account) internal view returns (Error, uint, uint) { - return getHypotheticalAccountLiquidityInternal(account, CToken(0), 0, 0); + return getHypotheticalAccountLiquidityInternal(account, SLToken(0), 0, 0); } /** * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed - * @param cTokenModify The market to hypothetically redeem/borrow in + * @param slTokenModify The market to hypothetically redeem/borrow in * @param account The account to determine liquidity for * @param redeemTokens The number of tokens to hypothetically redeem * @param borrowAmount The amount of underlying to hypothetically borrow - * @dev Note that we calculate the exchangeRateStored for each collateral cToken using stored data, + * @dev Note that we calculate the exchangeRateStored for each collateral slToken using stored data, * without calculating accumulated interest. * @return (possible error code, hypothetical account liquidity in excess of collateral requirements, @@ -645,7 +645,7 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle */ function getHypotheticalAccountLiquidityInternal( address account, - CToken cTokenModify, + SLToken slTokenModify, uint redeemTokens, uint borrowAmount) internal view returns (Error, uint, uint) { @@ -654,12 +654,12 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle MathError mErr; // For each asset the account is in - CToken[] memory assets = accountAssets[account]; + SLToken[] memory assets = accountAssets[account]; for (uint i = 0; i < assets.length; i++) { - CToken asset = assets[i]; + SLToken asset = assets[i]; - // Read the balances and exchange rate from the cToken - (oErr, vars.cTokenBalance, vars.borrowBalance, vars.exchangeRateMantissa) = asset.getAccountSnapshot(account); + // Read the balances and exchange rate from the slToken + (oErr, vars.slTokenBalance, vars.borrowBalance, vars.exchangeRateMantissa) = asset.getAccountSnapshot(account); if (oErr != 0) { // semi-opaque error code, we assume NO_ERROR == 0 is invariant between upgrades return (Error.SNAPSHOT_ERROR, 0, 0); } @@ -679,8 +679,8 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle return (Error.MATH_ERROR, 0, 0); } - // sumCollateral += tokensToEther * cTokenBalance - (mErr, vars.sumCollateral) = mulScalarTruncateAddUInt(vars.tokensToEther, vars.cTokenBalance, vars.sumCollateral); + // sumCollateral += tokensToEther * slTokenBalance + (mErr, vars.sumCollateral) = mulScalarTruncateAddUInt(vars.tokensToEther, vars.slTokenBalance, vars.sumCollateral); if (mErr != MathError.NO_ERROR) { return (Error.MATH_ERROR, 0, 0); } @@ -691,8 +691,8 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle return (Error.MATH_ERROR, 0, 0); } - // Calculate effects of interacting with cTokenModify - if (asset == cTokenModify) { + // Calculate effects of interacting with slTokenModify + if (asset == slTokenModify) { // redeem effect // sumBorrowPlusEffects += tokensToEther * redeemTokens (mErr, vars.sumBorrowPlusEffects) = mulScalarTruncateAddUInt(vars.tokensToEther, redeemTokens, vars.sumBorrowPlusEffects); @@ -719,16 +719,16 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle /** * @notice Calculate number of tokens of collateral asset to seize given an underlying amount - * @dev Used in liquidation (called in cToken.liquidateBorrowFresh) - * @param cTokenBorrowed The address of the borrowed cToken - * @param cTokenCollateral The address of the collateral cToken - * @param repayAmount The amount of cTokenBorrowed underlying to convert into cTokenCollateral tokens - * @return (errorCode, number of cTokenCollateral tokens to be seized in a liquidation) + * @dev Used in liquidation (called in slToken.liquidateBorrowFresh) + * @param slTokenBorrowed The address of the borrowed slToken + * @param slTokenCollateral The address of the collateral slToken + * @param repayAmount The amount of slTokenBorrowed underlying to convert into slTokenCollateral tokens + * @return (errorCode, number of slTokenCollateral tokens to be seized in a liquidation) */ - function liquidateCalculateSeizeTokens(address cTokenBorrowed, address cTokenCollateral, uint repayAmount) external view returns (uint, uint) { + function liquidateCalculateSeizeTokens(address slTokenBorrowed, address slTokenCollateral, uint repayAmount) external view returns (uint, uint) { /* Read oracle prices for borrowed and collateral markets */ - uint priceBorrowedMantissa = oracle.getUnderlyingPrice(CToken(cTokenBorrowed)); - uint priceCollateralMantissa = oracle.getUnderlyingPrice(CToken(cTokenCollateral)); + uint priceBorrowedMantissa = oracle.getUnderlyingPrice(SLToken(slTokenBorrowed)); + uint priceCollateralMantissa = oracle.getUnderlyingPrice(SLToken(slTokenCollateral)); if (priceBorrowedMantissa == 0 || priceCollateralMantissa == 0) { return (uint(Error.PRICE_ERROR), 0); } @@ -739,7 +739,7 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle * seizeTokens = seizeAmount / exchangeRate * = repayAmount * (liquidationIncentive * priceBorrowed) / (priceCollateral * exchangeRate) */ - uint exchangeRateMantissa = CToken(cTokenCollateral).exchangeRateStored(); // Note: reverts on error + uint exchangeRateMantissa = SLToken(slTokenCollateral).exchangeRateStored(); // Note: reverts on error uint seizeTokens; Exp memory numerator; Exp memory denominator; @@ -830,18 +830,18 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle /** * @notice Sets the collateralFactor for a market * @dev Admin function to set per-market collateralFactor - * @param cToken The market to set the factor on + * @param slToken The market to set the factor on * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18 * @return uint 0=success, otherwise a failure. (See ErrorReporter for details) */ - function _setCollateralFactor(CToken cToken, uint newCollateralFactorMantissa) external returns (uint256) { + function _setCollateralFactor(SLToken slToken, uint newCollateralFactorMantissa) external returns (uint256) { // Check caller is admin if (msg.sender != admin) { return fail(Error.UNAUTHORIZED, FailureInfo.SET_COLLATERAL_FACTOR_OWNER_CHECK); } // Verify market is listed - Market storage market = markets[address(cToken)]; + Market storage market = markets[address(slToken)]; if (!market.isListed) { return fail(Error.MARKET_NOT_LISTED, FailureInfo.SET_COLLATERAL_FACTOR_NO_EXISTS); } @@ -855,7 +855,7 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle } // If collateral factor != 0, fail if price == 0 - if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(cToken) == 0) { + if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(slToken) == 0) { return fail(Error.PRICE_ERROR, FailureInfo.SET_COLLATERAL_FACTOR_WITHOUT_PRICE); } @@ -864,7 +864,7 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle market.collateralFactorMantissa = newCollateralFactorMantissa; // Emit event with asset, old collateral factor, and new collateral factor - emit NewCollateralFactor(cToken, oldCollateralFactorMantissa, newCollateralFactorMantissa); + emit NewCollateralFactor(slToken, oldCollateralFactorMantissa, newCollateralFactorMantissa); return uint(Error.NO_ERROR); } @@ -927,22 +927,22 @@ contract ComptrollerG1 is ComptrollerV1Storage, ComptrollerInterface, Comptrolle /** * @notice Add the market to the markets mapping and set it as listed * @dev Admin function to set isListed and add support for the market - * @param cToken The address of the market (token) to list + * @param slToken The address of the market (token) to list * @return uint 0=success, otherwise a failure. (See enum Error for details) */ - function _supportMarket(CToken cToken) external returns (uint) { + function _supportMarket(SLToken slToken) external returns (uint) { if (msg.sender != admin) { return fail(Error.UNAUTHORIZED, FailureInfo.SUPPORT_MARKET_OWNER_CHECK); } - if (markets[address(cToken)].isListed) { + if (markets[address(slToken)].isListed) { return fail(Error.MARKET_ALREADY_LISTED, FailureInfo.SUPPORT_MARKET_EXISTS); } - cToken.isCToken(); // Sanity check to make sure its really a CToken + slToken.isSLToken(); // Sanity check to make sure its really a SLToken - markets[address(cToken)] = Market({isListed: true, collateralFactorMantissa: 0}); - emit MarketListed(cToken); + markets[address(slToken)] = Market({isListed: true, collateralFactorMantissa: 0}); + emit MarketListed(slToken); return uint(Error.NO_ERROR); } diff --git a/contracts/ComptrollerG2.sol b/contracts/ComptrollerG2.sol index d7aa0cbc4..46678b634 100644 --- a/contracts/ComptrollerG2.sol +++ b/contracts/ComptrollerG2.sol @@ -1,6 +1,6 @@ pragma solidity ^0.5.16; -import "./CToken.sol"; +import "./SLToken.sol"; import "./ErrorReporter.sol"; import "./Exponential.sol"; import "./PriceOracle.sol"; @@ -9,24 +9,24 @@ import "./ComptrollerStorage.sol"; import "./Unitroller.sol"; /** - * @title Compound's Comptroller Contract - * @author Compound + * @title SashimiLending's Comptroller Contract + * @author SashimiLending */ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, ComptrollerErrorReporter, Exponential { /** * @notice Emitted when an admin supports a market */ - event MarketListed(CToken cToken); + event MarketListed(SLToken slToken); /** * @notice Emitted when an account enters a market */ - event MarketEntered(CToken cToken, address account); + event MarketEntered(SLToken slToken, address account); /** * @notice Emitted when an account exits a market */ - event MarketExited(CToken cToken, address account); + event MarketExited(SLToken slToken, address account); /** * @notice Emitted when close factor is changed by admin @@ -36,7 +36,7 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle /** * @notice Emitted when a collateral factor is changed by admin */ - event NewCollateralFactor(CToken cToken, uint oldCollateralFactorMantissa, uint newCollateralFactorMantissa); + event NewCollateralFactor(SLToken slToken, uint oldCollateralFactorMantissa, uint newCollateralFactorMantissa); /** * @notice Emitted when liquidation incentive is changed by admin @@ -66,7 +66,7 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle /** * @notice Emitted when an action is paused on a market */ - event ActionPaused(CToken cToken, string action, bool pauseState); + event ActionPaused(SLToken slToken, string action, bool pauseState); // closeFactorMantissa must be strictly greater than this value uint internal constant closeFactorMinMantissa = 0.05e18; // 0.05 @@ -94,8 +94,8 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle * @param account The address of the account to pull assets for * @return A dynamic list with the assets the account has entered */ - function getAssetsIn(address account) external view returns (CToken[] memory) { - CToken[] memory assetsIn = accountAssets[account]; + function getAssetsIn(address account) external view returns (SLToken[] memory) { + SLToken[] memory assetsIn = accountAssets[account]; return assetsIn; } @@ -103,26 +103,26 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle /** * @notice Returns whether the given account is entered in the given asset * @param account The address of the account to check - * @param cToken The cToken to check + * @param slToken The slToken to check * @return True if the account is in the asset, otherwise false. */ - function checkMembership(address account, CToken cToken) external view returns (bool) { - return markets[address(cToken)].accountMembership[account]; + function checkMembership(address account, SLToken slToken) external view returns (bool) { + return markets[address(slToken)].accountMembership[account]; } /** * @notice Add assets to be included in account liquidity calculation - * @param cTokens The list of addresses of the cToken markets to be enabled + * @param slTokens The list of addresses of the slToken markets to be enabled * @return Success indicator for whether each corresponding market was entered */ - function enterMarkets(address[] memory cTokens) public returns (uint[] memory) { - uint len = cTokens.length; + function enterMarkets(address[] memory slTokens) public returns (uint[] memory) { + uint len = slTokens.length; uint[] memory results = new uint[](len); for (uint i = 0; i < len; i++) { - CToken cToken = CToken(cTokens[i]); + SLToken slToken = SLToken(slTokens[i]); - results[i] = uint(addToMarketInternal(cToken, msg.sender)); + results[i] = uint(addToMarketInternal(slToken, msg.sender)); } return results; @@ -130,12 +130,12 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle /** * @notice Add the market to the borrower's "assets in" for liquidity calculations - * @param cToken The market to enter + * @param slToken The market to enter * @param borrower The address of the account to modify * @return Success indicator for whether the market was entered */ - function addToMarketInternal(CToken cToken, address borrower) internal returns (Error) { - Market storage marketToJoin = markets[address(cToken)]; + function addToMarketInternal(SLToken slToken, address borrower) internal returns (Error) { + Market storage marketToJoin = markets[address(slToken)]; if (!marketToJoin.isListed) { // market is not listed, cannot join @@ -158,9 +158,9 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle // that is, only when we need to perform liquidity checks // and not whenever we want to check if an account is in a particular market marketToJoin.accountMembership[borrower] = true; - accountAssets[borrower].push(cToken); + accountAssets[borrower].push(slToken); - emit MarketEntered(cToken, borrower); + emit MarketEntered(slToken, borrower); return Error.NO_ERROR; } @@ -169,13 +169,13 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle * @notice Removes asset from sender's account liquidity calculation * @dev Sender must not have an outstanding borrow balance in the asset, * or be providing neccessary collateral for an outstanding borrow. - * @param cTokenAddress The address of the asset to be removed + * @param slTokenAddress The address of the asset to be removed * @return Whether or not the account successfully exited the market */ - function exitMarket(address cTokenAddress) external returns (uint) { - CToken cToken = CToken(cTokenAddress); - /* Get sender tokensHeld and amountOwed underlying from the cToken */ - (uint oErr, uint tokensHeld, uint amountOwed, ) = cToken.getAccountSnapshot(msg.sender); + function exitMarket(address slTokenAddress) external returns (uint) { + SLToken slToken = SLToken(slTokenAddress); + /* Get sender tokensHeld and amountOwed underlying from the slToken */ + (uint oErr, uint tokensHeld, uint amountOwed, ) = slToken.getAccountSnapshot(msg.sender); require(oErr == 0, "exitMarket: getAccountSnapshot failed"); // semi-opaque error code /* Fail if the sender has a borrow balance */ @@ -184,28 +184,28 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle } /* Fail if the sender is not permitted to redeem all of their tokens */ - uint allowed = redeemAllowedInternal(cTokenAddress, msg.sender, tokensHeld); + uint allowed = redeemAllowedInternal(slTokenAddress, msg.sender, tokensHeld); if (allowed != 0) { return failOpaque(Error.REJECTION, FailureInfo.EXIT_MARKET_REJECTION, allowed); } - Market storage marketToExit = markets[address(cToken)]; + Market storage marketToExit = markets[address(slToken)]; /* Return true if the sender is not already ‘in’ the market */ if (!marketToExit.accountMembership[msg.sender]) { return uint(Error.NO_ERROR); } - /* Set cToken account membership to false */ + /* Set slToken account membership to false */ delete marketToExit.accountMembership[msg.sender]; - /* Delete cToken from the account’s list of assets */ + /* Delete slToken from the account’s list of assets */ // load into memory for faster iteration - CToken[] memory userAssetList = accountAssets[msg.sender]; + SLToken[] memory userAssetList = accountAssets[msg.sender]; uint len = userAssetList.length; uint assetIndex = len; for (uint i = 0; i < len; i++) { - if (userAssetList[i] == cToken) { + if (userAssetList[i] == slToken) { assetIndex = i; break; } @@ -215,11 +215,11 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle assert(assetIndex < len); // copy last item in list to location of item to be removed, reduce length by 1 - CToken[] storage storedList = accountAssets[msg.sender]; + SLToken[] storage storedList = accountAssets[msg.sender]; storedList[assetIndex] = storedList[storedList.length - 1]; storedList.length--; - emit MarketExited(cToken, msg.sender); + emit MarketExited(slToken, msg.sender); return uint(Error.NO_ERROR); } @@ -228,20 +228,20 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the account should be allowed to mint tokens in the given market - * @param cToken The market to verify the mint against + * @param slToken The market to verify the mint against * @param minter The account which would get the minted tokens * @param mintAmount The amount of underlying being supplied to the market in exchange for tokens * @return 0 if the mint is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) */ - function mintAllowed(address cToken, address minter, uint mintAmount) external returns (uint) { + function mintAllowed(address slToken, address minter, uint mintAmount) external returns (uint) { // Pausing is a very serious situation - we revert to sound the alarms - require(!mintGuardianPaused[cToken], "mint is paused"); + require(!mintGuardianPaused[slToken], "mint is paused"); // Shh - currently unused minter; mintAmount; - if (!markets[cToken].isListed) { + if (!markets[slToken].isListed) { return uint(Error.MARKET_NOT_LISTED); } @@ -252,14 +252,14 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle /** * @notice Validates mint and reverts on rejection. May emit logs. - * @param cToken Asset being minted + * @param slToken Asset being minted * @param minter The address minting the tokens * @param actualMintAmount The amount of the underlying asset being minted * @param mintTokens The number of tokens being minted */ - function mintVerify(address cToken, address minter, uint actualMintAmount, uint mintTokens) external { + function mintVerify(address slToken, address minter, uint actualMintAmount, uint mintTokens) external { // Shh - currently unused - cToken; + slToken; minter; actualMintAmount; mintTokens; @@ -272,29 +272,29 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the account should be allowed to redeem tokens in the given market - * @param cToken The market to verify the redeem against + * @param slToken The market to verify the redeem against * @param redeemer The account which would redeem the tokens - * @param redeemTokens The number of cTokens to exchange for the underlying asset in the market + * @param redeemTokens The number of slTokens to exchange for the underlying asset in the market * @return 0 if the redeem is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) */ - function redeemAllowed(address cToken, address redeemer, uint redeemTokens) external returns (uint) { - return redeemAllowedInternal(cToken, redeemer, redeemTokens); + function redeemAllowed(address slToken, address redeemer, uint redeemTokens) external returns (uint) { + return redeemAllowedInternal(slToken, redeemer, redeemTokens); } - function redeemAllowedInternal(address cToken, address redeemer, uint redeemTokens) internal view returns (uint) { - if (!markets[cToken].isListed) { + function redeemAllowedInternal(address slToken, address redeemer, uint redeemTokens) internal view returns (uint) { + if (!markets[slToken].isListed) { return uint(Error.MARKET_NOT_LISTED); } // *may include Policy Hook-type checks /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */ - if (!markets[cToken].accountMembership[redeemer]) { + if (!markets[slToken].accountMembership[redeemer]) { return uint(Error.NO_ERROR); } /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */ - (Error err, , uint shortfall) = getHypotheticalAccountLiquidityInternal(redeemer, CToken(cToken), redeemTokens, 0); + (Error err, , uint shortfall) = getHypotheticalAccountLiquidityInternal(redeemer, SLToken(slToken), redeemTokens, 0); if (err != Error.NO_ERROR) { return uint(err); } @@ -307,14 +307,14 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle /** * @notice Validates redeem and reverts on rejection. May emit logs. - * @param cToken Asset being redeemed + * @param slToken Asset being redeemed * @param redeemer The address redeeming the tokens * @param redeemAmount The amount of the underlying asset being redeemed * @param redeemTokens The number of tokens being redeemed */ - function redeemVerify(address cToken, address redeemer, uint redeemAmount, uint redeemTokens) external { + function redeemVerify(address slToken, address redeemer, uint redeemAmount, uint redeemTokens) external { // Shh - currently unused - cToken; + slToken; redeemer; // Require tokens is zero or amount is also zero @@ -325,40 +325,40 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the account should be allowed to borrow the underlying asset of the given market - * @param cToken The market to verify the borrow against + * @param slToken The market to verify the borrow against * @param borrower The account which would borrow the asset * @param borrowAmount The amount of underlying the account would borrow * @return 0 if the borrow is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) */ - function borrowAllowed(address cToken, address borrower, uint borrowAmount) external returns (uint) { + function borrowAllowed(address slToken, address borrower, uint borrowAmount) external returns (uint) { // Pausing is a very serious situation - we revert to sound the alarms - require(!borrowGuardianPaused[cToken], "borrow is paused"); + require(!borrowGuardianPaused[slToken], "borrow is paused"); - if (!markets[cToken].isListed) { + if (!markets[slToken].isListed) { return uint(Error.MARKET_NOT_LISTED); } // *may include Policy Hook-type checks - if (!markets[cToken].accountMembership[borrower]) { - // only cTokens may call borrowAllowed if borrower not in market - require(msg.sender == cToken, "sender must be cToken"); + if (!markets[slToken].accountMembership[borrower]) { + // only slTokens may call borrowAllowed if borrower not in market + require(msg.sender == slToken, "sender must be slToken"); // attempt to add borrower to the market - Error err = addToMarketInternal(CToken(msg.sender), borrower); + Error err = addToMarketInternal(SLToken(msg.sender), borrower); if (err != Error.NO_ERROR) { return uint(err); } // it should be impossible to break the important invariant - assert(markets[cToken].accountMembership[borrower]); + assert(markets[slToken].accountMembership[borrower]); } - if (oracle.getUnderlyingPrice(CToken(cToken)) == 0) { + if (oracle.getUnderlyingPrice(SLToken(slToken)) == 0) { return uint(Error.PRICE_ERROR); } - (Error err, , uint shortfall) = getHypotheticalAccountLiquidityInternal(borrower, CToken(cToken), 0, borrowAmount); + (Error err, , uint shortfall) = getHypotheticalAccountLiquidityInternal(borrower, SLToken(slToken), 0, borrowAmount); if (err != Error.NO_ERROR) { return uint(err); } @@ -371,13 +371,13 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle /** * @notice Validates borrow and reverts on rejection. May emit logs. - * @param cToken Asset whose underlying is being borrowed + * @param slToken Asset whose underlying is being borrowed * @param borrower The address borrowing the underlying * @param borrowAmount The amount of the underlying asset requested to borrow */ - function borrowVerify(address cToken, address borrower, uint borrowAmount) external { + function borrowVerify(address slToken, address borrower, uint borrowAmount) external { // Shh - currently unused - cToken; + slToken; borrower; borrowAmount; @@ -389,14 +389,14 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the account should be allowed to repay a borrow in the given market - * @param cToken The market to verify the repay against + * @param slToken The market to verify the repay against * @param payer The account which would repay the asset * @param borrower The account which would borrowed the asset * @param repayAmount The amount of the underlying asset the account would repay * @return 0 if the repay is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) */ function repayBorrowAllowed( - address cToken, + address slToken, address payer, address borrower, uint repayAmount) external returns (uint) { @@ -405,7 +405,7 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle borrower; repayAmount; - if (!markets[cToken].isListed) { + if (!markets[slToken].isListed) { return uint(Error.MARKET_NOT_LISTED); } @@ -416,19 +416,19 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle /** * @notice Validates repayBorrow and reverts on rejection. May emit logs. - * @param cToken Asset being repaid + * @param slToken Asset being repaid * @param payer The address repaying the borrow * @param borrower The address of the borrower * @param actualRepayAmount The amount of underlying being repaid */ function repayBorrowVerify( - address cToken, + address slToken, address payer, address borrower, uint actualRepayAmount, uint borrowerIndex) external { // Shh - currently unused - cToken; + slToken; payer; borrower; actualRepayAmount; @@ -442,22 +442,22 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the liquidation should be allowed to occur - * @param cTokenBorrowed Asset which was borrowed by the borrower - * @param cTokenCollateral Asset which was used as collateral and will be seized + * @param slTokenBorrowed Asset which was borrowed by the borrower + * @param slTokenCollateral Asset which was used as collateral and will be seized * @param liquidator The address repaying the borrow and seizing the collateral * @param borrower The address of the borrower * @param repayAmount The amount of underlying being repaid */ function liquidateBorrowAllowed( - address cTokenBorrowed, - address cTokenCollateral, + address slTokenBorrowed, + address slTokenCollateral, address liquidator, address borrower, uint repayAmount) external returns (uint) { // Shh - currently unused liquidator; - if (!markets[cTokenBorrowed].isListed || !markets[cTokenCollateral].isListed) { + if (!markets[slTokenBorrowed].isListed || !markets[slTokenCollateral].isListed) { return uint(Error.MARKET_NOT_LISTED); } @@ -473,7 +473,7 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle } /* The liquidator may not repay more than what is allowed by the closeFactor */ - uint borrowBalance = CToken(cTokenBorrowed).borrowBalanceStored(borrower); + uint borrowBalance = SLToken(slTokenBorrowed).borrowBalanceStored(borrower); (MathError mathErr, uint maxClose) = mulScalarTruncate(Exp({mantissa: closeFactorMantissa}), borrowBalance); if (mathErr != MathError.NO_ERROR) { return uint(Error.MATH_ERROR); @@ -487,22 +487,22 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle /** * @notice Validates liquidateBorrow and reverts on rejection. May emit logs. - * @param cTokenBorrowed Asset which was borrowed by the borrower - * @param cTokenCollateral Asset which was used as collateral and will be seized + * @param slTokenBorrowed Asset which was borrowed by the borrower + * @param slTokenCollateral Asset which was used as collateral and will be seized * @param liquidator The address repaying the borrow and seizing the collateral * @param borrower The address of the borrower * @param actualRepayAmount The amount of underlying being repaid */ function liquidateBorrowVerify( - address cTokenBorrowed, - address cTokenCollateral, + address slTokenBorrowed, + address slTokenCollateral, address liquidator, address borrower, uint actualRepayAmount, uint seizeTokens) external { // Shh - currently unused - cTokenBorrowed; - cTokenCollateral; + slTokenBorrowed; + slTokenCollateral; liquidator; borrower; actualRepayAmount; @@ -516,15 +516,15 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the seizing of assets should be allowed to occur - * @param cTokenCollateral Asset which was used as collateral and will be seized - * @param cTokenBorrowed Asset which was borrowed by the borrower + * @param slTokenCollateral Asset which was used as collateral and will be seized + * @param slTokenBorrowed Asset which was borrowed by the borrower * @param liquidator The address repaying the borrow and seizing the collateral * @param borrower The address of the borrower * @param seizeTokens The number of collateral tokens to seize */ function seizeAllowed( - address cTokenCollateral, - address cTokenBorrowed, + address slTokenCollateral, + address slTokenBorrowed, address liquidator, address borrower, uint seizeTokens) external returns (uint) { @@ -536,11 +536,11 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle borrower; seizeTokens; - if (!markets[cTokenCollateral].isListed || !markets[cTokenBorrowed].isListed) { + if (!markets[slTokenCollateral].isListed || !markets[slTokenBorrowed].isListed) { return uint(Error.MARKET_NOT_LISTED); } - if (CToken(cTokenCollateral).comptroller() != CToken(cTokenBorrowed).comptroller()) { + if (SLToken(slTokenCollateral).comptroller() != SLToken(slTokenBorrowed).comptroller()) { return uint(Error.COMPTROLLER_MISMATCH); } @@ -551,21 +551,21 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle /** * @notice Validates seize and reverts on rejection. May emit logs. - * @param cTokenCollateral Asset which was used as collateral and will be seized - * @param cTokenBorrowed Asset which was borrowed by the borrower + * @param slTokenCollateral Asset which was used as collateral and will be seized + * @param slTokenBorrowed Asset which was borrowed by the borrower * @param liquidator The address repaying the borrow and seizing the collateral * @param borrower The address of the borrower * @param seizeTokens The number of collateral tokens to seize */ function seizeVerify( - address cTokenCollateral, - address cTokenBorrowed, + address slTokenCollateral, + address slTokenBorrowed, address liquidator, address borrower, uint seizeTokens) external { // Shh - currently unused - cTokenCollateral; - cTokenBorrowed; + slTokenCollateral; + slTokenBorrowed; liquidator; borrower; seizeTokens; @@ -578,13 +578,13 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the account should be allowed to transfer tokens in the given market - * @param cToken The market to verify the transfer against + * @param slToken The market to verify the transfer against * @param src The account which sources the tokens * @param dst The account which receives the tokens - * @param transferTokens The number of cTokens to transfer + * @param transferTokens The number of slTokens to transfer * @return 0 if the transfer is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) */ - function transferAllowed(address cToken, address src, address dst, uint transferTokens) external returns (uint) { + function transferAllowed(address slToken, address src, address dst, uint transferTokens) external returns (uint) { // Pausing is a very serious situation - we revert to sound the alarms require(!transferGuardianPaused, "transfer is paused"); @@ -595,19 +595,19 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle // Currently the only consideration is whether or not // the src is allowed to redeem this many tokens - return redeemAllowedInternal(cToken, src, transferTokens); + return redeemAllowedInternal(slToken, src, transferTokens); } /** * @notice Validates transfer and reverts on rejection. May emit logs. - * @param cToken Asset being transferred + * @param slToken Asset being transferred * @param src The account which sources the tokens * @param dst The account which receives the tokens - * @param transferTokens The number of cTokens to transfer + * @param transferTokens The number of slTokens to transfer */ - function transferVerify(address cToken, address src, address dst, uint transferTokens) external { + function transferVerify(address slToken, address src, address dst, uint transferTokens) external { // Shh - currently unused - cToken; + slToken; src; dst; transferTokens; @@ -622,13 +622,13 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle /** * @dev Local vars for avoiding stack-depth limits in calculating account liquidity. - * Note that `cTokenBalance` is the number of cTokens the account owns in the market, + * Note that `slTokenBalance` is the number of slTokens the account owns in the market, * whereas `borrowBalance` is the amount of underlying that the account has borrowed. */ struct AccountLiquidityLocalVars { uint sumCollateral; uint sumBorrowPlusEffects; - uint cTokenBalance; + uint slTokenBalance; uint borrowBalance; uint exchangeRateMantissa; uint oraclePriceMantissa; @@ -645,7 +645,7 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle * account shortfall below collateral requirements) */ function getAccountLiquidity(address account) public view returns (uint, uint, uint) { - (Error err, uint liquidity, uint shortfall) = getHypotheticalAccountLiquidityInternal(account, CToken(0), 0, 0); + (Error err, uint liquidity, uint shortfall) = getHypotheticalAccountLiquidityInternal(account, SLToken(0), 0, 0); return (uint(err), liquidity, shortfall); } @@ -657,12 +657,12 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle * account shortfall below collateral requirements) */ function getAccountLiquidityInternal(address account) internal view returns (Error, uint, uint) { - return getHypotheticalAccountLiquidityInternal(account, CToken(0), 0, 0); + return getHypotheticalAccountLiquidityInternal(account, SLToken(0), 0, 0); } /** * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed - * @param cTokenModify The market to hypothetically redeem/borrow in + * @param slTokenModify The market to hypothetically redeem/borrow in * @param account The account to determine liquidity for * @param redeemTokens The number of tokens to hypothetically redeem * @param borrowAmount The amount of underlying to hypothetically borrow @@ -672,20 +672,20 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle */ function getHypotheticalAccountLiquidity( address account, - address cTokenModify, + address slTokenModify, uint redeemTokens, uint borrowAmount) public view returns (uint, uint, uint) { - (Error err, uint liquidity, uint shortfall) = getHypotheticalAccountLiquidityInternal(account, CToken(cTokenModify), redeemTokens, borrowAmount); + (Error err, uint liquidity, uint shortfall) = getHypotheticalAccountLiquidityInternal(account, SLToken(slTokenModify), redeemTokens, borrowAmount); return (uint(err), liquidity, shortfall); } /** * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed - * @param cTokenModify The market to hypothetically redeem/borrow in + * @param slTokenModify The market to hypothetically redeem/borrow in * @param account The account to determine liquidity for * @param redeemTokens The number of tokens to hypothetically redeem * @param borrowAmount The amount of underlying to hypothetically borrow - * @dev Note that we calculate the exchangeRateStored for each collateral cToken using stored data, + * @dev Note that we calculate the exchangeRateStored for each collateral slToken using stored data, * without calculating accumulated interest. * @return (possible error code, hypothetical account liquidity in excess of collateral requirements, @@ -693,7 +693,7 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle */ function getHypotheticalAccountLiquidityInternal( address account, - CToken cTokenModify, + SLToken slTokenModify, uint redeemTokens, uint borrowAmount) internal view returns (Error, uint, uint) { @@ -702,12 +702,12 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle MathError mErr; // For each asset the account is in - CToken[] memory assets = accountAssets[account]; + SLToken[] memory assets = accountAssets[account]; for (uint i = 0; i < assets.length; i++) { - CToken asset = assets[i]; + SLToken asset = assets[i]; - // Read the balances and exchange rate from the cToken - (oErr, vars.cTokenBalance, vars.borrowBalance, vars.exchangeRateMantissa) = asset.getAccountSnapshot(account); + // Read the balances and exchange rate from the slToken + (oErr, vars.slTokenBalance, vars.borrowBalance, vars.exchangeRateMantissa) = asset.getAccountSnapshot(account); if (oErr != 0) { // semi-opaque error code, we assume NO_ERROR == 0 is invariant between upgrades return (Error.SNAPSHOT_ERROR, 0, 0); } @@ -727,8 +727,8 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle return (Error.MATH_ERROR, 0, 0); } - // sumCollateral += tokensToEther * cTokenBalance - (mErr, vars.sumCollateral) = mulScalarTruncateAddUInt(vars.tokensToEther, vars.cTokenBalance, vars.sumCollateral); + // sumCollateral += tokensToEther * slTokenBalance + (mErr, vars.sumCollateral) = mulScalarTruncateAddUInt(vars.tokensToEther, vars.slTokenBalance, vars.sumCollateral); if (mErr != MathError.NO_ERROR) { return (Error.MATH_ERROR, 0, 0); } @@ -739,8 +739,8 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle return (Error.MATH_ERROR, 0, 0); } - // Calculate effects of interacting with cTokenModify - if (asset == cTokenModify) { + // Calculate effects of interacting with slTokenModify + if (asset == slTokenModify) { // redeem effect // sumBorrowPlusEffects += tokensToEther * redeemTokens (mErr, vars.sumBorrowPlusEffects) = mulScalarTruncateAddUInt(vars.tokensToEther, redeemTokens, vars.sumBorrowPlusEffects); @@ -767,16 +767,16 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle /** * @notice Calculate number of tokens of collateral asset to seize given an underlying amount - * @dev Used in liquidation (called in cToken.liquidateBorrowFresh) - * @param cTokenBorrowed The address of the borrowed cToken - * @param cTokenCollateral The address of the collateral cToken - * @param actualRepayAmount The amount of cTokenBorrowed underlying to convert into cTokenCollateral tokens - * @return (errorCode, number of cTokenCollateral tokens to be seized in a liquidation) + * @dev Used in liquidation (called in slToken.liquidateBorrowFresh) + * @param slTokenBorrowed The address of the borrowed slToken + * @param slTokenCollateral The address of the collateral slToken + * @param actualRepayAmount The amount of slTokenBorrowed underlying to convert into slTokenCollateral tokens + * @return (errorCode, number of slTokenCollateral tokens to be seized in a liquidation) */ - function liquidateCalculateSeizeTokens(address cTokenBorrowed, address cTokenCollateral, uint actualRepayAmount) external view returns (uint, uint) { + function liquidateCalculateSeizeTokens(address slTokenBorrowed, address slTokenCollateral, uint actualRepayAmount) external view returns (uint, uint) { /* Read oracle prices for borrowed and collateral markets */ - uint priceBorrowedMantissa = oracle.getUnderlyingPrice(CToken(cTokenBorrowed)); - uint priceCollateralMantissa = oracle.getUnderlyingPrice(CToken(cTokenCollateral)); + uint priceBorrowedMantissa = oracle.getUnderlyingPrice(SLToken(slTokenBorrowed)); + uint priceCollateralMantissa = oracle.getUnderlyingPrice(SLToken(slTokenCollateral)); if (priceBorrowedMantissa == 0 || priceCollateralMantissa == 0) { return (uint(Error.PRICE_ERROR), 0); } @@ -787,7 +787,7 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle * seizeTokens = seizeAmount / exchangeRate * = actualRepayAmount * (liquidationIncentive * priceBorrowed) / (priceCollateral * exchangeRate) */ - uint exchangeRateMantissa = CToken(cTokenCollateral).exchangeRateStored(); // Note: reverts on error + uint exchangeRateMantissa = SLToken(slTokenCollateral).exchangeRateStored(); // Note: reverts on error uint seizeTokens; Exp memory numerator; Exp memory denominator; @@ -875,18 +875,18 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle /** * @notice Sets the collateralFactor for a market * @dev Admin function to set per-market collateralFactor - * @param cToken The market to set the factor on + * @param slToken The market to set the factor on * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18 * @return uint 0=success, otherwise a failure. (See ErrorReporter for details) */ - function _setCollateralFactor(CToken cToken, uint newCollateralFactorMantissa) external returns (uint256) { + function _setCollateralFactor(SLToken slToken, uint newCollateralFactorMantissa) external returns (uint256) { // Check caller is admin if (msg.sender != admin) { return fail(Error.UNAUTHORIZED, FailureInfo.SET_COLLATERAL_FACTOR_OWNER_CHECK); } // Verify market is listed - Market storage market = markets[address(cToken)]; + Market storage market = markets[address(slToken)]; if (!market.isListed) { return fail(Error.MARKET_NOT_LISTED, FailureInfo.SET_COLLATERAL_FACTOR_NO_EXISTS); } @@ -900,7 +900,7 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle } // If collateral factor != 0, fail if price == 0 - if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(cToken) == 0) { + if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(slToken) == 0) { return fail(Error.PRICE_ERROR, FailureInfo.SET_COLLATERAL_FACTOR_WITHOUT_PRICE); } @@ -909,7 +909,7 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle market.collateralFactorMantissa = newCollateralFactorMantissa; // Emit event with asset, old collateral factor, and new collateral factor - emit NewCollateralFactor(cToken, oldCollateralFactorMantissa, newCollateralFactorMantissa); + emit NewCollateralFactor(slToken, oldCollateralFactorMantissa, newCollateralFactorMantissa); return uint(Error.NO_ERROR); } @@ -972,22 +972,22 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle /** * @notice Add the market to the markets mapping and set it as listed * @dev Admin function to set isListed and add support for the market - * @param cToken The address of the market (token) to list + * @param slToken The address of the market (token) to list * @return uint 0=success, otherwise a failure. (See enum Error for details) */ - function _supportMarket(CToken cToken) external returns (uint) { + function _supportMarket(SLToken slToken) external returns (uint) { if (msg.sender != admin) { return fail(Error.UNAUTHORIZED, FailureInfo.SUPPORT_MARKET_OWNER_CHECK); } - if (markets[address(cToken)].isListed) { + if (markets[address(slToken)].isListed) { return fail(Error.MARKET_ALREADY_LISTED, FailureInfo.SUPPORT_MARKET_EXISTS); } - cToken.isCToken(); // Sanity check to make sure its really a CToken + slToken.isSLToken(); // Sanity check to make sure its really a SLToken - markets[address(cToken)] = Market({isListed: true, isComped: false, collateralFactorMantissa: 0}); - emit MarketListed(cToken); + markets[address(slToken)] = Market({isListed: true, isSashimied: false, collateralFactorMantissa: 0}); + emit MarketListed(slToken); return uint(Error.NO_ERROR); } @@ -1014,23 +1014,23 @@ contract ComptrollerG2 is ComptrollerV2Storage, ComptrollerInterface, Comptrolle return uint(Error.NO_ERROR); } - function _setMintPaused(CToken cToken, bool state) public returns (bool) { - require(markets[address(cToken)].isListed, "cannot pause a market that is not listed"); + function _setMintPaused(SLToken slToken, bool state) public returns (bool) { + require(markets[address(slToken)].isListed, "cannot pause a market that is not listed"); require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause"); require(msg.sender == admin || state == true, "only admin can unpause"); - mintGuardianPaused[address(cToken)] = state; - emit ActionPaused(cToken, "Mint", state); + mintGuardianPaused[address(slToken)] = state; + emit ActionPaused(slToken, "Mint", state); return state; } - function _setBorrowPaused(CToken cToken, bool state) public returns (bool) { - require(markets[address(cToken)].isListed, "cannot pause a market that is not listed"); + function _setBorrowPaused(SLToken slToken, bool state) public returns (bool) { + require(markets[address(slToken)].isListed, "cannot pause a market that is not listed"); require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause"); require(msg.sender == admin || state == true, "only admin can unpause"); - borrowGuardianPaused[address(cToken)] = state; - emit ActionPaused(cToken, "Borrow", state); + borrowGuardianPaused[address(slToken)] = state; + emit ActionPaused(slToken, "Borrow", state); return state; } diff --git a/contracts/ComptrollerG3.sol b/contracts/ComptrollerG3.sol index 2553ddc6f..c77f7bb71 100644 --- a/contracts/ComptrollerG3.sol +++ b/contracts/ComptrollerG3.sol @@ -1,33 +1,33 @@ pragma solidity ^0.5.16; -import "./CToken.sol"; +import "./SLToken.sol"; import "./ErrorReporter.sol"; import "./Exponential.sol"; import "./PriceOracle.sol"; import "./ComptrollerInterface.sol"; import "./ComptrollerStorage.sol"; import "./Unitroller.sol"; -import "./Governance/Comp.sol"; +import "./EIP20Interface.sol"; /** - * @title Compound's Comptroller Contract - * @author Compound + * @title SashimiLending's Comptroller Contract + * @author SashimiLending */ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, ComptrollerErrorReporter, Exponential { /// @notice Emitted when an admin supports a market - event MarketListed(CToken cToken); + event MarketListed(SLToken slToken); /// @notice Emitted when an account enters a market - event MarketEntered(CToken cToken, address account); + event MarketEntered(SLToken slToken, address account); /// @notice Emitted when an account exits a market - event MarketExited(CToken cToken, address account); + event MarketExited(SLToken slToken, address account); /// @notice Emitted when close factor is changed by admin event NewCloseFactor(uint oldCloseFactorMantissa, uint newCloseFactorMantissa); /// @notice Emitted when a collateral factor is changed by admin - event NewCollateralFactor(CToken cToken, uint oldCollateralFactorMantissa, uint newCollateralFactorMantissa); + event NewCollateralFactor(SLToken slToken, uint oldCollateralFactorMantissa, uint newCollateralFactorMantissa); /// @notice Emitted when liquidation incentive is changed by admin event NewLiquidationIncentive(uint oldLiquidationIncentiveMantissa, uint newLiquidationIncentiveMantissa); @@ -45,28 +45,28 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle event ActionPaused(string action, bool pauseState); /// @notice Emitted when an action is paused on a market - event ActionPaused(CToken cToken, string action, bool pauseState); + event ActionPaused(SLToken slToken, string action, bool pauseState); - /// @notice Emitted when market comped status is changed - event MarketComped(CToken cToken, bool isComped); + /// @notice Emitted when market sashimied status is changed + event MarketSashimied(SLToken slToken, bool isSashimied); - /// @notice Emitted when COMP rate is changed - event NewCompRate(uint oldCompRate, uint newCompRate); + /// @notice Emitted when SASHIMI rate is changed + event NewSashimiRate(uint oldSashimiRate, uint newSashimiRate); - /// @notice Emitted when a new COMP speed is calculated for a market - event CompSpeedUpdated(CToken indexed cToken, uint newSpeed); + /// @notice Emitted when a new SASHIMI speed is calculated for a market + event SashimiSpeedUpdated(SLToken indexed slToken, uint newSpeed); - /// @notice Emitted when COMP is distributed to a supplier - event DistributedSupplierComp(CToken indexed cToken, address indexed supplier, uint compDelta, uint compSupplyIndex); + /// @notice Emitted when SASHIMI is distributed to a supplier + event DistributedSupplierSashimi(SLToken indexed slToken, address indexed supplier, uint sashimiDelta, uint sashimiSupplyIndex); - /// @notice Emitted when COMP is distributed to a borrower - event DistributedBorrowerComp(CToken indexed cToken, address indexed borrower, uint compDelta, uint compBorrowIndex); + /// @notice Emitted when SASHIMI is distributed to a borrower + event DistributedBorrowerSashimi(SLToken indexed slToken, address indexed borrower, uint sashimiDelta, uint sashimiBorrowIndex); - /// @notice The threshold above which the flywheel transfers COMP, in wei - uint public constant compClaimThreshold = 0.001e18; + /// @notice The threshold above which the flywheel transfers SASHIMI, in wei + uint public constant sashimiClaimThreshold = 0.001e18; - /// @notice The initial COMP index for a market - uint224 public constant compInitialIndex = 1e36; + /// @notice The initial SASHIMI index for a market + uint224 public constant sashimiInitialIndex = 1e36; // closeFactorMantissa must be strictly greater than this value uint internal constant closeFactorMinMantissa = 0.05e18; // 0.05 @@ -94,8 +94,8 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle * @param account The address of the account to pull assets for * @return A dynamic list with the assets the account has entered */ - function getAssetsIn(address account) external view returns (CToken[] memory) { - CToken[] memory assetsIn = accountAssets[account]; + function getAssetsIn(address account) external view returns (SLToken[] memory) { + SLToken[] memory assetsIn = accountAssets[account]; return assetsIn; } @@ -103,26 +103,26 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Returns whether the given account is entered in the given asset * @param account The address of the account to check - * @param cToken The cToken to check + * @param slToken The slToken to check * @return True if the account is in the asset, otherwise false. */ - function checkMembership(address account, CToken cToken) external view returns (bool) { - return markets[address(cToken)].accountMembership[account]; + function checkMembership(address account, SLToken slToken) external view returns (bool) { + return markets[address(slToken)].accountMembership[account]; } /** * @notice Add assets to be included in account liquidity calculation - * @param cTokens The list of addresses of the cToken markets to be enabled + * @param slTokens The list of addresses of the slToken markets to be enabled * @return Success indicator for whether each corresponding market was entered */ - function enterMarkets(address[] memory cTokens) public returns (uint[] memory) { - uint len = cTokens.length; + function enterMarkets(address[] memory slTokens) public returns (uint[] memory) { + uint len = slTokens.length; uint[] memory results = new uint[](len); for (uint i = 0; i < len; i++) { - CToken cToken = CToken(cTokens[i]); + SLToken slToken = SLToken(slTokens[i]); - results[i] = uint(addToMarketInternal(cToken, msg.sender)); + results[i] = uint(addToMarketInternal(slToken, msg.sender)); } return results; @@ -130,12 +130,12 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Add the market to the borrower's "assets in" for liquidity calculations - * @param cToken The market to enter + * @param slToken The market to enter * @param borrower The address of the account to modify * @return Success indicator for whether the market was entered */ - function addToMarketInternal(CToken cToken, address borrower) internal returns (Error) { - Market storage marketToJoin = markets[address(cToken)]; + function addToMarketInternal(SLToken slToken, address borrower) internal returns (Error) { + Market storage marketToJoin = markets[address(slToken)]; if (!marketToJoin.isListed) { // market is not listed, cannot join @@ -158,9 +158,9 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle // that is, only when we need to perform liquidity checks // and not whenever we want to check if an account is in a particular market marketToJoin.accountMembership[borrower] = true; - accountAssets[borrower].push(cToken); + accountAssets[borrower].push(slToken); - emit MarketEntered(cToken, borrower); + emit MarketEntered(slToken, borrower); return Error.NO_ERROR; } @@ -169,13 +169,13 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle * @notice Removes asset from sender's account liquidity calculation * @dev Sender must not have an outstanding borrow balance in the asset, * or be providing neccessary collateral for an outstanding borrow. - * @param cTokenAddress The address of the asset to be removed + * @param slTokenAddress The address of the asset to be removed * @return Whether or not the account successfully exited the market */ - function exitMarket(address cTokenAddress) external returns (uint) { - CToken cToken = CToken(cTokenAddress); - /* Get sender tokensHeld and amountOwed underlying from the cToken */ - (uint oErr, uint tokensHeld, uint amountOwed, ) = cToken.getAccountSnapshot(msg.sender); + function exitMarket(address slTokenAddress) external returns (uint) { + SLToken slToken = SLToken(slTokenAddress); + /* Get sender tokensHeld and amountOwed underlying from the slToken */ + (uint oErr, uint tokensHeld, uint amountOwed, ) = slToken.getAccountSnapshot(msg.sender); require(oErr == 0, "exitMarket: getAccountSnapshot failed"); // semi-opaque error code /* Fail if the sender has a borrow balance */ @@ -184,28 +184,28 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle } /* Fail if the sender is not permitted to redeem all of their tokens */ - uint allowed = redeemAllowedInternal(cTokenAddress, msg.sender, tokensHeld); + uint allowed = redeemAllowedInternal(slTokenAddress, msg.sender, tokensHeld); if (allowed != 0) { return failOpaque(Error.REJECTION, FailureInfo.EXIT_MARKET_REJECTION, allowed); } - Market storage marketToExit = markets[address(cToken)]; + Market storage marketToExit = markets[address(slToken)]; /* Return true if the sender is not already ‘in’ the market */ if (!marketToExit.accountMembership[msg.sender]) { return uint(Error.NO_ERROR); } - /* Set cToken account membership to false */ + /* Set slToken account membership to false */ delete marketToExit.accountMembership[msg.sender]; - /* Delete cToken from the account’s list of assets */ + /* Delete slToken from the account’s list of assets */ // load into memory for faster iteration - CToken[] memory userAssetList = accountAssets[msg.sender]; + SLToken[] memory userAssetList = accountAssets[msg.sender]; uint len = userAssetList.length; uint assetIndex = len; for (uint i = 0; i < len; i++) { - if (userAssetList[i] == cToken) { + if (userAssetList[i] == slToken) { assetIndex = i; break; } @@ -215,11 +215,11 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle assert(assetIndex < len); // copy last item in list to location of item to be removed, reduce length by 1 - CToken[] storage storedList = accountAssets[msg.sender]; + SLToken[] storage storedList = accountAssets[msg.sender]; storedList[assetIndex] = storedList[storedList.length - 1]; storedList.length--; - emit MarketExited(cToken, msg.sender); + emit MarketExited(slToken, msg.sender); return uint(Error.NO_ERROR); } @@ -228,40 +228,40 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the account should be allowed to mint tokens in the given market - * @param cToken The market to verify the mint against + * @param slToken The market to verify the mint against * @param minter The account which would get the minted tokens * @param mintAmount The amount of underlying being supplied to the market in exchange for tokens * @return 0 if the mint is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) */ - function mintAllowed(address cToken, address minter, uint mintAmount) external returns (uint) { + function mintAllowed(address slToken, address minter, uint mintAmount) external returns (uint) { // Pausing is a very serious situation - we revert to sound the alarms - require(!mintGuardianPaused[cToken], "mint is paused"); + require(!mintGuardianPaused[slToken], "mint is paused"); // Shh - currently unused minter; mintAmount; - if (!markets[cToken].isListed) { + if (!markets[slToken].isListed) { return uint(Error.MARKET_NOT_LISTED); } // Keep the flywheel moving - updateCompSupplyIndex(cToken); - distributeSupplierComp(cToken, minter, false); + updateSashimiSupplyIndex(slToken); + distributeSupplierSashimi(slToken, minter, false); return uint(Error.NO_ERROR); } /** * @notice Validates mint and reverts on rejection. May emit logs. - * @param cToken Asset being minted + * @param slToken Asset being minted * @param minter The address minting the tokens * @param actualMintAmount The amount of the underlying asset being minted * @param mintTokens The number of tokens being minted */ - function mintVerify(address cToken, address minter, uint actualMintAmount, uint mintTokens) external { + function mintVerify(address slToken, address minter, uint actualMintAmount, uint mintTokens) external { // Shh - currently unused - cToken; + slToken; minter; actualMintAmount; mintTokens; @@ -274,36 +274,36 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the account should be allowed to redeem tokens in the given market - * @param cToken The market to verify the redeem against + * @param slToken The market to verify the redeem against * @param redeemer The account which would redeem the tokens - * @param redeemTokens The number of cTokens to exchange for the underlying asset in the market + * @param redeemTokens The number of slTokens to exchange for the underlying asset in the market * @return 0 if the redeem is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) */ - function redeemAllowed(address cToken, address redeemer, uint redeemTokens) external returns (uint) { - uint allowed = redeemAllowedInternal(cToken, redeemer, redeemTokens); + function redeemAllowed(address slToken, address redeemer, uint redeemTokens) external returns (uint) { + uint allowed = redeemAllowedInternal(slToken, redeemer, redeemTokens); if (allowed != uint(Error.NO_ERROR)) { return allowed; } // Keep the flywheel moving - updateCompSupplyIndex(cToken); - distributeSupplierComp(cToken, redeemer, false); + updateSashimiSupplyIndex(slToken); + distributeSupplierSashimi(slToken, redeemer, false); return uint(Error.NO_ERROR); } - function redeemAllowedInternal(address cToken, address redeemer, uint redeemTokens) internal view returns (uint) { - if (!markets[cToken].isListed) { + function redeemAllowedInternal(address slToken, address redeemer, uint redeemTokens) internal view returns (uint) { + if (!markets[slToken].isListed) { return uint(Error.MARKET_NOT_LISTED); } /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */ - if (!markets[cToken].accountMembership[redeemer]) { + if (!markets[slToken].accountMembership[redeemer]) { return uint(Error.NO_ERROR); } /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */ - (Error err, , uint shortfall) = getHypotheticalAccountLiquidityInternal(redeemer, CToken(cToken), redeemTokens, 0); + (Error err, , uint shortfall) = getHypotheticalAccountLiquidityInternal(redeemer, SLToken(slToken), redeemTokens, 0); if (err != Error.NO_ERROR) { return uint(err); } @@ -316,14 +316,14 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Validates redeem and reverts on rejection. May emit logs. - * @param cToken Asset being redeemed + * @param slToken Asset being redeemed * @param redeemer The address redeeming the tokens * @param redeemAmount The amount of the underlying asset being redeemed * @param redeemTokens The number of tokens being redeemed */ - function redeemVerify(address cToken, address redeemer, uint redeemAmount, uint redeemTokens) external { + function redeemVerify(address slToken, address redeemer, uint redeemAmount, uint redeemTokens) external { // Shh - currently unused - cToken; + slToken; redeemer; // Require tokens is zero or amount is also zero @@ -334,38 +334,38 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the account should be allowed to borrow the underlying asset of the given market - * @param cToken The market to verify the borrow against + * @param slToken The market to verify the borrow against * @param borrower The account which would borrow the asset * @param borrowAmount The amount of underlying the account would borrow * @return 0 if the borrow is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) */ - function borrowAllowed(address cToken, address borrower, uint borrowAmount) external returns (uint) { + function borrowAllowed(address slToken, address borrower, uint borrowAmount) external returns (uint) { // Pausing is a very serious situation - we revert to sound the alarms - require(!borrowGuardianPaused[cToken], "borrow is paused"); + require(!borrowGuardianPaused[slToken], "borrow is paused"); - if (!markets[cToken].isListed) { + if (!markets[slToken].isListed) { return uint(Error.MARKET_NOT_LISTED); } - if (!markets[cToken].accountMembership[borrower]) { - // only cTokens may call borrowAllowed if borrower not in market - require(msg.sender == cToken, "sender must be cToken"); + if (!markets[slToken].accountMembership[borrower]) { + // only slTokens may call borrowAllowed if borrower not in market + require(msg.sender == slToken, "sender must be slToken"); // attempt to add borrower to the market - Error err = addToMarketInternal(CToken(msg.sender), borrower); + Error err = addToMarketInternal(SLToken(msg.sender), borrower); if (err != Error.NO_ERROR) { return uint(err); } // it should be impossible to break the important invariant - assert(markets[cToken].accountMembership[borrower]); + assert(markets[slToken].accountMembership[borrower]); } - if (oracle.getUnderlyingPrice(CToken(cToken)) == 0) { + if (oracle.getUnderlyingPrice(SLToken(slToken)) == 0) { return uint(Error.PRICE_ERROR); } - (Error err, , uint shortfall) = getHypotheticalAccountLiquidityInternal(borrower, CToken(cToken), 0, borrowAmount); + (Error err, , uint shortfall) = getHypotheticalAccountLiquidityInternal(borrower, SLToken(slToken), 0, borrowAmount); if (err != Error.NO_ERROR) { return uint(err); } @@ -374,22 +374,22 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle } // Keep the flywheel moving - Exp memory borrowIndex = Exp({mantissa: CToken(cToken).borrowIndex()}); - updateCompBorrowIndex(cToken, borrowIndex); - distributeBorrowerComp(cToken, borrower, borrowIndex, false); + Exp memory borrowIndex = Exp({mantissa: SLToken(slToken).borrowIndex()}); + updateSashimiBorrowIndex(slToken, borrowIndex); + distributeBorrowerSashimi(slToken, borrower, borrowIndex, false); return uint(Error.NO_ERROR); } /** * @notice Validates borrow and reverts on rejection. May emit logs. - * @param cToken Asset whose underlying is being borrowed + * @param slToken Asset whose underlying is being borrowed * @param borrower The address borrowing the underlying * @param borrowAmount The amount of the underlying asset requested to borrow */ - function borrowVerify(address cToken, address borrower, uint borrowAmount) external { + function borrowVerify(address slToken, address borrower, uint borrowAmount) external { // Shh - currently unused - cToken; + slToken; borrower; borrowAmount; @@ -401,14 +401,14 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the account should be allowed to repay a borrow in the given market - * @param cToken The market to verify the repay against + * @param slToken The market to verify the repay against * @param payer The account which would repay the asset * @param borrower The account which would borrowed the asset * @param repayAmount The amount of the underlying asset the account would repay * @return 0 if the repay is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) */ function repayBorrowAllowed( - address cToken, + address slToken, address payer, address borrower, uint repayAmount) external returns (uint) { @@ -417,33 +417,33 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle borrower; repayAmount; - if (!markets[cToken].isListed) { + if (!markets[slToken].isListed) { return uint(Error.MARKET_NOT_LISTED); } // Keep the flywheel moving - Exp memory borrowIndex = Exp({mantissa: CToken(cToken).borrowIndex()}); - updateCompBorrowIndex(cToken, borrowIndex); - distributeBorrowerComp(cToken, borrower, borrowIndex, false); + Exp memory borrowIndex = Exp({mantissa: SLToken(slToken).borrowIndex()}); + updateSashimiBorrowIndex(slToken, borrowIndex); + distributeBorrowerSashimi(slToken, borrower, borrowIndex, false); return uint(Error.NO_ERROR); } /** * @notice Validates repayBorrow and reverts on rejection. May emit logs. - * @param cToken Asset being repaid + * @param slToken Asset being repaid * @param payer The address repaying the borrow * @param borrower The address of the borrower * @param actualRepayAmount The amount of underlying being repaid */ function repayBorrowVerify( - address cToken, + address slToken, address payer, address borrower, uint actualRepayAmount, uint borrowerIndex) external { // Shh - currently unused - cToken; + slToken; payer; borrower; actualRepayAmount; @@ -457,22 +457,22 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the liquidation should be allowed to occur - * @param cTokenBorrowed Asset which was borrowed by the borrower - * @param cTokenCollateral Asset which was used as collateral and will be seized + * @param slTokenBorrowed Asset which was borrowed by the borrower + * @param slTokenCollateral Asset which was used as collateral and will be seized * @param liquidator The address repaying the borrow and seizing the collateral * @param borrower The address of the borrower * @param repayAmount The amount of underlying being repaid */ function liquidateBorrowAllowed( - address cTokenBorrowed, - address cTokenCollateral, + address slTokenBorrowed, + address slTokenCollateral, address liquidator, address borrower, uint repayAmount) external returns (uint) { // Shh - currently unused liquidator; - if (!markets[cTokenBorrowed].isListed || !markets[cTokenCollateral].isListed) { + if (!markets[slTokenBorrowed].isListed || !markets[slTokenCollateral].isListed) { return uint(Error.MARKET_NOT_LISTED); } @@ -486,7 +486,7 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle } /* The liquidator may not repay more than what is allowed by the closeFactor */ - uint borrowBalance = CToken(cTokenBorrowed).borrowBalanceStored(borrower); + uint borrowBalance = SLToken(slTokenBorrowed).borrowBalanceStored(borrower); (MathError mathErr, uint maxClose) = mulScalarTruncate(Exp({mantissa: closeFactorMantissa}), borrowBalance); if (mathErr != MathError.NO_ERROR) { return uint(Error.MATH_ERROR); @@ -500,22 +500,22 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Validates liquidateBorrow and reverts on rejection. May emit logs. - * @param cTokenBorrowed Asset which was borrowed by the borrower - * @param cTokenCollateral Asset which was used as collateral and will be seized + * @param slTokenBorrowed Asset which was borrowed by the borrower + * @param slTokenCollateral Asset which was used as collateral and will be seized * @param liquidator The address repaying the borrow and seizing the collateral * @param borrower The address of the borrower * @param actualRepayAmount The amount of underlying being repaid */ function liquidateBorrowVerify( - address cTokenBorrowed, - address cTokenCollateral, + address slTokenBorrowed, + address slTokenCollateral, address liquidator, address borrower, uint actualRepayAmount, uint seizeTokens) external { // Shh - currently unused - cTokenBorrowed; - cTokenCollateral; + slTokenBorrowed; + slTokenCollateral; liquidator; borrower; actualRepayAmount; @@ -529,15 +529,15 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the seizing of assets should be allowed to occur - * @param cTokenCollateral Asset which was used as collateral and will be seized - * @param cTokenBorrowed Asset which was borrowed by the borrower + * @param slTokenCollateral Asset which was used as collateral and will be seized + * @param slTokenBorrowed Asset which was borrowed by the borrower * @param liquidator The address repaying the borrow and seizing the collateral * @param borrower The address of the borrower * @param seizeTokens The number of collateral tokens to seize */ function seizeAllowed( - address cTokenCollateral, - address cTokenBorrowed, + address slTokenCollateral, + address slTokenBorrowed, address liquidator, address borrower, uint seizeTokens) external returns (uint) { @@ -547,39 +547,39 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle // Shh - currently unused seizeTokens; - if (!markets[cTokenCollateral].isListed || !markets[cTokenBorrowed].isListed) { + if (!markets[slTokenCollateral].isListed || !markets[slTokenBorrowed].isListed) { return uint(Error.MARKET_NOT_LISTED); } - if (CToken(cTokenCollateral).comptroller() != CToken(cTokenBorrowed).comptroller()) { + if (SLToken(slTokenCollateral).comptroller() != SLToken(slTokenBorrowed).comptroller()) { return uint(Error.COMPTROLLER_MISMATCH); } // Keep the flywheel moving - updateCompSupplyIndex(cTokenCollateral); - distributeSupplierComp(cTokenCollateral, borrower, false); - distributeSupplierComp(cTokenCollateral, liquidator, false); + updateSashimiSupplyIndex(slTokenCollateral); + distributeSupplierSashimi(slTokenCollateral, borrower, false); + distributeSupplierSashimi(slTokenCollateral, liquidator, false); return uint(Error.NO_ERROR); } /** * @notice Validates seize and reverts on rejection. May emit logs. - * @param cTokenCollateral Asset which was used as collateral and will be seized - * @param cTokenBorrowed Asset which was borrowed by the borrower + * @param slTokenCollateral Asset which was used as collateral and will be seized + * @param slTokenBorrowed Asset which was borrowed by the borrower * @param liquidator The address repaying the borrow and seizing the collateral * @param borrower The address of the borrower * @param seizeTokens The number of collateral tokens to seize */ function seizeVerify( - address cTokenCollateral, - address cTokenBorrowed, + address slTokenCollateral, + address slTokenBorrowed, address liquidator, address borrower, uint seizeTokens) external { // Shh - currently unused - cTokenCollateral; - cTokenBorrowed; + slTokenCollateral; + slTokenBorrowed; liquidator; borrower; seizeTokens; @@ -592,41 +592,41 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the account should be allowed to transfer tokens in the given market - * @param cToken The market to verify the transfer against + * @param slToken The market to verify the transfer against * @param src The account which sources the tokens * @param dst The account which receives the tokens - * @param transferTokens The number of cTokens to transfer + * @param transferTokens The number of slTokens to transfer * @return 0 if the transfer is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) */ - function transferAllowed(address cToken, address src, address dst, uint transferTokens) external returns (uint) { + function transferAllowed(address slToken, address src, address dst, uint transferTokens) external returns (uint) { // Pausing is a very serious situation - we revert to sound the alarms require(!transferGuardianPaused, "transfer is paused"); // Currently the only consideration is whether or not // the src is allowed to redeem this many tokens - uint allowed = redeemAllowedInternal(cToken, src, transferTokens); + uint allowed = redeemAllowedInternal(slToken, src, transferTokens); if (allowed != uint(Error.NO_ERROR)) { return allowed; } // Keep the flywheel moving - updateCompSupplyIndex(cToken); - distributeSupplierComp(cToken, src, false); - distributeSupplierComp(cToken, dst, false); + updateSashimiSupplyIndex(slToken); + distributeSupplierSashimi(slToken, src, false); + distributeSupplierSashimi(slToken, dst, false); return uint(Error.NO_ERROR); } /** * @notice Validates transfer and reverts on rejection. May emit logs. - * @param cToken Asset being transferred + * @param slToken Asset being transferred * @param src The account which sources the tokens * @param dst The account which receives the tokens - * @param transferTokens The number of cTokens to transfer + * @param transferTokens The number of slTokens to transfer */ - function transferVerify(address cToken, address src, address dst, uint transferTokens) external { + function transferVerify(address slToken, address src, address dst, uint transferTokens) external { // Shh - currently unused - cToken; + slToken; src; dst; transferTokens; @@ -641,13 +641,13 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @dev Local vars for avoiding stack-depth limits in calculating account liquidity. - * Note that `cTokenBalance` is the number of cTokens the account owns in the market, + * Note that `slTokenBalance` is the number of slTokens the account owns in the market, * whereas `borrowBalance` is the amount of underlying that the account has borrowed. */ struct AccountLiquidityLocalVars { uint sumCollateral; uint sumBorrowPlusEffects; - uint cTokenBalance; + uint slTokenBalance; uint borrowBalance; uint exchangeRateMantissa; uint oraclePriceMantissa; @@ -664,7 +664,7 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle * account shortfall below collateral requirements) */ function getAccountLiquidity(address account) public view returns (uint, uint, uint) { - (Error err, uint liquidity, uint shortfall) = getHypotheticalAccountLiquidityInternal(account, CToken(0), 0, 0); + (Error err, uint liquidity, uint shortfall) = getHypotheticalAccountLiquidityInternal(account, SLToken(0), 0, 0); return (uint(err), liquidity, shortfall); } @@ -676,12 +676,12 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle * account shortfall below collateral requirements) */ function getAccountLiquidityInternal(address account) internal view returns (Error, uint, uint) { - return getHypotheticalAccountLiquidityInternal(account, CToken(0), 0, 0); + return getHypotheticalAccountLiquidityInternal(account, SLToken(0), 0, 0); } /** * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed - * @param cTokenModify The market to hypothetically redeem/borrow in + * @param slTokenModify The market to hypothetically redeem/borrow in * @param account The account to determine liquidity for * @param redeemTokens The number of tokens to hypothetically redeem * @param borrowAmount The amount of underlying to hypothetically borrow @@ -691,20 +691,20 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle */ function getHypotheticalAccountLiquidity( address account, - address cTokenModify, + address slTokenModify, uint redeemTokens, uint borrowAmount) public view returns (uint, uint, uint) { - (Error err, uint liquidity, uint shortfall) = getHypotheticalAccountLiquidityInternal(account, CToken(cTokenModify), redeemTokens, borrowAmount); + (Error err, uint liquidity, uint shortfall) = getHypotheticalAccountLiquidityInternal(account, SLToken(slTokenModify), redeemTokens, borrowAmount); return (uint(err), liquidity, shortfall); } /** * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed - * @param cTokenModify The market to hypothetically redeem/borrow in + * @param slTokenModify The market to hypothetically redeem/borrow in * @param account The account to determine liquidity for * @param redeemTokens The number of tokens to hypothetically redeem * @param borrowAmount The amount of underlying to hypothetically borrow - * @dev Note that we calculate the exchangeRateStored for each collateral cToken using stored data, + * @dev Note that we calculate the exchangeRateStored for each collateral slToken using stored data, * without calculating accumulated interest. * @return (possible error code, hypothetical account liquidity in excess of collateral requirements, @@ -712,7 +712,7 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle */ function getHypotheticalAccountLiquidityInternal( address account, - CToken cTokenModify, + SLToken slTokenModify, uint redeemTokens, uint borrowAmount) internal view returns (Error, uint, uint) { @@ -721,12 +721,12 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle MathError mErr; // For each asset the account is in - CToken[] memory assets = accountAssets[account]; + SLToken[] memory assets = accountAssets[account]; for (uint i = 0; i < assets.length; i++) { - CToken asset = assets[i]; + SLToken asset = assets[i]; - // Read the balances and exchange rate from the cToken - (oErr, vars.cTokenBalance, vars.borrowBalance, vars.exchangeRateMantissa) = asset.getAccountSnapshot(account); + // Read the balances and exchange rate from the slToken + (oErr, vars.slTokenBalance, vars.borrowBalance, vars.exchangeRateMantissa) = asset.getAccountSnapshot(account); if (oErr != 0) { // semi-opaque error code, we assume NO_ERROR == 0 is invariant between upgrades return (Error.SNAPSHOT_ERROR, 0, 0); } @@ -746,8 +746,8 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle return (Error.MATH_ERROR, 0, 0); } - // sumCollateral += tokensToDenom * cTokenBalance - (mErr, vars.sumCollateral) = mulScalarTruncateAddUInt(vars.tokensToDenom, vars.cTokenBalance, vars.sumCollateral); + // sumCollateral += tokensToDenom * slTokenBalance + (mErr, vars.sumCollateral) = mulScalarTruncateAddUInt(vars.tokensToDenom, vars.slTokenBalance, vars.sumCollateral); if (mErr != MathError.NO_ERROR) { return (Error.MATH_ERROR, 0, 0); } @@ -758,8 +758,8 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle return (Error.MATH_ERROR, 0, 0); } - // Calculate effects of interacting with cTokenModify - if (asset == cTokenModify) { + // Calculate effects of interacting with slTokenModify + if (asset == slTokenModify) { // redeem effect // sumBorrowPlusEffects += tokensToDenom * redeemTokens (mErr, vars.sumBorrowPlusEffects) = mulScalarTruncateAddUInt(vars.tokensToDenom, redeemTokens, vars.sumBorrowPlusEffects); @@ -786,16 +786,16 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Calculate number of tokens of collateral asset to seize given an underlying amount - * @dev Used in liquidation (called in cToken.liquidateBorrowFresh) - * @param cTokenBorrowed The address of the borrowed cToken - * @param cTokenCollateral The address of the collateral cToken - * @param actualRepayAmount The amount of cTokenBorrowed underlying to convert into cTokenCollateral tokens - * @return (errorCode, number of cTokenCollateral tokens to be seized in a liquidation) + * @dev Used in liquidation (called in slToken.liquidateBorrowFresh) + * @param slTokenBorrowed The address of the borrowed slToken + * @param slTokenCollateral The address of the collateral slToken + * @param actualRepayAmount The amount of slTokenBorrowed underlying to convert into slTokenCollateral tokens + * @return (errorCode, number of slTokenCollateral tokens to be seized in a liquidation) */ - function liquidateCalculateSeizeTokens(address cTokenBorrowed, address cTokenCollateral, uint actualRepayAmount) external view returns (uint, uint) { + function liquidateCalculateSeizeTokens(address slTokenBorrowed, address slTokenCollateral, uint actualRepayAmount) external view returns (uint, uint) { /* Read oracle prices for borrowed and collateral markets */ - uint priceBorrowedMantissa = oracle.getUnderlyingPrice(CToken(cTokenBorrowed)); - uint priceCollateralMantissa = oracle.getUnderlyingPrice(CToken(cTokenCollateral)); + uint priceBorrowedMantissa = oracle.getUnderlyingPrice(SLToken(slTokenBorrowed)); + uint priceCollateralMantissa = oracle.getUnderlyingPrice(SLToken(slTokenCollateral)); if (priceBorrowedMantissa == 0 || priceCollateralMantissa == 0) { return (uint(Error.PRICE_ERROR), 0); } @@ -806,7 +806,7 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle * seizeTokens = seizeAmount / exchangeRate * = actualRepayAmount * (liquidationIncentive * priceBorrowed) / (priceCollateral * exchangeRate) */ - uint exchangeRateMantissa = CToken(cTokenCollateral).exchangeRateStored(); // Note: reverts on error + uint exchangeRateMantissa = SLToken(slTokenCollateral).exchangeRateStored(); // Note: reverts on error uint seizeTokens; Exp memory numerator; Exp memory denominator; @@ -894,18 +894,18 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Sets the collateralFactor for a market * @dev Admin function to set per-market collateralFactor - * @param cToken The market to set the factor on + * @param slToken The market to set the factor on * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18 * @return uint 0=success, otherwise a failure. (See ErrorReporter for details) */ - function _setCollateralFactor(CToken cToken, uint newCollateralFactorMantissa) external returns (uint) { + function _setCollateralFactor(SLToken slToken, uint newCollateralFactorMantissa) external returns (uint) { // Check caller is admin if (msg.sender != admin) { return fail(Error.UNAUTHORIZED, FailureInfo.SET_COLLATERAL_FACTOR_OWNER_CHECK); } // Verify market is listed - Market storage market = markets[address(cToken)]; + Market storage market = markets[address(slToken)]; if (!market.isListed) { return fail(Error.MARKET_NOT_LISTED, FailureInfo.SET_COLLATERAL_FACTOR_NO_EXISTS); } @@ -919,7 +919,7 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle } // If collateral factor != 0, fail if price == 0 - if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(cToken) == 0) { + if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(slToken) == 0) { return fail(Error.PRICE_ERROR, FailureInfo.SET_COLLATERAL_FACTOR_WITHOUT_PRICE); } @@ -928,7 +928,7 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle market.collateralFactorMantissa = newCollateralFactorMantissa; // Emit event with asset, old collateral factor, and new collateral factor - emit NewCollateralFactor(cToken, oldCollateralFactorMantissa, newCollateralFactorMantissa); + emit NewCollateralFactor(slToken, oldCollateralFactorMantissa, newCollateralFactorMantissa); return uint(Error.NO_ERROR); } @@ -991,34 +991,34 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Add the market to the markets mapping and set it as listed * @dev Admin function to set isListed and add support for the market - * @param cToken The address of the market (token) to list + * @param slToken The address of the market (token) to list * @return uint 0=success, otherwise a failure. (See enum Error for details) */ - function _supportMarket(CToken cToken) external returns (uint) { + function _supportMarket(SLToken slToken) external returns (uint) { if (msg.sender != admin) { return fail(Error.UNAUTHORIZED, FailureInfo.SUPPORT_MARKET_OWNER_CHECK); } - if (markets[address(cToken)].isListed) { + if (markets[address(slToken)].isListed) { return fail(Error.MARKET_ALREADY_LISTED, FailureInfo.SUPPORT_MARKET_EXISTS); } - cToken.isCToken(); // Sanity check to make sure its really a CToken + slToken.isSLToken(); // Sanity check to make sure its really a SLToken - markets[address(cToken)] = Market({isListed: true, isComped: false, collateralFactorMantissa: 0}); + markets[address(slToken)] = Market({isListed: true, isSashimied: false, collateralFactorMantissa: 0}); - _addMarketInternal(address(cToken)); + _addMarketInternal(address(slToken)); - emit MarketListed(cToken); + emit MarketListed(slToken); return uint(Error.NO_ERROR); } - function _addMarketInternal(address cToken) internal { + function _addMarketInternal(address slToken) internal { for (uint i = 0; i < allMarkets.length; i ++) { - require(allMarkets[i] != CToken(cToken), "market already added"); + require(allMarkets[i] != SLToken(slToken), "market already added"); } - allMarkets.push(CToken(cToken)); + allMarkets.push(SLToken(slToken)); } /** @@ -1043,23 +1043,23 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle return uint(Error.NO_ERROR); } - function _setMintPaused(CToken cToken, bool state) public returns (bool) { - require(markets[address(cToken)].isListed, "cannot pause a market that is not listed"); + function _setMintPaused(SLToken slToken, bool state) public returns (bool) { + require(markets[address(slToken)].isListed, "cannot pause a market that is not listed"); require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause"); require(msg.sender == admin || state == true, "only admin can unpause"); - mintGuardianPaused[address(cToken)] = state; - emit ActionPaused(cToken, "Mint", state); + mintGuardianPaused[address(slToken)] = state; + emit ActionPaused(slToken, "Mint", state); return state; } - function _setBorrowPaused(CToken cToken, bool state) public returns (bool) { - require(markets[address(cToken)].isListed, "cannot pause a market that is not listed"); + function _setBorrowPaused(SLToken slToken, bool state) public returns (bool) { + require(markets[address(slToken)].isListed, "cannot pause a market that is not listed"); require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause"); require(msg.sender == admin || state == true, "only admin can unpause"); - borrowGuardianPaused[address(cToken)] = state; - emit ActionPaused(cToken, "Borrow", state); + borrowGuardianPaused[address(slToken)] = state; + emit ActionPaused(slToken, "Borrow", state); return state; } @@ -1081,26 +1081,26 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle return state; } - function _become(Unitroller unitroller, uint compRate_, address[] memory compMarketsToAdd, address[] memory otherMarketsToAdd) public { + function _become(Unitroller unitroller, uint sashimiRate_, address[] memory sashimiMarketsToAdd, address[] memory otherMarketsToAdd) public { require(msg.sender == unitroller.admin(), "only unitroller admin can change brains"); require(unitroller._acceptImplementation() == 0, "change not authorized"); - ComptrollerG3(address(unitroller))._becomeG3(compRate_, compMarketsToAdd, otherMarketsToAdd); + ComptrollerG3(address(unitroller))._becomeG3(sashimiRate_, sashimiMarketsToAdd, otherMarketsToAdd); } - function _becomeG3(uint compRate_, address[] memory compMarketsToAdd, address[] memory otherMarketsToAdd) public { + function _becomeG3(uint sashimiRate_, address[] memory sashimiMarketsToAdd, address[] memory otherMarketsToAdd) public { require(msg.sender == comptrollerImplementation, "only brains can become itself"); - for (uint i = 0; i < compMarketsToAdd.length; i++) { - _addMarketInternal(address(compMarketsToAdd[i])); + for (uint i = 0; i < sashimiMarketsToAdd.length; i++) { + _addMarketInternal(address(sashimiMarketsToAdd[i])); } for (uint i = 0; i < otherMarketsToAdd.length; i++) { _addMarketInternal(address(otherMarketsToAdd[i])); } - _setCompRate(compRate_); - _addCompMarkets(compMarketsToAdd); + _setSashimiRate(sashimiRate_); + _addSashimiMarkets(sashimiMarketsToAdd); } /** @@ -1110,28 +1110,28 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle return msg.sender == admin || msg.sender == comptrollerImplementation; } - /*** Comp Distribution ***/ + /*** Sashimi Distribution ***/ /** - * @notice Recalculate and update COMP speeds for all COMP markets + * @notice Recalculate and update SASHIMI speeds for all SASHIMI markets */ - function refreshCompSpeeds() public { - CToken[] memory allMarkets_ = allMarkets; + function refreshSashimiSpeeds() public { + SLToken[] memory allMarkets_ = allMarkets; for (uint i = 0; i < allMarkets_.length; i++) { - CToken cToken = allMarkets_[i]; - Exp memory borrowIndex = Exp({mantissa: cToken.borrowIndex()}); - updateCompSupplyIndex(address(cToken)); - updateCompBorrowIndex(address(cToken), borrowIndex); + SLToken slToken = allMarkets_[i]; + Exp memory borrowIndex = Exp({mantissa: slToken.borrowIndex()}); + updateSashimiSupplyIndex(address(slToken)); + updateSashimiBorrowIndex(address(slToken), borrowIndex); } Exp memory totalUtility = Exp({mantissa: 0}); Exp[] memory utilities = new Exp[](allMarkets_.length); for (uint i = 0; i < allMarkets_.length; i++) { - CToken cToken = allMarkets_[i]; - if (markets[address(cToken)].isComped) { - Exp memory assetPrice = Exp({mantissa: oracle.getUnderlyingPrice(cToken)}); - Exp memory interestPerBlock = mul_(Exp({mantissa: cToken.borrowRatePerBlock()}), cToken.totalBorrows()); + SLToken slToken = allMarkets_[i]; + if (markets[address(slToken)].isSashimied) { + Exp memory assetPrice = Exp({mantissa: oracle.getUnderlyingPrice(slToken)}); + Exp memory interestPerBlock = mul_(Exp({mantissa: slToken.borrowRatePerBlock()}), slToken.totalBorrows()); Exp memory utility = mul_(interestPerBlock, assetPrice); utilities[i] = utility; totalUtility = add_(totalUtility, utility); @@ -1139,28 +1139,28 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle } for (uint i = 0; i < allMarkets_.length; i++) { - CToken cToken = allMarkets[i]; - uint newSpeed = totalUtility.mantissa > 0 ? mul_(compRate, div_(utilities[i], totalUtility)) : 0; - compSpeeds[address(cToken)] = newSpeed; - emit CompSpeedUpdated(cToken, newSpeed); + SLToken slToken = allMarkets[i]; + uint newSpeed = totalUtility.mantissa > 0 ? mul_(sashimiRate, div_(utilities[i], totalUtility)) : 0; + sashimiSpeeds[address(slToken)] = newSpeed; + emit SashimiSpeedUpdated(slToken, newSpeed); } } /** - * @notice Accrue COMP to the market by updating the supply index - * @param cToken The market whose supply index to update + * @notice Accrue SASHIMI to the market by updating the supply index + * @param slToken The market whose supply index to update */ - function updateCompSupplyIndex(address cToken) internal { - CompMarketState storage supplyState = compSupplyState[cToken]; - uint supplySpeed = compSpeeds[cToken]; + function updateSashimiSupplyIndex(address slToken) internal { + SashimiMarketState storage supplyState = sashimiSupplyState[slToken]; + uint supplySpeed = sashimiSpeeds[slToken]; uint blockNumber = getBlockNumber(); uint deltaBlocks = sub_(blockNumber, uint(supplyState.block)); if (deltaBlocks > 0 && supplySpeed > 0) { - uint supplyTokens = CToken(cToken).totalSupply(); - uint compAccrued = mul_(deltaBlocks, supplySpeed); - Double memory ratio = supplyTokens > 0 ? fraction(compAccrued, supplyTokens) : Double({mantissa: 0}); + uint supplyTokens = SLToken(slToken).totalSupply(); + uint sashimiAccrued = mul_(deltaBlocks, supplySpeed); + Double memory ratio = supplyTokens > 0 ? fraction(sashimiAccrued, supplyTokens) : Double({mantissa: 0}); Double memory index = add_(Double({mantissa: supplyState.index}), ratio); - compSupplyState[cToken] = CompMarketState({ + sashimiSupplyState[slToken] = SashimiMarketState({ index: safe224(index.mantissa, "new index exceeds 224 bits"), block: safe32(blockNumber, "block number exceeds 32 bits") }); @@ -1170,20 +1170,20 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle } /** - * @notice Accrue COMP to the market by updating the borrow index - * @param cToken The market whose borrow index to update + * @notice Accrue SASHIMI to the market by updating the borrow index + * @param slToken The market whose borrow index to update */ - function updateCompBorrowIndex(address cToken, Exp memory marketBorrowIndex) internal { - CompMarketState storage borrowState = compBorrowState[cToken]; - uint borrowSpeed = compSpeeds[cToken]; + function updateSashimiBorrowIndex(address slToken, Exp memory marketBorrowIndex) internal { + SashimiMarketState storage borrowState = sashimiBorrowState[slToken]; + uint borrowSpeed = sashimiSpeeds[slToken]; uint blockNumber = getBlockNumber(); uint deltaBlocks = sub_(blockNumber, uint(borrowState.block)); if (deltaBlocks > 0 && borrowSpeed > 0) { - uint borrowAmount = div_(CToken(cToken).totalBorrows(), marketBorrowIndex); - uint compAccrued = mul_(deltaBlocks, borrowSpeed); - Double memory ratio = borrowAmount > 0 ? fraction(compAccrued, borrowAmount) : Double({mantissa: 0}); + uint borrowAmount = div_(SLToken(slToken).totalBorrows(), marketBorrowIndex); + uint sashimiAccrued = mul_(deltaBlocks, borrowSpeed); + Double memory ratio = borrowAmount > 0 ? fraction(sashimiAccrued, borrowAmount) : Double({mantissa: 0}); Double memory index = add_(Double({mantissa: borrowState.index}), ratio); - compBorrowState[cToken] = CompMarketState({ + sashimiBorrowState[slToken] = SashimiMarketState({ index: safe224(index.mantissa, "new index exceeds 224 bits"), block: safe32(blockNumber, "block number exceeds 32 bits") }); @@ -1193,63 +1193,63 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle } /** - * @notice Calculate COMP accrued by a supplier and possibly transfer it to them - * @param cToken The market in which the supplier is interacting - * @param supplier The address of the supplier to distribute COMP to + * @notice Calculate SASHIMI accrued by a supplier and possibly transfer it to them + * @param slToken The market in which the supplier is interacting + * @param supplier The address of the supplier to distribute SASHIMI to */ - function distributeSupplierComp(address cToken, address supplier, bool distributeAll) internal { - CompMarketState storage supplyState = compSupplyState[cToken]; + function distributeSupplierSashimi(address slToken, address supplier, bool distributeAll) internal { + SashimiMarketState storage supplyState = sashimiSupplyState[slToken]; Double memory supplyIndex = Double({mantissa: supplyState.index}); - Double memory supplierIndex = Double({mantissa: compSupplierIndex[cToken][supplier]}); - compSupplierIndex[cToken][supplier] = supplyIndex.mantissa; + Double memory supplierIndex = Double({mantissa: sashimiSupplierIndex[slToken][supplier]}); + sashimiSupplierIndex[slToken][supplier] = supplyIndex.mantissa; if (supplierIndex.mantissa == 0 && supplyIndex.mantissa > 0) { - supplierIndex.mantissa = compInitialIndex; + supplierIndex.mantissa = sashimiInitialIndex; } Double memory deltaIndex = sub_(supplyIndex, supplierIndex); - uint supplierTokens = CToken(cToken).balanceOf(supplier); + uint supplierTokens = SLToken(slToken).balanceOf(supplier); uint supplierDelta = mul_(supplierTokens, deltaIndex); - uint supplierAccrued = add_(compAccrued[supplier], supplierDelta); - compAccrued[supplier] = transferComp(supplier, supplierAccrued, distributeAll ? 0 : compClaimThreshold); - emit DistributedSupplierComp(CToken(cToken), supplier, supplierDelta, supplyIndex.mantissa); + uint supplierAccrued = add_(sashimiAccrued[supplier], supplierDelta); + sashimiAccrued[supplier] = transferSashimi(supplier, supplierAccrued, distributeAll ? 0 : sashimiClaimThreshold); + emit DistributedSupplierSashimi(SLToken(slToken), supplier, supplierDelta, supplyIndex.mantissa); } /** - * @notice Calculate COMP accrued by a borrower and possibly transfer it to them + * @notice Calculate SASHIMI accrued by a borrower and possibly transfer it to them * @dev Borrowers will not begin to accrue until after the first interaction with the protocol. - * @param cToken The market in which the borrower is interacting - * @param borrower The address of the borrower to distribute COMP to + * @param slToken The market in which the borrower is interacting + * @param borrower The address of the borrower to distribute SASHIMI to */ - function distributeBorrowerComp(address cToken, address borrower, Exp memory marketBorrowIndex, bool distributeAll) internal { - CompMarketState storage borrowState = compBorrowState[cToken]; + function distributeBorrowerSashimi(address slToken, address borrower, Exp memory marketBorrowIndex, bool distributeAll) internal { + SashimiMarketState storage borrowState = sashimiBorrowState[slToken]; Double memory borrowIndex = Double({mantissa: borrowState.index}); - Double memory borrowerIndex = Double({mantissa: compBorrowerIndex[cToken][borrower]}); - compBorrowerIndex[cToken][borrower] = borrowIndex.mantissa; + Double memory borrowerIndex = Double({mantissa: sashimiBorrowerIndex[slToken][borrower]}); + sashimiBorrowerIndex[slToken][borrower] = borrowIndex.mantissa; if (borrowerIndex.mantissa > 0) { Double memory deltaIndex = sub_(borrowIndex, borrowerIndex); - uint borrowerAmount = div_(CToken(cToken).borrowBalanceStored(borrower), marketBorrowIndex); + uint borrowerAmount = div_(SLToken(slToken).borrowBalanceStored(borrower), marketBorrowIndex); uint borrowerDelta = mul_(borrowerAmount, deltaIndex); - uint borrowerAccrued = add_(compAccrued[borrower], borrowerDelta); - compAccrued[borrower] = transferComp(borrower, borrowerAccrued, distributeAll ? 0 : compClaimThreshold); - emit DistributedBorrowerComp(CToken(cToken), borrower, borrowerDelta, borrowIndex.mantissa); + uint borrowerAccrued = add_(sashimiAccrued[borrower], borrowerDelta); + sashimiAccrued[borrower] = transferSashimi(borrower, borrowerAccrued, distributeAll ? 0 : sashimiClaimThreshold); + emit DistributedBorrowerSashimi(SLToken(slToken), borrower, borrowerDelta, borrowIndex.mantissa); } } /** - * @notice Transfer COMP to the user, if they are above the threshold - * @dev Note: If there is not enough COMP, we do not perform the transfer all. - * @param user The address of the user to transfer COMP to - * @param userAccrued The amount of COMP to (possibly) transfer - * @return The amount of COMP which was NOT transferred to the user + * @notice Transfer SASHIMI to the user, if they are above the threshold + * @dev Note: If there is not enough SASHIMI, we do not perform the transfer all. + * @param user The address of the user to transfer SASHIMI to + * @param userAccrued The amount of SASHIMI to (possibly) transfer + * @return The amount of SASHIMI which was NOT transferred to the user */ - function transferComp(address user, uint userAccrued, uint threshold) internal returns (uint) { + function transferSashimi(address user, uint userAccrued, uint threshold) internal returns (uint) { if (userAccrued >= threshold && userAccrued > 0) { - Comp comp = Comp(getCompAddress()); - uint compRemaining = comp.balanceOf(address(this)); - if (userAccrued <= compRemaining) { - comp.transfer(user, userAccrued); + EIP20Interface sashimi = EIP20Interface(getSashimiAddress()); + uint sashimiRemaining = sashimi.balanceOf(address(this)); + if (userAccrued <= sashimiRemaining) { + sashimi.transfer(user, userAccrued); return 0; } } @@ -1257,118 +1257,118 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle } /** - * @notice Claim all the comp accrued by holder in all markets - * @param holder The address to claim COMP for + * @notice Claim all the sashimi accrued by holder in all markets + * @param holder The address to claim SASHIMI for */ - function claimComp(address holder) public { - return claimComp(holder, allMarkets); + function claimSashimi(address holder) public { + return claimSashimi(holder, allMarkets); } /** - * @notice Claim all the comp accrued by holder in the specified markets - * @param holder The address to claim COMP for - * @param cTokens The list of markets to claim COMP in + * @notice Claim all the sashimi accrued by holder in the specified markets + * @param holder The address to claim SASHIMI for + * @param slTokens The list of markets to claim SASHIMI in */ - function claimComp(address holder, CToken[] memory cTokens) public { + function claimSashimi(address holder, SLToken[] memory slTokens) public { address[] memory holders = new address[](1); holders[0] = holder; - claimComp(holders, cTokens, true, true); + claimSashimi(holders, slTokens, true, true); } /** - * @notice Claim all comp accrued by the holders - * @param holders The addresses to claim COMP for - * @param cTokens The list of markets to claim COMP in - * @param borrowers Whether or not to claim COMP earned by borrowing - * @param suppliers Whether or not to claim COMP earned by supplying + * @notice Claim all sashimi accrued by the holders + * @param holders The addresses to claim SASHIMI for + * @param slTokens The list of markets to claim SASHIMI in + * @param borrowers Whether or not to claim SASHIMI earned by borrowing + * @param suppliers Whether or not to claim SASHIMI earned by supplying */ - function claimComp(address[] memory holders, CToken[] memory cTokens, bool borrowers, bool suppliers) public { - for (uint i = 0; i < cTokens.length; i++) { - CToken cToken = cTokens[i]; - require(markets[address(cToken)].isListed, "market must be listed"); + function claimSashimi(address[] memory holders, SLToken[] memory slTokens, bool borrowers, bool suppliers) public { + for (uint i = 0; i < slTokens.length; i++) { + SLToken slToken = slTokens[i]; + require(markets[address(slToken)].isListed, "market must be listed"); if (borrowers == true) { - Exp memory borrowIndex = Exp({mantissa: cToken.borrowIndex()}); - updateCompBorrowIndex(address(cToken), borrowIndex); + Exp memory borrowIndex = Exp({mantissa: slToken.borrowIndex()}); + updateSashimiBorrowIndex(address(slToken), borrowIndex); for (uint j = 0; j < holders.length; j++) { - distributeBorrowerComp(address(cToken), holders[j], borrowIndex, true); + distributeBorrowerSashimi(address(slToken), holders[j], borrowIndex, true); } } if (suppliers == true) { - updateCompSupplyIndex(address(cToken)); + updateSashimiSupplyIndex(address(slToken)); for (uint j = 0; j < holders.length; j++) { - distributeSupplierComp(address(cToken), holders[j], true); + distributeSupplierSashimi(address(slToken), holders[j], true); } } } } - /*** Comp Distribution Admin ***/ + /*** Sashimi Distribution Admin ***/ /** - * @notice Set the amount of COMP distributed per block - * @param compRate_ The amount of COMP wei per block to distribute + * @notice Set the amount of SASHIMI distributed per block + * @param sashimiRate_ The amount of SASHIMI wei per block to distribute */ - function _setCompRate(uint compRate_) public { - require(adminOrInitializing(), "only admin can change comp rate"); + function _setSashimiRate(uint sashimiRate_) public { + require(adminOrInitializing(), "only admin can change sashimi rate"); - uint oldRate = compRate; - compRate = compRate_; - emit NewCompRate(oldRate, compRate_); + uint oldRate = sashimiRate; + sashimiRate = sashimiRate_; + emit NewSashimiRate(oldRate, sashimiRate_); - refreshCompSpeeds(); + refreshSashimiSpeeds(); } /** - * @notice Add markets to compMarkets, allowing them to earn COMP in the flywheel - * @param cTokens The addresses of the markets to add + * @notice Add markets to sashimiMarkets, allowing them to earn SASHIMI in the flywheel + * @param slTokens The addresses of the markets to add */ - function _addCompMarkets(address[] memory cTokens) public { - require(adminOrInitializing(), "only admin can add comp market"); + function _addSashimiMarkets(address[] memory slTokens) public { + require(adminOrInitializing(), "only admin can add sashimi market"); - for (uint i = 0; i < cTokens.length; i++) { - _addCompMarketInternal(cTokens[i]); + for (uint i = 0; i < slTokens.length; i++) { + _addSashimiMarketInternal(slTokens[i]); } - refreshCompSpeeds(); + refreshSashimiSpeeds(); } - function _addCompMarketInternal(address cToken) internal { - Market storage market = markets[cToken]; - require(market.isListed == true, "comp market is not listed"); - require(market.isComped == false, "comp market already added"); + function _addSashimiMarketInternal(address slToken) internal { + Market storage market = markets[slToken]; + require(market.isListed == true, "sashimi market is not listed"); + require(market.isSashimied == false, "sashimi market already added"); - market.isComped = true; - emit MarketComped(CToken(cToken), true); + market.isSashimied = true; + emit MarketSashimied(SLToken(slToken), true); - if (compSupplyState[cToken].index == 0 && compSupplyState[cToken].block == 0) { - compSupplyState[cToken] = CompMarketState({ - index: compInitialIndex, + if (sashimiSupplyState[slToken].index == 0 && sashimiSupplyState[slToken].block == 0) { + sashimiSupplyState[slToken] = SashimiMarketState({ + index: sashimiInitialIndex, block: safe32(getBlockNumber(), "block number exceeds 32 bits") }); } - if (compBorrowState[cToken].index == 0 && compBorrowState[cToken].block == 0) { - compBorrowState[cToken] = CompMarketState({ - index: compInitialIndex, + if (sashimiBorrowState[slToken].index == 0 && sashimiBorrowState[slToken].block == 0) { + sashimiBorrowState[slToken] = SashimiMarketState({ + index: sashimiInitialIndex, block: safe32(getBlockNumber(), "block number exceeds 32 bits") }); } } /** - * @notice Remove a market from compMarkets, preventing it from earning COMP in the flywheel - * @param cToken The address of the market to drop + * @notice Remove a market from sashimiMarkets, preventing it from earning SASHIMI in the flywheel + * @param slToken The address of the market to drop */ - function _dropCompMarket(address cToken) public { - require(msg.sender == admin, "only admin can drop comp market"); + function _dropSashimiMarket(address slToken) public { + require(msg.sender == admin, "only admin can drop sashimi market"); - Market storage market = markets[cToken]; - require(market.isComped == true, "market is not a comp market"); + Market storage market = markets[slToken]; + require(market.isSashimied == true, "market is not a sashimi market"); - market.isComped = false; - emit MarketComped(CToken(cToken), false); + market.isSashimied = false; + emit MarketSashimied(SLToken(slToken), false); - refreshCompSpeeds(); + refreshSashimiSpeeds(); } /** @@ -1376,7 +1376,7 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle * @dev The automatic getter may be used to access an individual market. * @return The list of market addresses */ - function getAllMarkets() public view returns (CToken[] memory) { + function getAllMarkets() public view returns (SLToken[] memory) { return allMarkets; } @@ -1385,10 +1385,10 @@ contract ComptrollerG3 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle } /** - * @notice Return the address of the COMP token - * @return The address of COMP + * @notice Return the address of the SASHIMI token + * @return The address of SASHIMI */ - function getCompAddress() public view returns (address) { + function getSashimiAddress() public view returns (address) { return 0xc00e94Cb662C3520282E6f5717214004A7f26888; } } diff --git a/contracts/ComptrollerG4.sol b/contracts/ComptrollerG4.sol index 8563ef4e6..a66717d9a 100644 --- a/contracts/ComptrollerG4.sol +++ b/contracts/ComptrollerG4.sol @@ -1,33 +1,33 @@ pragma solidity ^0.5.16; -import "./CToken.sol"; +import "./SLToken.sol"; import "./ErrorReporter.sol"; import "./Exponential.sol"; import "./PriceOracle.sol"; import "./ComptrollerInterface.sol"; import "./ComptrollerStorage.sol"; import "./Unitroller.sol"; -import "./Governance/Comp.sol"; +import "./EIP20Interface.sol"; /** - * @title Compound's Comptroller Contract - * @author Compound + * @title SashimiLending's Comptroller Contract + * @author SashimiLending */ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, ComptrollerErrorReporter, Exponential { /// @notice Emitted when an admin supports a market - event MarketListed(CToken cToken); + event MarketListed(SLToken slToken); /// @notice Emitted when an account enters a market - event MarketEntered(CToken cToken, address account); + event MarketEntered(SLToken slToken, address account); /// @notice Emitted when an account exits a market - event MarketExited(CToken cToken, address account); + event MarketExited(SLToken slToken, address account); /// @notice Emitted when close factor is changed by admin event NewCloseFactor(uint oldCloseFactorMantissa, uint newCloseFactorMantissa); /// @notice Emitted when a collateral factor is changed by admin - event NewCollateralFactor(CToken cToken, uint oldCollateralFactorMantissa, uint newCollateralFactorMantissa); + event NewCollateralFactor(SLToken slToken, uint oldCollateralFactorMantissa, uint newCollateralFactorMantissa); /// @notice Emitted when liquidation incentive is changed by admin event NewLiquidationIncentive(uint oldLiquidationIncentiveMantissa, uint newLiquidationIncentiveMantissa); @@ -45,28 +45,28 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle event ActionPaused(string action, bool pauseState); /// @notice Emitted when an action is paused on a market - event ActionPaused(CToken cToken, string action, bool pauseState); + event ActionPaused(SLToken slToken, string action, bool pauseState); - /// @notice Emitted when market comped status is changed - event MarketComped(CToken cToken, bool isComped); + /// @notice Emitted when market sashimied status is changed + event MarketSashimied(SLToken slToken, bool isSashimied); - /// @notice Emitted when COMP rate is changed - event NewCompRate(uint oldCompRate, uint newCompRate); + /// @notice Emitted when SASHIMI rate is changed + event NewSashimiRate(uint oldSashimiRate, uint newSashimiRate); - /// @notice Emitted when a new COMP speed is calculated for a market - event CompSpeedUpdated(CToken indexed cToken, uint newSpeed); + /// @notice Emitted when a new SASHIMI speed is calculated for a market + event SashimiSpeedUpdated(SLToken indexed slToken, uint newSpeed); - /// @notice Emitted when COMP is distributed to a supplier - event DistributedSupplierComp(CToken indexed cToken, address indexed supplier, uint compDelta, uint compSupplyIndex); + /// @notice Emitted when SASHIMI is distributed to a supplier + event DistributedSupplierSashimi(SLToken indexed slToken, address indexed supplier, uint sashimiDelta, uint sashimiSupplyIndex); - /// @notice Emitted when COMP is distributed to a borrower - event DistributedBorrowerComp(CToken indexed cToken, address indexed borrower, uint compDelta, uint compBorrowIndex); + /// @notice Emitted when SASHIMI is distributed to a borrower + event DistributedBorrowerSashimi(SLToken indexed slToken, address indexed borrower, uint sashimiDelta, uint sashimiBorrowIndex); - /// @notice The threshold above which the flywheel transfers COMP, in wei - uint public constant compClaimThreshold = 0.001e18; + /// @notice The threshold above which the flywheel transfers SASHIMI, in wei + uint public constant sashimiClaimThreshold = 0.001e18; - /// @notice The initial COMP index for a market - uint224 public constant compInitialIndex = 1e36; + /// @notice The initial SASHIMI index for a market + uint224 public constant sashimiInitialIndex = 1e36; // closeFactorMantissa must be strictly greater than this value uint internal constant closeFactorMinMantissa = 0.05e18; // 0.05 @@ -94,8 +94,8 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle * @param account The address of the account to pull assets for * @return A dynamic list with the assets the account has entered */ - function getAssetsIn(address account) external view returns (CToken[] memory) { - CToken[] memory assetsIn = accountAssets[account]; + function getAssetsIn(address account) external view returns (SLToken[] memory) { + SLToken[] memory assetsIn = accountAssets[account]; return assetsIn; } @@ -103,26 +103,26 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Returns whether the given account is entered in the given asset * @param account The address of the account to check - * @param cToken The cToken to check + * @param slToken The slToken to check * @return True if the account is in the asset, otherwise false. */ - function checkMembership(address account, CToken cToken) external view returns (bool) { - return markets[address(cToken)].accountMembership[account]; + function checkMembership(address account, SLToken slToken) external view returns (bool) { + return markets[address(slToken)].accountMembership[account]; } /** * @notice Add assets to be included in account liquidity calculation - * @param cTokens The list of addresses of the cToken markets to be enabled + * @param slTokens The list of addresses of the slToken markets to be enabled * @return Success indicator for whether each corresponding market was entered */ - function enterMarkets(address[] memory cTokens) public returns (uint[] memory) { - uint len = cTokens.length; + function enterMarkets(address[] memory slTokens) public returns (uint[] memory) { + uint len = slTokens.length; uint[] memory results = new uint[](len); for (uint i = 0; i < len; i++) { - CToken cToken = CToken(cTokens[i]); + SLToken slToken = SLToken(slTokens[i]); - results[i] = uint(addToMarketInternal(cToken, msg.sender)); + results[i] = uint(addToMarketInternal(slToken, msg.sender)); } return results; @@ -130,12 +130,12 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Add the market to the borrower's "assets in" for liquidity calculations - * @param cToken The market to enter + * @param slToken The market to enter * @param borrower The address of the account to modify * @return Success indicator for whether the market was entered */ - function addToMarketInternal(CToken cToken, address borrower) internal returns (Error) { - Market storage marketToJoin = markets[address(cToken)]; + function addToMarketInternal(SLToken slToken, address borrower) internal returns (Error) { + Market storage marketToJoin = markets[address(slToken)]; if (!marketToJoin.isListed) { // market is not listed, cannot join @@ -158,9 +158,9 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle // that is, only when we need to perform liquidity checks // and not whenever we want to check if an account is in a particular market marketToJoin.accountMembership[borrower] = true; - accountAssets[borrower].push(cToken); + accountAssets[borrower].push(slToken); - emit MarketEntered(cToken, borrower); + emit MarketEntered(slToken, borrower); return Error.NO_ERROR; } @@ -169,13 +169,13 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle * @notice Removes asset from sender's account liquidity calculation * @dev Sender must not have an outstanding borrow balance in the asset, * or be providing necessary collateral for an outstanding borrow. - * @param cTokenAddress The address of the asset to be removed + * @param slTokenAddress The address of the asset to be removed * @return Whether or not the account successfully exited the market */ - function exitMarket(address cTokenAddress) external returns (uint) { - CToken cToken = CToken(cTokenAddress); - /* Get sender tokensHeld and amountOwed underlying from the cToken */ - (uint oErr, uint tokensHeld, uint amountOwed, ) = cToken.getAccountSnapshot(msg.sender); + function exitMarket(address slTokenAddress) external returns (uint) { + SLToken slToken = SLToken(slTokenAddress); + /* Get sender tokensHeld and amountOwed underlying from the slToken */ + (uint oErr, uint tokensHeld, uint amountOwed, ) = slToken.getAccountSnapshot(msg.sender); require(oErr == 0, "exitMarket: getAccountSnapshot failed"); // semi-opaque error code /* Fail if the sender has a borrow balance */ @@ -184,28 +184,28 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle } /* Fail if the sender is not permitted to redeem all of their tokens */ - uint allowed = redeemAllowedInternal(cTokenAddress, msg.sender, tokensHeld); + uint allowed = redeemAllowedInternal(slTokenAddress, msg.sender, tokensHeld); if (allowed != 0) { return failOpaque(Error.REJECTION, FailureInfo.EXIT_MARKET_REJECTION, allowed); } - Market storage marketToExit = markets[address(cToken)]; + Market storage marketToExit = markets[address(slToken)]; /* Return true if the sender is not already ‘in’ the market */ if (!marketToExit.accountMembership[msg.sender]) { return uint(Error.NO_ERROR); } - /* Set cToken account membership to false */ + /* Set slToken account membership to false */ delete marketToExit.accountMembership[msg.sender]; - /* Delete cToken from the account’s list of assets */ + /* Delete slToken from the account’s list of assets */ // load into memory for faster iteration - CToken[] memory userAssetList = accountAssets[msg.sender]; + SLToken[] memory userAssetList = accountAssets[msg.sender]; uint len = userAssetList.length; uint assetIndex = len; for (uint i = 0; i < len; i++) { - if (userAssetList[i] == cToken) { + if (userAssetList[i] == slToken) { assetIndex = i; break; } @@ -215,11 +215,11 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle assert(assetIndex < len); // copy last item in list to location of item to be removed, reduce length by 1 - CToken[] storage storedList = accountAssets[msg.sender]; + SLToken[] storage storedList = accountAssets[msg.sender]; storedList[assetIndex] = storedList[storedList.length - 1]; storedList.length--; - emit MarketExited(cToken, msg.sender); + emit MarketExited(slToken, msg.sender); return uint(Error.NO_ERROR); } @@ -228,40 +228,40 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the account should be allowed to mint tokens in the given market - * @param cToken The market to verify the mint against + * @param slToken The market to verify the mint against * @param minter The account which would get the minted tokens * @param mintAmount The amount of underlying being supplied to the market in exchange for tokens * @return 0 if the mint is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) */ - function mintAllowed(address cToken, address minter, uint mintAmount) external returns (uint) { + function mintAllowed(address slToken, address minter, uint mintAmount) external returns (uint) { // Pausing is a very serious situation - we revert to sound the alarms - require(!mintGuardianPaused[cToken], "mint is paused"); + require(!mintGuardianPaused[slToken], "mint is paused"); // Shh - currently unused minter; mintAmount; - if (!markets[cToken].isListed) { + if (!markets[slToken].isListed) { return uint(Error.MARKET_NOT_LISTED); } // Keep the flywheel moving - updateCompSupplyIndex(cToken); - distributeSupplierComp(cToken, minter, false); + updateSashimiSupplyIndex(slToken); + distributeSupplierSashimi(slToken, minter, false); return uint(Error.NO_ERROR); } /** * @notice Validates mint and reverts on rejection. May emit logs. - * @param cToken Asset being minted + * @param slToken Asset being minted * @param minter The address minting the tokens * @param actualMintAmount The amount of the underlying asset being minted * @param mintTokens The number of tokens being minted */ - function mintVerify(address cToken, address minter, uint actualMintAmount, uint mintTokens) external { + function mintVerify(address slToken, address minter, uint actualMintAmount, uint mintTokens) external { // Shh - currently unused - cToken; + slToken; minter; actualMintAmount; mintTokens; @@ -274,36 +274,36 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the account should be allowed to redeem tokens in the given market - * @param cToken The market to verify the redeem against + * @param slToken The market to verify the redeem against * @param redeemer The account which would redeem the tokens - * @param redeemTokens The number of cTokens to exchange for the underlying asset in the market + * @param redeemTokens The number of slTokens to exchange for the underlying asset in the market * @return 0 if the redeem is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) */ - function redeemAllowed(address cToken, address redeemer, uint redeemTokens) external returns (uint) { - uint allowed = redeemAllowedInternal(cToken, redeemer, redeemTokens); + function redeemAllowed(address slToken, address redeemer, uint redeemTokens) external returns (uint) { + uint allowed = redeemAllowedInternal(slToken, redeemer, redeemTokens); if (allowed != uint(Error.NO_ERROR)) { return allowed; } // Keep the flywheel moving - updateCompSupplyIndex(cToken); - distributeSupplierComp(cToken, redeemer, false); + updateSashimiSupplyIndex(slToken); + distributeSupplierSashimi(slToken, redeemer, false); return uint(Error.NO_ERROR); } - function redeemAllowedInternal(address cToken, address redeemer, uint redeemTokens) internal view returns (uint) { - if (!markets[cToken].isListed) { + function redeemAllowedInternal(address slToken, address redeemer, uint redeemTokens) internal view returns (uint) { + if (!markets[slToken].isListed) { return uint(Error.MARKET_NOT_LISTED); } /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */ - if (!markets[cToken].accountMembership[redeemer]) { + if (!markets[slToken].accountMembership[redeemer]) { return uint(Error.NO_ERROR); } /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */ - (Error err, , uint shortfall) = getHypotheticalAccountLiquidityInternal(redeemer, CToken(cToken), redeemTokens, 0); + (Error err, , uint shortfall) = getHypotheticalAccountLiquidityInternal(redeemer, SLToken(slToken), redeemTokens, 0); if (err != Error.NO_ERROR) { return uint(err); } @@ -316,14 +316,14 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Validates redeem and reverts on rejection. May emit logs. - * @param cToken Asset being redeemed + * @param slToken Asset being redeemed * @param redeemer The address redeeming the tokens * @param redeemAmount The amount of the underlying asset being redeemed * @param redeemTokens The number of tokens being redeemed */ - function redeemVerify(address cToken, address redeemer, uint redeemAmount, uint redeemTokens) external { + function redeemVerify(address slToken, address redeemer, uint redeemAmount, uint redeemTokens) external { // Shh - currently unused - cToken; + slToken; redeemer; // Require tokens is zero or amount is also zero @@ -334,38 +334,38 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the account should be allowed to borrow the underlying asset of the given market - * @param cToken The market to verify the borrow against + * @param slToken The market to verify the borrow against * @param borrower The account which would borrow the asset * @param borrowAmount The amount of underlying the account would borrow * @return 0 if the borrow is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) */ - function borrowAllowed(address cToken, address borrower, uint borrowAmount) external returns (uint) { + function borrowAllowed(address slToken, address borrower, uint borrowAmount) external returns (uint) { // Pausing is a very serious situation - we revert to sound the alarms - require(!borrowGuardianPaused[cToken], "borrow is paused"); + require(!borrowGuardianPaused[slToken], "borrow is paused"); - if (!markets[cToken].isListed) { + if (!markets[slToken].isListed) { return uint(Error.MARKET_NOT_LISTED); } - if (!markets[cToken].accountMembership[borrower]) { - // only cTokens may call borrowAllowed if borrower not in market - require(msg.sender == cToken, "sender must be cToken"); + if (!markets[slToken].accountMembership[borrower]) { + // only slTokens may call borrowAllowed if borrower not in market + require(msg.sender == slToken, "sender must be slToken"); // attempt to add borrower to the market - Error err = addToMarketInternal(CToken(msg.sender), borrower); + Error err = addToMarketInternal(SLToken(msg.sender), borrower); if (err != Error.NO_ERROR) { return uint(err); } // it should be impossible to break the important invariant - assert(markets[cToken].accountMembership[borrower]); + assert(markets[slToken].accountMembership[borrower]); } - if (oracle.getUnderlyingPrice(CToken(cToken)) == 0) { + if (oracle.getUnderlyingPrice(SLToken(slToken)) == 0) { return uint(Error.PRICE_ERROR); } - (Error err, , uint shortfall) = getHypotheticalAccountLiquidityInternal(borrower, CToken(cToken), 0, borrowAmount); + (Error err, , uint shortfall) = getHypotheticalAccountLiquidityInternal(borrower, SLToken(slToken), 0, borrowAmount); if (err != Error.NO_ERROR) { return uint(err); } @@ -374,22 +374,22 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle } // Keep the flywheel moving - Exp memory borrowIndex = Exp({mantissa: CToken(cToken).borrowIndex()}); - updateCompBorrowIndex(cToken, borrowIndex); - distributeBorrowerComp(cToken, borrower, borrowIndex, false); + Exp memory borrowIndex = Exp({mantissa: SLToken(slToken).borrowIndex()}); + updateSashimiBorrowIndex(slToken, borrowIndex); + distributeBorrowerSashimi(slToken, borrower, borrowIndex, false); return uint(Error.NO_ERROR); } /** * @notice Validates borrow and reverts on rejection. May emit logs. - * @param cToken Asset whose underlying is being borrowed + * @param slToken Asset whose underlying is being borrowed * @param borrower The address borrowing the underlying * @param borrowAmount The amount of the underlying asset requested to borrow */ - function borrowVerify(address cToken, address borrower, uint borrowAmount) external { + function borrowVerify(address slToken, address borrower, uint borrowAmount) external { // Shh - currently unused - cToken; + slToken; borrower; borrowAmount; @@ -401,14 +401,14 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the account should be allowed to repay a borrow in the given market - * @param cToken The market to verify the repay against + * @param slToken The market to verify the repay against * @param payer The account which would repay the asset * @param borrower The account which would borrowed the asset * @param repayAmount The amount of the underlying asset the account would repay * @return 0 if the repay is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) */ function repayBorrowAllowed( - address cToken, + address slToken, address payer, address borrower, uint repayAmount) external returns (uint) { @@ -417,33 +417,33 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle borrower; repayAmount; - if (!markets[cToken].isListed) { + if (!markets[slToken].isListed) { return uint(Error.MARKET_NOT_LISTED); } // Keep the flywheel moving - Exp memory borrowIndex = Exp({mantissa: CToken(cToken).borrowIndex()}); - updateCompBorrowIndex(cToken, borrowIndex); - distributeBorrowerComp(cToken, borrower, borrowIndex, false); + Exp memory borrowIndex = Exp({mantissa: SLToken(slToken).borrowIndex()}); + updateSashimiBorrowIndex(slToken, borrowIndex); + distributeBorrowerSashimi(slToken, borrower, borrowIndex, false); return uint(Error.NO_ERROR); } /** * @notice Validates repayBorrow and reverts on rejection. May emit logs. - * @param cToken Asset being repaid + * @param slToken Asset being repaid * @param payer The address repaying the borrow * @param borrower The address of the borrower * @param actualRepayAmount The amount of underlying being repaid */ function repayBorrowVerify( - address cToken, + address slToken, address payer, address borrower, uint actualRepayAmount, uint borrowerIndex) external { // Shh - currently unused - cToken; + slToken; payer; borrower; actualRepayAmount; @@ -457,22 +457,22 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the liquidation should be allowed to occur - * @param cTokenBorrowed Asset which was borrowed by the borrower - * @param cTokenCollateral Asset which was used as collateral and will be seized + * @param slTokenBorrowed Asset which was borrowed by the borrower + * @param slTokenCollateral Asset which was used as collateral and will be seized * @param liquidator The address repaying the borrow and seizing the collateral * @param borrower The address of the borrower * @param repayAmount The amount of underlying being repaid */ function liquidateBorrowAllowed( - address cTokenBorrowed, - address cTokenCollateral, + address slTokenBorrowed, + address slTokenCollateral, address liquidator, address borrower, uint repayAmount) external returns (uint) { // Shh - currently unused liquidator; - if (!markets[cTokenBorrowed].isListed || !markets[cTokenCollateral].isListed) { + if (!markets[slTokenBorrowed].isListed || !markets[slTokenCollateral].isListed) { return uint(Error.MARKET_NOT_LISTED); } @@ -486,7 +486,7 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle } /* The liquidator may not repay more than what is allowed by the closeFactor */ - uint borrowBalance = CToken(cTokenBorrowed).borrowBalanceStored(borrower); + uint borrowBalance = SLToken(slTokenBorrowed).borrowBalanceStored(borrower); (MathError mathErr, uint maxClose) = mulScalarTruncate(Exp({mantissa: closeFactorMantissa}), borrowBalance); if (mathErr != MathError.NO_ERROR) { return uint(Error.MATH_ERROR); @@ -500,22 +500,22 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Validates liquidateBorrow and reverts on rejection. May emit logs. - * @param cTokenBorrowed Asset which was borrowed by the borrower - * @param cTokenCollateral Asset which was used as collateral and will be seized + * @param slTokenBorrowed Asset which was borrowed by the borrower + * @param slTokenCollateral Asset which was used as collateral and will be seized * @param liquidator The address repaying the borrow and seizing the collateral * @param borrower The address of the borrower * @param actualRepayAmount The amount of underlying being repaid */ function liquidateBorrowVerify( - address cTokenBorrowed, - address cTokenCollateral, + address slTokenBorrowed, + address slTokenCollateral, address liquidator, address borrower, uint actualRepayAmount, uint seizeTokens) external { // Shh - currently unused - cTokenBorrowed; - cTokenCollateral; + slTokenBorrowed; + slTokenCollateral; liquidator; borrower; actualRepayAmount; @@ -529,15 +529,15 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the seizing of assets should be allowed to occur - * @param cTokenCollateral Asset which was used as collateral and will be seized - * @param cTokenBorrowed Asset which was borrowed by the borrower + * @param slTokenCollateral Asset which was used as collateral and will be seized + * @param slTokenBorrowed Asset which was borrowed by the borrower * @param liquidator The address repaying the borrow and seizing the collateral * @param borrower The address of the borrower * @param seizeTokens The number of collateral tokens to seize */ function seizeAllowed( - address cTokenCollateral, - address cTokenBorrowed, + address slTokenCollateral, + address slTokenBorrowed, address liquidator, address borrower, uint seizeTokens) external returns (uint) { @@ -547,39 +547,39 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle // Shh - currently unused seizeTokens; - if (!markets[cTokenCollateral].isListed || !markets[cTokenBorrowed].isListed) { + if (!markets[slTokenCollateral].isListed || !markets[slTokenBorrowed].isListed) { return uint(Error.MARKET_NOT_LISTED); } - if (CToken(cTokenCollateral).comptroller() != CToken(cTokenBorrowed).comptroller()) { + if (SLToken(slTokenCollateral).comptroller() != SLToken(slTokenBorrowed).comptroller()) { return uint(Error.COMPTROLLER_MISMATCH); } // Keep the flywheel moving - updateCompSupplyIndex(cTokenCollateral); - distributeSupplierComp(cTokenCollateral, borrower, false); - distributeSupplierComp(cTokenCollateral, liquidator, false); + updateSashimiSupplyIndex(slTokenCollateral); + distributeSupplierSashimi(slTokenCollateral, borrower, false); + distributeSupplierSashimi(slTokenCollateral, liquidator, false); return uint(Error.NO_ERROR); } /** * @notice Validates seize and reverts on rejection. May emit logs. - * @param cTokenCollateral Asset which was used as collateral and will be seized - * @param cTokenBorrowed Asset which was borrowed by the borrower + * @param slTokenCollateral Asset which was used as collateral and will be seized + * @param slTokenBorrowed Asset which was borrowed by the borrower * @param liquidator The address repaying the borrow and seizing the collateral * @param borrower The address of the borrower * @param seizeTokens The number of collateral tokens to seize */ function seizeVerify( - address cTokenCollateral, - address cTokenBorrowed, + address slTokenCollateral, + address slTokenBorrowed, address liquidator, address borrower, uint seizeTokens) external { // Shh - currently unused - cTokenCollateral; - cTokenBorrowed; + slTokenCollateral; + slTokenBorrowed; liquidator; borrower; seizeTokens; @@ -592,41 +592,41 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Checks if the account should be allowed to transfer tokens in the given market - * @param cToken The market to verify the transfer against + * @param slToken The market to verify the transfer against * @param src The account which sources the tokens * @param dst The account which receives the tokens - * @param transferTokens The number of cTokens to transfer + * @param transferTokens The number of slTokens to transfer * @return 0 if the transfer is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) */ - function transferAllowed(address cToken, address src, address dst, uint transferTokens) external returns (uint) { + function transferAllowed(address slToken, address src, address dst, uint transferTokens) external returns (uint) { // Pausing is a very serious situation - we revert to sound the alarms require(!transferGuardianPaused, "transfer is paused"); // Currently the only consideration is whether or not // the src is allowed to redeem this many tokens - uint allowed = redeemAllowedInternal(cToken, src, transferTokens); + uint allowed = redeemAllowedInternal(slToken, src, transferTokens); if (allowed != uint(Error.NO_ERROR)) { return allowed; } // Keep the flywheel moving - updateCompSupplyIndex(cToken); - distributeSupplierComp(cToken, src, false); - distributeSupplierComp(cToken, dst, false); + updateSashimiSupplyIndex(slToken); + distributeSupplierSashimi(slToken, src, false); + distributeSupplierSashimi(slToken, dst, false); return uint(Error.NO_ERROR); } /** * @notice Validates transfer and reverts on rejection. May emit logs. - * @param cToken Asset being transferred + * @param slToken Asset being transferred * @param src The account which sources the tokens * @param dst The account which receives the tokens - * @param transferTokens The number of cTokens to transfer + * @param transferTokens The number of slTokens to transfer */ - function transferVerify(address cToken, address src, address dst, uint transferTokens) external { + function transferVerify(address slToken, address src, address dst, uint transferTokens) external { // Shh - currently unused - cToken; + slToken; src; dst; transferTokens; @@ -641,13 +641,13 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @dev Local vars for avoiding stack-depth limits in calculating account liquidity. - * Note that `cTokenBalance` is the number of cTokens the account owns in the market, + * Note that `slTokenBalance` is the number of slTokens the account owns in the market, * whereas `borrowBalance` is the amount of underlying that the account has borrowed. */ struct AccountLiquidityLocalVars { uint sumCollateral; uint sumBorrowPlusEffects; - uint cTokenBalance; + uint slTokenBalance; uint borrowBalance; uint exchangeRateMantissa; uint oraclePriceMantissa; @@ -664,7 +664,7 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle * account shortfall below collateral requirements) */ function getAccountLiquidity(address account) public view returns (uint, uint, uint) { - (Error err, uint liquidity, uint shortfall) = getHypotheticalAccountLiquidityInternal(account, CToken(0), 0, 0); + (Error err, uint liquidity, uint shortfall) = getHypotheticalAccountLiquidityInternal(account, SLToken(0), 0, 0); return (uint(err), liquidity, shortfall); } @@ -676,12 +676,12 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle * account shortfall below collateral requirements) */ function getAccountLiquidityInternal(address account) internal view returns (Error, uint, uint) { - return getHypotheticalAccountLiquidityInternal(account, CToken(0), 0, 0); + return getHypotheticalAccountLiquidityInternal(account, SLToken(0), 0, 0); } /** * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed - * @param cTokenModify The market to hypothetically redeem/borrow in + * @param slTokenModify The market to hypothetically redeem/borrow in * @param account The account to determine liquidity for * @param redeemTokens The number of tokens to hypothetically redeem * @param borrowAmount The amount of underlying to hypothetically borrow @@ -691,20 +691,20 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle */ function getHypotheticalAccountLiquidity( address account, - address cTokenModify, + address slTokenModify, uint redeemTokens, uint borrowAmount) public view returns (uint, uint, uint) { - (Error err, uint liquidity, uint shortfall) = getHypotheticalAccountLiquidityInternal(account, CToken(cTokenModify), redeemTokens, borrowAmount); + (Error err, uint liquidity, uint shortfall) = getHypotheticalAccountLiquidityInternal(account, SLToken(slTokenModify), redeemTokens, borrowAmount); return (uint(err), liquidity, shortfall); } /** * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed - * @param cTokenModify The market to hypothetically redeem/borrow in + * @param slTokenModify The market to hypothetically redeem/borrow in * @param account The account to determine liquidity for * @param redeemTokens The number of tokens to hypothetically redeem * @param borrowAmount The amount of underlying to hypothetically borrow - * @dev Note that we calculate the exchangeRateStored for each collateral cToken using stored data, + * @dev Note that we calculate the exchangeRateStored for each collateral slToken using stored data, * without calculating accumulated interest. * @return (possible error code, hypothetical account liquidity in excess of collateral requirements, @@ -712,7 +712,7 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle */ function getHypotheticalAccountLiquidityInternal( address account, - CToken cTokenModify, + SLToken slTokenModify, uint redeemTokens, uint borrowAmount) internal view returns (Error, uint, uint) { @@ -721,12 +721,12 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle MathError mErr; // For each asset the account is in - CToken[] memory assets = accountAssets[account]; + SLToken[] memory assets = accountAssets[account]; for (uint i = 0; i < assets.length; i++) { - CToken asset = assets[i]; + SLToken asset = assets[i]; - // Read the balances and exchange rate from the cToken - (oErr, vars.cTokenBalance, vars.borrowBalance, vars.exchangeRateMantissa) = asset.getAccountSnapshot(account); + // Read the balances and exchange rate from the slToken + (oErr, vars.slTokenBalance, vars.borrowBalance, vars.exchangeRateMantissa) = asset.getAccountSnapshot(account); if (oErr != 0) { // semi-opaque error code, we assume NO_ERROR == 0 is invariant between upgrades return (Error.SNAPSHOT_ERROR, 0, 0); } @@ -746,8 +746,8 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle return (Error.MATH_ERROR, 0, 0); } - // sumCollateral += tokensToDenom * cTokenBalance - (mErr, vars.sumCollateral) = mulScalarTruncateAddUInt(vars.tokensToDenom, vars.cTokenBalance, vars.sumCollateral); + // sumCollateral += tokensToDenom * slTokenBalance + (mErr, vars.sumCollateral) = mulScalarTruncateAddUInt(vars.tokensToDenom, vars.slTokenBalance, vars.sumCollateral); if (mErr != MathError.NO_ERROR) { return (Error.MATH_ERROR, 0, 0); } @@ -758,8 +758,8 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle return (Error.MATH_ERROR, 0, 0); } - // Calculate effects of interacting with cTokenModify - if (asset == cTokenModify) { + // Calculate effects of interacting with slTokenModify + if (asset == slTokenModify) { // redeem effect // sumBorrowPlusEffects += tokensToDenom * redeemTokens (mErr, vars.sumBorrowPlusEffects) = mulScalarTruncateAddUInt(vars.tokensToDenom, redeemTokens, vars.sumBorrowPlusEffects); @@ -786,16 +786,16 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Calculate number of tokens of collateral asset to seize given an underlying amount - * @dev Used in liquidation (called in cToken.liquidateBorrowFresh) - * @param cTokenBorrowed The address of the borrowed cToken - * @param cTokenCollateral The address of the collateral cToken - * @param actualRepayAmount The amount of cTokenBorrowed underlying to convert into cTokenCollateral tokens - * @return (errorCode, number of cTokenCollateral tokens to be seized in a liquidation) + * @dev Used in liquidation (called in slToken.liquidateBorrowFresh) + * @param slTokenBorrowed The address of the borrowed slToken + * @param slTokenCollateral The address of the collateral slToken + * @param actualRepayAmount The amount of slTokenBorrowed underlying to convert into slTokenCollateral tokens + * @return (errorCode, number of slTokenCollateral tokens to be seized in a liquidation) */ - function liquidateCalculateSeizeTokens(address cTokenBorrowed, address cTokenCollateral, uint actualRepayAmount) external view returns (uint, uint) { + function liquidateCalculateSeizeTokens(address slTokenBorrowed, address slTokenCollateral, uint actualRepayAmount) external view returns (uint, uint) { /* Read oracle prices for borrowed and collateral markets */ - uint priceBorrowedMantissa = oracle.getUnderlyingPrice(CToken(cTokenBorrowed)); - uint priceCollateralMantissa = oracle.getUnderlyingPrice(CToken(cTokenCollateral)); + uint priceBorrowedMantissa = oracle.getUnderlyingPrice(SLToken(slTokenBorrowed)); + uint priceCollateralMantissa = oracle.getUnderlyingPrice(SLToken(slTokenCollateral)); if (priceBorrowedMantissa == 0 || priceCollateralMantissa == 0) { return (uint(Error.PRICE_ERROR), 0); } @@ -806,7 +806,7 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle * seizeTokens = seizeAmount / exchangeRate * = actualRepayAmount * (liquidationIncentive * priceBorrowed) / (priceCollateral * exchangeRate) */ - uint exchangeRateMantissa = CToken(cTokenCollateral).exchangeRateStored(); // Note: reverts on error + uint exchangeRateMantissa = SLToken(slTokenCollateral).exchangeRateStored(); // Note: reverts on error uint seizeTokens; Exp memory numerator; Exp memory denominator; @@ -894,18 +894,18 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Sets the collateralFactor for a market * @dev Admin function to set per-market collateralFactor - * @param cToken The market to set the factor on + * @param slToken The market to set the factor on * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18 * @return uint 0=success, otherwise a failure. (See ErrorReporter for details) */ - function _setCollateralFactor(CToken cToken, uint newCollateralFactorMantissa) external returns (uint) { + function _setCollateralFactor(SLToken slToken, uint newCollateralFactorMantissa) external returns (uint) { // Check caller is admin if (msg.sender != admin) { return fail(Error.UNAUTHORIZED, FailureInfo.SET_COLLATERAL_FACTOR_OWNER_CHECK); } // Verify market is listed - Market storage market = markets[address(cToken)]; + Market storage market = markets[address(slToken)]; if (!market.isListed) { return fail(Error.MARKET_NOT_LISTED, FailureInfo.SET_COLLATERAL_FACTOR_NO_EXISTS); } @@ -919,7 +919,7 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle } // If collateral factor != 0, fail if price == 0 - if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(cToken) == 0) { + if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(slToken) == 0) { return fail(Error.PRICE_ERROR, FailureInfo.SET_COLLATERAL_FACTOR_WITHOUT_PRICE); } @@ -928,7 +928,7 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle market.collateralFactorMantissa = newCollateralFactorMantissa; // Emit event with asset, old collateral factor, and new collateral factor - emit NewCollateralFactor(cToken, oldCollateralFactorMantissa, newCollateralFactorMantissa); + emit NewCollateralFactor(slToken, oldCollateralFactorMantissa, newCollateralFactorMantissa); return uint(Error.NO_ERROR); } @@ -991,34 +991,34 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle /** * @notice Add the market to the markets mapping and set it as listed * @dev Admin function to set isListed and add support for the market - * @param cToken The address of the market (token) to list + * @param slToken The address of the market (token) to list * @return uint 0=success, otherwise a failure. (See enum Error for details) */ - function _supportMarket(CToken cToken) external returns (uint) { + function _supportMarket(SLToken slToken) external returns (uint) { if (msg.sender != admin) { return fail(Error.UNAUTHORIZED, FailureInfo.SUPPORT_MARKET_OWNER_CHECK); } - if (markets[address(cToken)].isListed) { + if (markets[address(slToken)].isListed) { return fail(Error.MARKET_ALREADY_LISTED, FailureInfo.SUPPORT_MARKET_EXISTS); } - cToken.isCToken(); // Sanity check to make sure its really a CToken + slToken.isSLToken(); // Sanity check to make sure its really a SLToken - markets[address(cToken)] = Market({isListed: true, isComped: false, collateralFactorMantissa: 0}); + markets[address(slToken)] = Market({isListed: true, isSashimied: false, collateralFactorMantissa: 0}); - _addMarketInternal(address(cToken)); + _addMarketInternal(address(slToken)); - emit MarketListed(cToken); + emit MarketListed(slToken); return uint(Error.NO_ERROR); } - function _addMarketInternal(address cToken) internal { + function _addMarketInternal(address slToken) internal { for (uint i = 0; i < allMarkets.length; i ++) { - require(allMarkets[i] != CToken(cToken), "market already added"); + require(allMarkets[i] != SLToken(slToken), "market already added"); } - allMarkets.push(CToken(cToken)); + allMarkets.push(SLToken(slToken)); } /** @@ -1043,23 +1043,23 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle return uint(Error.NO_ERROR); } - function _setMintPaused(CToken cToken, bool state) public returns (bool) { - require(markets[address(cToken)].isListed, "cannot pause a market that is not listed"); + function _setMintPaused(SLToken slToken, bool state) public returns (bool) { + require(markets[address(slToken)].isListed, "cannot pause a market that is not listed"); require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause"); require(msg.sender == admin || state == true, "only admin can unpause"); - mintGuardianPaused[address(cToken)] = state; - emit ActionPaused(cToken, "Mint", state); + mintGuardianPaused[address(slToken)] = state; + emit ActionPaused(slToken, "Mint", state); return state; } - function _setBorrowPaused(CToken cToken, bool state) public returns (bool) { - require(markets[address(cToken)].isListed, "cannot pause a market that is not listed"); + function _setBorrowPaused(SLToken slToken, bool state) public returns (bool) { + require(markets[address(slToken)].isListed, "cannot pause a market that is not listed"); require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause"); require(msg.sender == admin || state == true, "only admin can unpause"); - borrowGuardianPaused[address(cToken)] = state; - emit ActionPaused(cToken, "Borrow", state); + borrowGuardianPaused[address(slToken)] = state; + emit ActionPaused(slToken, "Borrow", state); return state; } @@ -1093,61 +1093,61 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle return msg.sender == admin || msg.sender == comptrollerImplementation; } - /*** Comp Distribution ***/ + /*** Sashimi Distribution ***/ /** - * @notice Recalculate and update COMP speeds for all COMP markets + * @notice Recalculate and update SASHIMI speeds for all SASHIMI markets */ - function refreshCompSpeeds() public { + function refreshSashimiSpeeds() public { require(msg.sender == tx.origin, "only externally owned accounts may refresh speeds"); - refreshCompSpeedsInternal(); + refreshSashimiSpeedsInternal(); } - function refreshCompSpeedsInternal() internal { - CToken[] memory allMarkets_ = allMarkets; + function refreshSashimiSpeedsInternal() internal { + SLToken[] memory allMarkets_ = allMarkets; for (uint i = 0; i < allMarkets_.length; i++) { - CToken cToken = allMarkets_[i]; - Exp memory borrowIndex = Exp({mantissa: cToken.borrowIndex()}); - updateCompSupplyIndex(address(cToken)); - updateCompBorrowIndex(address(cToken), borrowIndex); + SLToken slToken = allMarkets_[i]; + Exp memory borrowIndex = Exp({mantissa: slToken.borrowIndex()}); + updateSashimiSupplyIndex(address(slToken)); + updateSashimiBorrowIndex(address(slToken), borrowIndex); } Exp memory totalUtility = Exp({mantissa: 0}); Exp[] memory utilities = new Exp[](allMarkets_.length); for (uint i = 0; i < allMarkets_.length; i++) { - CToken cToken = allMarkets_[i]; - if (markets[address(cToken)].isComped) { - Exp memory assetPrice = Exp({mantissa: oracle.getUnderlyingPrice(cToken)}); - Exp memory utility = mul_(assetPrice, cToken.totalBorrows()); + SLToken slToken = allMarkets_[i]; + if (markets[address(slToken)].isSashimied) { + Exp memory assetPrice = Exp({mantissa: oracle.getUnderlyingPrice(slToken)}); + Exp memory utility = mul_(assetPrice, slToken.totalBorrows()); utilities[i] = utility; totalUtility = add_(totalUtility, utility); } } for (uint i = 0; i < allMarkets_.length; i++) { - CToken cToken = allMarkets[i]; - uint newSpeed = totalUtility.mantissa > 0 ? mul_(compRate, div_(utilities[i], totalUtility)) : 0; - compSpeeds[address(cToken)] = newSpeed; - emit CompSpeedUpdated(cToken, newSpeed); + SLToken slToken = allMarkets[i]; + uint newSpeed = totalUtility.mantissa > 0 ? mul_(sashimiRate, div_(utilities[i], totalUtility)) : 0; + sashimiSpeeds[address(slToken)] = newSpeed; + emit SashimiSpeedUpdated(slToken, newSpeed); } } /** - * @notice Accrue COMP to the market by updating the supply index - * @param cToken The market whose supply index to update + * @notice Accrue SASHIMI to the market by updating the supply index + * @param slToken The market whose supply index to update */ - function updateCompSupplyIndex(address cToken) internal { - CompMarketState storage supplyState = compSupplyState[cToken]; - uint supplySpeed = compSpeeds[cToken]; + function updateSashimiSupplyIndex(address slToken) internal { + SashimiMarketState storage supplyState = sashimiSupplyState[slToken]; + uint supplySpeed = sashimiSpeeds[slToken]; uint blockNumber = getBlockNumber(); uint deltaBlocks = sub_(blockNumber, uint(supplyState.block)); if (deltaBlocks > 0 && supplySpeed > 0) { - uint supplyTokens = CToken(cToken).totalSupply(); - uint compAccrued = mul_(deltaBlocks, supplySpeed); - Double memory ratio = supplyTokens > 0 ? fraction(compAccrued, supplyTokens) : Double({mantissa: 0}); + uint supplyTokens = SLToken(slToken).totalSupply(); + uint sashimiAccrued = mul_(deltaBlocks, supplySpeed); + Double memory ratio = supplyTokens > 0 ? fraction(sashimiAccrued, supplyTokens) : Double({mantissa: 0}); Double memory index = add_(Double({mantissa: supplyState.index}), ratio); - compSupplyState[cToken] = CompMarketState({ + sashimiSupplyState[slToken] = SashimiMarketState({ index: safe224(index.mantissa, "new index exceeds 224 bits"), block: safe32(blockNumber, "block number exceeds 32 bits") }); @@ -1157,20 +1157,20 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle } /** - * @notice Accrue COMP to the market by updating the borrow index - * @param cToken The market whose borrow index to update + * @notice Accrue SASHIMI to the market by updating the borrow index + * @param slToken The market whose borrow index to update */ - function updateCompBorrowIndex(address cToken, Exp memory marketBorrowIndex) internal { - CompMarketState storage borrowState = compBorrowState[cToken]; - uint borrowSpeed = compSpeeds[cToken]; + function updateSashimiBorrowIndex(address slToken, Exp memory marketBorrowIndex) internal { + SashimiMarketState storage borrowState = sashimiBorrowState[slToken]; + uint borrowSpeed = sashimiSpeeds[slToken]; uint blockNumber = getBlockNumber(); uint deltaBlocks = sub_(blockNumber, uint(borrowState.block)); if (deltaBlocks > 0 && borrowSpeed > 0) { - uint borrowAmount = div_(CToken(cToken).totalBorrows(), marketBorrowIndex); - uint compAccrued = mul_(deltaBlocks, borrowSpeed); - Double memory ratio = borrowAmount > 0 ? fraction(compAccrued, borrowAmount) : Double({mantissa: 0}); + uint borrowAmount = div_(SLToken(slToken).totalBorrows(), marketBorrowIndex); + uint sashimiAccrued = mul_(deltaBlocks, borrowSpeed); + Double memory ratio = borrowAmount > 0 ? fraction(sashimiAccrued, borrowAmount) : Double({mantissa: 0}); Double memory index = add_(Double({mantissa: borrowState.index}), ratio); - compBorrowState[cToken] = CompMarketState({ + sashimiBorrowState[slToken] = SashimiMarketState({ index: safe224(index.mantissa, "new index exceeds 224 bits"), block: safe32(blockNumber, "block number exceeds 32 bits") }); @@ -1180,63 +1180,63 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle } /** - * @notice Calculate COMP accrued by a supplier and possibly transfer it to them - * @param cToken The market in which the supplier is interacting - * @param supplier The address of the supplier to distribute COMP to + * @notice Calculate SASHIMI accrued by a supplier and possibly transfer it to them + * @param slToken The market in which the supplier is interacting + * @param supplier The address of the supplier to distribute SASHIMI to */ - function distributeSupplierComp(address cToken, address supplier, bool distributeAll) internal { - CompMarketState storage supplyState = compSupplyState[cToken]; + function distributeSupplierSashimi(address slToken, address supplier, bool distributeAll) internal { + SashimiMarketState storage supplyState = sashimiSupplyState[slToken]; Double memory supplyIndex = Double({mantissa: supplyState.index}); - Double memory supplierIndex = Double({mantissa: compSupplierIndex[cToken][supplier]}); - compSupplierIndex[cToken][supplier] = supplyIndex.mantissa; + Double memory supplierIndex = Double({mantissa: sashimiSupplierIndex[slToken][supplier]}); + sashimiSupplierIndex[slToken][supplier] = supplyIndex.mantissa; if (supplierIndex.mantissa == 0 && supplyIndex.mantissa > 0) { - supplierIndex.mantissa = compInitialIndex; + supplierIndex.mantissa = sashimiInitialIndex; } Double memory deltaIndex = sub_(supplyIndex, supplierIndex); - uint supplierTokens = CToken(cToken).balanceOf(supplier); + uint supplierTokens = SLToken(slToken).balanceOf(supplier); uint supplierDelta = mul_(supplierTokens, deltaIndex); - uint supplierAccrued = add_(compAccrued[supplier], supplierDelta); - compAccrued[supplier] = transferComp(supplier, supplierAccrued, distributeAll ? 0 : compClaimThreshold); - emit DistributedSupplierComp(CToken(cToken), supplier, supplierDelta, supplyIndex.mantissa); + uint supplierAccrued = add_(sashimiAccrued[supplier], supplierDelta); + sashimiAccrued[supplier] = transferSashimi(supplier, supplierAccrued, distributeAll ? 0 : sashimiClaimThreshold); + emit DistributedSupplierSashimi(SLToken(slToken), supplier, supplierDelta, supplyIndex.mantissa); } /** - * @notice Calculate COMP accrued by a borrower and possibly transfer it to them + * @notice Calculate SASHIMI accrued by a borrower and possibly transfer it to them * @dev Borrowers will not begin to accrue until after the first interaction with the protocol. - * @param cToken The market in which the borrower is interacting - * @param borrower The address of the borrower to distribute COMP to + * @param slToken The market in which the borrower is interacting + * @param borrower The address of the borrower to distribute SASHIMI to */ - function distributeBorrowerComp(address cToken, address borrower, Exp memory marketBorrowIndex, bool distributeAll) internal { - CompMarketState storage borrowState = compBorrowState[cToken]; + function distributeBorrowerSashimi(address slToken, address borrower, Exp memory marketBorrowIndex, bool distributeAll) internal { + SashimiMarketState storage borrowState = sashimiBorrowState[slToken]; Double memory borrowIndex = Double({mantissa: borrowState.index}); - Double memory borrowerIndex = Double({mantissa: compBorrowerIndex[cToken][borrower]}); - compBorrowerIndex[cToken][borrower] = borrowIndex.mantissa; + Double memory borrowerIndex = Double({mantissa: sashimiBorrowerIndex[slToken][borrower]}); + sashimiBorrowerIndex[slToken][borrower] = borrowIndex.mantissa; if (borrowerIndex.mantissa > 0) { Double memory deltaIndex = sub_(borrowIndex, borrowerIndex); - uint borrowerAmount = div_(CToken(cToken).borrowBalanceStored(borrower), marketBorrowIndex); + uint borrowerAmount = div_(SLToken(slToken).borrowBalanceStored(borrower), marketBorrowIndex); uint borrowerDelta = mul_(borrowerAmount, deltaIndex); - uint borrowerAccrued = add_(compAccrued[borrower], borrowerDelta); - compAccrued[borrower] = transferComp(borrower, borrowerAccrued, distributeAll ? 0 : compClaimThreshold); - emit DistributedBorrowerComp(CToken(cToken), borrower, borrowerDelta, borrowIndex.mantissa); + uint borrowerAccrued = add_(sashimiAccrued[borrower], borrowerDelta); + sashimiAccrued[borrower] = transferSashimi(borrower, borrowerAccrued, distributeAll ? 0 : sashimiClaimThreshold); + emit DistributedBorrowerSashimi(SLToken(slToken), borrower, borrowerDelta, borrowIndex.mantissa); } } /** - * @notice Transfer COMP to the user, if they are above the threshold - * @dev Note: If there is not enough COMP, we do not perform the transfer all. - * @param user The address of the user to transfer COMP to - * @param userAccrued The amount of COMP to (possibly) transfer - * @return The amount of COMP which was NOT transferred to the user + * @notice Transfer SASHIMI to the user, if they are above the threshold + * @dev Note: If there is not enough SASHIMI, we do not perform the transfer all. + * @param user The address of the user to transfer SASHIMI to + * @param userAccrued The amount of SASHIMI to (possibly) transfer + * @return The amount of SASHIMI which was NOT transferred to the user */ - function transferComp(address user, uint userAccrued, uint threshold) internal returns (uint) { + function transferSashimi(address user, uint userAccrued, uint threshold) internal returns (uint) { if (userAccrued >= threshold && userAccrued > 0) { - Comp comp = Comp(getCompAddress()); - uint compRemaining = comp.balanceOf(address(this)); - if (userAccrued <= compRemaining) { - comp.transfer(user, userAccrued); + EIP20Interface sashimi = EIP20Interface(getSashimiAddress()); + uint sashimiRemaining = sashimi.balanceOf(address(this)); + if (userAccrued <= sashimiRemaining) { + sashimi.transfer(user, userAccrued); return 0; } } @@ -1244,118 +1244,118 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle } /** - * @notice Claim all the comp accrued by holder in all markets - * @param holder The address to claim COMP for + * @notice Claim all the sashimi accrued by holder in all markets + * @param holder The address to claim SASHIMI for */ - function claimComp(address holder) public { - return claimComp(holder, allMarkets); + function claimSashimi(address holder) public { + return claimSashimi(holder, allMarkets); } /** - * @notice Claim all the comp accrued by holder in the specified markets - * @param holder The address to claim COMP for - * @param cTokens The list of markets to claim COMP in + * @notice Claim all the sashimi accrued by holder in the specified markets + * @param holder The address to claim SASHIMI for + * @param slTokens The list of markets to claim SASHIMI in */ - function claimComp(address holder, CToken[] memory cTokens) public { + function claimSashimi(address holder, SLToken[] memory slTokens) public { address[] memory holders = new address[](1); holders[0] = holder; - claimComp(holders, cTokens, true, true); + claimSashimi(holders, slTokens, true, true); } /** - * @notice Claim all comp accrued by the holders - * @param holders The addresses to claim COMP for - * @param cTokens The list of markets to claim COMP in - * @param borrowers Whether or not to claim COMP earned by borrowing - * @param suppliers Whether or not to claim COMP earned by supplying + * @notice Claim all sashimi accrued by the holders + * @param holders The addresses to claim SASHIMI for + * @param slTokens The list of markets to claim SASHIMI in + * @param borrowers Whether or not to claim SASHIMI earned by borrowing + * @param suppliers Whether or not to claim SASHIMI earned by supplying */ - function claimComp(address[] memory holders, CToken[] memory cTokens, bool borrowers, bool suppliers) public { - for (uint i = 0; i < cTokens.length; i++) { - CToken cToken = cTokens[i]; - require(markets[address(cToken)].isListed, "market must be listed"); + function claimSashimi(address[] memory holders, SLToken[] memory slTokens, bool borrowers, bool suppliers) public { + for (uint i = 0; i < slTokens.length; i++) { + SLToken slToken = slTokens[i]; + require(markets[address(slToken)].isListed, "market must be listed"); if (borrowers == true) { - Exp memory borrowIndex = Exp({mantissa: cToken.borrowIndex()}); - updateCompBorrowIndex(address(cToken), borrowIndex); + Exp memory borrowIndex = Exp({mantissa: slToken.borrowIndex()}); + updateSashimiBorrowIndex(address(slToken), borrowIndex); for (uint j = 0; j < holders.length; j++) { - distributeBorrowerComp(address(cToken), holders[j], borrowIndex, true); + distributeBorrowerSashimi(address(slToken), holders[j], borrowIndex, true); } } if (suppliers == true) { - updateCompSupplyIndex(address(cToken)); + updateSashimiSupplyIndex(address(slToken)); for (uint j = 0; j < holders.length; j++) { - distributeSupplierComp(address(cToken), holders[j], true); + distributeSupplierSashimi(address(slToken), holders[j], true); } } } } - /*** Comp Distribution Admin ***/ + /*** Sashimi Distribution Admin ***/ /** - * @notice Set the amount of COMP distributed per block - * @param compRate_ The amount of COMP wei per block to distribute + * @notice Set the amount of SASHIMI distributed per block + * @param sashimiRate_ The amount of SASHIMI wei per block to distribute */ - function _setCompRate(uint compRate_) public { - require(adminOrInitializing(), "only admin can change comp rate"); + function _setSashimiRate(uint sashimiRate_) public { + require(adminOrInitializing(), "only admin can change sashimi rate"); - uint oldRate = compRate; - compRate = compRate_; - emit NewCompRate(oldRate, compRate_); + uint oldRate = sashimiRate; + sashimiRate = sashimiRate_; + emit NewSashimiRate(oldRate, sashimiRate_); - refreshCompSpeedsInternal(); + refreshSashimiSpeedsInternal(); } /** - * @notice Add markets to compMarkets, allowing them to earn COMP in the flywheel - * @param cTokens The addresses of the markets to add + * @notice Add markets to sashimiMarkets, allowing them to earn SASHIMI in the flywheel + * @param slTokens The addresses of the markets to add */ - function _addCompMarkets(address[] memory cTokens) public { - require(adminOrInitializing(), "only admin can add comp market"); + function _addSashimiMarkets(address[] memory slTokens) public { + require(adminOrInitializing(), "only admin can add sashimi market"); - for (uint i = 0; i < cTokens.length; i++) { - _addCompMarketInternal(cTokens[i]); + for (uint i = 0; i < slTokens.length; i++) { + _addSashimiMarketInternal(slTokens[i]); } - refreshCompSpeedsInternal(); + refreshSashimiSpeedsInternal(); } - function _addCompMarketInternal(address cToken) internal { - Market storage market = markets[cToken]; - require(market.isListed == true, "comp market is not listed"); - require(market.isComped == false, "comp market already added"); + function _addSashimiMarketInternal(address slToken) internal { + Market storage market = markets[slToken]; + require(market.isListed == true, "sashimi market is not listed"); + require(market.isSashimied == false, "sashimi market already added"); - market.isComped = true; - emit MarketComped(CToken(cToken), true); + market.isSashimied = true; + emit MarketSashimied(SLToken(slToken), true); - if (compSupplyState[cToken].index == 0 && compSupplyState[cToken].block == 0) { - compSupplyState[cToken] = CompMarketState({ - index: compInitialIndex, + if (sashimiSupplyState[slToken].index == 0 && sashimiSupplyState[slToken].block == 0) { + sashimiSupplyState[slToken] = SashimiMarketState({ + index: sashimiInitialIndex, block: safe32(getBlockNumber(), "block number exceeds 32 bits") }); } - if (compBorrowState[cToken].index == 0 && compBorrowState[cToken].block == 0) { - compBorrowState[cToken] = CompMarketState({ - index: compInitialIndex, + if (sashimiBorrowState[slToken].index == 0 && sashimiBorrowState[slToken].block == 0) { + sashimiBorrowState[slToken] = SashimiMarketState({ + index: sashimiInitialIndex, block: safe32(getBlockNumber(), "block number exceeds 32 bits") }); } } /** - * @notice Remove a market from compMarkets, preventing it from earning COMP in the flywheel - * @param cToken The address of the market to drop + * @notice Remove a market from sashimiMarkets, preventing it from earning SASHIMI in the flywheel + * @param slToken The address of the market to drop */ - function _dropCompMarket(address cToken) public { - require(msg.sender == admin, "only admin can drop comp market"); + function _dropSashimiMarket(address slToken) public { + require(msg.sender == admin, "only admin can drop sashimi market"); - Market storage market = markets[cToken]; - require(market.isComped == true, "market is not a comp market"); + Market storage market = markets[slToken]; + require(market.isSashimied == true, "market is not a sashimi market"); - market.isComped = false; - emit MarketComped(CToken(cToken), false); + market.isSashimied = false; + emit MarketSashimied(SLToken(slToken), false); - refreshCompSpeedsInternal(); + refreshSashimiSpeedsInternal(); } /** @@ -1363,7 +1363,7 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle * @dev The automatic getter may be used to access an individual market. * @return The list of market addresses */ - function getAllMarkets() public view returns (CToken[] memory) { + function getAllMarkets() public view returns (SLToken[] memory) { return allMarkets; } @@ -1372,10 +1372,10 @@ contract ComptrollerG4 is ComptrollerV3Storage, ComptrollerInterface, Comptrolle } /** - * @notice Return the address of the COMP token - * @return The address of COMP + * @notice Return the address of the SASHIMI token + * @return The address of SASHIMI */ - function getCompAddress() public view returns (address) { + function getSashimiAddress() public view returns (address) { return 0xc00e94Cb662C3520282E6f5717214004A7f26888; } } diff --git a/contracts/ComptrollerInterface.sol b/contracts/ComptrollerInterface.sol index ce63c7849..fe242b8c0 100644 --- a/contracts/ComptrollerInterface.sol +++ b/contracts/ComptrollerInterface.sol @@ -6,66 +6,66 @@ contract ComptrollerInterface { /*** Assets You Are In ***/ - function enterMarkets(address[] calldata cTokens) external returns (uint[] memory); - function exitMarket(address cToken) external returns (uint); + function enterMarkets(address[] calldata slTokens) external returns (uint[] memory); + function exitMarket(address slToken) external returns (uint); /*** Policy Hooks ***/ - function mintAllowed(address cToken, address minter, uint mintAmount) external returns (uint); - function mintVerify(address cToken, address minter, uint mintAmount, uint mintTokens) external; + function mintAllowed(address slToken, address minter, uint mintAmount) external returns (uint); + function mintVerify(address slToken, address minter, uint mintAmount, uint mintTokens) external; - function redeemAllowed(address cToken, address redeemer, uint redeemTokens) external returns (uint); - function redeemVerify(address cToken, address redeemer, uint redeemAmount, uint redeemTokens) external; + function redeemAllowed(address slToken, address redeemer, uint redeemTokens) external returns (uint); + function redeemVerify(address slToken, address redeemer, uint redeemAmount, uint redeemTokens) external; - function borrowAllowed(address cToken, address borrower, uint borrowAmount) external returns (uint); - function borrowVerify(address cToken, address borrower, uint borrowAmount) external; + function borrowAllowed(address slToken, address borrower, uint borrowAmount) external returns (uint); + function borrowVerify(address slToken, address borrower, uint borrowAmount) external; function repayBorrowAllowed( - address cToken, + address slToken, address payer, address borrower, uint repayAmount) external returns (uint); function repayBorrowVerify( - address cToken, + address slToken, address payer, address borrower, uint repayAmount, uint borrowerIndex) external; function liquidateBorrowAllowed( - address cTokenBorrowed, - address cTokenCollateral, + address slTokenBorrowed, + address slTokenCollateral, address liquidator, address borrower, uint repayAmount) external returns (uint); function liquidateBorrowVerify( - address cTokenBorrowed, - address cTokenCollateral, + address slTokenBorrowed, + address slTokenCollateral, address liquidator, address borrower, uint repayAmount, uint seizeTokens) external; function seizeAllowed( - address cTokenCollateral, - address cTokenBorrowed, + address slTokenCollateral, + address slTokenBorrowed, address liquidator, address borrower, uint seizeTokens) external returns (uint); function seizeVerify( - address cTokenCollateral, - address cTokenBorrowed, + address slTokenCollateral, + address slTokenBorrowed, address liquidator, address borrower, uint seizeTokens) external; - function transferAllowed(address cToken, address src, address dst, uint transferTokens) external returns (uint); - function transferVerify(address cToken, address src, address dst, uint transferTokens) external; + function transferAllowed(address slToken, address src, address dst, uint transferTokens) external returns (uint); + function transferVerify(address slToken, address src, address dst, uint transferTokens) external; /*** Liquidity/Liquidation Calculations ***/ function liquidateCalculateSeizeTokens( - address cTokenBorrowed, - address cTokenCollateral, + address slTokenBorrowed, + address slTokenCollateral, uint repayAmount) external view returns (uint, uint); } diff --git a/contracts/ComptrollerStorage.sol b/contracts/ComptrollerStorage.sol index 07429f4a2..b23679daf 100644 --- a/contracts/ComptrollerStorage.sol +++ b/contracts/ComptrollerStorage.sol @@ -1,6 +1,6 @@ pragma solidity ^0.5.16; -import "./CToken.sol"; +import "./SLToken.sol"; import "./PriceOracle.sol"; contract UnitrollerAdminStorage { @@ -50,7 +50,7 @@ contract ComptrollerV1Storage is UnitrollerAdminStorage { /** * @notice Per-account mapping of "assets you are in", capped by maxAssets */ - mapping(address => CToken[]) public accountAssets; + mapping(address => SLToken[]) public accountAssets; } @@ -69,12 +69,12 @@ contract ComptrollerV2Storage is ComptrollerV1Storage { /// @notice Per-market mapping of "accounts in this asset" mapping(address => bool) accountMembership; - /// @notice Whether or not this market receives COMP - bool isComped; + /// @notice Whether or not this market receives SASHIMI + bool isSashimied; } /** - * @notice Official mapping of cTokens -> Market metadata + * @notice Official mapping of slTokens -> Market metadata * @dev Used e.g. to determine if a market is supported */ mapping(address => Market) public markets; @@ -95,8 +95,8 @@ contract ComptrollerV2Storage is ComptrollerV1Storage { } contract ComptrollerV3Storage is ComptrollerV2Storage { - struct CompMarketState { - /// @notice The market's last updated compBorrowIndex or compSupplyIndex + struct SashimiMarketState { + /// @notice The market's last updated sashimiBorrowIndex or sashimiSupplyIndex uint224 index; /// @notice The block number the index was last updated at @@ -104,34 +104,34 @@ contract ComptrollerV3Storage is ComptrollerV2Storage { } /// @notice A list of all markets - CToken[] public allMarkets; + SLToken[] public allMarkets; - /// @notice The rate at which the flywheel distributes COMP, per block - uint public compRate; + /// @notice The rate at which the flywheel distributes SASHIMI, per block + uint public sashimiRate; - /// @notice The portion of compRate that each market currently receives - mapping(address => uint) public compSpeeds; + /// @notice The portion of sashimiRate that each market currently receives + mapping(address => uint) public sashimiSpeeds; - /// @notice The COMP market supply state for each market - mapping(address => CompMarketState) public compSupplyState; + /// @notice The SASHIMI market supply state for each market + mapping(address => SashimiMarketState) public sashimiSupplyState; - /// @notice The COMP market borrow state for each market - mapping(address => CompMarketState) public compBorrowState; + /// @notice The SASHIMI market borrow state for each market + mapping(address => SashimiMarketState) public sashimiBorrowState; - /// @notice The COMP borrow index for each market for each supplier as of the last time they accrued COMP - mapping(address => mapping(address => uint)) public compSupplierIndex; + /// @notice The SASHIMI borrow index for each market for each supplier as of the last time they accrued SASHIMI + mapping(address => mapping(address => uint)) public sashimiSupplierIndex; - /// @notice The COMP borrow index for each market for each borrower as of the last time they accrued COMP - mapping(address => mapping(address => uint)) public compBorrowerIndex; + /// @notice The SASHIMI borrow index for each market for each borrower as of the last time they accrued SASHIMI + mapping(address => mapping(address => uint)) public sashimiBorrowerIndex; - /// @notice The COMP accrued but not yet transferred to each user - mapping(address => uint) public compAccrued; + /// @notice The SASHIMI accrued but not yet transferred to each user + mapping(address => uint) public sashimiAccrued; } contract ComptrollerV4Storage is ComptrollerV3Storage { // @notice The borrowCapGuardian can set borrowCaps to any number for any market. Lowering the borrow cap could disable borrowing on the given market. address public borrowCapGuardian; - // @notice Borrow caps enforced by borrowAllowed for each cToken address. Defaults to zero which corresponds to unlimited borrowing. + // @notice Borrow caps enforced by borrowAllowed for each slToken address. Defaults to zero which corresponds to unlimited borrowing. mapping(address => uint) public borrowCaps; } diff --git a/contracts/Governance/Comp.sol b/contracts/Governance/Comp.sol deleted file mode 100644 index 6494bedce..000000000 --- a/contracts/Governance/Comp.sol +++ /dev/null @@ -1,301 +0,0 @@ -pragma solidity ^0.5.16; -pragma experimental ABIEncoderV2; - -contract Comp { - /// @notice EIP-20 token name for this token - string public constant name = "Compound"; - - /// @notice EIP-20 token symbol for this token - string public constant symbol = "COMP"; - - /// @notice EIP-20 token decimals for this token - uint8 public constant decimals = 18; - - /// @notice Total number of tokens in circulation - uint public constant totalSupply = 10000000e18; // 10 million Comp - - /// @notice Allowance amounts on behalf of others - mapping (address => mapping (address => uint96)) internal allowances; - - /// @notice Official record of token balances for each account - mapping (address => uint96) internal balances; - - /// @notice A record of each accounts delegate - mapping (address => address) public delegates; - - /// @notice A checkpoint for marking number of votes from a given block - struct Checkpoint { - uint32 fromBlock; - uint96 votes; - } - - /// @notice A record of votes checkpoints for each account, by index - mapping (address => mapping (uint32 => Checkpoint)) public checkpoints; - - /// @notice The number of checkpoints for each account - mapping (address => uint32) public numCheckpoints; - - /// @notice The EIP-712 typehash for the contract's domain - bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)"); - - /// @notice The EIP-712 typehash for the delegation struct used by the contract - bytes32 public constant DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); - - /// @notice A record of states for signing / validating signatures - mapping (address => uint) public nonces; - - /// @notice An event thats emitted when an account changes its delegate - event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate); - - /// @notice An event thats emitted when a delegate account's vote balance changes - event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance); - - /// @notice The standard EIP-20 transfer event - event Transfer(address indexed from, address indexed to, uint256 amount); - - /// @notice The standard EIP-20 approval event - event Approval(address indexed owner, address indexed spender, uint256 amount); - - /** - * @notice Construct a new Comp token - * @param account The initial account to grant all the tokens - */ - constructor(address account) public { - balances[account] = uint96(totalSupply); - emit Transfer(address(0), account, totalSupply); - } - - /** - * @notice Get the number of tokens `spender` is approved to spend on behalf of `account` - * @param account The address of the account holding the funds - * @param spender The address of the account spending the funds - * @return The number of tokens approved - */ - function allowance(address account, address spender) external view returns (uint) { - return allowances[account][spender]; - } - - /** - * @notice Approve `spender` to transfer up to `amount` from `src` - * @dev This will overwrite the approval amount for `spender` - * and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve) - * @param spender The address of the account which may transfer tokens - * @param rawAmount The number of tokens that are approved (2^256-1 means infinite) - * @return Whether or not the approval succeeded - */ - function approve(address spender, uint rawAmount) external returns (bool) { - uint96 amount; - if (rawAmount == uint(-1)) { - amount = uint96(-1); - } else { - amount = safe96(rawAmount, "Comp::approve: amount exceeds 96 bits"); - } - - allowances[msg.sender][spender] = amount; - - emit Approval(msg.sender, spender, amount); - return true; - } - - /** - * @notice Get the number of tokens held by the `account` - * @param account The address of the account to get the balance of - * @return The number of tokens held - */ - function balanceOf(address account) external view returns (uint) { - return balances[account]; - } - - /** - * @notice Transfer `amount` tokens from `msg.sender` to `dst` - * @param dst The address of the destination account - * @param rawAmount The number of tokens to transfer - * @return Whether or not the transfer succeeded - */ - function transfer(address dst, uint rawAmount) external returns (bool) { - uint96 amount = safe96(rawAmount, "Comp::transfer: amount exceeds 96 bits"); - _transferTokens(msg.sender, dst, amount); - return true; - } - - /** - * @notice Transfer `amount` tokens from `src` to `dst` - * @param src The address of the source account - * @param dst The address of the destination account - * @param rawAmount The number of tokens to transfer - * @return Whether or not the transfer succeeded - */ - function transferFrom(address src, address dst, uint rawAmount) external returns (bool) { - address spender = msg.sender; - uint96 spenderAllowance = allowances[src][spender]; - uint96 amount = safe96(rawAmount, "Comp::approve: amount exceeds 96 bits"); - - if (spender != src && spenderAllowance != uint96(-1)) { - uint96 newAllowance = sub96(spenderAllowance, amount, "Comp::transferFrom: transfer amount exceeds spender allowance"); - allowances[src][spender] = newAllowance; - - emit Approval(src, spender, newAllowance); - } - - _transferTokens(src, dst, amount); - return true; - } - - /** - * @notice Delegate votes from `msg.sender` to `delegatee` - * @param delegatee The address to delegate votes to - */ - function delegate(address delegatee) public { - return _delegate(msg.sender, delegatee); - } - - /** - * @notice Delegates votes from signatory to `delegatee` - * @param delegatee The address to delegate votes to - * @param nonce The contract state required to match the signature - * @param expiry The time at which to expire the signature - * @param v The recovery byte of the signature - * @param r Half of the ECDSA signature pair - * @param s Half of the ECDSA signature pair - */ - function delegateBySig(address delegatee, uint nonce, uint expiry, uint8 v, bytes32 r, bytes32 s) public { - bytes32 domainSeparator = keccak256(abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainId(), address(this))); - bytes32 structHash = keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry)); - bytes32 digest = keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); - address signatory = ecrecover(digest, v, r, s); - require(signatory != address(0), "Comp::delegateBySig: invalid signature"); - require(nonce == nonces[signatory]++, "Comp::delegateBySig: invalid nonce"); - require(now <= expiry, "Comp::delegateBySig: signature expired"); - return _delegate(signatory, delegatee); - } - - /** - * @notice Gets the current votes balance for `account` - * @param account The address to get votes balance - * @return The number of current votes for `account` - */ - function getCurrentVotes(address account) external view returns (uint96) { - uint32 nCheckpoints = numCheckpoints[account]; - return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0; - } - - /** - * @notice Determine the prior number of votes for an account as of a block number - * @dev Block number must be a finalized block or else this function will revert to prevent misinformation. - * @param account The address of the account to check - * @param blockNumber The block number to get the vote balance at - * @return The number of votes the account had as of the given block - */ - function getPriorVotes(address account, uint blockNumber) public view returns (uint96) { - require(blockNumber < block.number, "Comp::getPriorVotes: not yet determined"); - - uint32 nCheckpoints = numCheckpoints[account]; - if (nCheckpoints == 0) { - return 0; - } - - // First check most recent balance - if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) { - return checkpoints[account][nCheckpoints - 1].votes; - } - - // Next check implicit zero balance - if (checkpoints[account][0].fromBlock > blockNumber) { - return 0; - } - - uint32 lower = 0; - uint32 upper = nCheckpoints - 1; - while (upper > lower) { - uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow - Checkpoint memory cp = checkpoints[account][center]; - if (cp.fromBlock == blockNumber) { - return cp.votes; - } else if (cp.fromBlock < blockNumber) { - lower = center; - } else { - upper = center - 1; - } - } - return checkpoints[account][lower].votes; - } - - function _delegate(address delegator, address delegatee) internal { - address currentDelegate = delegates[delegator]; - uint96 delegatorBalance = balances[delegator]; - delegates[delegator] = delegatee; - - emit DelegateChanged(delegator, currentDelegate, delegatee); - - _moveDelegates(currentDelegate, delegatee, delegatorBalance); - } - - function _transferTokens(address src, address dst, uint96 amount) internal { - require(src != address(0), "Comp::_transferTokens: cannot transfer from the zero address"); - require(dst != address(0), "Comp::_transferTokens: cannot transfer to the zero address"); - - balances[src] = sub96(balances[src], amount, "Comp::_transferTokens: transfer amount exceeds balance"); - balances[dst] = add96(balances[dst], amount, "Comp::_transferTokens: transfer amount overflows"); - emit Transfer(src, dst, amount); - - _moveDelegates(delegates[src], delegates[dst], amount); - } - - function _moveDelegates(address srcRep, address dstRep, uint96 amount) internal { - if (srcRep != dstRep && amount > 0) { - if (srcRep != address(0)) { - uint32 srcRepNum = numCheckpoints[srcRep]; - uint96 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0; - uint96 srcRepNew = sub96(srcRepOld, amount, "Comp::_moveVotes: vote amount underflows"); - _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew); - } - - if (dstRep != address(0)) { - uint32 dstRepNum = numCheckpoints[dstRep]; - uint96 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0; - uint96 dstRepNew = add96(dstRepOld, amount, "Comp::_moveVotes: vote amount overflows"); - _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew); - } - } - } - - function _writeCheckpoint(address delegatee, uint32 nCheckpoints, uint96 oldVotes, uint96 newVotes) internal { - uint32 blockNumber = safe32(block.number, "Comp::_writeCheckpoint: block number exceeds 32 bits"); - - if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) { - checkpoints[delegatee][nCheckpoints - 1].votes = newVotes; - } else { - checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes); - numCheckpoints[delegatee] = nCheckpoints + 1; - } - - emit DelegateVotesChanged(delegatee, oldVotes, newVotes); - } - - function safe32(uint n, string memory errorMessage) internal pure returns (uint32) { - require(n < 2**32, errorMessage); - return uint32(n); - } - - function safe96(uint n, string memory errorMessage) internal pure returns (uint96) { - require(n < 2**96, errorMessage); - return uint96(n); - } - - function add96(uint96 a, uint96 b, string memory errorMessage) internal pure returns (uint96) { - uint96 c = a + b; - require(c >= a, errorMessage); - return c; - } - - function sub96(uint96 a, uint96 b, string memory errorMessage) internal pure returns (uint96) { - require(b <= a, errorMessage); - return a - b; - } - - function getChainId() internal pure returns (uint) { - uint256 chainId; - assembly { chainId := chainid() } - return chainId; - } -} diff --git a/contracts/Governance/GovernorAlpha.sol b/contracts/Governance/GovernorAlpha.sol deleted file mode 100644 index 6073d0c9c..000000000 --- a/contracts/Governance/GovernorAlpha.sol +++ /dev/null @@ -1,331 +0,0 @@ -pragma solidity ^0.5.16; -pragma experimental ABIEncoderV2; - -contract GovernorAlpha { - /// @notice The name of this contract - string public constant name = "Compound Governor Alpha"; - - /// @notice The number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed - function quorumVotes() public pure returns (uint) { return 400000e18; } // 400,000 = 4% of Comp - - /// @notice The number of votes required in order for a voter to become a proposer - function proposalThreshold() public pure returns (uint) { return 100000e18; } // 100,000 = 1% of Comp - - /// @notice The maximum number of actions that can be included in a proposal - function proposalMaxOperations() public pure returns (uint) { return 10; } // 10 actions - - /// @notice The delay before voting on a proposal may take place, once proposed - function votingDelay() public pure returns (uint) { return 1; } // 1 block - - /// @notice The duration of voting on a proposal, in blocks - function votingPeriod() public pure returns (uint) { return 17280; } // ~3 days in blocks (assuming 15s blocks) - - /// @notice The address of the Compound Protocol Timelock - TimelockInterface public timelock; - - /// @notice The address of the Compound governance token - CompInterface public comp; - - /// @notice The address of the Governor Guardian - address public guardian; - - /// @notice The total number of proposals - uint public proposalCount; - - struct Proposal { - /// @notice Unique id for looking up a proposal - uint id; - - /// @notice Creator of the proposal - address proposer; - - /// @notice The timestamp that the proposal will be available for execution, set once the vote succeeds - uint eta; - - /// @notice the ordered list of target addresses for calls to be made - address[] targets; - - /// @notice The ordered list of values (i.e. msg.value) to be passed to the calls to be made - uint[] values; - - /// @notice The ordered list of function signatures to be called - string[] signatures; - - /// @notice The ordered list of calldata to be passed to each call - bytes[] calldatas; - - /// @notice The block at which voting begins: holders must delegate their votes prior to this block - uint startBlock; - - /// @notice The block at which voting ends: votes must be cast prior to this block - uint endBlock; - - /// @notice Current number of votes in favor of this proposal - uint forVotes; - - /// @notice Current number of votes in opposition to this proposal - uint againstVotes; - - /// @notice Flag marking whether the proposal has been canceled - bool canceled; - - /// @notice Flag marking whether the proposal has been executed - bool executed; - - /// @notice Receipts of ballots for the entire set of voters - mapping (address => Receipt) receipts; - } - - /// @notice Ballot receipt record for a voter - struct Receipt { - /// @notice Whether or not a vote has been cast - bool hasVoted; - - /// @notice Whether or not the voter supports the proposal - bool support; - - /// @notice The number of votes the voter had, which were cast - uint96 votes; - } - - /// @notice Possible states that a proposal may be in - enum ProposalState { - Pending, - Active, - Canceled, - Defeated, - Succeeded, - Queued, - Expired, - Executed - } - - /// @notice The official record of all proposals ever proposed - mapping (uint => Proposal) public proposals; - - /// @notice The latest proposal for each proposer - mapping (address => uint) public latestProposalIds; - - /// @notice The EIP-712 typehash for the contract's domain - bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)"); - - /// @notice The EIP-712 typehash for the ballot struct used by the contract - bytes32 public constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,bool support)"); - - /// @notice An event emitted when a new proposal is created - event ProposalCreated(uint id, address proposer, address[] targets, uint[] values, string[] signatures, bytes[] calldatas, uint startBlock, uint endBlock, string description); - - /// @notice An event emitted when a vote has been cast on a proposal - event VoteCast(address voter, uint proposalId, bool support, uint votes); - - /// @notice An event emitted when a proposal has been canceled - event ProposalCanceled(uint id); - - /// @notice An event emitted when a proposal has been queued in the Timelock - event ProposalQueued(uint id, uint eta); - - /// @notice An event emitted when a proposal has been executed in the Timelock - event ProposalExecuted(uint id); - - constructor(address timelock_, address comp_, address guardian_) public { - timelock = TimelockInterface(timelock_); - comp = CompInterface(comp_); - guardian = guardian_; - } - - function propose(address[] memory targets, uint[] memory values, string[] memory signatures, bytes[] memory calldatas, string memory description) public returns (uint) { - require(comp.getPriorVotes(msg.sender, sub256(block.number, 1)) > proposalThreshold(), "GovernorAlpha::propose: proposer votes below proposal threshold"); - require(targets.length == values.length && targets.length == signatures.length && targets.length == calldatas.length, "GovernorAlpha::propose: proposal function information arity mismatch"); - require(targets.length != 0, "GovernorAlpha::propose: must provide actions"); - require(targets.length <= proposalMaxOperations(), "GovernorAlpha::propose: too many actions"); - - uint latestProposalId = latestProposalIds[msg.sender]; - if (latestProposalId != 0) { - ProposalState proposersLatestProposalState = state(latestProposalId); - require(proposersLatestProposalState != ProposalState.Active, "GovernorAlpha::propose: one live proposal per proposer, found an already active proposal"); - require(proposersLatestProposalState != ProposalState.Pending, "GovernorAlpha::propose: one live proposal per proposer, found an already pending proposal"); - } - - uint startBlock = add256(block.number, votingDelay()); - uint endBlock = add256(startBlock, votingPeriod()); - - proposalCount++; - Proposal memory newProposal = Proposal({ - id: proposalCount, - proposer: msg.sender, - eta: 0, - targets: targets, - values: values, - signatures: signatures, - calldatas: calldatas, - startBlock: startBlock, - endBlock: endBlock, - forVotes: 0, - againstVotes: 0, - canceled: false, - executed: false - }); - - proposals[newProposal.id] = newProposal; - latestProposalIds[newProposal.proposer] = newProposal.id; - - emit ProposalCreated(newProposal.id, msg.sender, targets, values, signatures, calldatas, startBlock, endBlock, description); - return newProposal.id; - } - - function queue(uint proposalId) public { - require(state(proposalId) == ProposalState.Succeeded, "GovernorAlpha::queue: proposal can only be queued if it is succeeded"); - Proposal storage proposal = proposals[proposalId]; - uint eta = add256(block.timestamp, timelock.delay()); - for (uint i = 0; i < proposal.targets.length; i++) { - _queueOrRevert(proposal.targets[i], proposal.values[i], proposal.signatures[i], proposal.calldatas[i], eta); - } - proposal.eta = eta; - emit ProposalQueued(proposalId, eta); - } - - function _queueOrRevert(address target, uint value, string memory signature, bytes memory data, uint eta) internal { - require(!timelock.queuedTransactions(keccak256(abi.encode(target, value, signature, data, eta))), "GovernorAlpha::_queueOrRevert: proposal action already queued at eta"); - timelock.queueTransaction(target, value, signature, data, eta); - } - - function execute(uint proposalId) public payable { - require(state(proposalId) == ProposalState.Queued, "GovernorAlpha::execute: proposal can only be executed if it is queued"); - Proposal storage proposal = proposals[proposalId]; - proposal.executed = true; - for (uint i = 0; i < proposal.targets.length; i++) { - timelock.executeTransaction.value(proposal.values[i])(proposal.targets[i], proposal.values[i], proposal.signatures[i], proposal.calldatas[i], proposal.eta); - } - emit ProposalExecuted(proposalId); - } - - function cancel(uint proposalId) public { - ProposalState state = state(proposalId); - require(state != ProposalState.Executed, "GovernorAlpha::cancel: cannot cancel executed proposal"); - - Proposal storage proposal = proposals[proposalId]; - require(msg.sender == guardian || comp.getPriorVotes(proposal.proposer, sub256(block.number, 1)) < proposalThreshold(), "GovernorAlpha::cancel: proposer above threshold"); - - proposal.canceled = true; - for (uint i = 0; i < proposal.targets.length; i++) { - timelock.cancelTransaction(proposal.targets[i], proposal.values[i], proposal.signatures[i], proposal.calldatas[i], proposal.eta); - } - - emit ProposalCanceled(proposalId); - } - - function getActions(uint proposalId) public view returns (address[] memory targets, uint[] memory values, string[] memory signatures, bytes[] memory calldatas) { - Proposal storage p = proposals[proposalId]; - return (p.targets, p.values, p.signatures, p.calldatas); - } - - function getReceipt(uint proposalId, address voter) public view returns (Receipt memory) { - return proposals[proposalId].receipts[voter]; - } - - function state(uint proposalId) public view returns (ProposalState) { - require(proposalCount >= proposalId && proposalId > 0, "GovernorAlpha::state: invalid proposal id"); - Proposal storage proposal = proposals[proposalId]; - if (proposal.canceled) { - return ProposalState.Canceled; - } else if (block.number <= proposal.startBlock) { - return ProposalState.Pending; - } else if (block.number <= proposal.endBlock) { - return ProposalState.Active; - } else if (proposal.forVotes <= proposal.againstVotes || proposal.forVotes < quorumVotes()) { - return ProposalState.Defeated; - } else if (proposal.eta == 0) { - return ProposalState.Succeeded; - } else if (proposal.executed) { - return ProposalState.Executed; - } else if (block.timestamp >= add256(proposal.eta, timelock.GRACE_PERIOD())) { - return ProposalState.Expired; - } else { - return ProposalState.Queued; - } - } - - function castVote(uint proposalId, bool support) public { - return _castVote(msg.sender, proposalId, support); - } - - function castVoteBySig(uint proposalId, bool support, uint8 v, bytes32 r, bytes32 s) public { - bytes32 domainSeparator = keccak256(abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainId(), address(this))); - bytes32 structHash = keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support)); - bytes32 digest = keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); - address signatory = ecrecover(digest, v, r, s); - require(signatory != address(0), "GovernorAlpha::castVoteBySig: invalid signature"); - return _castVote(signatory, proposalId, support); - } - - function _castVote(address voter, uint proposalId, bool support) internal { - require(state(proposalId) == ProposalState.Active, "GovernorAlpha::_castVote: voting is closed"); - Proposal storage proposal = proposals[proposalId]; - Receipt storage receipt = proposal.receipts[voter]; - require(receipt.hasVoted == false, "GovernorAlpha::_castVote: voter already voted"); - uint96 votes = comp.getPriorVotes(voter, proposal.startBlock); - - if (support) { - proposal.forVotes = add256(proposal.forVotes, votes); - } else { - proposal.againstVotes = add256(proposal.againstVotes, votes); - } - - receipt.hasVoted = true; - receipt.support = support; - receipt.votes = votes; - - emit VoteCast(voter, proposalId, support, votes); - } - - function __acceptAdmin() public { - require(msg.sender == guardian, "GovernorAlpha::__acceptAdmin: sender must be gov guardian"); - timelock.acceptAdmin(); - } - - function __abdicate() public { - require(msg.sender == guardian, "GovernorAlpha::__abdicate: sender must be gov guardian"); - guardian = address(0); - } - - function __queueSetTimelockPendingAdmin(address newPendingAdmin, uint eta) public { - require(msg.sender == guardian, "GovernorAlpha::__queueSetTimelockPendingAdmin: sender must be gov guardian"); - timelock.queueTransaction(address(timelock), 0, "setPendingAdmin(address)", abi.encode(newPendingAdmin), eta); - } - - function __executeSetTimelockPendingAdmin(address newPendingAdmin, uint eta) public { - require(msg.sender == guardian, "GovernorAlpha::__executeSetTimelockPendingAdmin: sender must be gov guardian"); - timelock.executeTransaction(address(timelock), 0, "setPendingAdmin(address)", abi.encode(newPendingAdmin), eta); - } - - function add256(uint256 a, uint256 b) internal pure returns (uint) { - uint c = a + b; - require(c >= a, "addition overflow"); - return c; - } - - function sub256(uint256 a, uint256 b) internal pure returns (uint) { - require(b <= a, "subtraction underflow"); - return a - b; - } - - function getChainId() internal pure returns (uint) { - uint chainId; - assembly { chainId := chainid() } - return chainId; - } -} - -interface TimelockInterface { - function delay() external view returns (uint); - function GRACE_PERIOD() external view returns (uint); - function acceptAdmin() external; - function queuedTransactions(bytes32 hash) external view returns (bool); - function queueTransaction(address target, uint value, string calldata signature, bytes calldata data, uint eta) external returns (bytes32); - function cancelTransaction(address target, uint value, string calldata signature, bytes calldata data, uint eta) external; - function executeTransaction(address target, uint value, string calldata signature, bytes calldata data, uint eta) external payable returns (bytes memory); -} - -interface CompInterface { - function getPriorVotes(address account, uint blockNumber) external view returns (uint96); -} diff --git a/contracts/Lens/CompoundLens.sol b/contracts/Lens/CompoundLens.sol deleted file mode 100644 index 9197dda63..000000000 --- a/contracts/Lens/CompoundLens.sol +++ /dev/null @@ -1,325 +0,0 @@ -pragma solidity ^0.5.16; -pragma experimental ABIEncoderV2; - -import "../CErc20.sol"; -import "../CToken.sol"; -import "../PriceOracle.sol"; -import "../EIP20Interface.sol"; -import "../Governance/GovernorAlpha.sol"; -import "../Governance/Comp.sol"; - -interface ComptrollerLensInterface { - function markets(address) external view returns (bool, uint); - function oracle() external view returns (PriceOracle); - function getAccountLiquidity(address) external view returns (uint, uint, uint); - function getAssetsIn(address) external view returns (CToken[] memory); - function claimComp(address) external; - function compAccrued(address) external view returns (uint); -} - -contract CompoundLens { - struct CTokenMetadata { - address cToken; - uint exchangeRateCurrent; - uint supplyRatePerBlock; - uint borrowRatePerBlock; - uint reserveFactorMantissa; - uint totalBorrows; - uint totalReserves; - uint totalSupply; - uint totalCash; - bool isListed; - uint collateralFactorMantissa; - address underlyingAssetAddress; - uint cTokenDecimals; - uint underlyingDecimals; - } - - function cTokenMetadata(CToken cToken) public returns (CTokenMetadata memory) { - uint exchangeRateCurrent = cToken.exchangeRateCurrent(); - ComptrollerLensInterface comptroller = ComptrollerLensInterface(address(cToken.comptroller())); - (bool isListed, uint collateralFactorMantissa) = comptroller.markets(address(cToken)); - address underlyingAssetAddress; - uint underlyingDecimals; - - if (compareStrings(cToken.symbol(), "cETH")) { - underlyingAssetAddress = address(0); - underlyingDecimals = 18; - } else { - CErc20 cErc20 = CErc20(address(cToken)); - underlyingAssetAddress = cErc20.underlying(); - underlyingDecimals = EIP20Interface(cErc20.underlying()).decimals(); - } - - return CTokenMetadata({ - cToken: address(cToken), - exchangeRateCurrent: exchangeRateCurrent, - supplyRatePerBlock: cToken.supplyRatePerBlock(), - borrowRatePerBlock: cToken.borrowRatePerBlock(), - reserveFactorMantissa: cToken.reserveFactorMantissa(), - totalBorrows: cToken.totalBorrows(), - totalReserves: cToken.totalReserves(), - totalSupply: cToken.totalSupply(), - totalCash: cToken.getCash(), - isListed: isListed, - collateralFactorMantissa: collateralFactorMantissa, - underlyingAssetAddress: underlyingAssetAddress, - cTokenDecimals: cToken.decimals(), - underlyingDecimals: underlyingDecimals - }); - } - - function cTokenMetadataAll(CToken[] calldata cTokens) external returns (CTokenMetadata[] memory) { - uint cTokenCount = cTokens.length; - CTokenMetadata[] memory res = new CTokenMetadata[](cTokenCount); - for (uint i = 0; i < cTokenCount; i++) { - res[i] = cTokenMetadata(cTokens[i]); - } - return res; - } - - struct CTokenBalances { - address cToken; - uint balanceOf; - uint borrowBalanceCurrent; - uint balanceOfUnderlying; - uint tokenBalance; - uint tokenAllowance; - } - - function cTokenBalances(CToken cToken, address payable account) public returns (CTokenBalances memory) { - uint balanceOf = cToken.balanceOf(account); - uint borrowBalanceCurrent = cToken.borrowBalanceCurrent(account); - uint balanceOfUnderlying = cToken.balanceOfUnderlying(account); - uint tokenBalance; - uint tokenAllowance; - - if (compareStrings(cToken.symbol(), "cETH")) { - tokenBalance = account.balance; - tokenAllowance = account.balance; - } else { - CErc20 cErc20 = CErc20(address(cToken)); - EIP20Interface underlying = EIP20Interface(cErc20.underlying()); - tokenBalance = underlying.balanceOf(account); - tokenAllowance = underlying.allowance(account, address(cToken)); - } - - return CTokenBalances({ - cToken: address(cToken), - balanceOf: balanceOf, - borrowBalanceCurrent: borrowBalanceCurrent, - balanceOfUnderlying: balanceOfUnderlying, - tokenBalance: tokenBalance, - tokenAllowance: tokenAllowance - }); - } - - function cTokenBalancesAll(CToken[] calldata cTokens, address payable account) external returns (CTokenBalances[] memory) { - uint cTokenCount = cTokens.length; - CTokenBalances[] memory res = new CTokenBalances[](cTokenCount); - for (uint i = 0; i < cTokenCount; i++) { - res[i] = cTokenBalances(cTokens[i], account); - } - return res; - } - - struct CTokenUnderlyingPrice { - address cToken; - uint underlyingPrice; - } - - function cTokenUnderlyingPrice(CToken cToken) public returns (CTokenUnderlyingPrice memory) { - ComptrollerLensInterface comptroller = ComptrollerLensInterface(address(cToken.comptroller())); - PriceOracle priceOracle = comptroller.oracle(); - - return CTokenUnderlyingPrice({ - cToken: address(cToken), - underlyingPrice: priceOracle.getUnderlyingPrice(cToken) - }); - } - - function cTokenUnderlyingPriceAll(CToken[] calldata cTokens) external returns (CTokenUnderlyingPrice[] memory) { - uint cTokenCount = cTokens.length; - CTokenUnderlyingPrice[] memory res = new CTokenUnderlyingPrice[](cTokenCount); - for (uint i = 0; i < cTokenCount; i++) { - res[i] = cTokenUnderlyingPrice(cTokens[i]); - } - return res; - } - - struct AccountLimits { - CToken[] markets; - uint liquidity; - uint shortfall; - } - - function getAccountLimits(ComptrollerLensInterface comptroller, address account) public returns (AccountLimits memory) { - (uint errorCode, uint liquidity, uint shortfall) = comptroller.getAccountLiquidity(account); - require(errorCode == 0); - - return AccountLimits({ - markets: comptroller.getAssetsIn(account), - liquidity: liquidity, - shortfall: shortfall - }); - } - - struct GovReceipt { - uint proposalId; - bool hasVoted; - bool support; - uint96 votes; - } - - function getGovReceipts(GovernorAlpha governor, address voter, uint[] memory proposalIds) public view returns (GovReceipt[] memory) { - uint proposalCount = proposalIds.length; - GovReceipt[] memory res = new GovReceipt[](proposalCount); - for (uint i = 0; i < proposalCount; i++) { - GovernorAlpha.Receipt memory receipt = governor.getReceipt(proposalIds[i], voter); - res[i] = GovReceipt({ - proposalId: proposalIds[i], - hasVoted: receipt.hasVoted, - support: receipt.support, - votes: receipt.votes - }); - } - return res; - } - - struct GovProposal { - uint proposalId; - address proposer; - uint eta; - address[] targets; - uint[] values; - string[] signatures; - bytes[] calldatas; - uint startBlock; - uint endBlock; - uint forVotes; - uint againstVotes; - bool canceled; - bool executed; - } - - function setProposal(GovProposal memory res, GovernorAlpha governor, uint proposalId) internal view { - ( - , - address proposer, - uint eta, - uint startBlock, - uint endBlock, - uint forVotes, - uint againstVotes, - bool canceled, - bool executed - ) = governor.proposals(proposalId); - res.proposalId = proposalId; - res.proposer = proposer; - res.eta = eta; - res.startBlock = startBlock; - res.endBlock = endBlock; - res.forVotes = forVotes; - res.againstVotes = againstVotes; - res.canceled = canceled; - res.executed = executed; - } - - function getGovProposals(GovernorAlpha governor, uint[] calldata proposalIds) external view returns (GovProposal[] memory) { - GovProposal[] memory res = new GovProposal[](proposalIds.length); - for (uint i = 0; i < proposalIds.length; i++) { - ( - address[] memory targets, - uint[] memory values, - string[] memory signatures, - bytes[] memory calldatas - ) = governor.getActions(proposalIds[i]); - res[i] = GovProposal({ - proposalId: 0, - proposer: address(0), - eta: 0, - targets: targets, - values: values, - signatures: signatures, - calldatas: calldatas, - startBlock: 0, - endBlock: 0, - forVotes: 0, - againstVotes: 0, - canceled: false, - executed: false - }); - setProposal(res[i], governor, proposalIds[i]); - } - return res; - } - - struct CompBalanceMetadata { - uint balance; - uint votes; - address delegate; - } - - function getCompBalanceMetadata(Comp comp, address account) external view returns (CompBalanceMetadata memory) { - return CompBalanceMetadata({ - balance: comp.balanceOf(account), - votes: uint256(comp.getCurrentVotes(account)), - delegate: comp.delegates(account) - }); - } - - struct CompBalanceMetadataExt { - uint balance; - uint votes; - address delegate; - uint allocated; - } - - function getCompBalanceMetadataExt(Comp comp, ComptrollerLensInterface comptroller, address account) external returns (CompBalanceMetadataExt memory) { - uint balance = comp.balanceOf(account); - comptroller.claimComp(account); - uint newBalance = comp.balanceOf(account); - uint accrued = comptroller.compAccrued(account); - uint total = add(accrued, newBalance, "sum comp total"); - uint allocated = sub(total, balance, "sub allocated"); - - return CompBalanceMetadataExt({ - balance: balance, - votes: uint256(comp.getCurrentVotes(account)), - delegate: comp.delegates(account), - allocated: allocated - }); - } - - struct CompVotes { - uint blockNumber; - uint votes; - } - - function getCompVotes(Comp comp, address account, uint32[] calldata blockNumbers) external view returns (CompVotes[] memory) { - CompVotes[] memory res = new CompVotes[](blockNumbers.length); - for (uint i = 0; i < blockNumbers.length; i++) { - res[i] = CompVotes({ - blockNumber: uint256(blockNumbers[i]), - votes: uint256(comp.getPriorVotes(account, blockNumbers[i])) - }); - } - return res; - } - - function compareStrings(string memory a, string memory b) internal pure returns (bool) { - return (keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b)))); - } - - function add(uint a, uint b, string memory errorMessage) internal pure returns (uint) { - uint c = a + b; - require(c >= a, errorMessage); - return c; - } - - function sub(uint a, uint b, string memory errorMessage) internal pure returns (uint) { - require(b <= a, errorMessage); - uint c = a - b; - return c; - } -} diff --git a/contracts/Lens/SashimiLendingLens.sol b/contracts/Lens/SashimiLendingLens.sol new file mode 100644 index 000000000..a9265900e --- /dev/null +++ b/contracts/Lens/SashimiLendingLens.sol @@ -0,0 +1,217 @@ +pragma solidity ^0.5.16; +pragma experimental ABIEncoderV2; + +import "../SLErc20.sol"; +import "../SLToken.sol"; +import "../PriceOracle.sol"; +import "../EIP20Interface.sol"; + +interface ComptrollerLensInterface { + function markets(address) external view returns (bool, uint); + function oracle() external view returns (PriceOracle); + function getAccountLiquidity(address) external view returns (uint, uint, uint); + function getAssetsIn(address) external view returns (SLToken[] memory); + function claimSashimi(address) external; + function sashimiAccrued(address) external view returns (uint); +} + +contract SashimiLendingLens { + struct SLTokenMetadata { + address slToken; + uint exchangeRateCurrent; + uint supplyRatePerBlock; + uint borrowRatePerBlock; + uint reserveFactorMantissa; + uint totalBorrows; + uint totalReserves; + uint totalSupply; + uint totalCash; + bool isListed; + uint collateralFactorMantissa; + address underlyingAssetAddress; + uint slTokenDecimals; + uint underlyingDecimals; + } + + function slTokenMetadata(SLToken slToken) public returns (SLTokenMetadata memory) { + uint exchangeRateCurrent = slToken.exchangeRateCurrent(); + ComptrollerLensInterface comptroller = ComptrollerLensInterface(address(slToken.comptroller())); + (bool isListed, uint collateralFactorMantissa) = comptroller.markets(address(slToken)); + address underlyingAssetAddress; + uint underlyingDecimals; + + if (compareStrings(slToken.symbol(), "slETH")) { + underlyingAssetAddress = address(0); + underlyingDecimals = 18; + } else { + SLErc20 slErc20 = SLErc20(address(slToken)); + underlyingAssetAddress = slErc20.underlying(); + underlyingDecimals = EIP20Interface(slErc20.underlying()).decimals(); + } + + return SLTokenMetadata({ + slToken: address(slToken), + exchangeRateCurrent: exchangeRateCurrent, + supplyRatePerBlock: slToken.supplyRatePerBlock(), + borrowRatePerBlock: slToken.borrowRatePerBlock(), + reserveFactorMantissa: slToken.reserveFactorMantissa(), + totalBorrows: slToken.totalBorrows(), + totalReserves: slToken.totalReserves(), + totalSupply: slToken.totalSupply(), + totalCash: slToken.getCash(), + isListed: isListed, + collateralFactorMantissa: collateralFactorMantissa, + underlyingAssetAddress: underlyingAssetAddress, + slTokenDecimals: slToken.decimals(), + underlyingDecimals: underlyingDecimals + }); + } + + function slTokenMetadataAll(SLToken[] calldata slTokens) external returns (SLTokenMetadata[] memory) { + uint slTokenCount = slTokens.length; + SLTokenMetadata[] memory res = new SLTokenMetadata[](slTokenCount); + for (uint i = 0; i < slTokenCount; i++) { + res[i] = slTokenMetadata(slTokens[i]); + } + return res; + } + + struct SLTokenBalances { + address slToken; + uint balanceOf; + uint borrowBalanceCurrent; + uint balanceOfUnderlying; + uint tokenBalance; + uint tokenAllowance; + } + + function slTokenBalances(SLToken slToken, address payable account) public returns (SLTokenBalances memory) { + uint balanceOf = slToken.balanceOf(account); + uint borrowBalanceCurrent = slToken.borrowBalanceCurrent(account); + uint balanceOfUnderlying = slToken.balanceOfUnderlying(account); + uint tokenBalance; + uint tokenAllowance; + + if (compareStrings(slToken.symbol(), "slETH")) { + tokenBalance = account.balance; + tokenAllowance = account.balance; + } else { + SLErc20 slErc20 = SLErc20(address(slToken)); + EIP20Interface underlying = EIP20Interface(slErc20.underlying()); + tokenBalance = underlying.balanceOf(account); + tokenAllowance = underlying.allowance(account, address(slToken)); + } + + return SLTokenBalances({ + slToken: address(slToken), + balanceOf: balanceOf, + borrowBalanceCurrent: borrowBalanceCurrent, + balanceOfUnderlying: balanceOfUnderlying, + tokenBalance: tokenBalance, + tokenAllowance: tokenAllowance + }); + } + + function slTokenBalancesAll(SLToken[] calldata slTokens, address payable account) external returns (SLTokenBalances[] memory) { + uint slTokenCount = slTokens.length; + SLTokenBalances[] memory res = new SLTokenBalances[](slTokenCount); + for (uint i = 0; i < slTokenCount; i++) { + res[i] = slTokenBalances(slTokens[i], account); + } + return res; + } + + struct SLTokenUnderlyingPrice { + address slToken; + uint underlyingPrice; + } + + function slTokenUnderlyingPrice(SLToken slToken) public returns (SLTokenUnderlyingPrice memory) { + ComptrollerLensInterface comptroller = ComptrollerLensInterface(address(slToken.comptroller())); + PriceOracle priceOracle = comptroller.oracle(); + + return SLTokenUnderlyingPrice({ + slToken: address(slToken), + underlyingPrice: priceOracle.getUnderlyingPrice(slToken) + }); + } + + function slTokenUnderlyingPriceAll(SLToken[] calldata slTokens) external returns (SLTokenUnderlyingPrice[] memory) { + uint slTokenCount = slTokens.length; + SLTokenUnderlyingPrice[] memory res = new SLTokenUnderlyingPrice[](slTokenCount); + for (uint i = 0; i < slTokenCount; i++) { + res[i] = slTokenUnderlyingPrice(slTokens[i]); + } + return res; + } + + struct AccountLimits { + SLToken[] markets; + uint liquidity; + uint shortfall; + } + + function getAccountLimits(ComptrollerLensInterface comptroller, address account) public returns (AccountLimits memory) { + (uint errorCode, uint liquidity, uint shortfall) = comptroller.getAccountLiquidity(account); + require(errorCode == 0); + + return AccountLimits({ + markets: comptroller.getAssetsIn(account), + liquidity: liquidity, + shortfall: shortfall + }); + } + + struct SashimiBalanceMetadata { + uint balance; + uint votes; + address delegate; + } + + function getSashimiBalanceMetadata(EIP20Interface sashimi, address account) external view returns (SashimiBalanceMetadata memory) { + return SashimiBalanceMetadata({ + balance: sashimi.balanceOf(account), + votes : 0, + delegate :address(0) + }); + } + + struct SashimiBalanceMetadataExt { + uint balance; + uint votes; + address delegate; + uint allocated; + } + + function getSashimiBalanceMetadataExt(EIP20Interface sashimi, ComptrollerLensInterface comptroller, address account) external returns (SashimiBalanceMetadataExt memory) { + uint balance = sashimi.balanceOf(account); + comptroller.claimSashimi(account); + uint newBalance = sashimi.balanceOf(account); + uint accrued = comptroller.sashimiAccrued(account); + uint total = add(accrued, newBalance, "sum sashimi total"); + uint allocated = sub(total, balance, "sub allocated"); + + return SashimiBalanceMetadataExt({ + balance: balance, + votes: 0, + delegate: address(0), + allocated: allocated + }); + } + + function compareStrings(string memory a, string memory b) internal pure returns (bool) { + return (keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b)))); + } + + function add(uint a, uint b, string memory errorMessage) internal pure returns (uint) { + uint c = a + b; + require(c >= a, errorMessage); + return c; + } + + function sub(uint a, uint b, string memory errorMessage) internal pure returns (uint) { + require(b <= a, errorMessage); + uint c = a - b; + return c; + } +} diff --git a/contracts/Maximillion.sol b/contracts/Maximillion.sol index a511c97a9..5e673b408 100644 --- a/contracts/Maximillion.sol +++ b/contracts/Maximillion.sol @@ -1,6 +1,6 @@ pragma solidity ^0.5.16; -import "./CEther.sol"; +import "./SLEther.sol"; /** * @title Compound's Maximillion Contract @@ -8,40 +8,40 @@ import "./CEther.sol"; */ contract Maximillion { /** - * @notice The default cEther market to repay in + * @notice The default slEther market to repay in */ - CEther public cEther; + SLEther public slEther; /** - * @notice Construct a Maximillion to repay max in a CEther market + * @notice Construct a Maximillion to repay max in a SLEther market */ - constructor(CEther cEther_) public { - cEther = cEther_; + constructor(SLEther slEther_) public { + slEther = slEther_; } /** - * @notice msg.sender sends Ether to repay an account's borrow in the cEther market + * @notice msg.sender sends Ether to repay an account's borrow in the slEther market * @dev The provided Ether is applied towards the borrow balance, any excess is refunded * @param borrower The address of the borrower account to repay on behalf of */ function repayBehalf(address borrower) public payable { - repayBehalfExplicit(borrower, cEther); + repayBehalfExplicit(borrower, slEther); } /** - * @notice msg.sender sends Ether to repay an account's borrow in a cEther market + * @notice msg.sender sends Ether to repay an account's borrow in a slEther market * @dev The provided Ether is applied towards the borrow balance, any excess is refunded * @param borrower The address of the borrower account to repay on behalf of - * @param cEther_ The address of the cEther contract to repay in + * @param slEther_ The address of the slEther contract to repay in */ - function repayBehalfExplicit(address borrower, CEther cEther_) public payable { + function repayBehalfExplicit(address borrower, SLEther slEther_) public payable { uint received = msg.value; - uint borrows = cEther_.borrowBalanceCurrent(borrower); + uint borrows = slEther_.borrowBalanceCurrent(borrower); if (received > borrows) { - cEther_.repayBorrowBehalf.value(borrows)(borrower); + slEther_.repayBorrowBehalf.value(borrows)(borrower); msg.sender.transfer(received - borrows); } else { - cEther_.repayBorrowBehalf.value(received)(borrower); + slEther_.repayBorrowBehalf.value(received)(borrower); } } } diff --git a/contracts/PriceOracle.sol b/contracts/PriceOracle.sol index 27bcc99e6..e3c2ba05a 100644 --- a/contracts/PriceOracle.sol +++ b/contracts/PriceOracle.sol @@ -1,16 +1,16 @@ pragma solidity ^0.5.16; -import "./CToken.sol"; +import "./SLToken.sol"; contract PriceOracle { /// @notice Indicator that this is a PriceOracle contract (for inspection) bool public constant isPriceOracle = true; /** - * @notice Get the underlying price of a cToken asset - * @param cToken The cToken to get the underlying price of + * @notice Get the underlying price of a slToken asset + * @param slToken The slToken to get the underlying price of * @return The underlying asset price mantissa (scaled by 1e18). * Zero means the price is unavailable. */ - function getUnderlyingPrice(CToken cToken) external view returns (uint); + function getUnderlyingPrice(SLToken slToken) external view returns (uint); } diff --git a/contracts/CDaiDelegate.sol b/contracts/SLDaiDelegate.sol similarity index 96% rename from contracts/CDaiDelegate.sol rename to contracts/SLDaiDelegate.sol index 363285abb..a5b740586 100644 --- a/contracts/CDaiDelegate.sol +++ b/contracts/SLDaiDelegate.sol @@ -1,13 +1,13 @@ pragma solidity ^0.5.16; -import "./CErc20Delegate.sol"; +import "./SLErc20Delegate.sol"; /** - * @title Compound's CDai Contract - * @notice CToken which wraps Multi-Collateral DAI - * @author Compound + * @title SashimiLending's SLDai Contract + * @notice SLToken which wraps Multi-Collateral DAI + * @author SashimiLending */ -contract CDaiDelegate is CErc20Delegate { +contract SLDaiDelegate is SLErc20Delegate { /** * @notice DAI adapter address */ @@ -91,7 +91,7 @@ contract CDaiDelegate is CErc20Delegate { daiJoin.exit(address(this), bal / RAY); } - /*** CToken Overrides ***/ + /*** SLToken Overrides ***/ /** * @notice Accrues DSR then applies accrued interest to total borrows and reserves @@ -102,7 +102,7 @@ contract CDaiDelegate is CErc20Delegate { // Accumulate DSR interest PotLike(potAddress).drip(); - // Accumulate CToken interest + // Accumulate SLToken interest return super.accrueInterest(); } diff --git a/contracts/CErc20.sol b/contracts/SLErc20.sol similarity index 90% rename from contracts/CErc20.sol rename to contracts/SLErc20.sol index 1e97b3dc6..f4ce24a02 100644 --- a/contracts/CErc20.sol +++ b/contracts/SLErc20.sol @@ -1,13 +1,19 @@ pragma solidity ^0.5.16; -import "./CToken.sol"; +import "./SLToken.sol"; /** - * @title Compound's CErc20 Contract - * @notice CTokens which wrap an EIP-20 underlying - * @author Compound + * @title SashimiLending's SLErc20 Contract + * @notice SLTokens which wrap an EIP-20 underlying + * @author SashimiLending */ -contract CErc20 is CToken, CErc20Interface { +contract SLErc20 is SLToken, SLErc20Interface { + + constructor() public { + // Creator of the contract is admin during initialization + admin = msg.sender; + } + /** * @notice Initialize the new money market * @param underlying_ The address of the underlying asset @@ -25,7 +31,7 @@ contract CErc20 is CToken, CErc20Interface { string memory name_, string memory symbol_, uint8 decimals_) public { - // CToken initialize does the bulk of the work + // SLToken initialize does the bulk of the work super.initialize(comptroller_, interestRateModel_, initialExchangeRateMantissa_, name_, symbol_, decimals_); // Set underlying and sanity check it @@ -36,7 +42,7 @@ contract CErc20 is CToken, CErc20Interface { /*** User Interface ***/ /** - * @notice Sender supplies assets into the market and receives cTokens in exchange + * @notice Sender supplies assets into the market and receives slTokens in exchange * @dev Accrues interest whether or not the operation succeeds, unless reverted * @param mintAmount The amount of the underlying asset to supply * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) @@ -47,9 +53,9 @@ contract CErc20 is CToken, CErc20Interface { } /** - * @notice Sender redeems cTokens in exchange for the underlying asset + * @notice Sender redeems slTokens in exchange for the underlying asset * @dev Accrues interest whether or not the operation succeeds, unless reverted - * @param redeemTokens The number of cTokens to redeem into underlying + * @param redeemTokens The number of slTokens to redeem into underlying * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ function redeem(uint redeemTokens) external returns (uint) { @@ -57,7 +63,7 @@ contract CErc20 is CToken, CErc20Interface { } /** - * @notice Sender redeems cTokens in exchange for a specified amount of underlying asset + * @notice Sender redeems slTokens in exchange for a specified amount of underlying asset * @dev Accrues interest whether or not the operation succeeds, unless reverted * @param redeemAmount The amount of underlying to redeem * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) @@ -99,13 +105,13 @@ contract CErc20 is CToken, CErc20Interface { /** * @notice The sender liquidates the borrowers collateral. * The collateral seized is transferred to the liquidator. - * @param borrower The borrower of this cToken to be liquidated + * @param borrower The borrower of this slToken to be liquidated * @param repayAmount The amount of the underlying borrowed asset to repay - * @param cTokenCollateral The market in which to seize collateral from the borrower + * @param slTokenCollateral The market in which to seize collateral from the borrower * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ - function liquidateBorrow(address borrower, uint repayAmount, CTokenInterface cTokenCollateral) external returns (uint) { - (uint err,) = liquidateBorrowInternal(borrower, repayAmount, cTokenCollateral); + function liquidateBorrow(address borrower, uint repayAmount, SLTokenInterface slTokenCollateral) external returns (uint) { + (uint err,) = liquidateBorrowInternal(borrower, repayAmount, slTokenCollateral); return err; } diff --git a/contracts/CErc20Delegate.sol b/contracts/SLErc20Delegate.sol similarity index 81% rename from contracts/CErc20Delegate.sol rename to contracts/SLErc20Delegate.sol index ad19ab448..78896f082 100644 --- a/contracts/CErc20Delegate.sol +++ b/contracts/SLErc20Delegate.sol @@ -1,13 +1,13 @@ pragma solidity ^0.5.16; -import "./CErc20.sol"; +import "./SLErc20.sol"; /** - * @title Compound's CErc20Delegate Contract - * @notice CTokens which wrap an EIP-20 underlying and are delegated to - * @author Compound + * @title SashimiLending's SLErc20Delegate Contract + * @notice SLTokens which wrap an EIP-20 underlying and are delegated to + * @author SashimiLending */ -contract CErc20Delegate is CErc20, CDelegateInterface { +contract SLErc20Delegate is SLErc20, SLDelegateInterface { /** * @notice Construct an empty delegate */ diff --git a/contracts/CErc20Delegator.sol b/contracts/SLErc20Delegator.sol similarity index 72% rename from contracts/CErc20Delegator.sol rename to contracts/SLErc20Delegator.sol index 0f6f749c9..d5fd0428d 100644 --- a/contracts/CErc20Delegator.sol +++ b/contracts/SLErc20Delegator.sol @@ -1,13 +1,13 @@ pragma solidity ^0.5.16; -import "./CTokenInterfaces.sol"; +import "./SLTokenInterfaces.sol"; /** - * @title Compound's CErc20Delegator Contract - * @notice CTokens which wrap an EIP-20 underlying and delegate to an implementation - * @author Compound + * @title SashimiLending's SLErc20Delegator Contract + * @notice SLTokens which wrap an EIP-20 underlying and delegate to an implementation + * @author SashimiLending */ -contract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterface { +contract SLErc20Delegator is SLTokenInterface, SLErc20Interface, SLDelegatorInterface { /** * @notice Construct a new money market * @param underlying_ The address of the underlying asset @@ -58,7 +58,7 @@ contract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterfac * @param becomeImplementationData The encoded bytes data to be passed to _becomeImplementation */ function _setImplementation(address implementation_, bool allowResign, bytes memory becomeImplementationData) public { - require(msg.sender == admin, "CErc20Delegator::_setImplementation: Caller must be admin"); + require(msg.sender == admin, "SLErc20Delegator::_setImplementation: Caller must be admin"); if (allowResign) { delegateToImplementation(abi.encodeWithSignature("_resignImplementation()")); @@ -73,36 +73,36 @@ contract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterfac } /** - * @notice Sender supplies assets into the market and receives cTokens in exchange + * @notice Sender supplies assets into the market and receives slTokens in exchange * @dev Accrues interest whether or not the operation succeeds, unless reverted * @param mintAmount The amount of the underlying asset to supply * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ function mint(uint mintAmount) external returns (uint) { - mintAmount; // Shh - delegateAndReturn(); + bytes memory data = delegateToImplementation(abi.encodeWithSignature("mint(uint256)", mintAmount)); + return abi.decode(data, (uint)); } /** - * @notice Sender redeems cTokens in exchange for the underlying asset + * @notice Sender redeems slTokens in exchange for the underlying asset * @dev Accrues interest whether or not the operation succeeds, unless reverted - * @param redeemTokens The number of cTokens to redeem into underlying + * @param redeemTokens The number of slTokens to redeem into underlying * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ function redeem(uint redeemTokens) external returns (uint) { - redeemTokens; // Shh - delegateAndReturn(); + bytes memory data = delegateToImplementation(abi.encodeWithSignature("redeem(uint256)", redeemTokens)); + return abi.decode(data, (uint)); } /** - * @notice Sender redeems cTokens in exchange for a specified amount of underlying asset + * @notice Sender redeems slTokens in exchange for a specified amount of underlying asset * @dev Accrues interest whether or not the operation succeeds, unless reverted * @param redeemAmount The amount of underlying to redeem * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ function redeemUnderlying(uint redeemAmount) external returns (uint) { - redeemAmount; // Shh - delegateAndReturn(); + bytes memory data = delegateToImplementation(abi.encodeWithSignature("redeemUnderlying(uint256)", redeemAmount)); + return abi.decode(data, (uint)); } /** @@ -111,8 +111,8 @@ contract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterfac * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ function borrow(uint borrowAmount) external returns (uint) { - borrowAmount; // Shh - delegateAndReturn(); + bytes memory data = delegateToImplementation(abi.encodeWithSignature("borrow(uint256)", borrowAmount)); + return abi.decode(data, (uint)); } /** @@ -121,8 +121,8 @@ contract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterfac * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ function repayBorrow(uint repayAmount) external returns (uint) { - repayAmount; // Shh - delegateAndReturn(); + bytes memory data = delegateToImplementation(abi.encodeWithSignature("repayBorrow(uint256)", repayAmount)); + return abi.decode(data, (uint)); } /** @@ -132,21 +132,21 @@ contract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterfac * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint) { - borrower; repayAmount; // Shh - delegateAndReturn(); + bytes memory data = delegateToImplementation(abi.encodeWithSignature("repayBorrowBehalf(address,uint256)", borrower, repayAmount)); + return abi.decode(data, (uint)); } /** * @notice The sender liquidates the borrowers collateral. * The collateral seized is transferred to the liquidator. - * @param borrower The borrower of this cToken to be liquidated - * @param cTokenCollateral The market in which to seize collateral from the borrower + * @param borrower The borrower of this slToken to be liquidated + * @param slTokenCollateral The market in which to seize collateral from the borrower * @param repayAmount The amount of the underlying borrowed asset to repay * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ - function liquidateBorrow(address borrower, uint repayAmount, CTokenInterface cTokenCollateral) external returns (uint) { - borrower; repayAmount; cTokenCollateral; // Shh - delegateAndReturn(); + function liquidateBorrow(address borrower, uint repayAmount, SLTokenInterface slTokenCollateral) external returns (uint) { + bytes memory data = delegateToImplementation(abi.encodeWithSignature("liquidateBorrow(address,uint256,address)", borrower, repayAmount, slTokenCollateral)); + return abi.decode(data, (uint)); } /** @@ -156,8 +156,8 @@ contract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterfac * @return Whether or not the transfer succeeded */ function transfer(address dst, uint amount) external returns (bool) { - dst; amount; // Shh - delegateAndReturn(); + bytes memory data = delegateToImplementation(abi.encodeWithSignature("transfer(address,uint256)", dst, amount)); + return abi.decode(data, (bool)); } /** @@ -168,8 +168,8 @@ contract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterfac * @return Whether or not the transfer succeeded */ function transferFrom(address src, address dst, uint256 amount) external returns (bool) { - src; dst; amount; // Shh - delegateAndReturn(); + bytes memory data = delegateToImplementation(abi.encodeWithSignature("transferFrom(address,address,uint256)", src, dst, amount)); + return abi.decode(data, (bool)); } /** @@ -181,8 +181,8 @@ contract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterfac * @return Whether or not the approval succeeded */ function approve(address spender, uint256 amount) external returns (bool) { - spender; amount; // Shh - delegateAndReturn(); + bytes memory data = delegateToImplementation(abi.encodeWithSignature("approve(address,uint256)", spender, amount)); + return abi.decode(data, (bool)); } /** @@ -192,8 +192,8 @@ contract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterfac * @return The number of tokens allowed to be spent (-1 means infinite) */ function allowance(address owner, address spender) external view returns (uint) { - owner; spender; // Shh - delegateToViewAndReturn(); + bytes memory data = delegateToViewImplementation(abi.encodeWithSignature("allowance(address,address)", owner, spender)); + return abi.decode(data, (uint)); } /** @@ -202,8 +202,8 @@ contract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterfac * @return The number of tokens owned by `owner` */ function balanceOf(address owner) external view returns (uint) { - owner; // Shh - delegateToViewAndReturn(); + bytes memory data = delegateToViewImplementation(abi.encodeWithSignature("balanceOf(address)", owner)); + return abi.decode(data, (uint)); } /** @@ -213,8 +213,8 @@ contract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterfac * @return The amount of underlying owned by `owner` */ function balanceOfUnderlying(address owner) external returns (uint) { - owner; // Shh - delegateAndReturn(); + bytes memory data = delegateToImplementation(abi.encodeWithSignature("balanceOfUnderlying(address)", owner)); + return abi.decode(data, (uint)); } /** @@ -224,24 +224,26 @@ contract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterfac * @return (possible error, token balance, borrow balance, exchange rate mantissa) */ function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint) { - account; // Shh - delegateToViewAndReturn(); + bytes memory data = delegateToViewImplementation(abi.encodeWithSignature("getAccountSnapshot(address)", account)); + return abi.decode(data, (uint, uint, uint, uint)); } /** - * @notice Returns the current per-block borrow interest rate for this cToken + * @notice Returns the current per-block borrow interest rate for this slToken * @return The borrow interest rate per block, scaled by 1e18 */ function borrowRatePerBlock() external view returns (uint) { - delegateToViewAndReturn(); + bytes memory data = delegateToViewImplementation(abi.encodeWithSignature("borrowRatePerBlock()")); + return abi.decode(data, (uint)); } /** - * @notice Returns the current per-block supply interest rate for this cToken + * @notice Returns the current per-block supply interest rate for this slToken * @return The supply interest rate per block, scaled by 1e18 */ function supplyRatePerBlock() external view returns (uint) { - delegateToViewAndReturn(); + bytes memory data = delegateToViewImplementation(abi.encodeWithSignature("supplyRatePerBlock()")); + return abi.decode(data, (uint)); } /** @@ -249,7 +251,8 @@ contract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterfac * @return The total borrows with interest */ function totalBorrowsCurrent() external returns (uint) { - delegateAndReturn(); + bytes memory data = delegateToImplementation(abi.encodeWithSignature("totalBorrowsCurrent()")); + return abi.decode(data, (uint)); } /** @@ -258,8 +261,8 @@ contract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterfac * @return The calculated balance */ function borrowBalanceCurrent(address account) external returns (uint) { - account; // Shh - delegateAndReturn(); + bytes memory data = delegateToImplementation(abi.encodeWithSignature("borrowBalanceCurrent(address)", account)); + return abi.decode(data, (uint)); } /** @@ -268,8 +271,8 @@ contract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterfac * @return The calculated balance */ function borrowBalanceStored(address account) public view returns (uint) { - account; // Shh - delegateToViewAndReturn(); + bytes memory data = delegateToViewImplementation(abi.encodeWithSignature("borrowBalanceStored(address)", account)); + return abi.decode(data, (uint)); } /** @@ -277,24 +280,27 @@ contract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterfac * @return Calculated exchange rate scaled by 1e18 */ function exchangeRateCurrent() public returns (uint) { - delegateAndReturn(); + bytes memory data = delegateToImplementation(abi.encodeWithSignature("exchangeRateCurrent()")); + return abi.decode(data, (uint)); } /** - * @notice Calculates the exchange rate from the underlying to the CToken + * @notice Calculates the exchange rate from the underlying to the SLToken * @dev This function does not accrue interest before calculating the exchange rate * @return Calculated exchange rate scaled by 1e18 */ function exchangeRateStored() public view returns (uint) { - delegateToViewAndReturn(); + bytes memory data = delegateToViewImplementation(abi.encodeWithSignature("exchangeRateStored()")); + return abi.decode(data, (uint)); } /** - * @notice Get cash balance of this cToken in the underlying asset + * @notice Get cash balance of this slToken in the underlying asset * @return The quantity of underlying asset owned by this contract */ function getCash() external view returns (uint) { - delegateToViewAndReturn(); + bytes memory data = delegateToViewImplementation(abi.encodeWithSignature("getCash()")); + return abi.decode(data, (uint)); } /** @@ -303,21 +309,22 @@ contract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterfac * up to the current block and writes new checkpoint to storage. */ function accrueInterest() public returns (uint) { - delegateAndReturn(); + bytes memory data = delegateToImplementation(abi.encodeWithSignature("accrueInterest()")); + return abi.decode(data, (uint)); } /** * @notice Transfers collateral tokens (this market) to the liquidator. - * @dev Will fail unless called by another cToken during the process of liquidation. - * Its absolutely critical to use msg.sender as the borrowed cToken and not a parameter. + * @dev Will fail unless called by another slToken during the process of liquidation. + * Its absolutely critical to use msg.sender as the borrowed slToken and not a parameter. * @param liquidator The account receiving seized collateral * @param borrower The account having collateral seized - * @param seizeTokens The number of cTokens to seize + * @param seizeTokens The number of slTokens to seize * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ function seize(address liquidator, address borrower, uint seizeTokens) external returns (uint) { - liquidator; borrower; seizeTokens; // Shh - delegateAndReturn(); + bytes memory data = delegateToImplementation(abi.encodeWithSignature("seize(address,address,uint256)", liquidator, borrower, seizeTokens)); + return abi.decode(data, (uint)); } /*** Admin Functions ***/ @@ -329,8 +336,8 @@ contract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterfac * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ function _setPendingAdmin(address payable newPendingAdmin) external returns (uint) { - newPendingAdmin; // Shh - delegateAndReturn(); + bytes memory data = delegateToImplementation(abi.encodeWithSignature("_setPendingAdmin(address)", newPendingAdmin)); + return abi.decode(data, (uint)); } /** @@ -339,8 +346,8 @@ contract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterfac * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ function _setComptroller(ComptrollerInterface newComptroller) public returns (uint) { - newComptroller; // Shh - delegateAndReturn(); + bytes memory data = delegateToImplementation(abi.encodeWithSignature("_setComptroller(address)", newComptroller)); + return abi.decode(data, (uint)); } /** @@ -349,8 +356,8 @@ contract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterfac * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ function _setReserveFactor(uint newReserveFactorMantissa) external returns (uint) { - newReserveFactorMantissa; // Shh - delegateAndReturn(); + bytes memory data = delegateToImplementation(abi.encodeWithSignature("_setReserveFactor(uint256)", newReserveFactorMantissa)); + return abi.decode(data, (uint)); } /** @@ -359,7 +366,8 @@ contract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterfac * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ function _acceptAdmin() external returns (uint) { - delegateAndReturn(); + bytes memory data = delegateToImplementation(abi.encodeWithSignature("_acceptAdmin()")); + return abi.decode(data, (uint)); } /** @@ -368,8 +376,8 @@ contract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterfac * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ function _addReserves(uint addAmount) external returns (uint) { - addAmount; // Shh - delegateAndReturn(); + bytes memory data = delegateToImplementation(abi.encodeWithSignature("_addReserves(uint256)", addAmount)); + return abi.decode(data, (uint)); } /** @@ -378,8 +386,8 @@ contract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterfac * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ function _reduceReserves(uint reduceAmount) external returns (uint) { - reduceAmount; // Shh - delegateAndReturn(); + bytes memory data = delegateToImplementation(abi.encodeWithSignature("_reduceReserves(uint256)", reduceAmount)); + return abi.decode(data, (uint)); } /** @@ -389,8 +397,8 @@ contract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterfac * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ function _setInterestRateModel(InterestRateModel newInterestRateModel) public returns (uint) { - newInterestRateModel; // Shh - delegateAndReturn(); + bytes memory data = delegateToImplementation(abi.encodeWithSignature("_setInterestRateModel(address)", newInterestRateModel)); + return abi.decode(data, (uint)); } /** @@ -437,20 +445,14 @@ contract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterfac return abi.decode(returnData, (bytes)); } - function delegateToViewAndReturn() private view returns (bytes memory) { - (bool success, ) = address(this).staticcall(abi.encodeWithSignature("delegateToImplementation(bytes)", msg.data)); - - assembly { - let free_mem_ptr := mload(0x40) - returndatacopy(free_mem_ptr, 0, returndatasize) - - switch success - case 0 { revert(free_mem_ptr, returndatasize) } - default { return(add(free_mem_ptr, 0x40), returndatasize) } - } - } + /** + * @notice Delegates execution to an implementation contract + * @dev It returns to the external caller whatever the implementation returns or forwards reverts + */ + function () external payable { + require(msg.value == 0,"SLErc20Delegator:fallback: cannot send value to fallback"); - function delegateAndReturn() private returns (bytes memory) { + // delegate all other functions to current implementation (bool success, ) = implementation.delegatecall(msg.data); assembly { @@ -462,15 +464,4 @@ contract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterfac default { return(free_mem_ptr, returndatasize) } } } - - /** - * @notice Delegates execution to an implementation contract - * @dev It returns to the external caller whatever the implementation returns or forwards reverts - */ - function () external payable { - require(msg.value == 0,"CErc20Delegator:fallback: cannot send value to fallback"); - - // delegate all other functions to current implementation - delegateAndReturn(); - } -} +} \ No newline at end of file diff --git a/contracts/CErc20Immutable.sol b/contracts/SLErc20Immutable.sol similarity index 85% rename from contracts/CErc20Immutable.sol rename to contracts/SLErc20Immutable.sol index 164f1bcc7..d52ffb179 100644 --- a/contracts/CErc20Immutable.sol +++ b/contracts/SLErc20Immutable.sol @@ -1,13 +1,13 @@ pragma solidity ^0.5.16; -import "./CErc20.sol"; +import "./SLErc20.sol"; /** - * @title Compound's CErc20Immutable Contract - * @notice CTokens which wrap an EIP-20 underlying and are immutable - * @author Compound + * @title SashimiLending's SLErc20Immutable Contract + * @notice SLTokens which wrap an EIP-20 underlying and are immutable + * @author SashimiLending */ -contract CErc20Immutable is CErc20 { +contract SLErc20Immutable is SLErc20 { /** * @notice Construct a new money market * @param underlying_ The address of the underlying asset diff --git a/contracts/CEther.sol b/contracts/SLEther.sol similarity index 87% rename from contracts/CEther.sol rename to contracts/SLEther.sol index e7bd14ea2..396c115e6 100644 --- a/contracts/CEther.sol +++ b/contracts/SLEther.sol @@ -1,15 +1,15 @@ pragma solidity ^0.5.16; -import "./CToken.sol"; +import "./SLToken.sol"; /** - * @title Compound's CEther Contract - * @notice CToken which wraps Ether - * @author Compound + * @title SashimiLending's SLEther Contract + * @notice SLToken which wraps Ether + * @author SashimiLending */ -contract CEther is CToken { +contract SLEther is SLToken { /** - * @notice Construct a new CEther money market + * @notice Construct a new SLEther money market * @param comptroller_ The address of the Comptroller * @param interestRateModel_ The address of the interest rate model * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18 @@ -38,7 +38,7 @@ contract CEther is CToken { /*** User Interface ***/ /** - * @notice Sender supplies assets into the market and receives cTokens in exchange + * @notice Sender supplies assets into the market and receives slTokens in exchange * @dev Reverts upon any failure */ function mint() external payable { @@ -47,9 +47,9 @@ contract CEther is CToken { } /** - * @notice Sender redeems cTokens in exchange for the underlying asset + * @notice Sender redeems slTokens in exchange for the underlying asset * @dev Accrues interest whether or not the operation succeeds, unless reverted - * @param redeemTokens The number of cTokens to redeem into underlying + * @param redeemTokens The number of slTokens to redeem into underlying * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ function redeem(uint redeemTokens) external returns (uint) { @@ -57,7 +57,7 @@ contract CEther is CToken { } /** - * @notice Sender redeems cTokens in exchange for a specified amount of underlying asset + * @notice Sender redeems slTokens in exchange for a specified amount of underlying asset * @dev Accrues interest whether or not the operation succeeds, unless reverted * @param redeemAmount The amount of underlying to redeem * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) @@ -98,16 +98,16 @@ contract CEther is CToken { * @notice The sender liquidates the borrowers collateral. * The collateral seized is transferred to the liquidator. * @dev Reverts upon any failure - * @param borrower The borrower of this cToken to be liquidated - * @param cTokenCollateral The market in which to seize collateral from the borrower + * @param borrower The borrower of this slToken to be liquidated + * @param slTokenCollateral The market in which to seize collateral from the borrower */ - function liquidateBorrow(address borrower, CToken cTokenCollateral) external payable { - (uint err,) = liquidateBorrowInternal(borrower, msg.value, cTokenCollateral); + function liquidateBorrow(address borrower, SLToken slTokenCollateral) external payable { + (uint err,) = liquidateBorrowInternal(borrower, msg.value, slTokenCollateral); requireNoError(err, "liquidateBorrow failed"); } /** - * @notice Send Ether to CEther to mint + * @notice Send Ether to SLEther to mint */ function () external payable { (uint err,) = mintInternal(msg.value); diff --git a/contracts/CToken.sol b/contracts/SLToken.sol similarity index 94% rename from contracts/CToken.sol rename to contracts/SLToken.sol index d1a697bb0..3a5722a33 100644 --- a/contracts/CToken.sol +++ b/contracts/SLToken.sol @@ -1,7 +1,7 @@ pragma solidity ^0.5.16; import "./ComptrollerInterface.sol"; -import "./CTokenInterfaces.sol"; +import "./SLTokenInterfaces.sol"; import "./ErrorReporter.sol"; import "./Exponential.sol"; import "./EIP20Interface.sol"; @@ -9,11 +9,11 @@ import "./EIP20NonStandardInterface.sol"; import "./InterestRateModel.sol"; /** - * @title Compound's CToken Contract - * @notice Abstract base for CTokens - * @author Compound + * @title SashimiLending's SLToken Contract + * @notice Abstract base for SLTokens + * @author SashimiLending */ -contract CToken is CTokenInterface, Exponential, TokenErrorReporter { +contract SLToken is SLTokenInterface, Exponential, TokenErrorReporter { /** * @notice Initialize the money market * @param comptroller_ The address of the Comptroller @@ -201,7 +201,7 @@ contract CToken is CTokenInterface, Exponential, TokenErrorReporter { * @return (possible error, token balance, borrow balance, exchange rate mantissa) */ function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint) { - uint cTokenBalance = accountTokens[account]; + uint slTokenBalance = accountTokens[account]; uint borrowBalance; uint exchangeRateMantissa; @@ -217,7 +217,7 @@ contract CToken is CTokenInterface, Exponential, TokenErrorReporter { return (uint(Error.MATH_ERROR), 0, 0, 0); } - return (uint(Error.NO_ERROR), cTokenBalance, borrowBalance, exchangeRateMantissa); + return (uint(Error.NO_ERROR), slTokenBalance, borrowBalance, exchangeRateMantissa); } /** @@ -229,7 +229,7 @@ contract CToken is CTokenInterface, Exponential, TokenErrorReporter { } /** - * @notice Returns the current per-block borrow interest rate for this cToken + * @notice Returns the current per-block borrow interest rate for this slToken * @return The borrow interest rate per block, scaled by 1e18 */ function borrowRatePerBlock() external view returns (uint) { @@ -237,7 +237,7 @@ contract CToken is CTokenInterface, Exponential, TokenErrorReporter { } /** - * @notice Returns the current per-block supply interest rate for this cToken + * @notice Returns the current per-block supply interest rate for this slToken * @return The supply interest rate per block, scaled by 1e18 */ function supplyRatePerBlock() external view returns (uint) { @@ -321,7 +321,7 @@ contract CToken is CTokenInterface, Exponential, TokenErrorReporter { } /** - * @notice Calculates the exchange rate from the underlying to the CToken + * @notice Calculates the exchange rate from the underlying to the SLToken * @dev This function does not accrue interest before calculating the exchange rate * @return Calculated exchange rate scaled by 1e18 */ @@ -332,7 +332,7 @@ contract CToken is CTokenInterface, Exponential, TokenErrorReporter { } /** - * @notice Calculates the exchange rate from the underlying to the CToken + * @notice Calculates the exchange rate from the underlying to the SLToken * @dev This function does not accrue interest before calculating the exchange rate * @return (error code, calculated exchange rate scaled by 1e18) */ @@ -369,7 +369,7 @@ contract CToken is CTokenInterface, Exponential, TokenErrorReporter { } /** - * @notice Get cash balance of this cToken in the underlying asset + * @notice Get cash balance of this slToken in the underlying asset * @return The quantity of underlying asset owned by this contract */ function getCash() external view returns (uint) { @@ -462,7 +462,7 @@ contract CToken is CTokenInterface, Exponential, TokenErrorReporter { } /** - * @notice Sender supplies assets into the market and receives cTokens in exchange + * @notice Sender supplies assets into the market and receives slTokens in exchange * @dev Accrues interest whether or not the operation succeeds, unless reverted * @param mintAmount The amount of the underlying asset to supply * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount. @@ -488,7 +488,7 @@ contract CToken is CTokenInterface, Exponential, TokenErrorReporter { } /** - * @notice User supplies assets into the market and receives cTokens in exchange + * @notice User supplies assets into the market and receives slTokens in exchange * @dev Assumes interest has already been accrued up to the current block * @param minter The address of the account which is supplying the assets * @param mintAmount The amount of the underlying asset to supply @@ -519,16 +519,16 @@ contract CToken is CTokenInterface, Exponential, TokenErrorReporter { /* * We call `doTransferIn` for the minter and the mintAmount. - * Note: The cToken must handle variations between ERC-20 and ETH underlying. + * Note: The slToken must handle variations between ERC-20 and ETH underlying. * `doTransferIn` reverts if anything goes wrong, since we can't be sure if * side-effects occurred. The function returns the amount actually transferred, - * in case of a fee. On success, the cToken holds an additional `actualMintAmount` + * in case of a fee. On success, the slToken holds an additional `actualMintAmount` * of cash. */ vars.actualMintAmount = doTransferIn(minter, mintAmount); /* - * We get the current exchange rate and calculate the number of cTokens to be minted: + * We get the current exchange rate and calculate the number of slTokens to be minted: * mintTokens = actualMintAmount / exchangeRate */ @@ -536,7 +536,7 @@ contract CToken is CTokenInterface, Exponential, TokenErrorReporter { require(vars.mathErr == MathError.NO_ERROR, "MINT_EXCHANGE_CALCULATION_FAILED"); /* - * We calculate the new total supply of cTokens and minter token balance, checking for overflow: + * We calculate the new total supply of slTokens and minter token balance, checking for overflow: * totalSupplyNew = totalSupply + mintTokens * accountTokensNew = accountTokens[minter] + mintTokens */ @@ -561,9 +561,9 @@ contract CToken is CTokenInterface, Exponential, TokenErrorReporter { } /** - * @notice Sender redeems cTokens in exchange for the underlying asset + * @notice Sender redeems slTokens in exchange for the underlying asset * @dev Accrues interest whether or not the operation succeeds, unless reverted - * @param redeemTokens The number of cTokens to redeem into underlying + * @param redeemTokens The number of slTokens to redeem into underlying * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ function redeemInternal(uint redeemTokens) internal nonReentrant returns (uint) { @@ -577,9 +577,9 @@ contract CToken is CTokenInterface, Exponential, TokenErrorReporter { } /** - * @notice Sender redeems cTokens in exchange for a specified amount of underlying asset + * @notice Sender redeems slTokens in exchange for a specified amount of underlying asset * @dev Accrues interest whether or not the operation succeeds, unless reverted - * @param redeemAmount The amount of underlying to receive from redeeming cTokens + * @param redeemAmount The amount of underlying to receive from redeeming slTokens * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ function redeemUnderlyingInternal(uint redeemAmount) internal nonReentrant returns (uint) { @@ -603,11 +603,11 @@ contract CToken is CTokenInterface, Exponential, TokenErrorReporter { } /** - * @notice User redeems cTokens in exchange for the underlying asset + * @notice User redeems slTokens in exchange for the underlying asset * @dev Assumes interest has already been accrued up to the current block * @param redeemer The address of the account which is redeeming the tokens - * @param redeemTokensIn The number of cTokens to redeem into underlying (only one of redeemTokensIn or redeemAmountIn may be non-zero) - * @param redeemAmountIn The number of underlying tokens to receive from redeeming cTokens (only one of redeemTokensIn or redeemAmountIn may be non-zero) + * @param redeemTokensIn The number of slTokens to redeem into underlying (only one of redeemTokensIn or redeemAmountIn may be non-zero) + * @param redeemAmountIn The number of underlying tokens to receive from redeeming slTokens (only one of redeemTokensIn or redeemAmountIn may be non-zero) * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ function redeemFresh(address payable redeemer, uint redeemTokensIn, uint redeemAmountIn) internal returns (uint) { @@ -686,8 +686,8 @@ contract CToken is CTokenInterface, Exponential, TokenErrorReporter { /* * We invoke doTransferOut for the redeemer and the redeemAmount. - * Note: The cToken must handle variations between ERC-20 and ETH underlying. - * On success, the cToken has redeemAmount less of cash. + * Note: The slToken must handle variations between ERC-20 and ETH underlying. + * On success, the slToken has redeemAmount less of cash. * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred. */ doTransferOut(redeemer, vars.redeemAmount); @@ -778,8 +778,8 @@ contract CToken is CTokenInterface, Exponential, TokenErrorReporter { /* * We invoke doTransferOut for the borrower and the borrowAmount. - * Note: The cToken must handle variations between ERC-20 and ETH underlying. - * On success, the cToken borrowAmount less of cash. + * Note: The slToken must handle variations between ERC-20 and ETH underlying. + * On success, the slToken borrowAmount less of cash. * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred. */ doTransferOut(borrower, borrowAmount); @@ -883,8 +883,8 @@ contract CToken is CTokenInterface, Exponential, TokenErrorReporter { /* * We call doTransferIn for the payer and the repayAmount - * Note: The cToken must handle variations between ERC-20 and ETH underlying. - * On success, the cToken holds an additional repayAmount of cash. + * Note: The slToken must handle variations between ERC-20 and ETH underlying. + * On success, the slToken holds an additional repayAmount of cash. * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred. * it returns the amount actually transferred, in case of a fee. */ @@ -918,40 +918,40 @@ contract CToken is CTokenInterface, Exponential, TokenErrorReporter { /** * @notice The sender liquidates the borrowers collateral. * The collateral seized is transferred to the liquidator. - * @param borrower The borrower of this cToken to be liquidated - * @param cTokenCollateral The market in which to seize collateral from the borrower + * @param borrower The borrower of this slToken to be liquidated + * @param slTokenCollateral The market in which to seize collateral from the borrower * @param repayAmount The amount of the underlying borrowed asset to repay * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount. */ - function liquidateBorrowInternal(address borrower, uint repayAmount, CTokenInterface cTokenCollateral) internal nonReentrant returns (uint, uint) { + function liquidateBorrowInternal(address borrower, uint repayAmount, SLTokenInterface slTokenCollateral) internal nonReentrant returns (uint, uint) { uint error = accrueInterest(); if (error != uint(Error.NO_ERROR)) { // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED), 0); } - error = cTokenCollateral.accrueInterest(); + error = slTokenCollateral.accrueInterest(); if (error != uint(Error.NO_ERROR)) { // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED), 0); } // liquidateBorrowFresh emits borrow-specific logs on errors, so we don't need to - return liquidateBorrowFresh(msg.sender, borrower, repayAmount, cTokenCollateral); + return liquidateBorrowFresh(msg.sender, borrower, repayAmount, slTokenCollateral); } /** * @notice The liquidator liquidates the borrowers collateral. * The collateral seized is transferred to the liquidator. - * @param borrower The borrower of this cToken to be liquidated + * @param borrower The borrower of this slToken to be liquidated * @param liquidator The address repaying the borrow and seizing collateral - * @param cTokenCollateral The market in which to seize collateral from the borrower + * @param slTokenCollateral The market in which to seize collateral from the borrower * @param repayAmount The amount of the underlying borrowed asset to repay * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount. */ - function liquidateBorrowFresh(address liquidator, address borrower, uint repayAmount, CTokenInterface cTokenCollateral) internal returns (uint, uint) { + function liquidateBorrowFresh(address liquidator, address borrower, uint repayAmount, SLTokenInterface slTokenCollateral) internal returns (uint, uint) { /* Fail if liquidate not allowed */ - uint allowed = comptroller.liquidateBorrowAllowed(address(this), address(cTokenCollateral), liquidator, borrower, repayAmount); + uint allowed = comptroller.liquidateBorrowAllowed(address(this), address(slTokenCollateral), liquidator, borrower, repayAmount); if (allowed != 0) { return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_COMPTROLLER_REJECTION, allowed), 0); } @@ -961,8 +961,8 @@ contract CToken is CTokenInterface, Exponential, TokenErrorReporter { return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_FRESHNESS_CHECK), 0); } - /* Verify cTokenCollateral market's block number equals current block number */ - if (cTokenCollateral.accrualBlockNumber() != getBlockNumber()) { + /* Verify slTokenCollateral market's block number equals current block number */ + if (slTokenCollateral.accrualBlockNumber() != getBlockNumber()) { return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_COLLATERAL_FRESHNESS_CHECK), 0); } @@ -993,39 +993,39 @@ contract CToken is CTokenInterface, Exponential, TokenErrorReporter { // (No safe failures beyond this point) /* We calculate the number of collateral tokens that will be seized */ - (uint amountSeizeError, uint seizeTokens) = comptroller.liquidateCalculateSeizeTokens(address(this), address(cTokenCollateral), actualRepayAmount); + (uint amountSeizeError, uint seizeTokens) = comptroller.liquidateCalculateSeizeTokens(address(this), address(slTokenCollateral), actualRepayAmount); require(amountSeizeError == uint(Error.NO_ERROR), "LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED"); /* Revert if borrower collateral token balance < seizeTokens */ - require(cTokenCollateral.balanceOf(borrower) >= seizeTokens, "LIQUIDATE_SEIZE_TOO_MUCH"); + require(slTokenCollateral.balanceOf(borrower) >= seizeTokens, "LIQUIDATE_SEIZE_TOO_MUCH"); // If this is also the collateral, run seizeInternal to avoid re-entrancy, otherwise make an external call uint seizeError; - if (address(cTokenCollateral) == address(this)) { + if (address(slTokenCollateral) == address(this)) { seizeError = seizeInternal(address(this), liquidator, borrower, seizeTokens); } else { - seizeError = cTokenCollateral.seize(liquidator, borrower, seizeTokens); + seizeError = slTokenCollateral.seize(liquidator, borrower, seizeTokens); } /* Revert if seize tokens fails (since we cannot be sure of side effects) */ require(seizeError == uint(Error.NO_ERROR), "token seizure failed"); /* We emit a LiquidateBorrow event */ - emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(cTokenCollateral), seizeTokens); + emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(slTokenCollateral), seizeTokens); /* We call the defense hook */ - comptroller.liquidateBorrowVerify(address(this), address(cTokenCollateral), liquidator, borrower, actualRepayAmount, seizeTokens); + comptroller.liquidateBorrowVerify(address(this), address(slTokenCollateral), liquidator, borrower, actualRepayAmount, seizeTokens); return (uint(Error.NO_ERROR), actualRepayAmount); } /** * @notice Transfers collateral tokens (this market) to the liquidator. - * @dev Will fail unless called by another cToken during the process of liquidation. - * Its absolutely critical to use msg.sender as the borrowed cToken and not a parameter. + * @dev Will fail unless called by another slToken during the process of liquidation. + * Its absolutely critical to use msg.sender as the borrowed slToken and not a parameter. * @param liquidator The account receiving seized collateral * @param borrower The account having collateral seized - * @param seizeTokens The number of cTokens to seize + * @param seizeTokens The number of slTokens to seize * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ function seize(address liquidator, address borrower, uint seizeTokens) external nonReentrant returns (uint) { @@ -1034,12 +1034,12 @@ contract CToken is CTokenInterface, Exponential, TokenErrorReporter { /** * @notice Transfers collateral tokens (this market) to the liquidator. - * @dev Called only during an in-kind liquidation, or by liquidateBorrow during the liquidation of another CToken. - * Its absolutely critical to use msg.sender as the seizer cToken and not a parameter. - * @param seizerToken The contract seizing the collateral (i.e. borrowed cToken) + * @dev Called only during an in-kind liquidation, or by liquidateBorrow during the liquidation of another SLToken. + * Its absolutely critical to use msg.sender as the seizer slToken and not a parameter. + * @param seizerToken The contract seizing the collateral (i.e. borrowed slToken) * @param liquidator The account receiving seized collateral * @param borrower The account having collateral seized - * @param seizeTokens The number of cTokens to seize + * @param seizeTokens The number of slTokens to seize * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ function seizeInternal(address seizerToken, address liquidator, address borrower, uint seizeTokens) internal returns (uint) { @@ -1251,8 +1251,8 @@ contract CToken is CTokenInterface, Exponential, TokenErrorReporter { /* * We call doTransferIn for the caller and the addAmount - * Note: The cToken must handle variations between ERC-20 and ETH underlying. - * On success, the cToken holds an additional addAmount of cash. + * Note: The slToken must handle variations between ERC-20 and ETH underlying. + * On success, the slToken holds an additional addAmount of cash. * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred. * it returns the amount actually transferred, in case of a fee. */ diff --git a/contracts/CTokenInterfaces.sol b/contracts/SLTokenInterfaces.sol similarity index 93% rename from contracts/CTokenInterfaces.sol rename to contracts/SLTokenInterfaces.sol index 6d9974a88..fe2c4b377 100644 --- a/contracts/CTokenInterfaces.sol +++ b/contracts/SLTokenInterfaces.sol @@ -3,7 +3,7 @@ pragma solidity ^0.5.16; import "./ComptrollerInterface.sol"; import "./InterestRateModel.sol"; -contract CTokenStorage { +contract SLTokenStorage { /** * @dev Guard variable for re-entrancy checks */ @@ -46,7 +46,7 @@ contract CTokenStorage { address payable public pendingAdmin; /** - * @notice Contract which oversees inter-cToken operations + * @notice Contract which oversees inter-slToken operations */ ComptrollerInterface public comptroller; @@ -56,7 +56,7 @@ contract CTokenStorage { InterestRateModel public interestRateModel; /** - * @notice Initial exchange rate used when minting the first CTokens (used when totalSupply = 0) + * @notice Initial exchange rate used when minting the first SLTokens (used when totalSupply = 0) */ uint internal initialExchangeRateMantissa; @@ -116,11 +116,11 @@ contract CTokenStorage { mapping(address => BorrowSnapshot) internal accountBorrows; } -contract CTokenInterface is CTokenStorage { +contract SLTokenInterface is SLTokenStorage { /** - * @notice Indicator that this is a CToken contract (for inspection) + * @notice Indicator that this is a SLToken contract (for inspection) */ - bool public constant isCToken = true; + bool public constant isSLToken = true; /*** Market Events ***/ @@ -153,7 +153,7 @@ contract CTokenInterface is CTokenStorage { /** * @notice Event emitted when a borrow is liquidated */ - event LiquidateBorrow(address liquidator, address borrower, uint repayAmount, address cTokenCollateral, uint seizeTokens); + event LiquidateBorrow(address liquidator, address borrower, uint repayAmount, address slTokenCollateral, uint seizeTokens); /*** Admin Events ***/ @@ -240,14 +240,14 @@ contract CTokenInterface is CTokenStorage { function _setInterestRateModel(InterestRateModel newInterestRateModel) public returns (uint); } -contract CErc20Storage { +contract SLErc20Storage { /** - * @notice Underlying asset for this CToken + * @notice Underlying asset for this SLToken */ address public underlying; } -contract CErc20Interface is CErc20Storage { +contract SLErc20Interface is SLErc20Storage { /*** User Interface ***/ @@ -257,7 +257,7 @@ contract CErc20Interface is CErc20Storage { function borrow(uint borrowAmount) external returns (uint); function repayBorrow(uint repayAmount) external returns (uint); function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint); - function liquidateBorrow(address borrower, uint repayAmount, CTokenInterface cTokenCollateral) external returns (uint); + function liquidateBorrow(address borrower, uint repayAmount, SLTokenInterface slTokenCollateral) external returns (uint); /*** Admin Functions ***/ @@ -265,14 +265,14 @@ contract CErc20Interface is CErc20Storage { function _addReserves(uint addAmount) external returns (uint); } -contract CDelegationStorage { +contract SLDelegationStorage { /** * @notice Implementation address for this contract */ address public implementation; } -contract CDelegatorInterface is CDelegationStorage { +contract SLDelegatorInterface is SLDelegationStorage { /** * @notice Emitted when implementation is changed */ @@ -287,7 +287,7 @@ contract CDelegatorInterface is CDelegationStorage { function _setImplementation(address implementation_, bool allowResign, bytes memory becomeImplementationData) public; } -contract CDelegateInterface is CDelegationStorage { +contract SLDelegateInterface is SLDelegationStorage { /** * @notice Called by the delegator on a delegate to initialize it for duty * @dev Should revert if any issues arise which make it unfit for delegation diff --git a/contracts/SimplePriceOracle.sol b/contracts/SimplePriceOracle.sol index 32d572f97..0661e4be9 100644 --- a/contracts/SimplePriceOracle.sol +++ b/contracts/SimplePriceOracle.sol @@ -1,22 +1,22 @@ pragma solidity ^0.5.16; import "./PriceOracle.sol"; -import "./CErc20.sol"; +import "./SLErc20.sol"; contract SimplePriceOracle is PriceOracle { mapping(address => uint) prices; event PricePosted(address asset, uint previousPriceMantissa, uint requestedPriceMantissa, uint newPriceMantissa); - function getUnderlyingPrice(CToken cToken) public view returns (uint) { - if (compareStrings(cToken.symbol(), "cETH")) { + function getUnderlyingPrice(SLToken slToken) public view returns (uint) { + if (compareStrings(slToken.symbol(), "slETH")) { return 1e18; } else { - return prices[address(CErc20(address(cToken)).underlying())]; + return prices[address(SLErc20(address(slToken)).underlying())]; } } - function setUnderlyingPrice(CToken cToken, uint underlyingPriceMantissa) public { - address asset = address(CErc20(address(cToken)).underlying()); + function setUnderlyingPrice(SLToken slToken, uint underlyingPriceMantissa) public { + address asset = address(SLErc20(address(slToken)).underlying()); emit PricePosted(asset, prices[asset], underlyingPriceMantissa, underlyingPriceMantissa); prices[asset] = underlyingPriceMantissa; } diff --git a/contracts/Unitroller.sol b/contracts/Unitroller.sol index 94765861c..447c3370d 100644 --- a/contracts/Unitroller.sol +++ b/contracts/Unitroller.sol @@ -5,7 +5,7 @@ import "./ComptrollerStorage.sol"; /** * @title ComptrollerCore * @dev Storage for the comptroller is at this address, while execution is delegated to the `comptrollerImplementation`. - * CTokens should reference this contract as their comptroller. + * SLTokens should reference this contract as their comptroller. */ contract Unitroller is UnitrollerAdminStorage, ComptrollerErrorReporter { diff --git a/saddle.config.js b/saddle.config.js index cafb1d983..be386077d 100644 --- a/saddle.config.js +++ b/saddle.config.js @@ -165,11 +165,11 @@ module.exports = { web3: { gas: [ {env: "GAS"}, - {default: "4600000"} + {default: "6600000"} ], gas_price: [ {env: "GAS_PRICE"}, - {default: "12000000000"} + {default: "1000000000"} ], options: { transactionConfirmationBlocks: 1, diff --git a/scenario/src/Builder/CTokenDelegateBuilder.ts b/scenario/src/Builder/CTokenDelegateBuilder.ts deleted file mode 100644 index f19477abd..000000000 --- a/scenario/src/Builder/CTokenDelegateBuilder.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { Event } from '../Event'; -import { World } from '../World'; -import { CErc20Delegate, CErc20DelegateScenario } from '../Contract/CErc20Delegate'; -import { CToken } from '../Contract/CToken'; -import { Invokation } from '../Invokation'; -import { getStringV } from '../CoreValue'; -import { AddressV, NumberV, StringV } from '../Value'; -import { Arg, Fetcher, getFetcherValue } from '../Command'; -import { storeAndSaveContract } from '../Networks'; -import { getContract, getTestContract } from '../Contract'; - -const CDaiDelegateContract = getContract('CDaiDelegate'); -const CDaiDelegateScenarioContract = getTestContract('CDaiDelegateScenario'); -const CErc20DelegateContract = getContract('CErc20Delegate'); -const CErc20DelegateScenarioContract = getTestContract('CErc20DelegateScenario'); - - -export interface CTokenDelegateData { - invokation: Invokation; - name: string; - contract: string; - description?: string; -} - -export async function buildCTokenDelegate( - world: World, - from: string, - params: Event -): Promise<{ world: World; cTokenDelegate: CErc20Delegate; delegateData: CTokenDelegateData }> { - const fetchers = [ - new Fetcher<{ name: StringV; }, CTokenDelegateData>( - ` - #### CDaiDelegate - - * "CDaiDelegate name:" - * E.g. "CTokenDelegate Deploy CDaiDelegate cDAIDelegate" - `, - 'CDaiDelegate', - [ - new Arg('name', getStringV) - ], - async ( - world, - { name } - ) => { - return { - invokation: await CDaiDelegateContract.deploy(world, from, []), - name: name.val, - contract: 'CDaiDelegate', - description: 'Standard CDai Delegate' - }; - } - ), - - new Fetcher<{ name: StringV; }, CTokenDelegateData>( - ` - #### CDaiDelegateScenario - - * "CDaiDelegateScenario name:" - A CDaiDelegate Scenario for local testing - * E.g. "CTokenDelegate Deploy CDaiDelegateScenario cDAIDelegate" - `, - 'CDaiDelegateScenario', - [ - new Arg('name', getStringV) - ], - async ( - world, - { name } - ) => { - return { - invokation: await CDaiDelegateScenarioContract.deploy(world, from, []), - name: name.val, - contract: 'CDaiDelegateScenario', - description: 'Scenario CDai Delegate' - }; - } - ), - - new Fetcher<{ name: StringV; }, CTokenDelegateData>( - ` - #### CErc20Delegate - - * "CErc20Delegate name:" - * E.g. "CTokenDelegate Deploy CErc20Delegate cDAIDelegate" - `, - 'CErc20Delegate', - [ - new Arg('name', getStringV) - ], - async ( - world, - { name } - ) => { - return { - invokation: await CErc20DelegateContract.deploy(world, from, []), - name: name.val, - contract: 'CErc20Delegate', - description: 'Standard CErc20 Delegate' - }; - } - ), - - new Fetcher<{ name: StringV; }, CTokenDelegateData>( - ` - #### CErc20DelegateScenario - - * "CErc20DelegateScenario name:" - A CErc20Delegate Scenario for local testing - * E.g. "CTokenDelegate Deploy CErc20DelegateScenario cDAIDelegate" - `, - 'CErc20DelegateScenario', - [ - new Arg('name', getStringV), - ], - async ( - world, - { name } - ) => { - return { - invokation: await CErc20DelegateScenarioContract.deploy(world, from, []), - name: name.val, - contract: 'CErc20DelegateScenario', - description: 'Scenario CErc20 Delegate' - }; - } - ) - ]; - - let delegateData = await getFetcherValue("DeployCToken", fetchers, world, params); - let invokation = delegateData.invokation; - delete delegateData.invokation; - - if (invokation.error) { - throw invokation.error; - } - - const cTokenDelegate = invokation.value!; - - world = await storeAndSaveContract( - world, - cTokenDelegate, - delegateData.name, - invokation, - [ - { - index: ['CTokenDelegate', delegateData.name], - data: { - address: cTokenDelegate._address, - contract: delegateData.contract, - description: delegateData.description - } - } - ] - ); - - return { world, cTokenDelegate, delegateData }; -} diff --git a/scenario/src/Builder/CompBuilder.ts b/scenario/src/Builder/CompBuilder.ts deleted file mode 100644 index 0d23cf5d1..000000000 --- a/scenario/src/Builder/CompBuilder.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { Event } from '../Event'; -import { World, addAction } from '../World'; -import { Comp, CompScenario } from '../Contract/Comp'; -import { Invokation } from '../Invokation'; -import { getAddressV } from '../CoreValue'; -import { StringV, AddressV } from '../Value'; -import { Arg, Fetcher, getFetcherValue } from '../Command'; -import { storeAndSaveContract } from '../Networks'; -import { getContract } from '../Contract'; - -const CompContract = getContract('Comp'); -const CompScenarioContract = getContract('CompScenario'); - -export interface TokenData { - invokation: Invokation; - contract: string; - address?: string; - symbol: string; - name: string; - decimals?: number; -} - -export async function buildComp( - world: World, - from: string, - params: Event -): Promise<{ world: World; comp: Comp; tokenData: TokenData }> { - const fetchers = [ - new Fetcher<{ account: AddressV }, TokenData>( - ` - #### Scenario - - * "Comp Deploy Scenario account:
" - Deploys Scenario Comp Token - * E.g. "Comp Deploy Scenario Geoff" - `, - 'Scenario', - [ - new Arg("account", getAddressV), - ], - async (world, { account }) => { - return { - invokation: await CompScenarioContract.deploy(world, from, [account.val]), - contract: 'CompScenario', - symbol: 'COMP', - name: 'Compound Governance Token', - decimals: 18 - }; - } - ), - - new Fetcher<{ account: AddressV }, TokenData>( - ` - #### Comp - - * "Comp Deploy account:
" - Deploys Comp Token - * E.g. "Comp Deploy Geoff" - `, - 'Comp', - [ - new Arg("account", getAddressV), - ], - async (world, { account }) => { - if (world.isLocalNetwork()) { - return { - invokation: await CompScenarioContract.deploy(world, from, [account.val]), - contract: 'CompScenario', - symbol: 'COMP', - name: 'Compound Governance Token', - decimals: 18 - }; - } else { - return { - invokation: await CompContract.deploy(world, from, [account.val]), - contract: 'Comp', - symbol: 'COMP', - name: 'Compound Governance Token', - decimals: 18 - }; - } - }, - { catchall: true } - ) - ]; - - let tokenData = await getFetcherValue("DeployComp", fetchers, world, params); - let invokation = tokenData.invokation; - delete tokenData.invokation; - - if (invokation.error) { - throw invokation.error; - } - - const comp = invokation.value!; - tokenData.address = comp._address; - - world = await storeAndSaveContract( - world, - comp, - 'Comp', - invokation, - [ - { index: ['Comp'], data: tokenData }, - { index: ['Tokens', tokenData.symbol], data: tokenData } - ] - ); - - tokenData.invokation = invokation; - - return { world, comp, tokenData }; -} diff --git a/scenario/src/Builder/Erc20Builder.ts b/scenario/src/Builder/Erc20Builder.ts index 4ccfad1ae..745e871d2 100644 --- a/scenario/src/Builder/Erc20Builder.ts +++ b/scenario/src/Builder/Erc20Builder.ts @@ -27,7 +27,7 @@ const FaucetTokenHarness = getContract("FaucetToken"); const FaucetTokenNonStandardHarness = getContract("FaucetNonStandardToken"); const FaucetTokenReEntrantHarness = getContract("FaucetTokenReEntrantHarness"); const EvilTokenHarness = getContract("EvilToken"); -const WBTCTokenHarness = getContract("WBTCToken"); +const WBTSLTokenHarness = getContract("WBTSLToken"); const FeeTokenHarness = getContract("FeeToken"); export interface TokenData { @@ -120,7 +120,7 @@ export async function buildErc20(world: World, from: string, event: Event): Prom #### ReEntrant * "ReEntrant symbol: name:string fun: funSig: ...funArgs:" - A token that loves to call back to spook its caller - * E.g. "Erc20 Deploy ReEntrant PHREAK PHREAK "transfer" "mint(uint256)" 0 - A token that will call back to a CToken's mint function + * E.g. "Erc20 Deploy ReEntrant PHREAK PHREAK "transfer" "mint(uint256)" 0 - A token that will call back to a SLToken's mint function Note: valid functions: totalSupply, balanceOf, transfer, transferFrom, approve, allowance `, @@ -209,12 +209,12 @@ export async function buildErc20(world: World, from: string, event: Event): Prom let decimals = 8; return { - invokation: await WBTCTokenHarness.deploy(world, from, []), + invokation: await WBTSLTokenHarness.deploy(world, from, []), description: "WBTC", name: name.val, symbol: symbol.val, decimals: decimals, - contract: 'WBTCToken' + contract: 'WBTSLToken' }; } ), diff --git a/scenario/src/Builder/GovernorBuilder.ts b/scenario/src/Builder/GovernorBuilder.ts deleted file mode 100644 index ac91e899e..000000000 --- a/scenario/src/Builder/GovernorBuilder.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { Event } from "../Event"; -import { World } from "../World"; -import { Governor } from "../Contract/Governor"; -import { Invokation } from "../Invokation"; -import { getAddressV, getNumberV, getStringV } from "../CoreValue"; -import { AddressV, NumberV, StringV } from "../Value"; -import { Arg, Fetcher, getFetcherValue } from "../Command"; -import { storeAndSaveContract } from "../Networks"; -import { getContract } from "../Contract"; - -const GovernorAlphaContract = getContract("GovernorAlpha"); -const GovernorAlphaHarnessContract = getContract("GovernorAlphaHarness"); - -export interface GovernorData { - invokation: Invokation; - name: string; - contract: string; - address?: string; -} - -export async function buildGovernor( - world: World, - from: string, - params: Event -): Promise<{ world: World; governor: Governor; govData: GovernorData }> { - const fetchers = [ - new Fetcher< - { name: StringV, timelock: AddressV, comp: AddressV, guardian: AddressV }, - GovernorData - >( - ` - #### GovernorAlpha - - * "Governor Deploy Alpha name: timelock:
comp:
guardian:
" - Deploys Compound Governor Alpha - * E.g. "Governor Deploy Alpha GovernorAlpha (Address Timelock) (Address Comp) Guardian" - `, - "Alpha", - [ - new Arg("name", getStringV), - new Arg("timelock", getAddressV), - new Arg("comp", getAddressV), - new Arg("guardian", getAddressV) - ], - async (world, { name, timelock, comp, guardian }) => { - return { - invokation: await GovernorAlphaContract.deploy( - world, - from, - [timelock.val, comp.val, guardian.val] - ), - name: name.val, - contract: "GovernorAlpha" - }; - } - ), - new Fetcher< - { name: StringV, timelock: AddressV, comp: AddressV, guardian: AddressV}, - GovernorData - >( - ` - #### GovernorAlphaHarness - - * "Governor Deploy AlphaHarness name: timelock:
comp:
guardian:
" - Deploys Compound Governor Alpha with a mocked voting period - * E.g. "Governor Deploy AlphaHarness GovernorAlphaHarness (Address Timelock) (Address Comp) Guardian" - `, - "AlphaHarness", - [ - new Arg("name", getStringV), - new Arg("timelock", getAddressV), - new Arg("comp", getAddressV), - new Arg("guardian", getAddressV) - ], - async (world, { name, timelock, comp, guardian }) => { - return { - invokation: await GovernorAlphaHarnessContract.deploy( - world, - from, - [timelock.val, comp.val, guardian.val] - ), - name: name.val, - contract: "GovernorAlphaHarness" - }; - } - ) - - ]; - - let govData = await getFetcherValue( - "DeployGovernor", - fetchers, - world, - params - ); - let invokation = govData.invokation; - delete govData.invokation; - - if (invokation.error) { - throw invokation.error; - } - - const governor = invokation.value!; - govData.address = governor._address; - - world = await storeAndSaveContract( - world, - governor, - govData.name, - invokation, - [ - { index: ["Governor", govData.name], data: govData }, - ] - ); - - return { world, governor, govData }; -} diff --git a/scenario/src/Builder/MaximillionBuilder.ts b/scenario/src/Builder/MaximillionBuilder.ts index c8eb81a03..db7b87e49 100644 --- a/scenario/src/Builder/MaximillionBuilder.ts +++ b/scenario/src/Builder/MaximillionBuilder.ts @@ -19,7 +19,7 @@ export interface MaximillionData { export async function buildMaximillion(world: World, from: string, event: Event): Promise<{world: World, maximillion: Maximillion, maximillionData: MaximillionData}> { const fetchers = [ - new Fetcher<{cEther: AddressV}, MaximillionData>(` + new Fetcher<{slEther: AddressV}, MaximillionData>(` #### Maximillion * "" - Maximum Eth Repays Contract @@ -27,13 +27,13 @@ export async function buildMaximillion(world: World, from: string, event: Event) `, "Maximillion", [ - new Arg("cEther", getAddressV) + new Arg("slEther", getAddressV) ], - async (world, {cEther}) => { + async (world, {slEther}) => { return { - invokation: await MaximillionContract.deploy(world, from, [cEther.val]), + invokation: await MaximillionContract.deploy(world, from, [slEther.val]), description: "Maximillion", - cEtherAddress: cEther.val + cEtherAddress: slEther.val }; }, {catchall: true} diff --git a/scenario/src/Builder/PriceOracleProxyBuilder.ts b/scenario/src/Builder/PriceOracleProxyBuilder.ts index 5807371ba..47523749b 100644 --- a/scenario/src/Builder/PriceOracleProxyBuilder.ts +++ b/scenario/src/Builder/PriceOracleProxyBuilder.ts @@ -15,38 +15,38 @@ export interface PriceOracleProxyData { contract?: PriceOracleProxy, description: string, address?: string, - cETH: string, - cUSDC: string, - cDAI: string + slETH: string, + slUSDC: string, + slDAI: string } export async function buildPriceOracleProxy(world: World, from: string, event: Event): Promise<{world: World, priceOracleProxy: PriceOracleProxy, invokation: Invokation}> { const fetchers = [ - new Fetcher<{guardian: AddressV, priceOracle: AddressV, cETH: AddressV, cUSDC: AddressV, cSAI: AddressV, cDAI: AddressV, cUSDT: AddressV}, PriceOracleProxyData>(` + new Fetcher<{guardian: AddressV, priceOracle: AddressV, slETH: AddressV, slUSDC: AddressV, cSAI: AddressV, slDAI: AddressV, slUSDT: AddressV}, PriceOracleProxyData>(` #### Price Oracle Proxy - * "Deploy " - The Price Oracle which proxies to a backing oracle - * E.g. "PriceOracleProxy Deploy Admin (PriceOracle Address) cETH cUSDC cSAI cDAI cUSDT" + * "Deploy " - The Price Oracle which proxies to a backing oracle + * E.g. "PriceOracleProxy Deploy Admin (PriceOracle Address) slETH slUSDC cSAI slDAI slUSDT" `, "PriceOracleProxy", [ new Arg("guardian", getAddressV), new Arg("priceOracle", getAddressV), - new Arg("cETH", getAddressV), - new Arg("cUSDC", getAddressV), + new Arg("slETH", getAddressV), + new Arg("slUSDC", getAddressV), new Arg("cSAI", getAddressV), - new Arg("cDAI", getAddressV), - new Arg("cUSDT", getAddressV) + new Arg("slDAI", getAddressV), + new Arg("slUSDT", getAddressV) ], - async (world, {guardian, priceOracle, cETH, cUSDC, cSAI, cDAI, cUSDT}) => { + async (world, {guardian, priceOracle, slETH, slUSDC, cSAI, slDAI, slUSDT}) => { return { - invokation: await PriceOracleProxyContract.deploy(world, from, [guardian.val, priceOracle.val, cETH.val, cUSDC.val, cSAI.val, cDAI.val, cUSDT.val]), + invokation: await PriceOracleProxyContract.deploy(world, from, [guardian.val, priceOracle.val, slETH.val, slUSDC.val, cSAI.val, slDAI.val, slUSDT.val]), description: "Price Oracle Proxy", - cETH: cETH.val, - cUSDC: cUSDC.val, + slETH: slETH.val, + slUSDC: slUSDC.val, cSAI: cSAI.val, - cDAI: cDAI.val, - cUSDT: cUSDT.val + slDAI: slDAI.val, + slUSDT: slUSDT.val }; }, {catchall: true} diff --git a/scenario/src/Builder/CTokenBuilder.ts b/scenario/src/Builder/SLTokenBuilder.ts similarity index 67% rename from scenario/src/Builder/CTokenBuilder.ts rename to scenario/src/Builder/SLTokenBuilder.ts index f998d3e0b..76eb10ef5 100644 --- a/scenario/src/Builder/CTokenBuilder.ts +++ b/scenario/src/Builder/SLTokenBuilder.ts @@ -1,7 +1,7 @@ import { Event } from '../Event'; import { World } from '../World'; -import { CErc20Delegator, CErc20DelegatorScenario } from '../Contract/CErc20Delegator'; -import { CToken } from '../Contract/CToken'; +import { SLErc20Delegator, SLErc20DelegatorScenario } from '../Contract/SLErc20Delegator'; +import { SLToken } from '../Contract/SLToken'; import { Invokation, invoke } from '../Invokation'; import { getAddressV, getExpNumberV, getNumberV, getStringV } from '../CoreValue'; import { AddressV, NumberV, StringV } from '../Value'; @@ -9,16 +9,16 @@ import { Arg, Fetcher, getFetcherValue } from '../Command'; import { storeAndSaveContract } from '../Networks'; import { getContract, getTestContract } from '../Contract'; -const CErc20Contract = getContract('CErc20Immutable'); -const CErc20Delegator = getContract('CErc20Delegator'); -const CErc20DelegatorScenario = getTestContract('CErc20DelegatorScenario'); -const CEtherContract = getContract('CEther'); -const CErc20ScenarioContract = getTestContract('CErc20Scenario'); -const CEtherScenarioContract = getTestContract('CEtherScenario'); -const CEvilContract = getTestContract('CEvil'); +const SLErc20Contract = getContract('SLErc20Immutable'); +const SLErc20Delegator = getContract('SLErc20Delegator'); +const SLErc20DelegatorScenario = getTestContract('SLErc20DelegatorScenario'); +const SLEtherContract = getContract('SLEther'); +const SLErc20ScenarioContract = getTestContract('SLErc20Scenario'); +const SLEtherScenarioContract = getTestContract('SLEtherScenario'); +const CEvilContract = getTestContract('SLEvil'); export interface TokenData { - invokation: Invokation; + invokation: Invokation; name: string; symbol: string; decimals?: number; @@ -29,11 +29,11 @@ export interface TokenData { admin?: string; } -export async function buildCToken( +export async function buildSLToken( world: World, from: string, params: Event -): Promise<{ world: World; cToken: CToken; tokenData: TokenData }> { +): Promise<{ world: World; slToken: SLToken; tokenData: TokenData }> { const fetchers = [ new Fetcher< { @@ -51,12 +51,12 @@ export async function buildCToken( TokenData >( ` - #### CErc20Delegator + #### SLErc20Delegator - * "CErc20Delegator symbol: name: underlying:
comptroller:
interestRateModel:
initialExchangeRate: decimals: admin:
implementation:
becomeImplementationData:" - The real deal CToken - * E.g. "CToken Deploy CErc20Delegator cDAI \"Compound DAI\" (Erc20 DAI Address) (Comptroller Address) (InterestRateModel Address) 1.0 8 Geoff (CToken CDaiDelegate Address) "0x0123434anyByTes314535q" " + * "SLErc20Delegator symbol: name: underlying:
comptroller:
interestRateModel:
initialExchangeRate: decimals: admin:
implementation:
becomeImplementationData:" - The real deal SLToken + * E.g. "SLToken Deploy SLErc20Delegator slDAI \"Compound DAI\" (Erc20 DAI Address) (Comptroller Address) (InterestRateModel Address) 1.0 8 Geoff (SLToken CDaiDelegate Address) "0x0123434anyByTes314535q" " `, - 'CErc20Delegator', + 'SLErc20Delegator', [ new Arg('symbol', getStringV), new Arg('name', getStringV), @@ -85,7 +85,7 @@ export async function buildCToken( } ) => { return { - invokation: await CErc20Delegator.deploy(world, from, [ + invokation: await SLErc20Delegator.deploy(world, from, [ underlying.val, comptroller.val, interestRateModel.val, @@ -101,7 +101,7 @@ export async function buildCToken( symbol: symbol.val, decimals: decimals.toNumber(), underlying: underlying.val, - contract: 'CErc20Delegator', + contract: 'SLErc20Delegator', initial_exchange_rate_mantissa: initialExchangeRate.encode().toString(), admin: admin.val }; @@ -124,12 +124,12 @@ export async function buildCToken( TokenData >( ` - #### CErc20DelegatorScenario + #### SLErc20DelegatorScenario - * "CErc20DelegatorScenario symbol: name: underlying:
comptroller:
interestRateModel:
initialExchangeRate: decimals: admin:
implementation:
becomeImplementationData:" - A CToken Scenario for local testing - * E.g. "CToken Deploy CErc20DelegatorScenario cDAI \"Compound DAI\" (Erc20 DAI Address) (Comptroller Address) (InterestRateModel Address) 1.0 8 Geoff (CToken CDaiDelegate Address) "0x0123434anyByTes314535q" " + * "SLErc20DelegatorScenario symbol: name: underlying:
comptroller:
interestRateModel:
initialExchangeRate: decimals: admin:
implementation:
becomeImplementationData:" - A SLToken Scenario for local testing + * E.g. "SLToken Deploy SLErc20DelegatorScenario slDAI \"Compound DAI\" (Erc20 DAI Address) (Comptroller Address) (InterestRateModel Address) 1.0 8 Geoff (SLToken CDaiDelegate Address) "0x0123434anyByTes314535q" " `, - 'CErc20DelegatorScenario', + 'SLErc20DelegatorScenario', [ new Arg('symbol', getStringV), new Arg('name', getStringV), @@ -158,7 +158,7 @@ export async function buildCToken( } ) => { return { - invokation: await CErc20DelegatorScenario.deploy(world, from, [ + invokation: await SLErc20DelegatorScenario.deploy(world, from, [ underlying.val, comptroller.val, interestRateModel.val, @@ -174,7 +174,7 @@ export async function buildCToken( symbol: symbol.val, decimals: decimals.toNumber(), underlying: underlying.val, - contract: 'CErc20DelegatorScenario', + contract: 'SLErc20DelegatorScenario', initial_exchange_rate_mantissa: initialExchangeRate.encode().toString(), admin: admin.val }; @@ -184,8 +184,8 @@ export async function buildCToken( new Fetcher<{symbol: StringV, name: StringV, decimals: NumberV, underlying: AddressV, comptroller: AddressV, interestRateModel: AddressV, initialExchangeRate: NumberV, admin: AddressV}, TokenData>(` #### Scenario - * "Scenario symbol: name: underlying:
comptroller:
interestRateModel:
initialExchangeRate: decimals: admin:
" - A CToken Scenario for local testing - * E.g. "CToken Deploy Scenario cZRX \"Compound ZRX\" (Erc20 ZRX Address) (Comptroller Address) (InterestRateModel Address) 1.0 8" + * "Scenario symbol: name: underlying:
comptroller:
interestRateModel:
initialExchangeRate: decimals: admin:
" - A SLToken Scenario for local testing + * E.g. "SLToken Deploy Scenario slZRX \"Compound ZRX\" (Erc20 ZRX Address) (Comptroller Address) (InterestRateModel Address) 1.0 8" `, "Scenario", [ @@ -200,12 +200,12 @@ export async function buildCToken( ], async (world, {symbol, name, underlying, comptroller, interestRateModel, initialExchangeRate, decimals, admin}) => { return { - invokation: await CErc20ScenarioContract.deploy(world, from, [underlying.val, comptroller.val, interestRateModel.val, initialExchangeRate.val, name.val, symbol.val, decimals.val, admin.val]), + invokation: await SLErc20ScenarioContract.deploy(world, from, [underlying.val, comptroller.val, interestRateModel.val, initialExchangeRate.val, name.val, symbol.val, decimals.val, admin.val]), name: name.val, symbol: symbol.val, decimals: decimals.toNumber(), underlying: underlying.val, - contract: 'CErc20Scenario', + contract: 'SLErc20Scenario', initial_exchange_rate_mantissa: initialExchangeRate.encode().toString(), admin: admin.val }; @@ -213,12 +213,12 @@ export async function buildCToken( ), new Fetcher<{symbol: StringV, name: StringV, decimals: NumberV, admin: AddressV, comptroller: AddressV, interestRateModel: AddressV, initialExchangeRate: NumberV}, TokenData>(` - #### CEtherScenario + #### SLEtherScenario - * "CEtherScenario symbol: name: comptroller:
interestRateModel:
initialExchangeRate: decimals: admin:
" - A CToken Scenario for local testing - * E.g. "CToken Deploy CEtherScenario cETH \"Compound Ether\" (Comptroller Address) (InterestRateModel Address) 1.0 8" + * "SLEtherScenario symbol: name: comptroller:
interestRateModel:
initialExchangeRate: decimals: admin:
" - A SLToken Scenario for local testing + * E.g. "SLToken Deploy SLEtherScenario slETH \"Compound Ether\" (Comptroller Address) (InterestRateModel Address) 1.0 8" `, - "CEtherScenario", + "SLEtherScenario", [ new Arg("symbol", getStringV), new Arg("name", getStringV), @@ -230,12 +230,12 @@ export async function buildCToken( ], async (world, {symbol, name, comptroller, interestRateModel, initialExchangeRate, decimals, admin}) => { return { - invokation: await CEtherScenarioContract.deploy(world, from, [name.val, symbol.val, decimals.val, admin.val, comptroller.val, interestRateModel.val, initialExchangeRate.val]), + invokation: await SLEtherScenarioContract.deploy(world, from, [name.val, symbol.val, decimals.val, admin.val, comptroller.val, interestRateModel.val, initialExchangeRate.val]), name: name.val, symbol: symbol.val, decimals: decimals.toNumber(), underlying: "", - contract: 'CEtherScenario', + contract: 'SLEtherScenario', initial_exchange_rate_mantissa: initialExchangeRate.encode().toString(), admin: admin.val }; @@ -243,12 +243,12 @@ export async function buildCToken( ), new Fetcher<{symbol: StringV, name: StringV, decimals: NumberV, admin: AddressV, comptroller: AddressV, interestRateModel: AddressV, initialExchangeRate: NumberV}, TokenData>(` - #### CEther + #### SLEther - * "CEther symbol: name: comptroller:
interestRateModel:
initialExchangeRate: decimals: admin:
" - A CToken Scenario for local testing - * E.g. "CToken Deploy CEther cETH \"Compound Ether\" (Comptroller Address) (InterestRateModel Address) 1.0 8" + * "SLEther symbol: name: comptroller:
interestRateModel:
initialExchangeRate: decimals: admin:
" - A SLToken Scenario for local testing + * E.g. "SLToken Deploy SLEther slETH \"Compound Ether\" (Comptroller Address) (InterestRateModel Address) 1.0 8" `, - "CEther", + "SLEther", [ new Arg("symbol", getStringV), new Arg("name", getStringV), @@ -260,12 +260,12 @@ export async function buildCToken( ], async (world, {symbol, name, comptroller, interestRateModel, initialExchangeRate, decimals, admin}) => { return { - invokation: await CEtherContract.deploy(world, from, [comptroller.val, interestRateModel.val, initialExchangeRate.val, name.val, symbol.val, decimals.val, admin.val]), + invokation: await SLEtherContract.deploy(world, from, [comptroller.val, interestRateModel.val, initialExchangeRate.val, name.val, symbol.val, decimals.val, admin.val]), name: name.val, symbol: symbol.val, decimals: decimals.toNumber(), underlying: "", - contract: 'CEther', + contract: 'SLEther', initial_exchange_rate_mantissa: initialExchangeRate.encode().toString(), admin: admin.val }; @@ -273,12 +273,12 @@ export async function buildCToken( ), new Fetcher<{symbol: StringV, name: StringV, decimals: NumberV, admin: AddressV, underlying: AddressV, comptroller: AddressV, interestRateModel: AddressV, initialExchangeRate: NumberV}, TokenData>(` - #### CErc20 + #### SLErc20 - * "CErc20 symbol: name: underlying:
comptroller:
interestRateModel:
initialExchangeRate: decimals: admin:
" - A official CToken contract - * E.g. "CToken Deploy CErc20 cZRX \"Compound ZRX\" (Erc20 ZRX Address) (Comptroller Address) (InterestRateModel Address) 1.0 8" + * "SLErc20 symbol: name: underlying:
comptroller:
interestRateModel:
initialExchangeRate: decimals: admin:
" - A official SLToken contract + * E.g. "SLToken Deploy SLErc20 slZRX \"Compound ZRX\" (Erc20 ZRX Address) (Comptroller Address) (InterestRateModel Address) 1.0 8" `, - "CErc20", + "SLErc20", [ new Arg("symbol", getStringV), new Arg("name", getStringV), @@ -292,12 +292,12 @@ export async function buildCToken( async (world, {symbol, name, underlying, comptroller, interestRateModel, initialExchangeRate, decimals, admin}) => { return { - invokation: await CErc20Contract.deploy(world, from, [underlying.val, comptroller.val, interestRateModel.val, initialExchangeRate.val, name.val, symbol.val, decimals.val, admin.val]), + invokation: await SLErc20Contract.deploy(world, from, [underlying.val, comptroller.val, interestRateModel.val, initialExchangeRate.val, name.val, symbol.val, decimals.val, admin.val]), name: name.val, symbol: symbol.val, decimals: decimals.toNumber(), underlying: underlying.val, - contract: 'CErc20', + contract: 'SLErc20', initial_exchange_rate_mantissa: initialExchangeRate.encode().toString(), admin: admin.val }; @@ -305,12 +305,12 @@ export async function buildCToken( ), new Fetcher<{symbol: StringV, name: StringV, decimals: NumberV, admin: AddressV, underlying: AddressV, comptroller: AddressV, interestRateModel: AddressV, initialExchangeRate: NumberV}, TokenData>(` - #### CEvil + #### SLEvil - * "CEvil symbol: name: underlying:
comptroller:
interestRateModel:
initialExchangeRate: decimals: admin:
" - A malicious CToken contract - * E.g. "CToken Deploy CEvil cEVL \"Compound EVL\" (Erc20 ZRX Address) (Comptroller Address) (InterestRateModel Address) 1.0 8" + * "SLEvil symbol: name: underlying:
comptroller:
interestRateModel:
initialExchangeRate: decimals: admin:
" - A malicious SLToken contract + * E.g. "SLToken Deploy SLEvil cEVL \"Compound EVL\" (Erc20 ZRX Address) (Comptroller Address) (InterestRateModel Address) 1.0 8" `, - "CEvil", + "SLEvil", [ new Arg("symbol", getStringV), new Arg("name", getStringV), @@ -323,12 +323,12 @@ export async function buildCToken( ], async (world, {symbol, name, underlying, comptroller, interestRateModel, initialExchangeRate, decimals, admin}) => { return { - invokation: await CEvilContract.deploy(world, from, [underlying.val, comptroller.val, interestRateModel.val, initialExchangeRate.val, name.val, symbol.val, decimals.val, admin.val]), + invokation: await CEvilContract.deploy(world, from, [underlying.val, comptroller.val, interestRateModel.val, initialExchangeRate.val, name.val, symbol.val, decimals.val, admin.val]), name: name.val, symbol: symbol.val, decimals: decimals.toNumber(), underlying: underlying.val, - contract: 'CEvil', + contract: 'SLEvil', initial_exchange_rate_mantissa: initialExchangeRate.encode().toString(), admin: admin.val }; @@ -338,8 +338,8 @@ export async function buildCToken( new Fetcher<{symbol: StringV, name: StringV, decimals: NumberV, admin: AddressV, underlying: AddressV, comptroller: AddressV, interestRateModel: AddressV, initialExchangeRate: NumberV}, TokenData>(` #### Standard - * "symbol: name: underlying:
comptroller:
interestRateModel:
initialExchangeRate: decimals: admin:
" - A official CToken contract - * E.g. "CToken Deploy Standard cZRX \"Compound ZRX\" (Erc20 ZRX Address) (Comptroller Address) (InterestRateModel Address) 1.0 8" + * "symbol: name: underlying:
comptroller:
interestRateModel:
initialExchangeRate: decimals: admin:
" - A official SLToken contract + * E.g. "SLToken Deploy Standard slZRX \"Compound ZRX\" (Erc20 ZRX Address) (Comptroller Address) (InterestRateModel Address) 1.0 8" `, "Standard", [ @@ -356,23 +356,23 @@ export async function buildCToken( // Note: we're going to use the scenario contract as the standard deployment on local networks if (world.isLocalNetwork()) { return { - invokation: await CErc20ScenarioContract.deploy(world, from, [underlying.val, comptroller.val, interestRateModel.val, initialExchangeRate.val, name.val, symbol.val, decimals.val, admin.val]), + invokation: await SLErc20ScenarioContract.deploy(world, from, [underlying.val, comptroller.val, interestRateModel.val, initialExchangeRate.val, name.val, symbol.val, decimals.val, admin.val]), name: name.val, symbol: symbol.val, decimals: decimals.toNumber(), underlying: underlying.val, - contract: 'CErc20Scenario', + contract: 'SLErc20Scenario', initial_exchange_rate_mantissa: initialExchangeRate.encode().toString(), admin: admin.val }; } else { return { - invokation: await CErc20Contract.deploy(world, from, [underlying.val, comptroller.val, interestRateModel.val, initialExchangeRate.val, name.val, symbol.val, decimals.val, admin.val]), + invokation: await SLErc20Contract.deploy(world, from, [underlying.val, comptroller.val, interestRateModel.val, initialExchangeRate.val, name.val, symbol.val, decimals.val, admin.val]), name: name.val, symbol: symbol.val, decimals: decimals.toNumber(), underlying: underlying.val, - contract: 'CErc20Immutable', + contract: 'SLErc20Immutable', initial_exchange_rate_mantissa: initialExchangeRate.encode().toString(), admin: admin.val }; @@ -382,7 +382,7 @@ export async function buildCToken( ) ]; - let tokenData = await getFetcherValue("DeployCToken", fetchers, world, params); + let tokenData = await getFetcherValue("DeploySLToken", fetchers, world, params); let invokation = tokenData.invokation; delete tokenData.invokation; @@ -390,19 +390,19 @@ export async function buildCToken( throw invokation.error; } - const cToken = invokation.value!; - tokenData.address = cToken._address; + const slToken = invokation.value!; + tokenData.address = slToken._address; world = await storeAndSaveContract( world, - cToken, + slToken, tokenData.symbol, invokation, [ - { index: ['cTokens', tokenData.symbol], data: tokenData }, + { index: ['slTokens', tokenData.symbol], data: tokenData }, { index: ['Tokens', tokenData.symbol], data: tokenData } ] ); - return {world, cToken, tokenData}; + return {world, slToken, tokenData}; } diff --git a/scenario/src/Builder/SLTokenDelegateBuilder.ts b/scenario/src/Builder/SLTokenDelegateBuilder.ts new file mode 100644 index 000000000..5cc2a835d --- /dev/null +++ b/scenario/src/Builder/SLTokenDelegateBuilder.ts @@ -0,0 +1,156 @@ +import { Event } from '../Event'; +import { World } from '../World'; +import { SLErc20Delegate, SLErc20DelegateScenario } from '../Contract/SLErc20Delegate'; +import { SLToken } from '../Contract/SLToken'; +import { Invokation } from '../Invokation'; +import { getStringV } from '../CoreValue'; +import { AddressV, NumberV, StringV } from '../Value'; +import { Arg, Fetcher, getFetcherValue } from '../Command'; +import { storeAndSaveContract } from '../Networks'; +import { getContract, getTestContract } from '../Contract'; + +const SLDaiDelegateContract = getContract('SLDaiDelegate'); +const SLDaiDelegateScenarioContract = getTestContract('SLDaiDelegateScenario'); +const SLErc20DelegateContract = getContract('SLErc20Delegate'); +const SLErc20DelegateScenarioContract = getTestContract('SLErc20DelegateScenario'); + + +export interface SLTokenDelegateData { + invokation: Invokation; + name: string; + contract: string; + description?: string; +} + +export async function buildSLTokenDelegate( + world: World, + from: string, + params: Event +): Promise<{ world: World; slTokenDelegate: SLErc20Delegate; delegateData: SLTokenDelegateData }> { + const fetchers = [ + new Fetcher<{ name: StringV; }, SLTokenDelegateData>( + ` + #### SLDaiDelegate + + * "SLDaiDelegate name:" + * E.g. "SLTokenDelegate Deploy SLDaiDelegate slDAIDelegate" + `, + 'SLDaiDelegate', + [ + new Arg('name', getStringV) + ], + async ( + world, + { name } + ) => { + return { + invokation: await SLDaiDelegateContract.deploy(world, from, []), + name: name.val, + contract: 'SLDaiDelegate', + description: 'Standard SLDai Delegate' + }; + } + ), + + new Fetcher<{ name: StringV; }, SLTokenDelegateData>( + ` + #### SLDaiDelegateScenario + + * "SLDaiDelegateScenario name:" - A SLDaiDelegate Scenario for local testing + * E.g. "SLTokenDelegate Deploy SLDaiDelegateScenario slDAIDelegate" + `, + 'SLDaiDelegateScenario', + [ + new Arg('name', getStringV) + ], + async ( + world, + { name } + ) => { + return { + invokation: await SLDaiDelegateScenarioContract.deploy(world, from, []), + name: name.val, + contract: 'SLDaiDelegateScenario', + description: 'Scenario SLDai Delegate' + }; + } + ), + + new Fetcher<{ name: StringV; }, SLTokenDelegateData>( + ` + #### SLErc20Delegate + + * "SLErc20Delegate name:" + * E.g. "SLTokenDelegate Deploy SLErc20Delegate slDAIDelegate" + `, + 'SLErc20Delegate', + [ + new Arg('name', getStringV) + ], + async ( + world, + { name } + ) => { + return { + invokation: await SLErc20DelegateContract.deploy(world, from, []), + name: name.val, + contract: 'SLErc20Delegate', + description: 'Standard SLErc20 Delegate' + }; + } + ), + + new Fetcher<{ name: StringV; }, SLTokenDelegateData>( + ` + #### SLErc20DelegateScenario + + * "SLErc20DelegateScenario name:" - A SLErc20Delegate Scenario for local testing + * E.g. "SLTokenDelegate Deploy SLErc20DelegateScenario slDAIDelegate" + `, + 'SLErc20DelegateScenario', + [ + new Arg('name', getStringV), + ], + async ( + world, + { name } + ) => { + return { + invokation: await SLErc20DelegateScenarioContract.deploy(world, from, []), + name: name.val, + contract: 'SLErc20DelegateScenario', + description: 'Scenario SLErc20 Delegate' + }; + } + ) + ]; + + let delegateData = await getFetcherValue("DeploySLToken", fetchers, world, params); + let invokation = delegateData.invokation; + delete delegateData.invokation; + + if (invokation.error) { + throw invokation.error; + } + + const slTokenDelegate = invokation.value!; + + world = await storeAndSaveContract( + world, + slTokenDelegate, + delegateData.name, + invokation, + [ + { + index: ['SLTokenDelegate', delegateData.name], + data: { + address: slTokenDelegate._address, + contract: delegateData.contract, + description: delegateData.description + } + } + ] + ); + + return { world, slTokenDelegate, delegateData }; +} diff --git a/scenario/src/Command.ts b/scenario/src/Command.ts index 56206c40b..6e65eb90e 100644 --- a/scenario/src/Command.ts +++ b/scenario/src/Command.ts @@ -141,9 +141,9 @@ export abstract class Expression { if (arg.rescue) { // Rescue is meant to allow Gate to work for checks that // fail due to the missing components, e.g.: - // `Gate (CToken Eth Address) (... deploy cToken)` - // could be used to deploy a cToken if it doesn't exist, but - // since there is no CToken, that check would raise (when we'd + // `Gate (SLToken Eth Address) (... deploy slToken)` + // could be used to deploy a slToken if it doesn't exist, but + // since there is no SLToken, that check would raise (when we'd // hope it just returns null). So here, we allow our code to rescue // errors and recover, but we need to be smarter about catching specific // errors instead of all errors. For now, to assist debugging, we may print diff --git a/scenario/src/Completer.ts b/scenario/src/Completer.ts index 35f90782b..0f32efd4c 100644 --- a/scenario/src/Completer.ts +++ b/scenario/src/Completer.ts @@ -11,7 +11,7 @@ const actions: string[] = [ "From", "Invariant", "Comptroller", - "cToken", + "slToken", "Erc20", ]; diff --git a/scenario/src/Contract/CErc20Delegate.ts b/scenario/src/Contract/CErc20Delegate.ts deleted file mode 100644 index a805103f9..000000000 --- a/scenario/src/Contract/CErc20Delegate.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Contract } from '../Contract'; -import { Sendable } from '../Invokation'; -import { CTokenMethods, CTokenScenarioMethods } from './CToken'; - -interface CErc20DelegateMethods extends CTokenMethods { - _becomeImplementation(data: string): Sendable; - _resignImplementation(): Sendable; -} - -interface CErc20DelegateScenarioMethods extends CTokenScenarioMethods { - _becomeImplementation(data: string): Sendable; - _resignImplementation(): Sendable; -} - -export interface CErc20Delegate extends Contract { - methods: CErc20DelegateMethods; - name: string; -} - -export interface CErc20DelegateScenario extends Contract { - methods: CErc20DelegateScenarioMethods; - name: string; -} diff --git a/scenario/src/Contract/Comp.ts b/scenario/src/Contract/Comp.ts deleted file mode 100644 index 53e1692a3..000000000 --- a/scenario/src/Contract/Comp.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Contract } from '../Contract'; -import { encodedNumber } from '../Encoding'; -import { Callable, Sendable } from '../Invokation'; - -interface Checkpoint { - fromBlock: number; - votes: number; -} - -export interface CompMethods { - name(): Callable; - symbol(): Callable; - decimals(): Callable; - totalSupply(): Callable; - balanceOf(address: string): Callable; - allowance(owner: string, spender: string): Callable; - approve(address: string, amount: encodedNumber): Sendable; - transfer(address: string, amount: encodedNumber): Sendable; - transferFrom(owner: string, spender: string, amount: encodedNumber): Sendable; - checkpoints(account: string, index: number): Callable; - numCheckpoints(account: string): Callable; - delegate(account: string): Sendable; - getCurrentVotes(account: string): Callable; - getPriorVotes(account: string, blockNumber: encodedNumber): Callable; - setBlockNumber(blockNumber: encodedNumber): Sendable; -} - -export interface CompScenarioMethods extends CompMethods { - transferScenario(destinations: string[], amount: encodedNumber): Sendable; - transferFromScenario(froms: string[], amount: encodedNumber): Sendable; -} - -export interface Comp extends Contract { - methods: CompMethods; - name: string; -} - -export interface CompScenario extends Contract { - methods: CompScenarioMethods; - name: string; -} diff --git a/scenario/src/Contract/CompoundLens.ts b/scenario/src/Contract/CompoundLens.ts deleted file mode 100644 index 3d4cd2975..000000000 --- a/scenario/src/Contract/CompoundLens.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Contract } from '../Contract'; -import { encodedNumber } from '../Encoding'; -import { Callable, Sendable } from '../Invokation'; - -export interface CompoundLensMethods { - cTokenBalances(cToken: string, account: string): Sendable<[string,number,number,number,number,number]>; - cTokenBalancesAll(cTokens: string[], account: string): Sendable<[string,number,number,number,number,number][]>; - cTokenMetadata(cToken: string): Sendable<[string,number,number,number,number,number,number,number,number,boolean,number,string,number,number]>; - cTokenMetadataAll(cTokens: string[]): Sendable<[string,number,number,number,number,number,number,number,number,boolean,number,string,number,number][]>; - cTokenUnderlyingPrice(cToken: string): Sendable<[string,number]>; - cTokenUnderlyingPriceAll(cTokens: string[]): Sendable<[string,number][]>; - getAccountLimits(comptroller: string, account: string): Sendable<[string[],number,number]>; -} - -export interface CompoundLens extends Contract { - methods: CompoundLensMethods; - name: string; -} diff --git a/scenario/src/Contract/Comptroller.ts b/scenario/src/Contract/Comptroller.ts index fafe0959c..c843392f8 100644 --- a/scenario/src/Contract/Comptroller.ts +++ b/scenario/src/Contract/Comptroller.ts @@ -6,7 +6,7 @@ interface ComptrollerMethods { getAccountLiquidity(string): Callable<{0: number, 1: number, 2: number}> getHypotheticalAccountLiquidity(account: string, asset: string, redeemTokens: encodedNumber, borrowAmount: encodedNumber): Callable<{0: number, 1: number, 2: number}> membershipLength(string): Callable - checkMembership(user: string, cToken: string): Callable + checkMembership(user: string, slToken: string): Callable getAssetsIn(string): Callable admin(): Callable oracle(): Callable @@ -45,20 +45,20 @@ interface ComptrollerMethods { seizeGuardianPaused(): Callable mintGuardianPaused(market: string): Callable borrowGuardianPaused(market: string): Callable - _addCompMarkets(markets: string[]): Sendable - _dropCompMarket(market: string): Sendable - getCompMarkets(): Callable - refreshCompSpeeds(): Sendable - compRate(): Callable - compSupplyState(string): Callable - compBorrowState(string): Callable - compAccrued(string): Callable - compSupplierIndex(market: string, account: string): Callable - compBorrowerIndex(market: string, account: string): Callable - compSpeeds(string): Callable - claimComp(string): Sendable - _setCompRate(encodedNumber): Sendable - _setMarketBorrowCaps(cTokens:string[], borrowCaps:encodedNumber[]): Sendable + _addSashimiMarkets(markets: string[]): Sendable + _dropSashimiMarket(market: string): Sendable + getSashimiMarkets(): Callable + refreshSashimiSpeeds(): Sendable + sashimiRate(): Callable + sashimiSupplyState(string): Callable + sashimiBorrowState(string): Callable + sashimiAccrued(string): Callable + sashimiSupplierIndex(market: string, account: string): Callable + sashimiBorrowerIndex(market: string, account: string): Callable + sashimiSpeeds(string): Callable + claimSashimi(string): Sendable + _setSashimiRate(encodedNumber): Sendable + _setMarketBorrowCaps(slTokens:string[], borrowCaps:encodedNumber[]): Sendable _setBorrowCapGuardian(string): Sendable borrowCapGuardian(): Callable borrowCaps(string): Callable diff --git a/scenario/src/Contract/ComptrollerImpl.ts b/scenario/src/Contract/ComptrollerImpl.ts index af4b29224..d836d0f61 100644 --- a/scenario/src/Contract/ComptrollerImpl.ts +++ b/scenario/src/Contract/ComptrollerImpl.ts @@ -13,8 +13,8 @@ interface ComptrollerImplMethods { _become( comptroller: string, - compRate: encodedNumber, - compMarkets: string[], + sashimiRate: encodedNumber, + sashimiMarkets: string[], otherMarkets: string[] ): Sendable; } diff --git a/scenario/src/Contract/Governor.ts b/scenario/src/Contract/Governor.ts deleted file mode 100644 index c0af3242f..000000000 --- a/scenario/src/Contract/Governor.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Contract } from '../Contract'; -import { Callable, Sendable } from '../Invokation'; -import { encodedNumber } from '../Encoding'; - -export interface Proposal { - id: number - proposer: string - eta: number - targets: string[] - values: number[] - signatures: string[] - calldatas: string[] - startBlock: number - endBlock: number - forVotes: number - againstVotes: number -} - -export const proposalStateEnums = { - 0: "Pending", - 1: "Active", - 2: "Canceled", - 3: "Defeated", - 4: "Succeeded", - 5: "Queued", - 6: "Expired", - 7: "Executed" -} - -export interface GovernorMethods { - guardian(): Callable; - propose(targets: string[], values: encodedNumber[], signatures: string[], calldatas: string[], description: string): Sendable - proposals(proposalId: number): Callable; - proposalCount(): Callable; - latestProposalIds(proposer: string): Callable; - getReceipt(proposalId: number, voter: string): Callable<{ hasVoted: boolean, support: boolean, votes: number }>; - castVote(proposalId: number, support: boolean): Sendable; - queue(proposalId: encodedNumber): Sendable; - execute(proposalId: encodedNumber): Sendable; - cancel(proposalId: encodedNumber): Sendable; - setBlockNumber(blockNumber: encodedNumber): Sendable; - setBlockTimestamp(blockTimestamp: encodedNumber): Sendable; - state(proposalId: encodedNumber): Callable; - __queueSetTimelockPendingAdmin(newPendingAdmin: string, eta: encodedNumber): Sendable; - __executeSetTimelockPendingAdmin(newPendingAdmin: string, eta: encodedNumber): Sendable; - __acceptAdmin(): Sendable; - __abdicate(): Sendable; -} - -export interface Governor extends Contract { - methods: GovernorMethods; - name: string; -} diff --git a/scenario/src/Contract/Maximillion.ts b/scenario/src/Contract/Maximillion.ts index 02b955278..5eacf3779 100644 --- a/scenario/src/Contract/Maximillion.ts +++ b/scenario/src/Contract/Maximillion.ts @@ -2,7 +2,7 @@ import {Contract} from '../Contract'; import {Callable, Sendable} from '../Invokation'; interface MaximillionMethods { - cEther(): Callable + slEther(): Callable repayBehalf(string): Sendable } diff --git a/scenario/src/Contract/PriceOracle.ts b/scenario/src/Contract/PriceOracle.ts index 04d283668..55fa85e5c 100644 --- a/scenario/src/Contract/PriceOracle.ts +++ b/scenario/src/Contract/PriceOracle.ts @@ -4,7 +4,7 @@ import {encodedNumber} from '../Encoding'; interface PriceOracleMethods { assetPrices(asset: string): Callable - setUnderlyingPrice(cToken: string, amount: encodedNumber): Sendable + setUnderlyingPrice(slToken: string, amount: encodedNumber): Sendable setDirectPrice(address: string, amount: encodedNumber): Sendable // Anchor Price Oracle diff --git a/scenario/src/Contract/SLErc20Delegate.ts b/scenario/src/Contract/SLErc20Delegate.ts new file mode 100644 index 000000000..78d85b48b --- /dev/null +++ b/scenario/src/Contract/SLErc20Delegate.ts @@ -0,0 +1,23 @@ +import { Contract } from '../Contract'; +import { Sendable } from '../Invokation'; +import { SLTokenMethods, SLTokenScenarioMethods } from './SLToken'; + +interface SLErc20DelegateMethods extends SLTokenMethods { + _becomeImplementation(data: string): Sendable; + _resignImplementation(): Sendable; +} + +interface SLErc20DelegateScenarioMethods extends SLTokenScenarioMethods { + _becomeImplementation(data: string): Sendable; + _resignImplementation(): Sendable; +} + +export interface SLErc20Delegate extends Contract { + methods: SLErc20DelegateMethods; + name: string; +} + +export interface SLErc20DelegateScenario extends Contract { + methods: SLErc20DelegateScenarioMethods; + name: string; +} diff --git a/scenario/src/Contract/CErc20Delegator.ts b/scenario/src/Contract/SLErc20Delegator.ts similarity index 56% rename from scenario/src/Contract/CErc20Delegator.ts rename to scenario/src/Contract/SLErc20Delegator.ts index 8787c414e..7f4602de3 100644 --- a/scenario/src/Contract/CErc20Delegator.ts +++ b/scenario/src/Contract/SLErc20Delegator.ts @@ -1,9 +1,9 @@ import { Contract } from '../Contract'; import { Callable, Sendable } from '../Invokation'; -import { CTokenMethods } from './CToken'; +import { SLTokenMethods } from './SLToken'; import { encodedNumber } from '../Encoding'; -interface CErc20DelegatorMethods extends CTokenMethods { +interface SLErc20DelegatorMethods extends SLTokenMethods { implementation(): Callable; _setImplementation( implementation_: string, @@ -12,17 +12,17 @@ interface CErc20DelegatorMethods extends CTokenMethods { ): Sendable; } -interface CErc20DelegatorScenarioMethods extends CErc20DelegatorMethods { +interface SLErc20DelegatorScenarioMethods extends SLErc20DelegatorMethods { setTotalBorrows(amount: encodedNumber): Sendable; setTotalReserves(amount: encodedNumber): Sendable; } -export interface CErc20Delegator extends Contract { - methods: CErc20DelegatorMethods; +export interface SLErc20Delegator extends Contract { + methods: SLErc20DelegatorMethods; name: string; } -export interface CErc20DelegatorScenario extends Contract { - methods: CErc20DelegatorMethods; +export interface SLErc20DelegatorScenario extends Contract { + methods: SLErc20DelegatorMethods; name: string; } diff --git a/scenario/src/Contract/CToken.ts b/scenario/src/Contract/SLToken.ts similarity index 90% rename from scenario/src/Contract/CToken.ts rename to scenario/src/Contract/SLToken.ts index 81742a7e4..3312f3254 100644 --- a/scenario/src/Contract/CToken.ts +++ b/scenario/src/Contract/SLToken.ts @@ -2,7 +2,7 @@ import { Contract } from '../Contract'; import { Callable, Sendable } from '../Invokation'; import { encodedNumber } from '../Encoding'; -export interface CTokenMethods { +export interface SLTokenMethods { _resignImplementation(): Sendable; balanceOfUnderlying(address: string): Callable; borrowBalanceCurrent(address: string): Callable; @@ -49,17 +49,17 @@ export interface CTokenMethods { _acceptAdmin(): Sendable; } -export interface CTokenScenarioMethods extends CTokenMethods { +export interface SLTokenScenarioMethods extends SLTokenMethods { setTotalBorrows(amount: encodedNumber): Sendable; setTotalReserves(amount: encodedNumber): Sendable; } -export interface CToken extends Contract { - methods: CTokenMethods; +export interface SLToken extends Contract { + methods: SLTokenMethods; name: string; } -export interface CTokenScenario extends Contract { - methods: CTokenScenarioMethods; +export interface SLTokenScenario extends Contract { + methods: SLTokenScenarioMethods; name: string; } diff --git a/scenario/src/Contract/SashimiLendingLens.ts b/scenario/src/Contract/SashimiLendingLens.ts new file mode 100644 index 000000000..d0b5d3483 --- /dev/null +++ b/scenario/src/Contract/SashimiLendingLens.ts @@ -0,0 +1,18 @@ +import { Contract } from '../Contract'; +import { encodedNumber } from '../Encoding'; +import { Callable, Sendable } from '../Invokation'; + +export interface SashimiLendingLensMethods { + slTokenBalances(slToken: string, account: string): Sendable<[string,number,number,number,number,number]>; + slTokenBalancesAll(cTokens: string[], account: string): Sendable<[string,number,number,number,number,number][]>; + slTokenMetadata(slToken: string): Sendable<[string,number,number,number,number,number,number,number,number,boolean,number,string,number,number]>; + slTokenMetadataAll(cTokens: string[]): Sendable<[string,number,number,number,number,number,number,number,number,boolean,number,string,number,number][]>; + slTokenUnderlyingPrice(slToken: string): Sendable<[string,number]>; + slTokenUnderlyingPriceAll(cTokens: string[]): Sendable<[string,number][]>; + getAccountLimits(comptroller: string, account: string): Sendable<[string[],number,number]>; +} + +export interface SashimiLendingLens extends Contract { + methods: SashimiLendingLensMethods; + name: string; +} diff --git a/scenario/src/ContractLookup.ts b/scenario/src/ContractLookup.ts index 7af5be8fa..3242aafd4 100644 --- a/scenario/src/ContractLookup.ts +++ b/scenario/src/ContractLookup.ts @@ -5,12 +5,10 @@ import { World } from './World'; import { Contract } from './Contract'; import { mustString } from './Utils'; -import { CErc20Delegate } from './Contract/CErc20Delegate'; -import { Comp } from './Contract/Comp'; +import { SLErc20Delegate } from './Contract/SLErc20Delegate'; import { Comptroller } from './Contract/Comptroller'; import { ComptrollerImpl } from './Contract/ComptrollerImpl'; -import { CToken } from './Contract/CToken'; -import { Governor } from './Contract/Governor'; +import { SLToken } from './Contract/SLToken'; import { Erc20 } from './Contract/Erc20'; import { InterestRateModel } from './Contract/InterestRateModel'; import { PriceOracle } from './Contract/PriceOracle'; @@ -93,12 +91,12 @@ export async function getComptrollerImpl(world: World, comptrollerImplArg: Event return getWorldContract(world, [['Comptroller', mustString(comptrollerImplArg), 'address']]); } -export function getCTokenAddress(world: World, cTokenArg: string): string { - return getContractDataString(world, [['cTokens', cTokenArg, 'address']]); +export function getSLTokenAddress(world: World, slTokenArg: string): string { + return getContractDataString(world, [['slTokens', slTokenArg, 'address']]); } -export function getCTokenDelegateAddress(world: World, cTokenDelegateArg: string): string { - return getContractDataString(world, [['CTokenDelegate', cTokenDelegateArg, 'address']]); +export function getSLTokenDelegateAddress(world: World, slTokenDelegateArg: string): string { + return getContractDataString(world, [['SLTokenDelegate', slTokenDelegateArg, 'address']]); } export function getErc20Address(world: World, erc20Arg: string): string { @@ -121,33 +119,6 @@ export async function getPriceOracle(world: World): Promise { return getWorldContract(world, [['Contracts', 'PriceOracle']]); } -export async function getComp( - world: World, - compArg: Event -): Promise { - return getWorldContract(world, [['Comp', 'address']]); -} - -export async function getCompData( - world: World, - compArg: string -): Promise<[Comp, string, Map]> { - let contract = await getComp(world, (compArg)); - let data = getContractData(world, [['Comp', compArg]]); - - return [contract, compArg, >(data)]; -} - -export async function getGovernorData( - world: World, - governorArg: string -): Promise<[Governor, string, Map]> { - let contract = getWorldContract(world, [['Governor', governorArg, 'address']]); - let data = getContractData(world, [['Governor', governorArg]]); - - return [contract, governorArg, >(data)]; -} - export async function getInterestRateModel( world: World, interestRateModelArg: Event @@ -175,24 +146,24 @@ export async function getErc20Data( return [contract, erc20Arg, >(data)]; } -export async function getCTokenData( +export async function getSLTokenData( world: World, - cTokenArg: string -): Promise<[CToken, string, Map]> { - let contract = getWorldContract(world, [['cTokens', cTokenArg, 'address']]); - let data = getContractData(world, [['CTokens', cTokenArg]]); + slTokenArg: string +): Promise<[SLToken, string, Map]> { + let contract = getWorldContract(world, [['slTokens', slTokenArg, 'address']]); + let data = getContractData(world, [['SLTokens', slTokenArg]]); - return [contract, cTokenArg, >(data)]; + return [contract, slTokenArg, >(data)]; } -export async function getCTokenDelegateData( +export async function getSLTokenDelegateData( world: World, - cTokenDelegateArg: string -): Promise<[CErc20Delegate, string, Map]> { - let contract = getWorldContract(world, [['CTokenDelegate', cTokenDelegateArg, 'address']]); - let data = getContractData(world, [['CTokenDelegate', cTokenDelegateArg]]); + slTokenDelegateArg: string +): Promise<[SLErc20Delegate, string, Map]> { + let contract = getWorldContract(world, [['SLTokenDelegate', slTokenDelegateArg, 'address']]); + let data = getContractData(world, [['SLTokenDelegate', slTokenDelegateArg]]); - return [contract, cTokenDelegateArg, >(data)]; + return [contract, slTokenDelegateArg, >(data)]; } export async function getComptrollerImplData( @@ -228,8 +199,8 @@ export function getAddress(world: World, addressArg: string): string { return getContractDataString(world, [ ['Contracts', addressArg], - ['cTokens', addressArg, 'address'], - ['CTokenDelegate', addressArg, 'address'], + ['slTokens', addressArg, 'address'], + ['SLTokenDelegate', addressArg, 'address'], ['Tokens', addressArg, 'address'], ['Comptroller', addressArg, 'address'] ]); diff --git a/scenario/src/CoreEvent.ts b/scenario/src/CoreEvent.ts index 094cb64f3..f71e50219 100644 --- a/scenario/src/CoreEvent.ts +++ b/scenario/src/CoreEvent.ts @@ -15,8 +15,8 @@ import { assertionCommands, processAssertionEvent } from './Event/AssertionEvent import { comptrollerCommands, processComptrollerEvent } from './Event/ComptrollerEvent'; import { processUnitrollerEvent, unitrollerCommands } from './Event/UnitrollerEvent'; import { comptrollerImplCommands, processComptrollerImplEvent } from './Event/ComptrollerImplEvent'; -import { cTokenCommands, processCTokenEvent } from './Event/CTokenEvent'; -import { cTokenDelegateCommands, processCTokenDelegateEvent } from './Event/CTokenDelegateEvent'; +import { slTokenCommands, processSLTokenEvent } from './Event/SLTokenEvent'; +import { slTokenDelegateCommands, processSLTokenDelegateEvent } from './Event/SLTokenDelegateEvent'; import { erc20Commands, processErc20Event } from './Event/Erc20Event'; import { interestRateModelCommands, processInterestRateModelEvent } from './Event/InterestRateModelEvent'; import { priceOracleCommands, processPriceOracleEvent } from './Event/PriceOracleEvent'; @@ -25,8 +25,6 @@ import { maximillionCommands, processMaximillionEvent } from './Event/Maximillio import { invariantCommands, processInvariantEvent } from './Event/InvariantEvent'; import { expectationCommands, processExpectationEvent } from './Event/ExpectationEvent'; import { timelockCommands, processTimelockEvent } from './Event/TimelockEvent'; -import { compCommands, processCompEvent } from './Event/CompEvent'; -import { governorCommands, processGovernorEvent } from './Event/GovernorEvent'; import { processTrxEvent, trxCommands } from './Event/TrxEvent'; import { getFetchers, getCoreValue } from './CoreValue'; import { formatEvent } from './Formatter'; @@ -39,7 +37,7 @@ import { loadContracts } from './Networks'; import { fork } from './Hypothetical'; import { buildContractEvent } from './EventBuilder'; import { Counter } from './Contract/Counter'; -import { CompoundLens } from './Contract/CompoundLens'; +import { SashimiLendingLens } from './Contract/SashimiLendingLens'; import { Reservoir } from './Contract/Reservoir'; import Web3 from 'web3'; @@ -221,7 +219,7 @@ export const commands: (View | ((world: World) => Promise>))[] = #### Read * "Read ..." - Reads given value and prints result - * E.g. "Read CToken cBAT ExchangeRateStored" - Returns exchange rate of cBAT + * E.g. "Read SLToken cBAT ExchangeRateStored" - Returns exchange rate of cBAT `, 'Read', [new Arg('res', getCoreValue, { variadic: true })], @@ -435,7 +433,7 @@ export const commands: (View | ((world: World) => Promise>))[] = #### Block * "Block 10 (...event)" - Set block to block N and run event - * E.g. "Block 10 (Comp Deploy Admin)" + * E.g. "Block 10 (Sashimi Deploy Admin)" `, 'Block', [ @@ -491,7 +489,7 @@ export const commands: (View | ((world: World) => Promise>))[] = #### From * "From " - Runs event as the given user - * E.g. "From Geoff (CToken cZRX Mint 5e18)" + * E.g. "From Geoff (SLToken slZRX Mint 5e18)" `, 'From', [new Arg('account', getAddressV), new Arg('event', getEventV)], @@ -503,7 +501,7 @@ export const commands: (View | ((world: World) => Promise>))[] = #### Trx * "Trx ...trxEvent" - Handles event to set details of next transaction - * E.g. "Trx Value 1.0e18 (CToken cEth Mint 1.0e18)" + * E.g. "Trx Value 1.0e18 (SLToken slETH Mint 1.0e18)" `, 'Trx', [new Arg('event', getEventV, { variadic: true })], @@ -516,7 +514,7 @@ export const commands: (View | ((world: World) => Promise>))[] = #### Invariant * "Invariant ...invariant" - Adds a new invariant to the world which is checked after each transaction - * E.g. "Invariant Static (CToken cZRX TotalSupply)" + * E.g. "Invariant Static (SLToken slZRX TotalSupply)" `, 'Invariant', [new Arg('event', getEventV, { variadic: true })], @@ -529,7 +527,7 @@ export const commands: (View | ((world: World) => Promise>))[] = #### Expect * "Expect ...expectation" - Adds an expectation to hold after the next transaction - * E.g. "Expect Changes (CToken cZRX TotalSupply) +10.0e18" + * E.g. "Expect Changes (SLToken slZRX TotalSupply) +10.0e18" `, 'Expect', [new Arg('event', getEventV, { variadic: true })], @@ -623,7 +621,7 @@ export const commands: (View | ((world: World) => Promise>))[] = #### Send * "Send
" - Sends a given amount of eth to given address - * E.g. "Send cETH 0.5e18" + * E.g. "Send slETH 0.5e18" `, 'Send', [new Arg('address', getAddressV), new Arg('amount', getNumberV)], @@ -671,28 +669,28 @@ export const commands: (View | ((world: World) => Promise>))[] = new Command<{ event: EventV }>( ` - #### CToken + #### SLToken - * "CToken ...event" - Runs given CToken event - * E.g. "CToken cZRX Mint 5e18" + * "SLToken ...event" - Runs given SLToken event + * E.g. "SLToken slZRX Mint 5e18" `, - 'CToken', + 'SLToken', [new Arg('event', getEventV, { variadic: true })], - (world, from, { event }) => processCTokenEvent(world, event.val, from), - { subExpressions: cTokenCommands() } + (world, from, { event }) => processSLTokenEvent(world, event.val, from), + { subExpressions: slTokenCommands() } ), new Command<{ event: EventV }>( ` - #### CTokenDelegate + #### SLTokenDelegate - * "CTokenDelegate ...event" - Runs given CTokenDelegate event - * E.g. "CTokenDelegate Deploy CDaiDelegate cDaiDelegate" + * "SLTokenDelegate ...event" - Runs given SLTokenDelegate event + * E.g. "SLTokenDelegate Deploy CDaiDelegate slDaiDelegate" `, - 'CTokenDelegate', + 'SLTokenDelegate', [new Arg('event', getEventV, { variadic: true })], - (world, from, { event }) => processCTokenDelegateEvent(world, event.val, from), - { subExpressions: cTokenDelegateCommands() } + (world, from, { event }) => processSLTokenDelegateEvent(world, event.val, from), + { subExpressions: slTokenDelegateCommands() } ), new Command<{ event: EventV }>( @@ -726,7 +724,7 @@ export const commands: (View | ((world: World) => Promise>))[] = #### PriceOracle * "PriceOracle ...event" - Runs given Price Oracle event - * E.g. "PriceOracle SetPrice cZRX 1.5" + * E.g. "PriceOracle SetPrice slZRX 1.5" `, 'PriceOracle', [new Arg('event', getEventV, { variadic: true })], @@ -739,7 +737,7 @@ export const commands: (View | ((world: World) => Promise>))[] = #### PriceOracleProxy * "PriceOracleProxy ...event" - Runs given Price Oracle event - * E.g. "PriceOracleProxy Deploy (Unitroller Address) (PriceOracle Address) (CToken cETH Address)" + * E.g. "PriceOracleProxy Deploy (Unitroller Address) (PriceOracle Address) (SLToken slETH Address)" `, 'PriceOracleProxy', [new Arg('event', getEventV, { variadic: true })], @@ -754,7 +752,7 @@ export const commands: (View | ((world: World) => Promise>))[] = #### Maximillion * "Maximillion ...event" - Runs given Maximillion event - * E.g. "Maximillion Deploy (CToken cETH Address)" + * E.g. "Maximillion Deploy (SLToken slETH Address)" `, 'Maximillion', [new Arg('event', getEventV, { variadic: true })], @@ -779,38 +777,23 @@ export const commands: (View | ((world: World) => Promise>))[] = { subExpressions: timelockCommands() } ), - new Command<{ event: EventV }>( - ` - #### Comp - - * "Comp ...event" - Runs given comp event - * E.g. "Comp Deploy" - `, - 'Comp', - [new Arg('event', getEventV, { variadic: true })], - (world, from, { event }) => { - return processCompEvent(world, event.val, from); - }, - { subExpressions: compCommands() } - ), + // new Command<{ event: EventV }>( + // ` + // #### Sashimi - new Command<{ event: EventV }>( - ` - #### Governor - - * "Governor ...event" - Runs given governor event - * E.g. "Governor Deploy Alpha" - `, - 'Governor', - [new Arg('event', getEventV, { variadic: true })], - (world, from, { event }) => { - return processGovernorEvent(world, event.val, from); - }, - { subExpressions: governorCommands() } - ), + // * "Sashimi ...event" - Runs given sashimi event + // * E.g. "Sashimi Deploy" + // `, + // 'Sashimi', + // [new Arg('event', getEventV, { variadic: true })], + // (world, from, { event }) => { + // return processCompEvent(world, event.val, from); + // }, + // { subExpressions: compCommands() } + // ), buildContractEvent("Counter", false), - buildContractEvent("CompoundLens", false), + buildContractEvent("SashimiLendingLens", false), buildContractEvent("Reservoir", true), new View<{ event: EventV }>( diff --git a/scenario/src/CoreValue.ts b/scenario/src/CoreValue.ts index 1d18be6e6..611d5fa56 100644 --- a/scenario/src/CoreValue.ts +++ b/scenario/src/CoreValue.ts @@ -21,8 +21,8 @@ import { getUserValue, userFetchers } from './Value/UserValue'; import { comptrollerFetchers, getComptrollerValue } from './Value/ComptrollerValue'; import { comptrollerImplFetchers, getComptrollerImplValue } from './Value/ComptrollerImplValue'; import { getUnitrollerValue, unitrollerFetchers } from './Value/UnitrollerValue'; -import { cTokenFetchers, getCTokenValue } from './Value/CTokenValue'; -import { cTokenDelegateFetchers, getCTokenDelegateValue } from './Value/CTokenDelegateValue'; +import { slTokenFetchers, getSLTokenValue } from './Value/SLTokenValue'; +import { slTokenDelegateFetchers, getSLTokenDelegateValue } from './Value/SLTokenDelegateValue'; import { erc20Fetchers, getErc20Value } from './Value/Erc20Value'; import { mcdFetchers, getMCDValue } from './Value/MCDValue'; import { getInterestRateModelValue, interestRateModelFetchers } from './Value/InterestRateModelValue'; @@ -31,8 +31,6 @@ import { getPriceOracleProxyValue, priceOracleProxyFetchers } from './Value/Pric import { getAnchoredViewValue, anchoredViewFetchers } from './Value/AnchoredViewValue'; import { getTimelockValue, timelockFetchers, getTimelockAddress } from './Value/TimelockValue'; import { getMaximillionValue, maximillionFetchers } from './Value/MaximillionValue'; -import { getCompValue, compFetchers } from './Value/CompValue'; -import { getGovernorValue, governorFetchers } from './Value/GovernorValue'; import { getAddress } from './ContractLookup'; import { getCurrentBlockNumber, getCurrentTimestamp, mustArray, sendRPC } from './Utils'; import { toEncodableNum } from './Encoding'; @@ -778,8 +776,8 @@ const fetchers = [ * "Equal given: expected:" - Returns true if given values are equal * E.g. "Equal (Exactly 0) Zero" - * E.g. "Equal (CToken cZRX TotalSupply) (Exactly 55)" - * E.g. "Equal (CToken cZRX Comptroller) (Comptroller Address)" + * E.g. "Equal (SLToken slZRX TotalSupply) (Exactly 55)" + * E.g. "Equal (SLToken slZRX Comptroller) (Comptroller Address)" `, 'Equal', [new Arg('given', getCoreValue), new Arg('expected', getCoreValue)], @@ -847,25 +845,25 @@ const fetchers = [ ), new Fetcher<{ res: Value }, Value>( ` - #### CToken + #### SLToken - * "CToken ...cTokenArgs" - Returns cToken value + * "SLToken ...slTokenArgs" - Returns slToken value `, - 'CToken', - [new Arg('res', getCTokenValue, { variadic: true })], + 'SLToken', + [new Arg('res', getSLTokenValue, { variadic: true })], async (world, { res }) => res, - { subExpressions: cTokenFetchers() } + { subExpressions: slTokenFetchers() } ), new Fetcher<{ res: Value }, Value>( ` - #### CTokenDelegate + #### SLTokenDelegate - * "CTokenDelegate ...cTokenDelegateArgs" - Returns cToken delegate value + * "SLTokenDelegate ...slTokenDelegateArgs" - Returns slToken delegate value `, - 'CTokenDelegate', - [new Arg('res', getCTokenDelegateValue, { variadic: true })], + 'SLTokenDelegate', + [new Arg('res', getSLTokenDelegateValue, { variadic: true })], async (world, { res }) => res, - { subExpressions: cTokenDelegateFetchers() } + { subExpressions: slTokenDelegateFetchers() } ), new Fetcher<{ res: Value }, Value>( ` @@ -955,33 +953,11 @@ const fetchers = [ async (world, { res }) => res, { subExpressions: mcdFetchers() } ), - new Fetcher<{ res: Value }, Value>( - ` - #### Comp - - * "Comp ...compArgs" - Returns Comp value - `, - 'Comp', - [new Arg('res', getCompValue, { variadic: true })], - async (world, { res }) => res, - { subExpressions: compFetchers() } - ), - new Fetcher<{ res: Value }, Value>( - ` - #### Governor - - * "Governor ...governorArgs" - Returns Governor value - `, - 'Governor', - [new Arg('res', getGovernorValue, { variadic: true })], - async (world, { res }) => res, - { subExpressions: governorFetchers() } - ), ]; let contractFetchers = [ { contract: "Counter", implicit: false }, - { contract: "CompoundLens", implicit: false }, + { contract: "SashimiLendingLens", implicit: false }, { contract: "Reservoir", implicit: true } ]; diff --git a/scenario/src/ErrorReporter.ts b/scenario/src/ErrorReporter.ts index 820b30aa1..c4226d695 100644 --- a/scenario/src/ErrorReporter.ts +++ b/scenario/src/ErrorReporter.ts @@ -20,7 +20,7 @@ class NoErrorReporterType implements ErrorReporter { } } -class CTokenErrorReporterType implements ErrorReporter { +class SLTokenErrorReporterType implements ErrorReporter { getError(error: any): string | null { if (error === null) { return null; @@ -94,5 +94,5 @@ export function formatResult(errorReporter: ErrorReporter, result: any): string // Singleton instances export const NoErrorReporter = new NoErrorReporterType(); -export const CTokenErrorReporter = new CTokenErrorReporterType(); +export const SLTokenErrorReporter = new SLTokenErrorReporterType(); export const ComptrollerErrorReporter = new ComptrollerErrorReporterType(); diff --git a/scenario/src/Event/AssertionEvent.ts b/scenario/src/Event/AssertionEvent.ts index 4934a900f..781ca0f92 100644 --- a/scenario/src/Event/AssertionEvent.ts +++ b/scenario/src/Event/AssertionEvent.ts @@ -260,8 +260,8 @@ export function assertionCommands() { * "Approx given: expected: tolerance:" - Asserts that given approximately matches expected. * E.g. "Assert Approx (Exactly 0) Zero " - * E.g. "Assert Approx (CToken cZRX TotalSupply) (Exactly 55) 1e-18" - * E.g. "Assert Approx (CToken cZRX Comptroller) (Comptroller Address) 1" + * E.g. "Assert Approx (SLToken slZRX TotalSupply) (Exactly 55) 1e-18" + * E.g. "Assert Approx (SLToken slZRX Comptroller) (Comptroller Address) 1" `, "Approx", [ @@ -277,8 +277,8 @@ export function assertionCommands() { * "Equal given: expected:" - Asserts that given matches expected. * E.g. "Assert Equal (Exactly 0) Zero" - * E.g. "Assert Equal (CToken cZRX TotalSupply) (Exactly 55)" - * E.g. "Assert Equal (CToken cZRX Comptroller) (Comptroller Address)" + * E.g. "Assert Equal (SLToken slZRX TotalSupply) (Exactly 55)" + * E.g. "Assert Equal (SLToken slZRX Comptroller) (Comptroller Address)" `, "Equal", [ @@ -322,7 +322,7 @@ export function assertionCommands() { #### True * "True given:" - Asserts that given is true. - * E.g. "Assert True (Comptroller CheckMembership Geoff cETH)" + * E.g. "Assert True (Comptroller CheckMembership Geoff slETH)" `, "True", [ @@ -335,7 +335,7 @@ export function assertionCommands() { #### False * "False given:" - Asserts that given is false. - * E.g. "Assert False (Comptroller CheckMembership Geoff cETH)" + * E.g. "Assert False (Comptroller CheckMembership Geoff slETH)" `, "False", [ @@ -347,7 +347,7 @@ export function assertionCommands() { #### ReadRevert * "ReadRevert event: message:" - Asserts that reading the given value reverts with given message. - * E.g. "Assert ReadRevert (Comptroller CheckMembership Geoff cETH) \"revert\"" + * E.g. "Assert ReadRevert (Comptroller CheckMembership Geoff slETH) \"revert\"" `, "ReadRevert", [ diff --git a/scenario/src/Event/CTokenDelegateEvent.ts b/scenario/src/Event/CTokenDelegateEvent.ts deleted file mode 100644 index 30f6ec966..000000000 --- a/scenario/src/Event/CTokenDelegateEvent.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { Event } from '../Event'; -import { addAction, describeUser, World } from '../World'; -import { decodeCall, getPastEvents } from '../Contract'; -import { CToken, CTokenScenario } from '../Contract/CToken'; -import { CErc20Delegate } from '../Contract/CErc20Delegate' -import { invoke, Sendable } from '../Invokation'; -import { - getAddressV, - getEventV, - getExpNumberV, - getNumberV, - getStringV, - getBoolV -} from '../CoreValue'; -import { - AddressV, - BoolV, - EventV, - NothingV, - NumberV, - StringV -} from '../Value'; -import { Arg, Command, View, processCommandEvent } from '../Command'; -import { getCTokenDelegateData } from '../ContractLookup'; -import { buildCTokenDelegate } from '../Builder/CTokenDelegateBuilder'; -import { verify } from '../Verify'; - -async function genCTokenDelegate(world: World, from: string, event: Event): Promise { - let { world: nextWorld, cTokenDelegate, delegateData } = await buildCTokenDelegate(world, from, event); - world = nextWorld; - - world = addAction( - world, - `Added cToken ${delegateData.name} (${delegateData.contract}) at address ${cTokenDelegate._address}`, - delegateData.invokation - ); - - return world; -} - -async function verifyCTokenDelegate(world: World, cTokenDelegate: CErc20Delegate, name: string, contract: string, apiKey: string): Promise { - if (world.isLocalNetwork()) { - world.printer.printLine(`Politely declining to verify on local network: ${world.network}.`); - } else { - await verify(world, apiKey, name, contract, cTokenDelegate._address); - } - - return world; -} - -export function cTokenDelegateCommands() { - return [ - new Command<{ cTokenDelegateParams: EventV }>(` - #### Deploy - - * "CTokenDelegate Deploy ...cTokenDelegateParams" - Generates a new CTokenDelegate - * E.g. "CTokenDelegate Deploy CDaiDelegate cDAIDelegate" - `, - "Deploy", - [new Arg("cTokenDelegateParams", getEventV, { variadic: true })], - (world, from, { cTokenDelegateParams }) => genCTokenDelegate(world, from, cTokenDelegateParams.val) - ), - new View<{ cTokenDelegateArg: StringV, apiKey: StringV }>(` - #### Verify - - * "CTokenDelegate Verify apiKey:" - Verifies CTokenDelegate in Etherscan - * E.g. "CTokenDelegate cDaiDelegate Verify "myApiKey" - `, - "Verify", - [ - new Arg("cTokenDelegateArg", getStringV), - new Arg("apiKey", getStringV) - ], - async (world, { cTokenDelegateArg, apiKey }) => { - let [cToken, name, data] = await getCTokenDelegateData(world, cTokenDelegateArg.val); - - return await verifyCTokenDelegate(world, cToken, name, data.get('contract')!, apiKey.val); - }, - { namePos: 1 } - ), - ]; -} - -export async function processCTokenDelegateEvent(world: World, event: Event, from: string | null): Promise { - return await processCommandEvent("CTokenDelegate", cTokenDelegateCommands(), world, event, from); -} diff --git a/scenario/src/Event/CTokenEvent.ts b/scenario/src/Event/CTokenEvent.ts deleted file mode 100644 index 71282faea..000000000 --- a/scenario/src/Event/CTokenEvent.ts +++ /dev/null @@ -1,908 +0,0 @@ -import { Event } from '../Event'; -import { addAction, describeUser, World } from '../World'; -import { decodeCall, getPastEvents } from '../Contract'; -import { CToken, CTokenScenario } from '../Contract/CToken'; -import { CErc20Delegate } from '../Contract/CErc20Delegate' -import { CErc20Delegator } from '../Contract/CErc20Delegator' -import { invoke, Sendable } from '../Invokation'; -import { - getAddressV, - getEventV, - getExpNumberV, - getNumberV, - getStringV, - getBoolV -} from '../CoreValue'; -import { - AddressV, - BoolV, - EventV, - NothingV, - NumberV, - StringV -} from '../Value'; -import { getContract } from '../Contract'; -import { Arg, Command, View, processCommandEvent } from '../Command'; -import { CTokenErrorReporter } from '../ErrorReporter'; -import { getComptroller, getCTokenData } from '../ContractLookup'; -import { getExpMantissa } from '../Encoding'; -import { buildCToken } from '../Builder/CTokenBuilder'; -import { verify } from '../Verify'; -import { getLiquidity } from '../Value/ComptrollerValue'; -import { encodedNumber } from '../Encoding'; -import { getCTokenV, getCErc20DelegatorV } from '../Value/CTokenValue'; - -function showTrxValue(world: World): string { - return new NumberV(world.trxInvokationOpts.get('value')).show(); -} - -async function genCToken(world: World, from: string, event: Event): Promise { - let { world: nextWorld, cToken, tokenData } = await buildCToken(world, from, event); - world = nextWorld; - - world = addAction( - world, - `Added cToken ${tokenData.name} (${tokenData.contract}) at address ${cToken._address}`, - tokenData.invokation - ); - - return world; -} - -async function accrueInterest(world: World, from: string, cToken: CToken): Promise { - let invokation = await invoke(world, cToken.methods.accrueInterest(), from, CTokenErrorReporter); - - world = addAction( - world, - `CToken ${cToken.name}: Interest accrued`, - invokation - ); - - return world; -} - -async function mint(world: World, from: string, cToken: CToken, amount: NumberV | NothingV): Promise { - let invokation; - let showAmount; - - if (amount instanceof NumberV) { - showAmount = amount.show(); - invokation = await invoke(world, cToken.methods.mint(amount.encode()), from, CTokenErrorReporter); - } else { - showAmount = showTrxValue(world); - invokation = await invoke(world, cToken.methods.mint(), from, CTokenErrorReporter); - } - - world = addAction( - world, - `CToken ${cToken.name}: ${describeUser(world, from)} mints ${showAmount}`, - invokation - ); - - return world; -} - -async function redeem(world: World, from: string, cToken: CToken, tokens: NumberV): Promise { - let invokation = await invoke(world, cToken.methods.redeem(tokens.encode()), from, CTokenErrorReporter); - - world = addAction( - world, - `CToken ${cToken.name}: ${describeUser(world, from)} redeems ${tokens.show()} tokens`, - invokation - ); - - return world; -} - -async function redeemUnderlying(world: World, from: string, cToken: CToken, amount: NumberV): Promise { - let invokation = await invoke(world, cToken.methods.redeemUnderlying(amount.encode()), from, CTokenErrorReporter); - - world = addAction( - world, - `CToken ${cToken.name}: ${describeUser(world, from)} redeems ${amount.show()} underlying`, - invokation - ); - - return world; -} - -async function borrow(world: World, from: string, cToken: CToken, amount: NumberV): Promise { - let invokation = await invoke(world, cToken.methods.borrow(amount.encode()), from, CTokenErrorReporter); - - world = addAction( - world, - `CToken ${cToken.name}: ${describeUser(world, from)} borrows ${amount.show()}`, - invokation - ); - - return world; -} - -async function repayBorrow(world: World, from: string, cToken: CToken, amount: NumberV | NothingV): Promise { - let invokation; - let showAmount; - - if (amount instanceof NumberV) { - showAmount = amount.show(); - invokation = await invoke(world, cToken.methods.repayBorrow(amount.encode()), from, CTokenErrorReporter); - } else { - showAmount = showTrxValue(world); - invokation = await invoke(world, cToken.methods.repayBorrow(), from, CTokenErrorReporter); - } - - world = addAction( - world, - `CToken ${cToken.name}: ${describeUser(world, from)} repays ${showAmount} of borrow`, - invokation - ); - - return world; -} - -async function repayBorrowBehalf(world: World, from: string, behalf: string, cToken: CToken, amount: NumberV | NothingV): Promise { - let invokation; - let showAmount; - - if (amount instanceof NumberV) { - showAmount = amount.show(); - invokation = await invoke(world, cToken.methods.repayBorrowBehalf(behalf, amount.encode()), from, CTokenErrorReporter); - } else { - showAmount = showTrxValue(world); - invokation = await invoke(world, cToken.methods.repayBorrowBehalf(behalf), from, CTokenErrorReporter); - } - - world = addAction( - world, - `CToken ${cToken.name}: ${describeUser(world, from)} repays ${showAmount} of borrow on behalf of ${describeUser(world, behalf)}`, - invokation - ); - - return world; -} - -async function liquidateBorrow(world: World, from: string, cToken: CToken, borrower: string, collateral: CToken, repayAmount: NumberV | NothingV): Promise { - let invokation; - let showAmount; - - if (repayAmount instanceof NumberV) { - showAmount = repayAmount.show(); - invokation = await invoke(world, cToken.methods.liquidateBorrow(borrower, repayAmount.encode(), collateral._address), from, CTokenErrorReporter); - } else { - showAmount = showTrxValue(world); - invokation = await invoke(world, cToken.methods.liquidateBorrow(borrower, collateral._address), from, CTokenErrorReporter); - } - - world = addAction( - world, - `CToken ${cToken.name}: ${describeUser(world, from)} liquidates ${showAmount} from of ${describeUser(world, borrower)}, seizing ${collateral.name}.`, - invokation - ); - - return world; -} - -async function seize(world: World, from: string, cToken: CToken, liquidator: string, borrower: string, seizeTokens: NumberV): Promise { - let invokation = await invoke(world, cToken.methods.seize(liquidator, borrower, seizeTokens.encode()), from, CTokenErrorReporter); - - world = addAction( - world, - `CToken ${cToken.name}: ${describeUser(world, from)} initiates seizing ${seizeTokens.show()} to ${describeUser(world, liquidator)} from ${describeUser(world, borrower)}.`, - invokation - ); - - return world; -} - -async function evilSeize(world: World, from: string, cToken: CToken, treasure: CToken, liquidator: string, borrower: string, seizeTokens: NumberV): Promise { - let invokation = await invoke(world, cToken.methods.evilSeize(treasure._address, liquidator, borrower, seizeTokens.encode()), from, CTokenErrorReporter); - - world = addAction( - world, - `CToken ${cToken.name}: ${describeUser(world, from)} initiates illegal seizing ${seizeTokens.show()} to ${describeUser(world, liquidator)} from ${describeUser(world, borrower)}.`, - invokation - ); - - return world; -} - -async function setPendingAdmin(world: World, from: string, cToken: CToken, newPendingAdmin: string): Promise { - let invokation = await invoke(world, cToken.methods._setPendingAdmin(newPendingAdmin), from, CTokenErrorReporter); - - world = addAction( - world, - `CToken ${cToken.name}: ${describeUser(world, from)} sets pending admin to ${newPendingAdmin}`, - invokation - ); - - return world; -} - -async function acceptAdmin(world: World, from: string, cToken: CToken): Promise { - let invokation = await invoke(world, cToken.methods._acceptAdmin(), from, CTokenErrorReporter); - - world = addAction( - world, - `CToken ${cToken.name}: ${describeUser(world, from)} accepts admin`, - invokation - ); - - return world; -} - -async function addReserves(world: World, from: string, cToken: CToken, amount: NumberV): Promise { - let invokation = await invoke(world, cToken.methods._addReserves(amount.encode()), from, CTokenErrorReporter); - - world = addAction( - world, - `CToken ${cToken.name}: ${describeUser(world, from)} adds to reserves by ${amount.show()}`, - invokation - ); - - return world; -} - -async function reduceReserves(world: World, from: string, cToken: CToken, amount: NumberV): Promise { - let invokation = await invoke(world, cToken.methods._reduceReserves(amount.encode()), from, CTokenErrorReporter); - - world = addAction( - world, - `CToken ${cToken.name}: ${describeUser(world, from)} reduces reserves by ${amount.show()}`, - invokation - ); - - return world; -} - -async function setReserveFactor(world: World, from: string, cToken: CToken, reserveFactor: NumberV): Promise { - let invokation = await invoke(world, cToken.methods._setReserveFactor(reserveFactor.encode()), from, CTokenErrorReporter); - - world = addAction( - world, - `CToken ${cToken.name}: ${describeUser(world, from)} sets reserve factor to ${reserveFactor.show()}`, - invokation - ); - - return world; -} - -async function setInterestRateModel(world: World, from: string, cToken: CToken, interestRateModel: string): Promise { - let invokation = await invoke(world, cToken.methods._setInterestRateModel(interestRateModel), from, CTokenErrorReporter); - - world = addAction( - world, - `Set interest rate for ${cToken.name} to ${interestRateModel} as ${describeUser(world, from)}`, - invokation - ); - - return world; -} - -async function setComptroller(world: World, from: string, cToken: CToken, comptroller: string): Promise { - let invokation = await invoke(world, cToken.methods._setComptroller(comptroller), from, CTokenErrorReporter); - - world = addAction( - world, - `Set comptroller for ${cToken.name} to ${comptroller} as ${describeUser(world, from)}`, - invokation - ); - - return world; -} - -async function becomeImplementation( - world: World, - from: string, - cToken: CToken, - becomeImplementationData: string -): Promise { - - const cErc20Delegate = getContract('CErc20Delegate'); - const cErc20DelegateContract = await cErc20Delegate.at(world, cToken._address); - - let invokation = await invoke( - world, - cErc20DelegateContract.methods._becomeImplementation(becomeImplementationData), - from, - CTokenErrorReporter - ); - - world = addAction( - world, - `CToken ${cToken.name}: ${describeUser( - world, - from - )} initiates _becomeImplementation with data:${becomeImplementationData}.`, - invokation - ); - - return world; -} - -async function resignImplementation( - world: World, - from: string, - cToken: CToken, -): Promise { - - const cErc20Delegate = getContract('CErc20Delegate'); - const cErc20DelegateContract = await cErc20Delegate.at(world, cToken._address); - - let invokation = await invoke( - world, - cErc20DelegateContract.methods._resignImplementation(), - from, - CTokenErrorReporter - ); - - world = addAction( - world, - `CToken ${cToken.name}: ${describeUser( - world, - from - )} initiates _resignImplementation.`, - invokation - ); - - return world; -} - -async function setImplementation( - world: World, - from: string, - cToken: CErc20Delegator, - implementation: string, - allowResign: boolean, - becomeImplementationData: string -): Promise { - let invokation = await invoke( - world, - cToken.methods._setImplementation( - implementation, - allowResign, - becomeImplementationData - ), - from, - CTokenErrorReporter - ); - - world = addAction( - world, - `CToken ${cToken.name}: ${describeUser( - world, - from - )} initiates setImplementation with implementation:${implementation} allowResign:${allowResign} data:${becomeImplementationData}.`, - invokation - ); - - return world; -} - -async function donate(world: World, from: string, cToken: CToken): Promise { - let invokation = await invoke(world, cToken.methods.donate(), from, CTokenErrorReporter); - - world = addAction( - world, - `Donate for ${cToken.name} as ${describeUser(world, from)} with value ${showTrxValue(world)}`, - invokation - ); - - return world; -} - -async function setCTokenMock(world: World, from: string, cToken: CTokenScenario, mock: string, value: NumberV): Promise { - let mockMethod: (number) => Sendable; - - switch (mock.toLowerCase()) { - case "totalborrows": - mockMethod = cToken.methods.setTotalBorrows; - break; - case "totalreserves": - mockMethod = cToken.methods.setTotalReserves; - break; - default: - throw new Error(`Mock "${mock}" not defined for cToken`); - } - - let invokation = await invoke(world, mockMethod(value.encode()), from); - - world = addAction( - world, - `Mocked ${mock}=${value.show()} for ${cToken.name}`, - invokation - ); - - return world; -} - -async function verifyCToken(world: World, cToken: CToken, name: string, contract: string, apiKey: string): Promise { - if (world.isLocalNetwork()) { - world.printer.printLine(`Politely declining to verify on local network: ${world.network}.`); - } else { - await verify(world, apiKey, name, contract, cToken._address); - } - - return world; -} - -async function printMinters(world: World, cToken: CToken): Promise { - let events = await getPastEvents(world, cToken, cToken.name, 'Mint'); - let addresses = events.map((event) => event.returnValues['minter']); - let uniq = [...new Set(addresses)]; - - world.printer.printLine("Minters:") - - uniq.forEach((address) => { - world.printer.printLine(`\t${address}`) - }); - - return world; -} - -async function printBorrowers(world: World, cToken: CToken): Promise { - let events = await getPastEvents(world, cToken, cToken.name, 'Borrow'); - let addresses = events.map((event) => event.returnValues['borrower']); - let uniq = [...new Set(addresses)]; - - world.printer.printLine("Borrowers:") - - uniq.forEach((address) => { - world.printer.printLine(`\t${address}`) - }); - - return world; -} - -async function printLiquidity(world: World, cToken: CToken): Promise { - let mintEvents = await getPastEvents(world, cToken, cToken.name, 'Mint'); - let mintAddresses = mintEvents.map((event) => event.returnValues['minter']); - let borrowEvents = await getPastEvents(world, cToken, cToken.name, 'Borrow'); - let borrowAddresses = borrowEvents.map((event) => event.returnValues['borrower']); - let uniq = [...new Set(mintAddresses.concat(borrowAddresses))]; - let comptroller = await getComptroller(world); - - world.printer.printLine("Liquidity:") - - const liquidityMap = await Promise.all(uniq.map(async (address) => { - let userLiquidity = await getLiquidity(world, comptroller, address); - - return [address, userLiquidity.val]; - })); - - liquidityMap.forEach(([address, liquidity]) => { - world.printer.printLine(`\t${world.settings.lookupAlias(address)}: ${liquidity / 1e18}e18`) - }); - - return world; -} - -export function cTokenCommands() { - return [ - new Command<{ cTokenParams: EventV }>(` - #### Deploy - - * "CToken Deploy ...cTokenParams" - Generates a new CToken - * E.g. "CToken cZRX Deploy" - `, - "Deploy", - [new Arg("cTokenParams", getEventV, { variadic: true })], - (world, from, { cTokenParams }) => genCToken(world, from, cTokenParams.val) - ), - new View<{ cTokenArg: StringV, apiKey: StringV }>(` - #### Verify - - * "CToken Verify apiKey:" - Verifies CToken in Etherscan - * E.g. "CToken cZRX Verify "myApiKey" - `, - "Verify", - [ - new Arg("cTokenArg", getStringV), - new Arg("apiKey", getStringV) - ], - async (world, { cTokenArg, apiKey }) => { - let [cToken, name, data] = await getCTokenData(world, cTokenArg.val); - - return await verifyCToken(world, cToken, name, data.get('contract')!, apiKey.val); - }, - { namePos: 1 } - ), - new Command<{ cToken: CToken }>(` - #### AccrueInterest - - * "CToken AccrueInterest" - Accrues interest for given token - * E.g. "CToken cZRX AccrueInterest" - `, - "AccrueInterest", - [ - new Arg("cToken", getCTokenV) - ], - (world, from, { cToken }) => accrueInterest(world, from, cToken), - { namePos: 1 } - ), - new Command<{ cToken: CToken, amount: NumberV | NothingV }>(` - #### Mint - - * "CToken Mint amount:" - Mints the given amount of cToken as specified user - * E.g. "CToken cZRX Mint 1.0e18" - `, - "Mint", - [ - new Arg("cToken", getCTokenV), - new Arg("amount", getNumberV, { nullable: true }) - ], - (world, from, { cToken, amount }) => mint(world, from, cToken, amount), - { namePos: 1 } - ), - new Command<{ cToken: CToken, tokens: NumberV }>(` - #### Redeem - - * "CToken Redeem tokens:" - Redeems the given amount of cTokens as specified user - * E.g. "CToken cZRX Redeem 1.0e9" - `, - "Redeem", - [ - new Arg("cToken", getCTokenV), - new Arg("tokens", getNumberV) - ], - (world, from, { cToken, tokens }) => redeem(world, from, cToken, tokens), - { namePos: 1 } - ), - new Command<{ cToken: CToken, amount: NumberV }>(` - #### RedeemUnderlying - - * "CToken RedeemUnderlying amount:" - Redeems the given amount of underlying as specified user - * E.g. "CToken cZRX RedeemUnderlying 1.0e18" - `, - "RedeemUnderlying", - [ - new Arg("cToken", getCTokenV), - new Arg("amount", getNumberV) - ], - (world, from, { cToken, amount }) => redeemUnderlying(world, from, cToken, amount), - { namePos: 1 } - ), - new Command<{ cToken: CToken, amount: NumberV }>(` - #### Borrow - - * "CToken Borrow amount:" - Borrows the given amount of this cToken as specified user - * E.g. "CToken cZRX Borrow 1.0e18" - `, - "Borrow", - [ - new Arg("cToken", getCTokenV), - new Arg("amount", getNumberV) - ], - // Note: we override from - (world, from, { cToken, amount }) => borrow(world, from, cToken, amount), - { namePos: 1 } - ), - new Command<{ cToken: CToken, amount: NumberV | NothingV }>(` - #### RepayBorrow - - * "CToken RepayBorrow underlyingAmount:" - Repays borrow in the given underlying amount as specified user - * E.g. "CToken cZRX RepayBorrow 1.0e18" - `, - "RepayBorrow", - [ - new Arg("cToken", getCTokenV), - new Arg("amount", getNumberV, { nullable: true }) - ], - (world, from, { cToken, amount }) => repayBorrow(world, from, cToken, amount), - { namePos: 1 } - ), - new Command<{ cToken: CToken, behalf: AddressV, amount: NumberV | NothingV }>(` - #### RepayBorrowBehalf - - * "CToken RepayBorrowBehalf behalf: underlyingAmount:" - Repays borrow in the given underlying amount on behalf of another user - * E.g. "CToken cZRX RepayBorrowBehalf Geoff 1.0e18" - `, - "RepayBorrowBehalf", - [ - new Arg("cToken", getCTokenV), - new Arg("behalf", getAddressV), - new Arg("amount", getNumberV, { nullable: true }) - ], - (world, from, { cToken, behalf, amount }) => repayBorrowBehalf(world, from, behalf.val, cToken, amount), - { namePos: 1 } - ), - new Command<{ borrower: AddressV, cToken: CToken, collateral: CToken, repayAmount: NumberV | NothingV }>(` - #### Liquidate - - * "CToken Liquidate borrower: cTokenCollateral:
repayAmount:" - Liquidates repayAmount of given token seizing collateral token - * E.g. "CToken cZRX Liquidate Geoff cBAT 1.0e18" - `, - "Liquidate", - [ - new Arg("cToken", getCTokenV), - new Arg("borrower", getAddressV), - new Arg("collateral", getCTokenV), - new Arg("repayAmount", getNumberV, { nullable: true }) - ], - (world, from, { borrower, cToken, collateral, repayAmount }) => liquidateBorrow(world, from, cToken, borrower.val, collateral, repayAmount), - { namePos: 1 } - ), - new Command<{ cToken: CToken, liquidator: AddressV, borrower: AddressV, seizeTokens: NumberV }>(` - #### Seize - - * "CToken Seize liquidator: borrower: seizeTokens:" - Seizes a given number of tokens from a user (to be called from other CToken) - * E.g. "CToken cZRX Seize Geoff Torrey 1.0e18" - `, - "Seize", - [ - new Arg("cToken", getCTokenV), - new Arg("liquidator", getAddressV), - new Arg("borrower", getAddressV), - new Arg("seizeTokens", getNumberV) - ], - (world, from, { cToken, liquidator, borrower, seizeTokens }) => seize(world, from, cToken, liquidator.val, borrower.val, seizeTokens), - { namePos: 1 } - ), - new Command<{ cToken: CToken, treasure: CToken, liquidator: AddressV, borrower: AddressV, seizeTokens: NumberV }>(` - #### EvilSeize - - * "CToken EvilSeize treasure: liquidator: borrower: seizeTokens:" - Improperly seizes a given number of tokens from a user - * E.g. "CToken cEVL EvilSeize cZRX Geoff Torrey 1.0e18" - `, - "EvilSeize", - [ - new Arg("cToken", getCTokenV), - new Arg("treasure", getCTokenV), - new Arg("liquidator", getAddressV), - new Arg("borrower", getAddressV), - new Arg("seizeTokens", getNumberV) - ], - (world, from, { cToken, treasure, liquidator, borrower, seizeTokens }) => evilSeize(world, from, cToken, treasure, liquidator.val, borrower.val, seizeTokens), - { namePos: 1 } - ), - new Command<{ cToken: CToken, amount: NumberV }>(` - #### ReduceReserves - - * "CToken ReduceReserves amount:" - Reduces the reserves of the cToken - * E.g. "CToken cZRX ReduceReserves 1.0e18" - `, - "ReduceReserves", - [ - new Arg("cToken", getCTokenV), - new Arg("amount", getNumberV) - ], - (world, from, { cToken, amount }) => reduceReserves(world, from, cToken, amount), - { namePos: 1 } - ), - new Command<{ cToken: CToken, amount: NumberV }>(` - #### AddReserves - - * "CToken AddReserves amount:" - Adds reserves to the cToken - * E.g. "CToken cZRX AddReserves 1.0e18" - `, - "AddReserves", - [ - new Arg("cToken", getCTokenV), - new Arg("amount", getNumberV) - ], - (world, from, { cToken, amount }) => addReserves(world, from, cToken, amount), - { namePos: 1 } - ), - new Command<{ cToken: CToken, newPendingAdmin: AddressV }>(` - #### SetPendingAdmin - - * "CToken SetPendingAdmin newPendingAdmin:
" - Sets the pending admin for the cToken - * E.g. "CToken cZRX SetPendingAdmin Geoff" - `, - "SetPendingAdmin", - [ - new Arg("cToken", getCTokenV), - new Arg("newPendingAdmin", getAddressV) - ], - (world, from, { cToken, newPendingAdmin }) => setPendingAdmin(world, from, cToken, newPendingAdmin.val), - { namePos: 1 } - ), - new Command<{ cToken: CToken }>(` - #### AcceptAdmin - - * "CToken AcceptAdmin" - Accepts admin for the cToken - * E.g. "From Geoff (CToken cZRX AcceptAdmin)" - `, - "AcceptAdmin", - [ - new Arg("cToken", getCTokenV) - ], - (world, from, { cToken }) => acceptAdmin(world, from, cToken), - { namePos: 1 } - ), - new Command<{ cToken: CToken, reserveFactor: NumberV }>(` - #### SetReserveFactor - - * "CToken SetReserveFactor reserveFactor:" - Sets the reserve factor for the cToken - * E.g. "CToken cZRX SetReserveFactor 0.1" - `, - "SetReserveFactor", - [ - new Arg("cToken", getCTokenV), - new Arg("reserveFactor", getExpNumberV) - ], - (world, from, { cToken, reserveFactor }) => setReserveFactor(world, from, cToken, reserveFactor), - { namePos: 1 } - ), - new Command<{ cToken: CToken, interestRateModel: AddressV }>(` - #### SetInterestRateModel - - * "CToken SetInterestRateModel interestRateModel:" - Sets the interest rate model for the given cToken - * E.g. "CToken cZRX SetInterestRateModel (FixedRate 1.5)" - `, - "SetInterestRateModel", - [ - new Arg("cToken", getCTokenV), - new Arg("interestRateModel", getAddressV) - ], - (world, from, { cToken, interestRateModel }) => setInterestRateModel(world, from, cToken, interestRateModel.val), - { namePos: 1 } - ), - new Command<{ cToken: CToken, comptroller: AddressV }>(` - #### SetComptroller - - * "CToken SetComptroller comptroller:" - Sets the comptroller for the given cToken - * E.g. "CToken cZRX SetComptroller Comptroller" - `, - "SetComptroller", - [ - new Arg("cToken", getCTokenV), - new Arg("comptroller", getAddressV) - ], - (world, from, { cToken, comptroller }) => setComptroller(world, from, cToken, comptroller.val), - { namePos: 1 } - ), - new Command<{ - cToken: CToken; - becomeImplementationData: StringV; - }>( - ` - #### BecomeImplementation - - * "CToken BecomeImplementation becomeImplementationData:" - * E.g. "CToken cDAI BecomeImplementation "0x01234anyByTeS56789"" - `, - 'BecomeImplementation', - [ - new Arg('cToken', getCTokenV), - new Arg('becomeImplementationData', getStringV) - ], - (world, from, { cToken, becomeImplementationData }) => - becomeImplementation( - world, - from, - cToken, - becomeImplementationData.val - ), - { namePos: 1 } - ), - new Command<{cToken: CToken;}>( - ` - #### ResignImplementation - - * "CToken ResignImplementation" - * E.g. "CToken cDAI ResignImplementation" - `, - 'ResignImplementation', - [new Arg('cToken', getCTokenV)], - (world, from, { cToken }) => - resignImplementation( - world, - from, - cToken - ), - { namePos: 1 } - ), - new Command<{ - cToken: CErc20Delegator; - implementation: AddressV; - allowResign: BoolV; - becomeImplementationData: StringV; - }>( - ` - #### SetImplementation - - * "CToken SetImplementation implementation:
allowResign: becomeImplementationData:" - * E.g. "CToken cDAI SetImplementation (CToken cDAIDelegate Address) True "0x01234anyByTeS56789" - `, - 'SetImplementation', - [ - new Arg('cToken', getCErc20DelegatorV), - new Arg('implementation', getAddressV), - new Arg('allowResign', getBoolV), - new Arg('becomeImplementationData', getStringV) - ], - (world, from, { cToken, implementation, allowResign, becomeImplementationData }) => - setImplementation( - world, - from, - cToken, - implementation.val, - allowResign.val, - becomeImplementationData.val - ), - { namePos: 1 } - ), - new Command<{ cToken: CToken }>(` - #### Donate - - * "CToken Donate" - Calls the donate (payable no-op) function - * E.g. "(Trx Value 5.0e18 (CToken cETH Donate))" - `, - "Donate", - [ - new Arg("cToken", getCTokenV) - ], - (world, from, { cToken }) => donate(world, from, cToken), - { namePos: 1 } - ), - new Command<{ cToken: CToken, variable: StringV, value: NumberV }>(` - #### Mock - - * "CToken Mock variable: value:" - Mocks a given value on cToken. Note: value must be a supported mock and this will only work on a "CTokenScenario" contract. - * E.g. "CToken cZRX Mock totalBorrows 5.0e18" - * E.g. "CToken cZRX Mock totalReserves 0.5e18" - `, - "Mock", - [ - new Arg("cToken", getCTokenV), - new Arg("variable", getStringV), - new Arg("value", getNumberV), - ], - (world, from, { cToken, variable, value }) => setCTokenMock(world, from, cToken, variable.val, value), - { namePos: 1 } - ), - new View<{ cToken: CToken }>(` - #### Minters - - * "CToken Minters" - Print address of all minters - `, - "Minters", - [ - new Arg("cToken", getCTokenV) - ], - (world, { cToken }) => printMinters(world, cToken), - { namePos: 1 } - ), - new View<{ cToken: CToken }>(` - #### Borrowers - - * "CToken Borrowers" - Print address of all borrowers - `, - "Borrowers", - [ - new Arg("cToken", getCTokenV) - ], - (world, { cToken }) => printBorrowers(world, cToken), - { namePos: 1 } - ), - new View<{ cToken: CToken }>(` - #### Liquidity - - * "CToken Liquidity" - Prints liquidity of all minters or borrowers - `, - "Liquidity", - [ - new Arg("cToken", getCTokenV) - ], - (world, { cToken }) => printLiquidity(world, cToken), - { namePos: 1 } - ), - new View<{ cToken: CToken, input: StringV }>(` - #### Decode - - * "Decode input:" - Prints information about a call to a cToken contract - `, - "Decode", - [ - new Arg("cToken", getCTokenV), - new Arg("input", getStringV) - - ], - (world, { cToken, input }) => decodeCall(world, cToken, input.val), - { namePos: 1 } - ) - ]; -} - -export async function processCTokenEvent(world: World, event: Event, from: string | null): Promise { - return await processCommandEvent("CToken", cTokenCommands(), world, event, from); -} diff --git a/scenario/src/Event/CompEvent.ts b/scenario/src/Event/CompEvent.ts deleted file mode 100644 index 1f420131f..000000000 --- a/scenario/src/Event/CompEvent.ts +++ /dev/null @@ -1,270 +0,0 @@ -import { Event } from '../Event'; -import { addAction, World, describeUser } from '../World'; -import { Comp, CompScenario } from '../Contract/Comp'; -import { buildComp } from '../Builder/CompBuilder'; -import { invoke } from '../Invokation'; -import { - getAddressV, - getEventV, - getNumberV, - getStringV, -} from '../CoreValue'; -import { - AddressV, - EventV, - NumberV, - StringV -} from '../Value'; -import { Arg, Command, processCommandEvent, View } from '../Command'; -import { getComp } from '../ContractLookup'; -import { NoErrorReporter } from '../ErrorReporter'; -import { verify } from '../Verify'; -import { encodedNumber } from '../Encoding'; - -async function genComp(world: World, from: string, params: Event): Promise { - let { world: nextWorld, comp, tokenData } = await buildComp(world, from, params); - world = nextWorld; - - world = addAction( - world, - `Deployed Comp (${comp.name}) to address ${comp._address}`, - tokenData.invokation - ); - - return world; -} - -async function verifyComp(world: World, comp: Comp, apiKey: string, modelName: string, contractName: string): Promise { - if (world.isLocalNetwork()) { - world.printer.printLine(`Politely declining to verify on local network: ${world.network}.`); - } else { - await verify(world, apiKey, modelName, contractName, comp._address); - } - - return world; -} - -async function approve(world: World, from: string, comp: Comp, address: string, amount: NumberV): Promise { - let invokation = await invoke(world, comp.methods.approve(address, amount.encode()), from, NoErrorReporter); - - world = addAction( - world, - `Approved Comp token for ${from} of ${amount.show()}`, - invokation - ); - - return world; -} - -async function transfer(world: World, from: string, comp: Comp, address: string, amount: NumberV): Promise { - let invokation = await invoke(world, comp.methods.transfer(address, amount.encode()), from, NoErrorReporter); - - world = addAction( - world, - `Transferred ${amount.show()} Comp tokens from ${from} to ${address}`, - invokation - ); - - return world; -} - -async function transferFrom(world: World, from: string, comp: Comp, owner: string, spender: string, amount: NumberV): Promise { - let invokation = await invoke(world, comp.methods.transferFrom(owner, spender, amount.encode()), from, NoErrorReporter); - - world = addAction( - world, - `"Transferred from" ${amount.show()} Comp tokens from ${owner} to ${spender}`, - invokation - ); - - return world; -} - -async function transferScenario(world: World, from: string, comp: CompScenario, addresses: string[], amount: NumberV): Promise { - let invokation = await invoke(world, comp.methods.transferScenario(addresses, amount.encode()), from, NoErrorReporter); - - world = addAction( - world, - `Transferred ${amount.show()} Comp tokens from ${from} to ${addresses}`, - invokation - ); - - return world; -} - -async function transferFromScenario(world: World, from: string, comp: CompScenario, addresses: string[], amount: NumberV): Promise { - let invokation = await invoke(world, comp.methods.transferFromScenario(addresses, amount.encode()), from, NoErrorReporter); - - world = addAction( - world, - `Transferred ${amount.show()} Comp tokens from ${addresses} to ${from}`, - invokation - ); - - return world; -} - -async function delegate(world: World, from: string, comp: Comp, account: string): Promise { - let invokation = await invoke(world, comp.methods.delegate(account), from, NoErrorReporter); - - world = addAction( - world, - `"Delegated from" ${from} to ${account}`, - invokation - ); - - return world; -} - -async function setBlockNumber( - world: World, - from: string, - comp: Comp, - blockNumber: NumberV -): Promise { - return addAction( - world, - `Set Comp blockNumber to ${blockNumber.show()}`, - await invoke(world, comp.methods.setBlockNumber(blockNumber.encode()), from) - ); -} - -export function compCommands() { - return [ - new Command<{ params: EventV }>(` - #### Deploy - - * "Deploy ...params" - Generates a new Comp token - * E.g. "Comp Deploy" - `, - "Deploy", - [ - new Arg("params", getEventV, { variadic: true }) - ], - (world, from, { params }) => genComp(world, from, params.val) - ), - - new View<{ comp: Comp, apiKey: StringV, contractName: StringV }>(` - #### Verify - - * " Verify apiKey: contractName:=Comp" - Verifies Comp token in Etherscan - * E.g. "Comp Verify "myApiKey" - `, - "Verify", - [ - new Arg("comp", getComp, { implicit: true }), - new Arg("apiKey", getStringV), - new Arg("contractName", getStringV, { default: new StringV("Comp") }) - ], - async (world, { comp, apiKey, contractName }) => { - return await verifyComp(world, comp, apiKey.val, comp.name, contractName.val) - } - ), - - new Command<{ comp: Comp, spender: AddressV, amount: NumberV }>(` - #### Approve - - * "Comp Approve spender:
" - Adds an allowance between user and address - * E.g. "Comp Approve Geoff 1.0e18" - `, - "Approve", - [ - new Arg("comp", getComp, { implicit: true }), - new Arg("spender", getAddressV), - new Arg("amount", getNumberV) - ], - (world, from, { comp, spender, amount }) => { - return approve(world, from, comp, spender.val, amount) - } - ), - - new Command<{ comp: Comp, recipient: AddressV, amount: NumberV }>(` - #### Transfer - - * "Comp Transfer recipient: " - Transfers a number of tokens via "transfer" as given user to recipient (this does not depend on allowance) - * E.g. "Comp Transfer Torrey 1.0e18" - `, - "Transfer", - [ - new Arg("comp", getComp, { implicit: true }), - new Arg("recipient", getAddressV), - new Arg("amount", getNumberV) - ], - (world, from, { comp, recipient, amount }) => transfer(world, from, comp, recipient.val, amount) - ), - - new Command<{ comp: Comp, owner: AddressV, spender: AddressV, amount: NumberV }>(` - #### TransferFrom - - * "Comp TransferFrom owner: spender: " - Transfers a number of tokens via "transfeFrom" to recipient (this depends on allowances) - * E.g. "Comp TransferFrom Geoff Torrey 1.0e18" - `, - "TransferFrom", - [ - new Arg("comp", getComp, { implicit: true }), - new Arg("owner", getAddressV), - new Arg("spender", getAddressV), - new Arg("amount", getNumberV) - ], - (world, from, { comp, owner, spender, amount }) => transferFrom(world, from, comp, owner.val, spender.val, amount) - ), - - new Command<{ comp: CompScenario, recipients: AddressV[], amount: NumberV }>(` - #### TransferScenario - - * "Comp TransferScenario recipients: " - Transfers a number of tokens via "transfer" to the given recipients (this does not depend on allowance) - * E.g. "Comp TransferScenario (Jared Torrey) 10" - `, - "TransferScenario", - [ - new Arg("comp", getComp, { implicit: true }), - new Arg("recipients", getAddressV, { mapped: true }), - new Arg("amount", getNumberV) - ], - (world, from, { comp, recipients, amount }) => transferScenario(world, from, comp, recipients.map(recipient => recipient.val), amount) - ), - - new Command<{ comp: CompScenario, froms: AddressV[], amount: NumberV }>(` - #### TransferFromScenario - - * "Comp TransferFromScenario froms: " - Transfers a number of tokens via "transferFrom" from the given users to msg.sender (this depends on allowance) - * E.g. "Comp TransferFromScenario (Jared Torrey) 10" - `, - "TransferFromScenario", - [ - new Arg("comp", getComp, { implicit: true }), - new Arg("froms", getAddressV, { mapped: true }), - new Arg("amount", getNumberV) - ], - (world, from, { comp, froms, amount }) => transferFromScenario(world, from, comp, froms.map(_from => _from.val), amount) - ), - - new Command<{ comp: Comp, account: AddressV }>(` - #### Delegate - - * "Comp Delegate account:
" - Delegates votes to a given account - * E.g. "Comp Delegate Torrey" - `, - "Delegate", - [ - new Arg("comp", getComp, { implicit: true }), - new Arg("account", getAddressV), - ], - (world, from, { comp, account }) => delegate(world, from, comp, account.val) - ), - new Command<{ comp: Comp, blockNumber: NumberV }>(` - #### SetBlockNumber - - * "SetBlockNumber " - Sets the blockTimestamp of the Comp Harness - * E.g. "Comp SetBlockNumber 500" - `, - 'SetBlockNumber', - [new Arg('comp', getComp, { implicit: true }), new Arg('blockNumber', getNumberV)], - (world, from, { comp, blockNumber }) => setBlockNumber(world, from, comp, blockNumber) - ) - ]; -} - -export async function processCompEvent(world: World, event: Event, from: string | null): Promise { - return await processCommandEvent("Comp", compCommands(), world, event, from); -} diff --git a/scenario/src/Event/ComptrollerEvent.ts b/scenario/src/Event/ComptrollerEvent.ts index 95f812569..cac6278fd 100644 --- a/scenario/src/Event/ComptrollerEvent.ts +++ b/scenario/src/Event/ComptrollerEvent.ts @@ -3,7 +3,7 @@ import {addAction, describeUser, World} from '../World'; import {decodeCall, getPastEvents} from '../Contract'; import {Comptroller} from '../Contract/Comptroller'; import {ComptrollerImpl} from '../Contract/ComptrollerImpl'; -import {CToken} from '../Contract/CToken'; +import {SLToken} from '../Contract/SLToken'; import {invoke} from '../Invokation'; import { getAddressV, @@ -27,7 +27,7 @@ import {buildComptrollerImpl} from '../Builder/ComptrollerImplBuilder'; import {ComptrollerErrorReporter} from '../ErrorReporter'; import {getComptroller, getComptrollerImpl} from '../ContractLookup'; import {getLiquidity} from '../Value/ComptrollerValue'; -import {getCTokenV} from '../Value/CTokenValue'; +import {getSLTokenV} from '../Value/SLTokenValue'; import {encodedNumber} from '../Encoding'; import {encodeABI, rawValues} from "../Utils"; @@ -88,30 +88,30 @@ async function setLiquidationIncentive(world: World, from: string, comptroller: return world; } -async function supportMarket(world: World, from: string, comptroller: Comptroller, cToken: CToken): Promise { +async function supportMarket(world: World, from: string, comptroller: Comptroller, slToken: SLToken): Promise { if (world.dryRun) { // Skip this specifically on dry runs since it's likely to crash due to a number of reasons - world.printer.printLine(`Dry run: Supporting market \`${cToken._address}\``); + world.printer.printLine(`Dry run: Supporting market \`${slToken._address}\``); return world; } - let invokation = await invoke(world, comptroller.methods._supportMarket(cToken._address), from, ComptrollerErrorReporter); + let invokation = await invoke(world, comptroller.methods._supportMarket(slToken._address), from, ComptrollerErrorReporter); world = addAction( world, - `Supported market ${cToken.name}`, + `Supported market ${slToken.name}`, invokation ); return world; } -async function unlistMarket(world: World, from: string, comptroller: Comptroller, cToken: CToken): Promise { - let invokation = await invoke(world, comptroller.methods.unlist(cToken._address), from, ComptrollerErrorReporter); +async function unlistMarket(world: World, from: string, comptroller: Comptroller, slToken: SLToken): Promise { + let invokation = await invoke(world, comptroller.methods.unlist(slToken._address), from, ComptrollerErrorReporter); world = addAction( world, - `Unlisted market ${cToken.name}`, + `Unlisted market ${slToken.name}`, invokation ); @@ -154,12 +154,12 @@ async function setPriceOracle(world: World, from: string, comptroller: Comptroll return world; } -async function setCollateralFactor(world: World, from: string, comptroller: Comptroller, cToken: CToken, collateralFactor: NumberV): Promise { - let invokation = await invoke(world, comptroller.methods._setCollateralFactor(cToken._address, collateralFactor.encode()), from, ComptrollerErrorReporter); +async function setCollateralFactor(world: World, from: string, comptroller: Comptroller, slToken: SLToken, collateralFactor: NumberV): Promise { + let invokation = await invoke(world, comptroller.methods._setCollateralFactor(slToken._address, collateralFactor.encode()), from, ComptrollerErrorReporter); world = addAction( world, - `Set collateral factor for ${cToken.name} to ${collateralFactor.show()}`, + `Set collateral factor for ${slToken.name} to ${collateralFactor.show()}`, invokation ); @@ -200,60 +200,60 @@ async function sendAny(world: World, from:string, comptroller: Comptroller, sign return world; } -async function addCompMarkets(world: World, from: string, comptroller: Comptroller, cTokens: CToken[]): Promise { - let invokation = await invoke(world, comptroller.methods._addCompMarkets(cTokens.map(c => c._address)), from, ComptrollerErrorReporter); +async function addSashimiMarkets(world: World, from: string, comptroller: Comptroller, slTokens: SLToken[]): Promise { + let invokation = await invoke(world, comptroller.methods._addSashimiMarkets(slTokens.map(c => c._address)), from, ComptrollerErrorReporter); world = addAction( world, - `Added COMP markets ${cTokens.map(c => c.name)}`, + `Added SASHIMI markets ${slTokens.map(c => c.name)}`, invokation ); return world; } -async function dropCompMarket(world: World, from: string, comptroller: Comptroller, cToken: CToken): Promise { - let invokation = await invoke(world, comptroller.methods._dropCompMarket(cToken._address), from, ComptrollerErrorReporter); +async function dropSashimiMarket(world: World, from: string, comptroller: Comptroller, slToken: SLToken): Promise { + let invokation = await invoke(world, comptroller.methods._dropSashimiMarket(slToken._address), from, ComptrollerErrorReporter); world = addAction( world, - `Drop COMP market ${cToken.name}`, + `Drop SASHIMI market ${slToken.name}`, invokation ); return world; } -async function refreshCompSpeeds(world: World, from: string, comptroller: Comptroller): Promise { - let invokation = await invoke(world, comptroller.methods.refreshCompSpeeds(), from, ComptrollerErrorReporter); +async function refreshSashimiSpeeds(world: World, from: string, comptroller: Comptroller): Promise { + let invokation = await invoke(world, comptroller.methods.refreshSashimiSpeeds(), from, ComptrollerErrorReporter); world = addAction( world, - `Refreshed COMP speeds`, + `Refreshed SASHIMI speeds`, invokation ); return world; } -async function claimComp(world: World, from: string, comptroller: Comptroller, holder: string): Promise { - let invokation = await invoke(world, comptroller.methods.claimComp(holder), from, ComptrollerErrorReporter); +async function claimSashimi(world: World, from: string, comptroller: Comptroller, holder: string): Promise { + let invokation = await invoke(world, comptroller.methods.claimSashimi(holder), from, ComptrollerErrorReporter); world = addAction( world, - `Comp claimed by ${holder}`, + `Sashimi claimed by ${holder}`, invokation ); return world; } -async function setCompRate(world: World, from: string, comptroller: Comptroller, rate: NumberV): Promise { - let invokation = await invoke(world, comptroller.methods._setCompRate(rate.encode()), from, ComptrollerErrorReporter); +async function setSashimiRate(world: World, from: string, comptroller: Comptroller, rate: NumberV): Promise { + let invokation = await invoke(world, comptroller.methods._setSashimiRate(rate.encode()), from, ComptrollerErrorReporter); world = addAction( world, - `Comp rate set to ${rate.show()}`, + `Sashimi rate set to ${rate.show()}`, invokation ); @@ -337,7 +337,7 @@ async function setGuardianPaused(world: World, from: string, comptroller: Comptr return world; } -async function setGuardianMarketPaused(world: World, from: string, comptroller: Comptroller, cToken: CToken, action: string, state: boolean): Promise { +async function setGuardianMarketPaused(world: World, from: string, comptroller: Comptroller, slToken: SLToken, action: string, state: boolean): Promise { let fun; switch(action){ case "Mint": @@ -347,7 +347,7 @@ async function setGuardianMarketPaused(world: World, from: string, comptroller: fun = comptroller.methods._setBorrowPaused break; } - let invokation = await invoke(world, fun(cToken._address, state), from, ComptrollerErrorReporter); + let invokation = await invoke(world, fun(slToken._address, state), from, ComptrollerErrorReporter); world = addAction( world, @@ -358,12 +358,12 @@ async function setGuardianMarketPaused(world: World, from: string, comptroller: return world; } -async function setMarketBorrowCaps(world: World, from: string, comptroller: Comptroller, cTokens: CToken[], borrowCaps: NumberV[]): Promise { - let invokation = await invoke(world, comptroller.methods._setMarketBorrowCaps(cTokens.map(c => c._address), borrowCaps.map(c => c.encode())), from, ComptrollerErrorReporter); +async function setMarketBorrowCaps(world: World, from: string, comptroller: Comptroller, slTokens: SLToken[], borrowCaps: NumberV[]): Promise { + let invokation = await invoke(world, comptroller.methods._setMarketBorrowCaps(slTokens.map(c => c._address), borrowCaps.map(c => c.encode())), from, ComptrollerErrorReporter); world = addAction( world, - `Borrow caps on ${cTokens} set to ${borrowCaps}`, + `Borrow caps on ${slTokens} set to ${borrowCaps}`, invokation ); @@ -397,7 +397,7 @@ export function comptrollerCommands() { new Command<{comptroller: Comptroller, action: StringV, isPaused: BoolV}>(` #### SetPaused - * "Comptroller SetPaused " - Pauses or unpaused given cToken function + * "Comptroller SetPaused " - Pauses or unpaused given slToken function * E.g. "Comptroller SetPaused "Mint" True" `, "SetPaused", @@ -408,57 +408,57 @@ export function comptrollerCommands() { ], (world, from, {comptroller, action, isPaused}) => setPaused(world, from, comptroller, action.val, isPaused.val) ), - new Command<{comptroller: Comptroller, cToken: CToken}>(` + new Command<{comptroller: Comptroller, slToken: SLToken}>(` #### SupportMarket - * "Comptroller SupportMarket " - Adds support in the Comptroller for the given cToken - * E.g. "Comptroller SupportMarket cZRX" + * "Comptroller SupportMarket " - Adds support in the Comptroller for the given slToken + * E.g. "Comptroller SupportMarket slZRX" `, "SupportMarket", [ new Arg("comptroller", getComptroller, {implicit: true}), - new Arg("cToken", getCTokenV) + new Arg("slToken", getSLTokenV) ], - (world, from, {comptroller, cToken}) => supportMarket(world, from, comptroller, cToken) + (world, from, {comptroller, slToken}) => supportMarket(world, from, comptroller, slToken) ), - new Command<{comptroller: Comptroller, cToken: CToken}>(` + new Command<{comptroller: Comptroller, slToken: SLToken}>(` #### UnList - * "Comptroller UnList " - Mock unlists a given market in tests - * E.g. "Comptroller UnList cZRX" + * "Comptroller UnList " - Mock unlists a given market in tests + * E.g. "Comptroller UnList slZRX" `, "UnList", [ new Arg("comptroller", getComptroller, {implicit: true}), - new Arg("cToken", getCTokenV) + new Arg("slToken", getSLTokenV) ], - (world, from, {comptroller, cToken}) => unlistMarket(world, from, comptroller, cToken) + (world, from, {comptroller, slToken}) => unlistMarket(world, from, comptroller, slToken) ), - new Command<{comptroller: Comptroller, cTokens: CToken[]}>(` + new Command<{comptroller: Comptroller, slTokens: SLToken[]}>(` #### EnterMarkets - * "Comptroller EnterMarkets ( ...)" - User enters the given markets - * E.g. "Comptroller EnterMarkets (cZRX cETH)" + * "Comptroller EnterMarkets ( ...)" - User enters the given markets + * E.g. "Comptroller EnterMarkets (slZRX slETH)" `, "EnterMarkets", [ new Arg("comptroller", getComptroller, {implicit: true}), - new Arg("cTokens", getCTokenV, {mapped: true}) + new Arg("slTokens", getSLTokenV, {mapped: true}) ], - (world, from, {comptroller, cTokens}) => enterMarkets(world, from, comptroller, cTokens.map((c) => c._address)) + (world, from, {comptroller, slTokens}) => enterMarkets(world, from, comptroller, slTokens.map((c) => c._address)) ), - new Command<{comptroller: Comptroller, cToken: CToken}>(` + new Command<{comptroller: Comptroller, slToken: SLToken}>(` #### ExitMarket - * "Comptroller ExitMarket " - User exits the given markets - * E.g. "Comptroller ExitMarket cZRX" + * "Comptroller ExitMarket " - User exits the given markets + * E.g. "Comptroller ExitMarket slZRX" `, "ExitMarket", [ new Arg("comptroller", getComptroller, {implicit: true}), - new Arg("cToken", getCTokenV) + new Arg("slToken", getSLTokenV) ], - (world, from, {comptroller, cToken}) => exitMarket(world, from, comptroller, cToken._address) + (world, from, {comptroller, slToken}) => exitMarket(world, from, comptroller, slToken._address) ), new Command<{comptroller: Comptroller, maxAssets: NumberV}>(` #### SetMaxAssets @@ -499,19 +499,19 @@ export function comptrollerCommands() { ], (world, from, {comptroller, priceOracle}) => setPriceOracle(world, from, comptroller, priceOracle.val) ), - new Command<{comptroller: Comptroller, cToken: CToken, collateralFactor: NumberV}>(` + new Command<{comptroller: Comptroller, slToken: SLToken, collateralFactor: NumberV}>(` #### SetCollateralFactor - * "Comptroller SetCollateralFactor " - Sets the collateral factor for given cToken to number - * E.g. "Comptroller SetCollateralFactor cZRX 0.1" + * "Comptroller SetCollateralFactor " - Sets the collateral factor for given slToken to number + * E.g. "Comptroller SetCollateralFactor slZRX 0.1" `, "SetCollateralFactor", [ new Arg("comptroller", getComptroller, {implicit: true}), - new Arg("cToken", getCTokenV), + new Arg("slToken", getSLTokenV), new Arg("collateralFactor", getExpNumberV) ], - (world, from, {comptroller, cToken, collateralFactor}) => setCollateralFactor(world, from, comptroller, cToken, collateralFactor) + (world, from, {comptroller, slToken, collateralFactor}) => setCollateralFactor(world, from, comptroller, slToken, collateralFactor) ), new Command<{comptroller: Comptroller, closeFactor: NumberV}>(` #### SetCloseFactor @@ -568,7 +568,7 @@ export function comptrollerCommands() { new Command<{comptroller: Comptroller, action: StringV, isPaused: BoolV}>(` #### SetGuardianPaused - * "Comptroller SetGuardianPaused " - Pauses or unpaused given cToken function + * "Comptroller SetGuardianPaused " - Pauses or unpaused given slToken function * E.g. "Comptroller SetGuardianPaused "Transfer" True" `, "SetGuardianPaused", @@ -580,26 +580,26 @@ export function comptrollerCommands() { (world, from, {comptroller, action, isPaused}) => setGuardianPaused(world, from, comptroller, action.val, isPaused.val) ), - new Command<{comptroller: Comptroller, cToken: CToken, action: StringV, isPaused: BoolV}>(` + new Command<{comptroller: Comptroller, slToken: SLToken, action: StringV, isPaused: BoolV}>(` #### SetGuardianMarketPaused - * "Comptroller SetGuardianMarketPaused " - Pauses or unpaused given cToken function - * E.g. "Comptroller SetGuardianMarketPaused cREP "Mint" True" + * "Comptroller SetGuardianMarketPaused " - Pauses or unpaused given slToken function + * E.g. "Comptroller SetGuardianMarketPaused slREP "Mint" True" `, "SetGuardianMarketPaused", [ new Arg("comptroller", getComptroller, {implicit: true}), - new Arg("cToken", getCTokenV), + new Arg("slToken", getSLTokenV), new Arg("action", getStringV), new Arg("isPaused", getBoolV) ], - (world, from, {comptroller, cToken, action, isPaused}) => setGuardianMarketPaused(world, from, comptroller, cToken, action.val, isPaused.val) + (world, from, {comptroller, slToken, action, isPaused}) => setGuardianMarketPaused(world, from, comptroller, slToken, action.val, isPaused.val) ), new Command<{comptroller: Comptroller, blocks: NumberV, _keyword: StringV}>(` #### FastForward - * "FastForward n: Blocks" - Moves the block number forward "n" blocks. Note: in "CTokenScenario" and "ComptrollerScenario" the current block number is mocked (starting at 100000). This is the only way for the protocol to see a higher block number (for accruing interest). + * "FastForward n: Blocks" - Moves the block number forward "n" blocks. Note: in "SLTokenScenario" and "ComptrollerScenario" the current block number is mocked (starting at 100000). This is the only way for the protocol to see a higher block number (for accruing interest). * E.g. "Comptroller FastForward 5 Blocks" - Move block number forward 5 blocks. `, "FastForward", @@ -638,7 +638,7 @@ export function comptrollerCommands() { new Command<{comptroller: Comptroller, signature: StringV, callArgs: StringV[]}>(` #### Send * Comptroller Send functionSignature: callArgs[] - Sends any transaction to comptroller - * E.g: Comptroller Send "setCompAddress(address)" (Address COMP) + * E.g: Comptroller Send "setSashimiAddress(address)" (Address SASHIMI) `, "Send", [ @@ -648,84 +648,84 @@ export function comptrollerCommands() { ], (world, from, {comptroller, signature, callArgs}) => sendAny(world, from, comptroller, signature.val, rawValues(callArgs)) ), - new Command<{comptroller: Comptroller, cTokens: CToken[]}>(` - #### AddCompMarkets + new Command<{comptroller: Comptroller, slTokens: SLToken[]}>(` + #### AddSashimiMarkets - * "Comptroller AddCompMarkets (
...)" - Makes a market COMP-enabled - * E.g. "Comptroller AddCompMarkets (cZRX cBAT) + * "Comptroller AddSashimiMarkets (
...)" - Makes a market SASHIMI-enabled + * E.g. "Comptroller AddSashimiMarkets (slZRX cBAT) `, - "AddCompMarkets", + "AddSashimiMarkets", [ new Arg("comptroller", getComptroller, {implicit: true}), - new Arg("cTokens", getCTokenV, {mapped: true}) + new Arg("slTokens", getSLTokenV, {mapped: true}) ], - (world, from, {comptroller, cTokens}) => addCompMarkets(world, from, comptroller, cTokens) + (world, from, {comptroller, slTokens}) => addSashimiMarkets(world, from, comptroller, slTokens) ), - new Command<{comptroller: Comptroller, cToken: CToken}>(` - #### DropCompMarket + new Command<{comptroller: Comptroller, slToken: SLToken}>(` + #### DropSashimiMarket - * "Comptroller DropCompMarket
" - Makes a market COMP - * E.g. "Comptroller DropCompMarket cZRX + * "Comptroller DropSashimiMarket
" - Makes a market SASHIMI + * E.g. "Comptroller DropSashimiMarket slZRX `, - "DropCompMarket", + "DropSashimiMarket", [ new Arg("comptroller", getComptroller, {implicit: true}), - new Arg("cToken", getCTokenV) + new Arg("slToken", getSLTokenV) ], - (world, from, {comptroller, cToken}) => dropCompMarket(world, from, comptroller, cToken) + (world, from, {comptroller, slToken}) => dropSashimiMarket(world, from, comptroller, slToken) ), new Command<{comptroller: Comptroller}>(` - #### RefreshCompSpeeds + #### RefreshSashimiSpeeds - * "Comptroller RefreshCompSpeeds" - Recalculates all the COMP market speeds - * E.g. "Comptroller RefreshCompSpeeds + * "Comptroller RefreshSashimiSpeeds" - Recalculates all the SASHIMI market speeds + * E.g. "Comptroller RefreshSashimiSpeeds `, - "RefreshCompSpeeds", + "RefreshSashimiSpeeds", [ new Arg("comptroller", getComptroller, {implicit: true}) ], - (world, from, {comptroller}) => refreshCompSpeeds(world, from, comptroller) + (world, from, {comptroller}) => refreshSashimiSpeeds(world, from, comptroller) ), new Command<{comptroller: Comptroller, holder: AddressV}>(` - #### ClaimComp + #### ClaimSashimi - * "Comptroller ClaimComp " - Claims comp - * E.g. "Comptroller ClaimComp Geoff + * "Comptroller ClaimSashimi " - Claims sashimi + * E.g. "Comptroller ClaimSashimi Geoff `, - "ClaimComp", + "ClaimSashimi", [ new Arg("comptroller", getComptroller, {implicit: true}), new Arg("holder", getAddressV) ], - (world, from, {comptroller, holder}) => claimComp(world, from, comptroller, holder.val) + (world, from, {comptroller, holder}) => claimSashimi(world, from, comptroller, holder.val) ), new Command<{comptroller: Comptroller, rate: NumberV}>(` - #### SetCompRate + #### SetSashimiRate - * "Comptroller SetCompRate " - Sets COMP rate - * E.g. "Comptroller SetCompRate 1e18 + * "Comptroller SetSashimiRate " - Sets SASHIMI rate + * E.g. "Comptroller SetSashimiRate 1e18 `, - "SetCompRate", + "SetSashimiRate", [ new Arg("comptroller", getComptroller, {implicit: true}), new Arg("rate", getNumberV) ], - (world, from, {comptroller, rate}) => setCompRate(world, from, comptroller, rate) + (world, from, {comptroller, rate}) => setSashimiRate(world, from, comptroller, rate) ), - new Command<{comptroller: Comptroller, cTokens: CToken[], borrowCaps: NumberV[]}>(` + new Command<{comptroller: Comptroller, slTokens: SLToken[], borrowCaps: NumberV[]}>(` #### SetMarketBorrowCaps - * "Comptroller SetMarketBorrowCaps ( ...) ( ...)" - Sets Market Borrow Caps - * E.g "Comptroller SetMarketBorrowCaps (cZRX cUSDC) (10000.0e18, 1000.0e6) + * "Comptroller SetMarketBorrowCaps ( ...) ( ...)" - Sets Market Borrow Caps + * E.g "Comptroller SetMarketBorrowCaps (slZRX slUSDC) (10000.0e18, 1000.0e6) `, "SetMarketBorrowCaps", [ new Arg("comptroller", getComptroller, {implicit: true}), - new Arg("cTokens", getCTokenV, {mapped: true}), + new Arg("slTokens", getSLTokenV, {mapped: true}), new Arg("borrowCaps", getNumberV, {mapped: true}) ], - (world, from, {comptroller,cTokens,borrowCaps}) => setMarketBorrowCaps(world, from, comptroller, cTokens, borrowCaps) + (world, from, {comptroller,slTokens,borrowCaps}) => setMarketBorrowCaps(world, from, comptroller, slTokens, borrowCaps) ), new Command<{comptroller: Comptroller, newBorrowCapGuardian: AddressV}>(` #### SetBorrowCapGuardian diff --git a/scenario/src/Event/ComptrollerImplEvent.ts b/scenario/src/Event/ComptrollerImplEvent.ts index 49e2daf5e..c7174bd8a 100644 --- a/scenario/src/Event/ComptrollerImplEvent.ts +++ b/scenario/src/Event/ComptrollerImplEvent.ts @@ -129,13 +129,13 @@ async function becomeG3( from: string, comptrollerImpl: ComptrollerImpl, unitroller: Unitroller, - compRate: encodedNumber, - compMarkets: string[], + sashimiRate: encodedNumber, + sashimiMarkets: string[], otherMarkets: string[] ): Promise { let invokation = await invoke( world, - comptrollerImpl.methods._become(unitroller._address, compRate, compMarkets, otherMarkets), + comptrollerImpl.methods._become(unitroller._address, sashimiRate, sashimiMarkets, otherMarkets), from, ComptrollerErrorReporter ); @@ -274,26 +274,26 @@ export function comptrollerImplCommands() { new Command<{ unitroller: Unitroller; comptrollerImpl: ComptrollerImpl; - compRate: NumberV; - compMarkets: ArrayV; + sashimiRate: NumberV; + sashimiMarkets: ArrayV; otherMarkets: ArrayV; }>( ` #### BecomeG3 - * "ComptrollerImpl BecomeG3 " - Become the comptroller, if possible. - * E.g. "ComptrollerImpl MyImpl BecomeG3 0.1e18 [cDAI, cETH, cUSDC] + * "ComptrollerImpl BecomeG3 " - Become the comptroller, if possible. + * E.g. "ComptrollerImpl MyImpl BecomeG3 0.1e18 [slDAI, slETH, slUSDC] `, 'BecomeG3', [ new Arg('unitroller', getUnitroller, { implicit: true }), new Arg('comptrollerImpl', getComptrollerImpl), - new Arg('compRate', getNumberV, { default: new NumberV(1e18) }), - new Arg('compMarkets', getArrayV(getAddressV), {default: new ArrayV([]) }), + new Arg('sashimiRate', getNumberV, { default: new NumberV(1e18) }), + new Arg('sashimiMarkets', getArrayV(getAddressV), {default: new ArrayV([]) }), new Arg('otherMarkets', getArrayV(getAddressV), { default: new ArrayV([]) }) ], - (world, from, { unitroller, comptrollerImpl, compRate, compMarkets, otherMarkets }) => { - return becomeG3(world, from, comptrollerImpl, unitroller, compRate.encode(), compMarkets.val.map(a => a.val), otherMarkets.val.map(a => a.val)) + (world, from, { unitroller, comptrollerImpl, sashimiRate, sashimiMarkets, otherMarkets }) => { + return becomeG3(world, from, comptrollerImpl, unitroller, sashimiRate.encode(), sashimiMarkets.val.map(a => a.val), otherMarkets.val.map(a => a.val)) }, { namePos: 1 } ), @@ -305,8 +305,8 @@ export function comptrollerImplCommands() { ` #### Become - * "ComptrollerImpl Become " - Become the comptroller, if possible. - * E.g. "ComptrollerImpl MyImpl Become 0.1e18 [cDAI, cETH, cUSDC] + * "ComptrollerImpl Become " - Become the comptroller, if possible. + * E.g. "ComptrollerImpl MyImpl Become 0.1e18 [slDAI, slETH, slUSDC] `, 'Become', [ diff --git a/scenario/src/Event/Erc20Event.ts b/scenario/src/Event/Erc20Event.ts index c3ccb99d5..e5f069f45 100644 --- a/scenario/src/Event/Erc20Event.ts +++ b/scenario/src/Event/Erc20Event.ts @@ -19,7 +19,7 @@ import { import {getErc20V} from '../Value/Erc20Value'; import {verify} from '../Verify'; import {Arg, Command, View, processCommandEvent} from '../Command'; -import {CTokenErrorReporter} from '../ErrorReporter'; +import {SLTokenErrorReporter} from '../ErrorReporter'; import {encodedNumber} from '../Encoding'; import {getErc20Data} from '../ContractLookup'; @@ -47,7 +47,7 @@ async function verifyErc20(world: World, erc20: Erc20, name: string, contract: s } async function approve(world: World, from: string, erc20: Erc20, address: string, amount: NumberV): Promise { - let invokation = await invoke(world, erc20.methods.approve(address, amount.encode()), from, CTokenErrorReporter); + let invokation = await invoke(world, erc20.methods.approve(address, amount.encode()), from, SLTokenErrorReporter); world = addAction( world, @@ -59,7 +59,7 @@ async function approve(world: World, from: string, erc20: Erc20, address: string } async function faucet(world: World, from: string, erc20: Erc20, address: string, amount: NumberV): Promise { - let invokation = await invoke(world, erc20.methods.allocateTo(address, amount.encode()), from, CTokenErrorReporter); + let invokation = await invoke(world, erc20.methods.allocateTo(address, amount.encode()), from, SLTokenErrorReporter); world = addAction( world, @@ -71,7 +71,7 @@ async function faucet(world: World, from: string, erc20: Erc20, address: string, } async function transfer(world: World, from: string, erc20: Erc20, address: string, amount: NumberV): Promise { - let invokation = await invoke(world, erc20.methods.transfer(address, amount.encode()), from, CTokenErrorReporter); + let invokation = await invoke(world, erc20.methods.transfer(address, amount.encode()), from, SLTokenErrorReporter); world = addAction( world, @@ -83,7 +83,7 @@ async function transfer(world: World, from: string, erc20: Erc20, address: strin } async function transferFrom(world: World, from: string, erc20: Erc20, owner: string, spender: string, amount: NumberV): Promise { - let invokation = await invoke(world, erc20.methods.transferFrom(owner, spender, amount.encode()), from, CTokenErrorReporter); + let invokation = await invoke(world, erc20.methods.transferFrom(owner, spender, amount.encode()), from, SLTokenErrorReporter); world = addAction( world, @@ -95,7 +95,7 @@ async function transferFrom(world: World, from: string, erc20: Erc20, owner: str } async function setFail(world: World, from: string, erc20: Erc20, fail: boolean): Promise { - let invokation = await invoke(world, erc20.methods.setFail(fail), from, CTokenErrorReporter); + let invokation = await invoke(world, erc20.methods.setFail(fail), from, SLTokenErrorReporter); world = addAction( world, diff --git a/scenario/src/Event/ExpectationEvent.ts b/scenario/src/Event/ExpectationEvent.ts index 82429d348..22efbbc45 100644 --- a/scenario/src/Event/ExpectationEvent.ts +++ b/scenario/src/Event/ExpectationEvent.ts @@ -38,7 +38,7 @@ export function expectationCommands() { #### Changes * "Changes amount: tolerance:" - Expects that given value changes by amount - * E.g ."Expect Changes (CToken cZRX UnderlyingBalance Geoff) +10e18" + * E.g ."Expect Changes (SLToken slZRX UnderlyingBalance Geoff) +10e18" `, "Changes", [ @@ -53,7 +53,7 @@ export function expectationCommands() { #### Remains * "Expect Remains " - Ensures that the given condition starts at and remains a given value - * E.g ."Expect Remains (CToken cZRX UnderlyingBalance Geoff) (Exactly 0)" + * E.g ."Expect Remains (SLToken slZRX UnderlyingBalance Geoff) (Exactly 0)" `, "Remains", [ diff --git a/scenario/src/Event/GovGuardianEvent.ts b/scenario/src/Event/GovGuardianEvent.ts deleted file mode 100644 index 1dcf43bbe..000000000 --- a/scenario/src/Event/GovGuardianEvent.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { Event } from '../Event'; -import { addAction, describeUser, World } from '../World'; -import { Governor } from '../Contract/Governor'; -import { invoke } from '../Invokation'; -import { - getAddressV, - getEventV, - getNumberV, - getStringV, - getCoreValue -} from '../CoreValue'; -import { - AddressV, - EventV, - NumberV, - StringV -} from '../Value'; -import { Arg, Command, processCommandEvent, View } from '../Command'; - -export function guardianCommands(governor: Governor) { - return [ - new Command<{ newPendingAdmin: AddressV, eta: NumberV }>( - ` - #### QueueSetTimelockPendingAdmin - - * "Governor QueueSetTimelockPendingAdmin newPendingAdmin:
eta:" - Queues in the timelock a function to set a new pending admin - * E.g. "Governor GovernorScenario Guardian QueueSetTimelockPendingAdmin Geoff 604900" - `, - 'QueueSetTimelockPendingAdmin', - [ - new Arg('newPendingAdmin', getAddressV), - new Arg('eta', getNumberV) - ], - async (world, from, { newPendingAdmin, eta }) => { - const invokation = await invoke(world, governor.methods.__queueSetTimelockPendingAdmin(newPendingAdmin.val, eta.encode()), from); - - return addAction( - world, - `Gov Guardian has queued in the timelock a new pending admin command for ${describeUser(world, newPendingAdmin.val)}`, - invokation - ) - } - ), - - new Command<{ newPendingAdmin: AddressV, eta: NumberV }>( - ` - #### ExecuteSetTimelockPendingAdmin - - * "Governor ExecuteSetTimelockPendingAdmin newPendingAdmin:
eta:" - Executes on the timelock the function to set a new pending admin - * E.g. "Governor GovernorScenario Guardian ExecuteSetTimelockPendingAdmin Geoff 604900" - `, - 'ExecuteSetTimelockPendingAdmin', - [ - new Arg('newPendingAdmin', getAddressV), - new Arg('eta', getNumberV) - ], - async (world, from, { newPendingAdmin, eta }) => { - const invokation = await invoke(world, governor.methods.__executeSetTimelockPendingAdmin(newPendingAdmin.val, eta.encode()), from); - - return addAction( - world, - `Gov Guardian has executed via the timelock a new pending admin to ${describeUser(world, newPendingAdmin.val)}`, - invokation - ) - } - ), - - new Command<{}>( - ` - #### AcceptAdmin - - * "Governor Guardian AcceptAdmin" - Calls \`acceptAdmin\` on the Timelock - * E.g. "Governor GovernorScenario Guardian AcceptAdmin" - `, - 'AcceptAdmin', - [], - async (world, from, { }) => { - const invokation = await invoke(world, governor.methods.__acceptAdmin(), from); - - return addAction( - world, - `Gov Guardian has accepted admin`, - invokation - ) - } - ), - - new Command<{}>( - ` - #### Abdicate - - * "Governor Guardian Abdicate" - Abdicates gov guardian role - * E.g. "Governor GovernorScenario Guardian Abdicate" - `, - 'Abdicate', - [], - async (world, from, { }) => { - const invokation = await invoke(world, governor.methods.__abdicate(), from); - - return addAction( - world, - `Gov Guardian has abdicated`, - invokation - ) - } - ) - ]; -} - -export async function processGuardianEvent(world: World, governor: Governor, event: Event, from: string | null): Promise { - return await processCommandEvent('Guardian', guardianCommands(governor), world, event, from); -} diff --git a/scenario/src/Event/GovernorEvent.ts b/scenario/src/Event/GovernorEvent.ts deleted file mode 100644 index 39c5263f4..000000000 --- a/scenario/src/Event/GovernorEvent.ts +++ /dev/null @@ -1,209 +0,0 @@ -import { Event } from '../Event'; -import { addAction, World } from '../World'; -import { Governor } from '../Contract/Governor'; -import { buildGovernor } from '../Builder/GovernorBuilder'; -import { invoke } from '../Invokation'; -import { - getAddressV, - getArrayV, - getEventV, - getNumberV, - getStringV, - getCoreValue, -} from '../CoreValue'; -import { - AddressV, - ArrayV, - EventV, - NumberV, - StringV -} from '../Value'; -import { Arg, Command, processCommandEvent, View } from '../Command'; -import { getGovernorData } from '../ContractLookup'; -import { verify } from '../Verify'; -import { encodedNumber } from '../Encoding'; -import { processProposalEvent } from './ProposalEvent'; -import { processGuardianEvent } from './GovGuardianEvent'; -import { encodeParameters, rawValues } from '../Utils'; -import { getGovernorV } from '../Value/GovernorValue'; - -async function genGovernor(world: World, from: string, params: Event): Promise { - let { world: nextWorld, governor, govData } = await buildGovernor(world, from, params); - world = nextWorld; - - return addAction( - world, - `Deployed Governor ${govData.contract} to address ${governor._address}`, - govData.invokation - ); -} - -async function verifyGovernor(world: World, governor: Governor, apiKey: string, modelName: string, contractName: string): Promise { - if (world.isLocalNetwork()) { - world.printer.printLine(`Politely declining to verify on local network: ${world.network}.`); - } else { - await verify(world, apiKey, modelName, contractName, governor._address); - } - - return world; -} - -async function propose(world: World, from: string, governor: Governor, targets: string[], values: encodedNumber[], signatures: string[], calldatas: string[], description: string): Promise { - const invokation = await invoke(world, governor.methods.propose(targets, values, signatures, calldatas, description), from); - return addAction( - world, - `Created new proposal "${description}" with id=${invokation.value} in Governor`, - invokation - ); -} - -async function setBlockNumber( - world: World, - from: string, - governor: Governor, - blockNumber: NumberV -): Promise { - return addAction( - world, - `Set Governor blockNumber to ${blockNumber.show()}`, - await invoke(world, governor.methods.setBlockNumber(blockNumber.encode()), from) - ); -} - -async function setBlockTimestamp( - world: World, - from: string, - governor: Governor, - blockTimestamp: NumberV -): Promise { - return addAction( - world, - `Set Governor blockTimestamp to ${blockTimestamp.show()}`, - await invoke(world, governor.methods.setBlockTimestamp(blockTimestamp.encode()), from) - ); -} - -export function governorCommands() { - return [ - new Command<{ params: EventV }>(` - #### Deploy - - * "Deploy ...params" - Generates a new Governor - * E.g. "Governor Deploy Alpha" - `, - "Deploy", - [ - new Arg("params", getEventV, { variadic: true }) - ], - (world, from, { params }) => genGovernor(world, from, params.val) - ), - - new View<{ governorArg: StringV, apiKey: StringV }>(` - #### Verify - - * " Verify apiKey:" - Verifies Governor in Etherscan - * E.g. "Governor Verify "myApiKey" - `, - "Verify", - [ - new Arg("governorArg", getStringV), - new Arg("apiKey", getStringV) - ], - async (world, { governorArg, apiKey }) => { - let [governor, name, data] = await getGovernorData(world, governorArg.val); - - return await verifyGovernor(world, governor, apiKey.val, name, data.get('contract')!) - }, - { namePos: 1 } - ), - - new Command<{ governor: Governor, description: StringV, targets: ArrayV, values: ArrayV, signatures: ArrayV, callDataArgs: ArrayV> }>(` - #### Propose - - * "Governor Propose description: targets: signatures: callDataArgs:" - Creates a new proposal in Governor - * E.g. "Governor GovernorScenario Propose "New Interest Rate" [(Address cDAI)] [0] [("_setInterestRateModel(address)")] [[(Address MyInterestRateModel)]] - `, - "Propose", - [ - new Arg("governor", getGovernorV), - new Arg("description", getStringV), - new Arg("targets", getArrayV(getAddressV)), - new Arg("values", getArrayV(getNumberV)), - new Arg("signatures", getArrayV(getStringV)), - new Arg("callDataArgs", getArrayV(getArrayV(getCoreValue))), - ], - async (world, from, { governor, description, targets, values, signatures, callDataArgs }) => { - const targetsU = targets.val.map(a => a.val); - const valuesU = values.val.map(a => a.encode()); - const signaturesU = signatures.val.map(a => a.val); - const callDatasU: string[] = signatures.val.reduce((acc, cur, idx) => { - const args = rawValues(callDataArgs.val[idx]); - acc.push(encodeParameters(world, cur.val, args)); - return acc; - }, []); - return await propose(world, from, governor, targetsU, valuesU, signaturesU, callDatasU, description.val); - }, - { namePos: 1 } - ), - new Command<{ governor: Governor, params: EventV }>(` - #### Proposal - - * "Governor Proposal <...proposalEvent>" - Returns information about a proposal - * E.g. "Governor GovernorScenario Proposal LastProposal Vote For" - `, - "Proposal", - [ - new Arg('governor', getGovernorV), - new Arg("params", getEventV, { variadic: true }) - ], - (world, from, { governor, params }) => processProposalEvent(world, governor, params.val, from), - { namePos: 1 } - ), - new Command<{ governor: Governor, params: EventV }>(` - #### Guardian - - * "Governor Guardian <...guardianEvent>" - Returns information about a guardian - * E.g. "Governor GovernorScenario Guardian Abdicate" - `, - "Guardian", - [ - new Arg('governor', getGovernorV), - new Arg("params", getEventV, { variadic: true }) - ], - (world, from, { governor, params }) => processGuardianEvent(world, governor, params.val, from), - { namePos: 1 } - ), - new Command<{ governor: Governor, blockNumber: NumberV }>(` - #### SetBlockNumber - - * "Governor SetBlockNumber " - Sets the blockNumber of the Governance Harness - * E.g. "Governor SetBlockNumber 500" - `, - 'SetBlockNumber', - [ - new Arg('governor', getGovernorV), - new Arg('blockNumber', getNumberV) - ], - (world, from, { governor, blockNumber }) => setBlockNumber(world, from, governor, blockNumber), - { namePos: 1 } - ), - new Command<{ governor: Governor, blockTimestamp: NumberV }>(` - #### SetBlockTimestamp - - * "Governor SetBlockNumber " - Sets the blockTimestamp of the Governance Harness - * E.g. "Governor GovernorScenario SetBlockTimestamp 500" - `, - 'SetBlockTimestamp', - [ - new Arg('governor', getGovernorV), - new Arg('blockTimestamp', getNumberV) - ], - (world, from, { governor, blockTimestamp }) => setBlockTimestamp(world, from, governor, blockTimestamp), - { namePos: 1 } - ) - ]; -} - -export async function processGovernorEvent(world: World, event: Event, from: string | null): Promise { - return await processCommandEvent("Governor", governorCommands(), world, event, from); -} diff --git a/scenario/src/Event/InvariantEvent.ts b/scenario/src/Event/InvariantEvent.ts index 9a94b9c8c..b2716742a 100644 --- a/scenario/src/Event/InvariantEvent.ts +++ b/scenario/src/Event/InvariantEvent.ts @@ -44,7 +44,7 @@ export function invariantCommands() { #### Static * "Static " - Ensures that the given condition retains a consistent value - * E.g ."Invariant Static (CToken cZRX UnderlyingBalance Geoff)" + * E.g ."Invariant Static (SLToken slZRX UnderlyingBalance Geoff)" `, "Static", [ @@ -56,7 +56,7 @@ export function invariantCommands() { #### Remains * "Invariant Remains " - Ensures that the given condition starts at and remains a given value - * E.g ."Invariant Remains (CToken cZRX UnderlyingBalance Geoff) (Exactly 0)" + * E.g ."Invariant Remains (SLToken slZRX UnderlyingBalance Geoff) (Exactly 0)" `, "Remains", [ diff --git a/scenario/src/Event/PriceOracleEvent.ts b/scenario/src/Event/PriceOracleEvent.ts index fadbd9dca..270383986 100644 --- a/scenario/src/Event/PriceOracleEvent.ts +++ b/scenario/src/Event/PriceOracleEvent.ts @@ -39,11 +39,11 @@ async function setPriceOracleFn(world: World, params: Event): Promise { return nextWorld; } -async function setPrice(world: World, from: string, priceOracle: PriceOracle, cToken: string, amount: NumberV): Promise { +async function setPrice(world: World, from: string, priceOracle: PriceOracle, slToken: string, amount: NumberV): Promise { return addAction( world, - `Set price oracle price for ${cToken} to ${amount.show()}`, - await invoke(world, priceOracle.methods.setUnderlyingPrice(cToken, amount.encode()), from) + `Set price oracle price for ${slToken} to ${amount.show()}`, + await invoke(world, priceOracle.methods.setUnderlyingPrice(slToken, amount.encode()), from) ); } @@ -94,25 +94,25 @@ export function priceOracleCommands() { (world, from, {params}) => setPriceOracleFn(world, params.val) ), - new Command<{priceOracle: PriceOracle, cToken: AddressV, amount: NumberV}>(` + new Command<{priceOracle: PriceOracle, slToken: AddressV, amount: NumberV}>(` #### SetPrice - * "SetPrice " - Sets the per-ether price for the given cToken - * E.g. "PriceOracle SetPrice cZRX 1.0" + * "SetPrice " - Sets the per-ether price for the given slToken + * E.g. "PriceOracle SetPrice slZRX 1.0" `, "SetPrice", [ new Arg("priceOracle", getPriceOracle, {implicit: true}), - new Arg("cToken", getAddressV), + new Arg("slToken", getAddressV), new Arg("amount", getExpNumberV) ], - (world, from, {priceOracle, cToken, amount}) => setPrice(world, from, priceOracle, cToken.val, amount) + (world, from, {priceOracle, slToken, amount}) => setPrice(world, from, priceOracle, slToken.val, amount) ), new Command<{priceOracle: PriceOracle, address: AddressV, amount: NumberV}>(` #### SetDirectPrice - * "SetDirectPrice
" - Sets the per-ether price for the given cToken + * "SetDirectPrice
" - Sets the per-ether price for the given slToken * E.g. "PriceOracle SetDirectPrice (Address Zero) 1.0" `, "SetDirectPrice", diff --git a/scenario/src/Event/PriceOracleProxyEvent.ts b/scenario/src/Event/PriceOracleProxyEvent.ts index a75af5b8b..f602e7b80 100644 --- a/scenario/src/Event/PriceOracleProxyEvent.ts +++ b/scenario/src/Event/PriceOracleProxyEvent.ts @@ -59,7 +59,7 @@ export function priceOracleProxyCommands() { #### Deploy * "Deploy ...params" - Generates a new price oracle proxy - * E.g. "PriceOracleProxy Deploy (Unitroller Address) (PriceOracle Address) (cEther Address)" + * E.g. "PriceOracleProxy Deploy (Unitroller Address) (PriceOracle Address) (slEther Address)" `, "Deploy", [ diff --git a/scenario/src/Event/ProposalEvent.ts b/scenario/src/Event/ProposalEvent.ts deleted file mode 100644 index 63daaa418..000000000 --- a/scenario/src/Event/ProposalEvent.ts +++ /dev/null @@ -1,127 +0,0 @@ -import { Event } from '../Event'; -import { addAction, describeUser, World } from '../World'; -import { Governor } from '../Contract/Governor'; -import { invoke } from '../Invokation'; -import { - getEventV, -} from '../CoreValue'; -import { - EventV, -} from '../Value'; -import { Arg, Command, processCommandEvent } from '../Command'; -import { getProposalId } from '../Value/ProposalValue'; - -function getSupport(support: Event): boolean { - if (typeof support === 'string') { - if (support === 'For' || support === 'Against') { - return support === 'For'; - } - } - - throw new Error(`Unknown support flag \`${support}\`, expected "For" or "Against"`); -} - -async function describeProposal(world: World, governor: Governor, proposalId: number): Promise { - // const proposal = await governor.methods.proposals(proposalId).call(); - return `proposal ${proposalId.toString()}`; // TODO: Cleanup -} - -export function proposalCommands(governor: Governor) { - return [ - new Command<{ proposalIdent: EventV, support: EventV }>( - ` - #### Vote - - * "Governor Vote " - Votes for or against a given proposal - * E.g. "Governor GovernorScenario Proposal LastProposal Vote For" - `, - 'Vote', - [ - new Arg("proposalIdent", getEventV), - new Arg("support", getEventV), - ], - async (world, from, { proposalIdent, support }) => { - const proposalId = await getProposalId(world, governor, proposalIdent.val); - const invokation = await invoke(world, governor.methods.castVote(proposalId, getSupport(support.val)), from); - - return addAction( - world, - `Cast ${support.val.toString()} vote from ${describeUser(world, from)} for proposal ${proposalId}`, - invokation - ) - }, - { namePos: 1 } - ), - - new Command<{ proposalIdent: EventV }>( - ` - #### Queue - * "Governor Queue" - Queues given proposal - * E.g. "Governor GovernorScenario Proposal LastProposal Queue" - `, - 'Queue', - [ - new Arg("proposalIdent", getEventV) - ], - async (world, from, { proposalIdent }) => { - const proposalId = await getProposalId(world, governor, proposalIdent.val); - const invokation = await invoke(world, governor.methods.queue(proposalId), from); - - return addAction( - world, - `Queue proposal ${await describeProposal(world, governor, proposalId)} from ${describeUser(world, from)}`, - invokation - ) - }, - { namePos: 1 } - ), - new Command<{ proposalIdent: EventV }>( - ` - #### Execute - * "Governor Execute" - Executes given proposal - * E.g. "Governor GovernorScenario Proposal LastProposal Execute" - `, - 'Execute', - [ - new Arg("proposalIdent", getEventV) - ], - async (world, from, { proposalIdent }) => { - const proposalId = await getProposalId(world, governor, proposalIdent.val); - const invokation = await invoke(world, governor.methods.execute(proposalId), from); - - return addAction( - world, - `Execute proposal ${await describeProposal(world, governor, proposalId)} from ${describeUser(world, from)}`, - invokation - ) - }, - { namePos: 1 } - ), - new Command<{ proposalIdent: EventV }>( - ` - #### Cancel - * "Cancel" - cancels given proposal - * E.g. "Governor Proposal LastProposal Cancel" - `, - 'Cancel', - [ - new Arg("proposalIdent", getEventV) - ], - async (world, from, { proposalIdent }) => { - const proposalId = await getProposalId(world, governor, proposalIdent.val); - const invokation = await invoke(world, governor.methods.cancel(proposalId), from); - - return addAction( - world, - `Cancel proposal ${await describeProposal(world, governor, proposalId)} from ${describeUser(world, from)}`, - invokation - ) - }, - { namePos: 1 } - ), - ]; -} - -export async function processProposalEvent(world: World, governor: Governor, event: Event, from: string | null): Promise { - return await processCommandEvent('Proposal', proposalCommands(governor), world, event, from); -} diff --git a/scenario/src/Event/SLTokenDelegateEvent.ts b/scenario/src/Event/SLTokenDelegateEvent.ts new file mode 100644 index 000000000..91d3f5571 --- /dev/null +++ b/scenario/src/Event/SLTokenDelegateEvent.ts @@ -0,0 +1,86 @@ +import { Event } from '../Event'; +import { addAction, describeUser, World } from '../World'; +import { decodeCall, getPastEvents } from '../Contract'; +import { SLToken, SLTokenScenario } from '../Contract/SLToken'; +import { SLErc20Delegate } from '../Contract/SLErc20Delegate' +import { invoke, Sendable } from '../Invokation'; +import { + getAddressV, + getEventV, + getExpNumberV, + getNumberV, + getStringV, + getBoolV +} from '../CoreValue'; +import { + AddressV, + BoolV, + EventV, + NothingV, + NumberV, + StringV +} from '../Value'; +import { Arg, Command, View, processCommandEvent } from '../Command'; +import { getSLTokenDelegateData } from '../ContractLookup'; +import { buildSLTokenDelegate } from '../Builder/SLTokenDelegateBuilder'; +import { verify } from '../Verify'; + +async function genSLTokenDelegate(world: World, from: string, event: Event): Promise { + let { world: nextWorld, slTokenDelegate, delegateData } = await buildSLTokenDelegate(world, from, event); + world = nextWorld; + + world = addAction( + world, + `Added slToken ${delegateData.name} (${delegateData.contract}) at address ${slTokenDelegate._address}`, + delegateData.invokation + ); + + return world; +} + +async function verifySLTokenDelegate(world: World, slTokenDelegate: SLErc20Delegate, name: string, contract: string, apiKey: string): Promise { + if (world.isLocalNetwork()) { + world.printer.printLine(`Politely declining to verify on local network: ${world.network}.`); + } else { + await verify(world, apiKey, name, contract, slTokenDelegate._address); + } + + return world; +} + +export function slTokenDelegateCommands() { + return [ + new Command<{ slTokenDelegateParams: EventV }>(` + #### Deploy + + * "SLTokenDelegate Deploy ...slTokenDelegateParams" - Generates a new SLTokenDelegate + * E.g. "SLTokenDelegate Deploy CDaiDelegate cDAIDelegate" + `, + "Deploy", + [new Arg("slTokenDelegateParams", getEventV, { variadic: true })], + (world, from, { slTokenDelegateParams }) => genSLTokenDelegate(world, from, slTokenDelegateParams.val) + ), + new View<{ slTokenDelegateArg: StringV, apiKey: StringV }>(` + #### Verify + + * "SLTokenDelegate Verify apiKey:" - Verifies SLTokenDelegate in Etherscan + * E.g. "SLTokenDelegate slDaiDelegate Verify "myApiKey" + `, + "Verify", + [ + new Arg("slTokenDelegateArg", getStringV), + new Arg("apiKey", getStringV) + ], + async (world, { slTokenDelegateArg, apiKey }) => { + let [slToken, name, data] = await getSLTokenDelegateData(world, slTokenDelegateArg.val); + + return await verifySLTokenDelegate(world, slToken, name, data.get('contract')!, apiKey.val); + }, + { namePos: 1 } + ), + ]; +} + +export async function processSLTokenDelegateEvent(world: World, event: Event, from: string | null): Promise { + return await processCommandEvent("SLTokenDelegate", slTokenDelegateCommands(), world, event, from); +} diff --git a/scenario/src/Event/SLTokenEvent.ts b/scenario/src/Event/SLTokenEvent.ts new file mode 100644 index 000000000..a0a4b8ced --- /dev/null +++ b/scenario/src/Event/SLTokenEvent.ts @@ -0,0 +1,908 @@ +import { Event } from '../Event'; +import { addAction, describeUser, World } from '../World'; +import { decodeCall, getPastEvents } from '../Contract'; +import { SLToken, SLTokenScenario } from '../Contract/SLToken'; +import { SLErc20Delegate } from '../Contract/SLErc20Delegate' +import { SLErc20Delegator } from '../Contract/SLErc20Delegator' +import { invoke, Sendable } from '../Invokation'; +import { + getAddressV, + getEventV, + getExpNumberV, + getNumberV, + getStringV, + getBoolV +} from '../CoreValue'; +import { + AddressV, + BoolV, + EventV, + NothingV, + NumberV, + StringV +} from '../Value'; +import { getContract } from '../Contract'; +import { Arg, Command, View, processCommandEvent } from '../Command'; +import { SLTokenErrorReporter } from '../ErrorReporter'; +import { getComptroller, getSLTokenData } from '../ContractLookup'; +import { getExpMantissa } from '../Encoding'; +import { buildSLToken } from '../Builder/SLTokenBuilder'; +import { verify } from '../Verify'; +import { getLiquidity } from '../Value/ComptrollerValue'; +import { encodedNumber } from '../Encoding'; +import { getSLTokenV, getSLErc20DelegatorV } from '../Value/SLTokenValue'; + +function showTrxValue(world: World): string { + return new NumberV(world.trxInvokationOpts.get('value')).show(); +} + +async function genSLToken(world: World, from: string, event: Event): Promise { + let { world: nextWorld, slToken, tokenData } = await buildSLToken(world, from, event); + world = nextWorld; + + world = addAction( + world, + `Added slToken ${tokenData.name} (${tokenData.contract}) at address ${slToken._address}`, + tokenData.invokation + ); + + return world; +} + +async function accrueInterest(world: World, from: string, slToken: SLToken): Promise { + let invokation = await invoke(world, slToken.methods.accrueInterest(), from, SLTokenErrorReporter); + + world = addAction( + world, + `SLToken ${slToken.name}: Interest accrued`, + invokation + ); + + return world; +} + +async function mint(world: World, from: string, slToken: SLToken, amount: NumberV | NothingV): Promise { + let invokation; + let showAmount; + + if (amount instanceof NumberV) { + showAmount = amount.show(); + invokation = await invoke(world, slToken.methods.mint(amount.encode()), from, SLTokenErrorReporter); + } else { + showAmount = showTrxValue(world); + invokation = await invoke(world, slToken.methods.mint(), from, SLTokenErrorReporter); + } + + world = addAction( + world, + `SLToken ${slToken.name}: ${describeUser(world, from)} mints ${showAmount}`, + invokation + ); + + return world; +} + +async function redeem(world: World, from: string, slToken: SLToken, tokens: NumberV): Promise { + let invokation = await invoke(world, slToken.methods.redeem(tokens.encode()), from, SLTokenErrorReporter); + + world = addAction( + world, + `SLToken ${slToken.name}: ${describeUser(world, from)} redeems ${tokens.show()} tokens`, + invokation + ); + + return world; +} + +async function redeemUnderlying(world: World, from: string, slToken: SLToken, amount: NumberV): Promise { + let invokation = await invoke(world, slToken.methods.redeemUnderlying(amount.encode()), from, SLTokenErrorReporter); + + world = addAction( + world, + `SLToken ${slToken.name}: ${describeUser(world, from)} redeems ${amount.show()} underlying`, + invokation + ); + + return world; +} + +async function borrow(world: World, from: string, slToken: SLToken, amount: NumberV): Promise { + let invokation = await invoke(world, slToken.methods.borrow(amount.encode()), from, SLTokenErrorReporter); + + world = addAction( + world, + `SLToken ${slToken.name}: ${describeUser(world, from)} borrows ${amount.show()}`, + invokation + ); + + return world; +} + +async function repayBorrow(world: World, from: string, slToken: SLToken, amount: NumberV | NothingV): Promise { + let invokation; + let showAmount; + + if (amount instanceof NumberV) { + showAmount = amount.show(); + invokation = await invoke(world, slToken.methods.repayBorrow(amount.encode()), from, SLTokenErrorReporter); + } else { + showAmount = showTrxValue(world); + invokation = await invoke(world, slToken.methods.repayBorrow(), from, SLTokenErrorReporter); + } + + world = addAction( + world, + `SLToken ${slToken.name}: ${describeUser(world, from)} repays ${showAmount} of borrow`, + invokation + ); + + return world; +} + +async function repayBorrowBehalf(world: World, from: string, behalf: string, slToken: SLToken, amount: NumberV | NothingV): Promise { + let invokation; + let showAmount; + + if (amount instanceof NumberV) { + showAmount = amount.show(); + invokation = await invoke(world, slToken.methods.repayBorrowBehalf(behalf, amount.encode()), from, SLTokenErrorReporter); + } else { + showAmount = showTrxValue(world); + invokation = await invoke(world, slToken.methods.repayBorrowBehalf(behalf), from, SLTokenErrorReporter); + } + + world = addAction( + world, + `SLToken ${slToken.name}: ${describeUser(world, from)} repays ${showAmount} of borrow on behalf of ${describeUser(world, behalf)}`, + invokation + ); + + return world; +} + +async function liquidateBorrow(world: World, from: string, slToken: SLToken, borrower: string, collateral: SLToken, repayAmount: NumberV | NothingV): Promise { + let invokation; + let showAmount; + + if (repayAmount instanceof NumberV) { + showAmount = repayAmount.show(); + invokation = await invoke(world, slToken.methods.liquidateBorrow(borrower, repayAmount.encode(), collateral._address), from, SLTokenErrorReporter); + } else { + showAmount = showTrxValue(world); + invokation = await invoke(world, slToken.methods.liquidateBorrow(borrower, collateral._address), from, SLTokenErrorReporter); + } + + world = addAction( + world, + `SLToken ${slToken.name}: ${describeUser(world, from)} liquidates ${showAmount} from of ${describeUser(world, borrower)}, seizing ${collateral.name}.`, + invokation + ); + + return world; +} + +async function seize(world: World, from: string, slToken: SLToken, liquidator: string, borrower: string, seizeTokens: NumberV): Promise { + let invokation = await invoke(world, slToken.methods.seize(liquidator, borrower, seizeTokens.encode()), from, SLTokenErrorReporter); + + world = addAction( + world, + `SLToken ${slToken.name}: ${describeUser(world, from)} initiates seizing ${seizeTokens.show()} to ${describeUser(world, liquidator)} from ${describeUser(world, borrower)}.`, + invokation + ); + + return world; +} + +async function evilSeize(world: World, from: string, slToken: SLToken, treasure: SLToken, liquidator: string, borrower: string, seizeTokens: NumberV): Promise { + let invokation = await invoke(world, slToken.methods.evilSeize(treasure._address, liquidator, borrower, seizeTokens.encode()), from, SLTokenErrorReporter); + + world = addAction( + world, + `SLToken ${slToken.name}: ${describeUser(world, from)} initiates illegal seizing ${seizeTokens.show()} to ${describeUser(world, liquidator)} from ${describeUser(world, borrower)}.`, + invokation + ); + + return world; +} + +async function setPendingAdmin(world: World, from: string, slToken: SLToken, newPendingAdmin: string): Promise { + let invokation = await invoke(world, slToken.methods._setPendingAdmin(newPendingAdmin), from, SLTokenErrorReporter); + + world = addAction( + world, + `SLToken ${slToken.name}: ${describeUser(world, from)} sets pending admin to ${newPendingAdmin}`, + invokation + ); + + return world; +} + +async function acceptAdmin(world: World, from: string, slToken: SLToken): Promise { + let invokation = await invoke(world, slToken.methods._acceptAdmin(), from, SLTokenErrorReporter); + + world = addAction( + world, + `SLToken ${slToken.name}: ${describeUser(world, from)} accepts admin`, + invokation + ); + + return world; +} + +async function addReserves(world: World, from: string, slToken: SLToken, amount: NumberV): Promise { + let invokation = await invoke(world, slToken.methods._addReserves(amount.encode()), from, SLTokenErrorReporter); + + world = addAction( + world, + `SLToken ${slToken.name}: ${describeUser(world, from)} adds to reserves by ${amount.show()}`, + invokation + ); + + return world; +} + +async function reduceReserves(world: World, from: string, slToken: SLToken, amount: NumberV): Promise { + let invokation = await invoke(world, slToken.methods._reduceReserves(amount.encode()), from, SLTokenErrorReporter); + + world = addAction( + world, + `SLToken ${slToken.name}: ${describeUser(world, from)} reduces reserves by ${amount.show()}`, + invokation + ); + + return world; +} + +async function setReserveFactor(world: World, from: string, slToken: SLToken, reserveFactor: NumberV): Promise { + let invokation = await invoke(world, slToken.methods._setReserveFactor(reserveFactor.encode()), from, SLTokenErrorReporter); + + world = addAction( + world, + `SLToken ${slToken.name}: ${describeUser(world, from)} sets reserve factor to ${reserveFactor.show()}`, + invokation + ); + + return world; +} + +async function setInterestRateModel(world: World, from: string, slToken: SLToken, interestRateModel: string): Promise { + let invokation = await invoke(world, slToken.methods._setInterestRateModel(interestRateModel), from, SLTokenErrorReporter); + + world = addAction( + world, + `Set interest rate for ${slToken.name} to ${interestRateModel} as ${describeUser(world, from)}`, + invokation + ); + + return world; +} + +async function setComptroller(world: World, from: string, slToken: SLToken, comptroller: string): Promise { + let invokation = await invoke(world, slToken.methods._setComptroller(comptroller), from, SLTokenErrorReporter); + + world = addAction( + world, + `Set comptroller for ${slToken.name} to ${comptroller} as ${describeUser(world, from)}`, + invokation + ); + + return world; +} + +async function becomeImplementation( + world: World, + from: string, + slToken: SLToken, + becomeImplementationData: string +): Promise { + + const slErc20Delegate = getContract('SLErc20Delegate'); + const slErc20DelegateContract = await slErc20Delegate.at(world, slToken._address); + + let invokation = await invoke( + world, + slErc20DelegateContract.methods._becomeImplementation(becomeImplementationData), + from, + SLTokenErrorReporter + ); + + world = addAction( + world, + `SLToken ${slToken.name}: ${describeUser( + world, + from + )} initiates _becomeImplementation with data:${becomeImplementationData}.`, + invokation + ); + + return world; +} + +async function resignImplementation( + world: World, + from: string, + slToken: SLToken, +): Promise { + + const slErc20Delegate = getContract('SLErc20Delegate'); + const slErc20DelegateContract = await slErc20Delegate.at(world, slToken._address); + + let invokation = await invoke( + world, + slErc20DelegateContract.methods._resignImplementation(), + from, + SLTokenErrorReporter + ); + + world = addAction( + world, + `SLToken ${slToken.name}: ${describeUser( + world, + from + )} initiates _resignImplementation.`, + invokation + ); + + return world; +} + +async function setImplementation( + world: World, + from: string, + slToken: SLErc20Delegator, + implementation: string, + allowResign: boolean, + becomeImplementationData: string +): Promise { + let invokation = await invoke( + world, + slToken.methods._setImplementation( + implementation, + allowResign, + becomeImplementationData + ), + from, + SLTokenErrorReporter + ); + + world = addAction( + world, + `SLToken ${slToken.name}: ${describeUser( + world, + from + )} initiates setImplementation with implementation:${implementation} allowResign:${allowResign} data:${becomeImplementationData}.`, + invokation + ); + + return world; +} + +async function donate(world: World, from: string, slToken: SLToken): Promise { + let invokation = await invoke(world, slToken.methods.donate(), from, SLTokenErrorReporter); + + world = addAction( + world, + `Donate for ${slToken.name} as ${describeUser(world, from)} with value ${showTrxValue(world)}`, + invokation + ); + + return world; +} + +async function setSLTokenMock(world: World, from: string, slToken: SLTokenScenario, mock: string, value: NumberV): Promise { + let mockMethod: (number) => Sendable; + + switch (mock.toLowerCase()) { + case "totalborrows": + mockMethod = slToken.methods.setTotalBorrows; + break; + case "totalreserves": + mockMethod = slToken.methods.setTotalReserves; + break; + default: + throw new Error(`Mock "${mock}" not defined for slToken`); + } + + let invokation = await invoke(world, mockMethod(value.encode()), from); + + world = addAction( + world, + `Mocked ${mock}=${value.show()} for ${slToken.name}`, + invokation + ); + + return world; +} + +async function verifySLToken(world: World, slToken: SLToken, name: string, contract: string, apiKey: string): Promise { + if (world.isLocalNetwork()) { + world.printer.printLine(`Politely declining to verify on local network: ${world.network}.`); + } else { + await verify(world, apiKey, name, contract, slToken._address); + } + + return world; +} + +async function printMinters(world: World, slToken: SLToken): Promise { + let events = await getPastEvents(world, slToken, slToken.name, 'Mint'); + let addresses = events.map((event) => event.returnValues['minter']); + let uniq = [...new Set(addresses)]; + + world.printer.printLine("Minters:") + + uniq.forEach((address) => { + world.printer.printLine(`\t${address}`) + }); + + return world; +} + +async function printBorrowers(world: World, slToken: SLToken): Promise { + let events = await getPastEvents(world, slToken, slToken.name, 'Borrow'); + let addresses = events.map((event) => event.returnValues['borrower']); + let uniq = [...new Set(addresses)]; + + world.printer.printLine("Borrowers:") + + uniq.forEach((address) => { + world.printer.printLine(`\t${address}`) + }); + + return world; +} + +async function printLiquidity(world: World, slToken: SLToken): Promise { + let mintEvents = await getPastEvents(world, slToken, slToken.name, 'Mint'); + let mintAddresses = mintEvents.map((event) => event.returnValues['minter']); + let borrowEvents = await getPastEvents(world, slToken, slToken.name, 'Borrow'); + let borrowAddresses = borrowEvents.map((event) => event.returnValues['borrower']); + let uniq = [...new Set(mintAddresses.concat(borrowAddresses))]; + let comptroller = await getComptroller(world); + + world.printer.printLine("Liquidity:") + + const liquidityMap = await Promise.all(uniq.map(async (address) => { + let userLiquidity = await getLiquidity(world, comptroller, address); + + return [address, userLiquidity.val]; + })); + + liquidityMap.forEach(([address, liquidity]) => { + world.printer.printLine(`\t${world.settings.lookupAlias(address)}: ${liquidity / 1e18}e18`) + }); + + return world; +} + +export function slTokenCommands() { + return [ + new Command<{ slTokenParams: EventV }>(` + #### Deploy + + * "SLToken Deploy ...slTokenParams" - Generates a new SLToken + * E.g. "SLToken slZRX Deploy" + `, + "Deploy", + [new Arg("slTokenParams", getEventV, { variadic: true })], + (world, from, { slTokenParams }) => genSLToken(world, from, slTokenParams.val) + ), + new View<{ slTokenArg: StringV, apiKey: StringV }>(` + #### Verify + + * "SLToken Verify apiKey:" - Verifies SLToken in Etherscan + * E.g. "SLToken slZRX Verify "myApiKey" + `, + "Verify", + [ + new Arg("slTokenArg", getStringV), + new Arg("apiKey", getStringV) + ], + async (world, { slTokenArg, apiKey }) => { + let [slToken, name, data] = await getSLTokenData(world, slTokenArg.val); + + return await verifySLToken(world, slToken, name, data.get('contract')!, apiKey.val); + }, + { namePos: 1 } + ), + new Command<{ slToken: SLToken }>(` + #### AccrueInterest + + * "SLToken AccrueInterest" - Accrues interest for given token + * E.g. "SLToken slZRX AccrueInterest" + `, + "AccrueInterest", + [ + new Arg("slToken", getSLTokenV) + ], + (world, from, { slToken }) => accrueInterest(world, from, slToken), + { namePos: 1 } + ), + new Command<{ slToken: SLToken, amount: NumberV | NothingV }>(` + #### Mint + + * "SLToken Mint amount:" - Mints the given amount of slToken as specified user + * E.g. "SLToken slZRX Mint 1.0e18" + `, + "Mint", + [ + new Arg("slToken", getSLTokenV), + new Arg("amount", getNumberV, { nullable: true }) + ], + (world, from, { slToken, amount }) => mint(world, from, slToken, amount), + { namePos: 1 } + ), + new Command<{ slToken: SLToken, tokens: NumberV }>(` + #### Redeem + + * "SLToken Redeem tokens:" - Redeems the given amount of slTokens as specified user + * E.g. "SLToken slZRX Redeem 1.0e9" + `, + "Redeem", + [ + new Arg("slToken", getSLTokenV), + new Arg("tokens", getNumberV) + ], + (world, from, { slToken, tokens }) => redeem(world, from, slToken, tokens), + { namePos: 1 } + ), + new Command<{ slToken: SLToken, amount: NumberV }>(` + #### RedeemUnderlying + + * "SLToken RedeemUnderlying amount:" - Redeems the given amount of underlying as specified user + * E.g. "SLToken slZRX RedeemUnderlying 1.0e18" + `, + "RedeemUnderlying", + [ + new Arg("slToken", getSLTokenV), + new Arg("amount", getNumberV) + ], + (world, from, { slToken, amount }) => redeemUnderlying(world, from, slToken, amount), + { namePos: 1 } + ), + new Command<{ slToken: SLToken, amount: NumberV }>(` + #### Borrow + + * "SLToken Borrow amount:" - Borrows the given amount of this slToken as specified user + * E.g. "SLToken slZRX Borrow 1.0e18" + `, + "Borrow", + [ + new Arg("slToken", getSLTokenV), + new Arg("amount", getNumberV) + ], + // Note: we override from + (world, from, { slToken, amount }) => borrow(world, from, slToken, amount), + { namePos: 1 } + ), + new Command<{ slToken: SLToken, amount: NumberV | NothingV }>(` + #### RepayBorrow + + * "SLToken RepayBorrow underlyingAmount:" - Repays borrow in the given underlying amount as specified user + * E.g. "SLToken slZRX RepayBorrow 1.0e18" + `, + "RepayBorrow", + [ + new Arg("slToken", getSLTokenV), + new Arg("amount", getNumberV, { nullable: true }) + ], + (world, from, { slToken, amount }) => repayBorrow(world, from, slToken, amount), + { namePos: 1 } + ), + new Command<{ slToken: SLToken, behalf: AddressV, amount: NumberV | NothingV }>(` + #### RepayBorrowBehalf + + * "SLToken RepayBorrowBehalf behalf: underlyingAmount:" - Repays borrow in the given underlying amount on behalf of another user + * E.g. "SLToken slZRX RepayBorrowBehalf Geoff 1.0e18" + `, + "RepayBorrowBehalf", + [ + new Arg("slToken", getSLTokenV), + new Arg("behalf", getAddressV), + new Arg("amount", getNumberV, { nullable: true }) + ], + (world, from, { slToken, behalf, amount }) => repayBorrowBehalf(world, from, behalf.val, slToken, amount), + { namePos: 1 } + ), + new Command<{ borrower: AddressV, slToken: SLToken, collateral: SLToken, repayAmount: NumberV | NothingV }>(` + #### Liquidate + + * "SLToken Liquidate borrower: slTokenCollateral:
repayAmount:" - Liquidates repayAmount of given token seizing collateral token + * E.g. "SLToken slZRX Liquidate Geoff cBAT 1.0e18" + `, + "Liquidate", + [ + new Arg("slToken", getSLTokenV), + new Arg("borrower", getAddressV), + new Arg("collateral", getSLTokenV), + new Arg("repayAmount", getNumberV, { nullable: true }) + ], + (world, from, { borrower, slToken, collateral, repayAmount }) => liquidateBorrow(world, from, slToken, borrower.val, collateral, repayAmount), + { namePos: 1 } + ), + new Command<{ slToken: SLToken, liquidator: AddressV, borrower: AddressV, seizeTokens: NumberV }>(` + #### Seize + + * "SLToken Seize liquidator: borrower: seizeTokens:" - Seizes a given number of tokens from a user (to be called from other SLToken) + * E.g. "SLToken slZRX Seize Geoff Torrey 1.0e18" + `, + "Seize", + [ + new Arg("slToken", getSLTokenV), + new Arg("liquidator", getAddressV), + new Arg("borrower", getAddressV), + new Arg("seizeTokens", getNumberV) + ], + (world, from, { slToken, liquidator, borrower, seizeTokens }) => seize(world, from, slToken, liquidator.val, borrower.val, seizeTokens), + { namePos: 1 } + ), + new Command<{ slToken: SLToken, treasure: SLToken, liquidator: AddressV, borrower: AddressV, seizeTokens: NumberV }>(` + #### EvilSeize + + * "SLToken EvilSeize treasure: liquidator: borrower: seizeTokens:" - Improperly seizes a given number of tokens from a user + * E.g. "SLToken slEVL EvilSeize slZRX Geoff Torrey 1.0e18" + `, + "EvilSeize", + [ + new Arg("slToken", getSLTokenV), + new Arg("treasure", getSLTokenV), + new Arg("liquidator", getAddressV), + new Arg("borrower", getAddressV), + new Arg("seizeTokens", getNumberV) + ], + (world, from, { slToken, treasure, liquidator, borrower, seizeTokens }) => evilSeize(world, from, slToken, treasure, liquidator.val, borrower.val, seizeTokens), + { namePos: 1 } + ), + new Command<{ slToken: SLToken, amount: NumberV }>(` + #### ReduceReserves + + * "SLToken ReduceReserves amount:" - Reduces the reserves of the slToken + * E.g. "SLToken slZRX ReduceReserves 1.0e18" + `, + "ReduceReserves", + [ + new Arg("slToken", getSLTokenV), + new Arg("amount", getNumberV) + ], + (world, from, { slToken, amount }) => reduceReserves(world, from, slToken, amount), + { namePos: 1 } + ), + new Command<{ slToken: SLToken, amount: NumberV }>(` + #### AddReserves + + * "SLToken AddReserves amount:" - Adds reserves to the slToken + * E.g. "SLToken slZRX AddReserves 1.0e18" + `, + "AddReserves", + [ + new Arg("slToken", getSLTokenV), + new Arg("amount", getNumberV) + ], + (world, from, { slToken, amount }) => addReserves(world, from, slToken, amount), + { namePos: 1 } + ), + new Command<{ slToken: SLToken, newPendingAdmin: AddressV }>(` + #### SetPendingAdmin + + * "SLToken SetPendingAdmin newPendingAdmin:
" - Sets the pending admin for the slToken + * E.g. "SLToken slZRX SetPendingAdmin Geoff" + `, + "SetPendingAdmin", + [ + new Arg("slToken", getSLTokenV), + new Arg("newPendingAdmin", getAddressV) + ], + (world, from, { slToken, newPendingAdmin }) => setPendingAdmin(world, from, slToken, newPendingAdmin.val), + { namePos: 1 } + ), + new Command<{ slToken: SLToken }>(` + #### AcceptAdmin + + * "SLToken AcceptAdmin" - Accepts admin for the slToken + * E.g. "From Geoff (SLToken slZRX AcceptAdmin)" + `, + "AcceptAdmin", + [ + new Arg("slToken", getSLTokenV) + ], + (world, from, { slToken }) => acceptAdmin(world, from, slToken), + { namePos: 1 } + ), + new Command<{ slToken: SLToken, reserveFactor: NumberV }>(` + #### SetReserveFactor + + * "SLToken SetReserveFactor reserveFactor:" - Sets the reserve factor for the slToken + * E.g. "SLToken slZRX SetReserveFactor 0.1" + `, + "SetReserveFactor", + [ + new Arg("slToken", getSLTokenV), + new Arg("reserveFactor", getExpNumberV) + ], + (world, from, { slToken, reserveFactor }) => setReserveFactor(world, from, slToken, reserveFactor), + { namePos: 1 } + ), + new Command<{ slToken: SLToken, interestRateModel: AddressV }>(` + #### SetInterestRateModel + + * "SLToken SetInterestRateModel interestRateModel:" - Sets the interest rate model for the given slToken + * E.g. "SLToken slZRX SetInterestRateModel (FixedRate 1.5)" + `, + "SetInterestRateModel", + [ + new Arg("slToken", getSLTokenV), + new Arg("interestRateModel", getAddressV) + ], + (world, from, { slToken, interestRateModel }) => setInterestRateModel(world, from, slToken, interestRateModel.val), + { namePos: 1 } + ), + new Command<{ slToken: SLToken, comptroller: AddressV }>(` + #### SetComptroller + + * "SLToken SetComptroller comptroller:" - Sets the comptroller for the given slToken + * E.g. "SLToken slZRX SetComptroller Comptroller" + `, + "SetComptroller", + [ + new Arg("slToken", getSLTokenV), + new Arg("comptroller", getAddressV) + ], + (world, from, { slToken, comptroller }) => setComptroller(world, from, slToken, comptroller.val), + { namePos: 1 } + ), + new Command<{ + slToken: SLToken; + becomeImplementationData: StringV; + }>( + ` + #### BecomeImplementation + + * "SLToken BecomeImplementation becomeImplementationData:" + * E.g. "SLToken slDAI BecomeImplementation "0x01234anyByTeS56789"" + `, + 'BecomeImplementation', + [ + new Arg('slToken', getSLTokenV), + new Arg('becomeImplementationData', getStringV) + ], + (world, from, { slToken, becomeImplementationData }) => + becomeImplementation( + world, + from, + slToken, + becomeImplementationData.val + ), + { namePos: 1 } + ), + new Command<{slToken: SLToken;}>( + ` + #### ResignImplementation + + * "SLToken ResignImplementation" + * E.g. "SLToken slDAI ResignImplementation" + `, + 'ResignImplementation', + [new Arg('slToken', getSLTokenV)], + (world, from, { slToken }) => + resignImplementation( + world, + from, + slToken + ), + { namePos: 1 } + ), + new Command<{ + slToken: SLErc20Delegator; + implementation: AddressV; + allowResign: BoolV; + becomeImplementationData: StringV; + }>( + ` + #### SetImplementation + + * "SLToken SetImplementation implementation:
allowResign: becomeImplementationData:" + * E.g. "SLToken slDAI SetImplementation (SLToken slDAIDelegate Address) True "0x01234anyByTeS56789" + `, + 'SetImplementation', + [ + new Arg('slToken', getSLErc20DelegatorV), + new Arg('implementation', getAddressV), + new Arg('allowResign', getBoolV), + new Arg('becomeImplementationData', getStringV) + ], + (world, from, { slToken, implementation, allowResign, becomeImplementationData }) => + setImplementation( + world, + from, + slToken, + implementation.val, + allowResign.val, + becomeImplementationData.val + ), + { namePos: 1 } + ), + new Command<{ slToken: SLToken }>(` + #### Donate + + * "SLToken Donate" - Calls the donate (payable no-op) function + * E.g. "(Trx Value 5.0e18 (SLToken slETH Donate))" + `, + "Donate", + [ + new Arg("slToken", getSLTokenV) + ], + (world, from, { slToken }) => donate(world, from, slToken), + { namePos: 1 } + ), + new Command<{ slToken: SLToken, variable: StringV, value: NumberV }>(` + #### Mock + + * "SLToken Mock variable: value:" - Mocks a given value on slToken. Note: value must be a supported mock and this will only work on a "SLTokenScenario" contract. + * E.g. "SLToken slZRX Mock totalBorrows 5.0e18" + * E.g. "SLToken slZRX Mock totalReserves 0.5e18" + `, + "Mock", + [ + new Arg("slToken", getSLTokenV), + new Arg("variable", getStringV), + new Arg("value", getNumberV), + ], + (world, from, { slToken, variable, value }) => setSLTokenMock(world, from, slToken, variable.val, value), + { namePos: 1 } + ), + new View<{ slToken: SLToken }>(` + #### Minters + + * "SLToken Minters" - Print address of all minters + `, + "Minters", + [ + new Arg("slToken", getSLTokenV) + ], + (world, { slToken }) => printMinters(world, slToken), + { namePos: 1 } + ), + new View<{ slToken: SLToken }>(` + #### Borrowers + + * "SLToken Borrowers" - Print address of all borrowers + `, + "Borrowers", + [ + new Arg("slToken", getSLTokenV) + ], + (world, { slToken }) => printBorrowers(world, slToken), + { namePos: 1 } + ), + new View<{ slToken: SLToken }>(` + #### Liquidity + + * "SLToken Liquidity" - Prints liquidity of all minters or borrowers + `, + "Liquidity", + [ + new Arg("slToken", getSLTokenV) + ], + (world, { slToken }) => printLiquidity(world, slToken), + { namePos: 1 } + ), + new View<{ slToken: SLToken, input: StringV }>(` + #### Decode + + * "Decode input:" - Prints information about a call to a slToken contract + `, + "Decode", + [ + new Arg("slToken", getSLTokenV), + new Arg("input", getStringV) + + ], + (world, { slToken, input }) => decodeCall(world, slToken, input.val), + { namePos: 1 } + ) + ]; +} + +export async function processSLTokenEvent(world: World, event: Event, from: string | null): Promise { + return await processCommandEvent("SLToken", slTokenCommands(), world, event, from); +} diff --git a/scenario/src/Event/TrxEvent.ts b/scenario/src/Event/TrxEvent.ts index ae8285298..cf96fa444 100644 --- a/scenario/src/Event/TrxEvent.ts +++ b/scenario/src/Event/TrxEvent.ts @@ -26,7 +26,7 @@ export function trxCommands() { #### Value * "Value " - Runs event with a set amount for any transactions - * E.g. "Value 1.0e18 (CToken cEth Mint 1.0e18)" + * E.g. "Value 1.0e18 (SLToken slETH Mint 1.0e18)" `, "Value", [ @@ -39,7 +39,7 @@ export function trxCommands() { #### GasPrice * "GasPrice " - Runs event with a given gas price - * E.g. "GasPrice 0 (CToken cEth Mint 1.0e18)" + * E.g. "GasPrice 0 (SLToken slETH Mint 1.0e18)" `, "GasPrice", [ diff --git a/scenario/src/EventBuilder.ts b/scenario/src/EventBuilder.ts index e857193ef..54d7a9d0e 100644 --- a/scenario/src/EventBuilder.ts +++ b/scenario/src/EventBuilder.ts @@ -1,6 +1,5 @@ import { Event } from './Event'; import { addAction, World } from './World'; -import { Governor } from './Contract/Governor'; import { Invokation } from './Invokation'; import { Arg, Command, Fetcher, getFetcherValue, processCommandEvent, View } from './Command'; import { storeAndSaveContract } from './Networks'; diff --git a/scenario/src/Help.ts b/scenario/src/Help.ts index c67d53170..a24adc553 100644 --- a/scenario/src/Help.ts +++ b/scenario/src/Help.ts @@ -15,7 +15,7 @@ export function printHelp(printer: Printer, event: Event, expressions: Expressio The Compound Command Runner makes it easy to interact with Compound. You can input simple commands and it will construct Web3 calls to pull data or generate transactions. A list of available commands is included below. To dig further into a command run \`Help \`, such as \`Help From\` or for -sub-commands run \`Help CToken\` or \`Help CToken Mint\`. +sub-commands run \`Help SLToken\` or \`Help SLToken Mint\`. `).trim(); } else { if (expressions.length > 0) { diff --git a/scenario/src/Value/CTokenDelegateValue.ts b/scenario/src/Value/CTokenDelegateValue.ts deleted file mode 100644 index b368552a5..000000000 --- a/scenario/src/Value/CTokenDelegateValue.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { Event } from '../Event'; -import { World } from '../World'; -import { CErc20Delegate } from '../Contract/CErc20Delegate'; -import { - getCoreValue, - mapValue -} from '../CoreValue'; -import { Arg, Fetcher, getFetcherValue } from '../Command'; -import { - AddressV, - Value, -} from '../Value'; -import { getWorldContractByAddress, getCTokenDelegateAddress } from '../ContractLookup'; - -export async function getCTokenDelegateV(world: World, event: Event): Promise { - const address = await mapValue( - world, - event, - (str) => new AddressV(getCTokenDelegateAddress(world, str)), - getCoreValue, - AddressV - ); - - return getWorldContractByAddress(world, address.val); -} - -async function cTokenDelegateAddress(world: World, cTokenDelegate: CErc20Delegate): Promise { - return new AddressV(cTokenDelegate._address); -} - -export function cTokenDelegateFetchers() { - return [ - new Fetcher<{ cTokenDelegate: CErc20Delegate }, AddressV>(` - #### Address - - * "CTokenDelegate Address" - Returns address of CTokenDelegate contract - * E.g. "CTokenDelegate cDaiDelegate Address" - Returns cDaiDelegate's address - `, - "Address", - [ - new Arg("cTokenDelegate", getCTokenDelegateV) - ], - (world, { cTokenDelegate }) => cTokenDelegateAddress(world, cTokenDelegate), - { namePos: 1 } - ), - ]; -} - -export async function getCTokenDelegateValue(world: World, event: Event): Promise { - return await getFetcherValue("CTokenDelegate", cTokenDelegateFetchers(), world, event); -} diff --git a/scenario/src/Value/CTokenValue.ts b/scenario/src/Value/CTokenValue.ts deleted file mode 100644 index f0cd18342..000000000 --- a/scenario/src/Value/CTokenValue.ts +++ /dev/null @@ -1,395 +0,0 @@ -import { Event } from '../Event'; -import { World } from '../World'; -import { CToken } from '../Contract/CToken'; -import { CErc20Delegator } from '../Contract/CErc20Delegator'; -import { Erc20 } from '../Contract/Erc20'; -import { - getAddressV, - getCoreValue, - getStringV, - mapValue -} from '../CoreValue'; -import { Arg, Fetcher, getFetcherValue } from '../Command'; -import { - AddressV, - NumberV, - Value, - StringV -} from '../Value'; -import { getWorldContractByAddress, getCTokenAddress } from '../ContractLookup'; - -export async function getCTokenV(world: World, event: Event): Promise { - const address = await mapValue( - world, - event, - (str) => new AddressV(getCTokenAddress(world, str)), - getCoreValue, - AddressV - ); - - return getWorldContractByAddress(world, address.val); -} - -export async function getCErc20DelegatorV(world: World, event: Event): Promise { - const address = await mapValue( - world, - event, - (str) => new AddressV(getCTokenAddress(world, str)), - getCoreValue, - AddressV - ); - - return getWorldContractByAddress(world, address.val); -} - -async function getInterestRateModel(world: World, cToken: CToken): Promise { - return new AddressV(await cToken.methods.interestRateModel().call()); -} - -async function cTokenAddress(world: World, cToken: CToken): Promise { - return new AddressV(cToken._address); -} - -async function getCTokenAdmin(world: World, cToken: CToken): Promise { - return new AddressV(await cToken.methods.admin().call()); -} - -async function getCTokenPendingAdmin(world: World, cToken: CToken): Promise { - return new AddressV(await cToken.methods.pendingAdmin().call()); -} - -async function balanceOfUnderlying(world: World, cToken: CToken, user: string): Promise { - return new NumberV(await cToken.methods.balanceOfUnderlying(user).call()); -} - -async function getBorrowBalance(world: World, cToken: CToken, user): Promise { - return new NumberV(await cToken.methods.borrowBalanceCurrent(user).call()); -} - -async function getBorrowBalanceStored(world: World, cToken: CToken, user): Promise { - return new NumberV(await cToken.methods.borrowBalanceStored(user).call()); -} - -async function getTotalBorrows(world: World, cToken: CToken): Promise { - return new NumberV(await cToken.methods.totalBorrows().call()); -} - -async function getTotalBorrowsCurrent(world: World, cToken: CToken): Promise { - return new NumberV(await cToken.methods.totalBorrowsCurrent().call()); -} - -async function getReserveFactor(world: World, cToken: CToken): Promise { - return new NumberV(await cToken.methods.reserveFactorMantissa().call(), 1.0e18); -} - -async function getTotalReserves(world: World, cToken: CToken): Promise { - return new NumberV(await cToken.methods.totalReserves().call()); -} - -async function getComptroller(world: World, cToken: CToken): Promise { - return new AddressV(await cToken.methods.comptroller().call()); -} - -async function getExchangeRateStored(world: World, cToken: CToken): Promise { - return new NumberV(await cToken.methods.exchangeRateStored().call()); -} - -async function getExchangeRate(world: World, cToken: CToken): Promise { - return new NumberV(await cToken.methods.exchangeRateCurrent().call(), 1e18); -} - -async function getCash(world: World, cToken: CToken): Promise { - return new NumberV(await cToken.methods.getCash().call()); -} - -async function getInterestRate(world: World, cToken: CToken): Promise { - return new NumberV(await cToken.methods.borrowRatePerBlock().call(), 1.0e18 / 2102400); -} - -async function getImplementation(world: World, cToken: CToken): Promise { - return new AddressV(await (cToken as CErc20Delegator).methods.implementation().call()); -} - -export function cTokenFetchers() { - return [ - new Fetcher<{ cToken: CToken }, AddressV>(` - #### Address - - * "CToken Address" - Returns address of CToken contract - * E.g. "CToken cZRX Address" - Returns cZRX's address - `, - "Address", - [ - new Arg("cToken", getCTokenV) - ], - (world, { cToken }) => cTokenAddress(world, cToken), - { namePos: 1 } - ), - - new Fetcher<{ cToken: CToken }, AddressV>(` - #### InterestRateModel - - * "CToken InterestRateModel" - Returns the interest rate model of CToken contract - * E.g. "CToken cZRX InterestRateModel" - Returns cZRX's interest rate model - `, - "InterestRateModel", - [ - new Arg("cToken", getCTokenV) - ], - (world, { cToken }) => getInterestRateModel(world, cToken), - { namePos: 1 } - ), - - new Fetcher<{ cToken: CToken }, AddressV>(` - #### Admin - - * "CToken Admin" - Returns the admin of CToken contract - * E.g. "CToken cZRX Admin" - Returns cZRX's admin - `, - "Admin", - [ - new Arg("cToken", getCTokenV) - ], - (world, { cToken }) => getCTokenAdmin(world, cToken), - { namePos: 1 } - ), - - new Fetcher<{ cToken: CToken }, AddressV>(` - #### PendingAdmin - - * "CToken PendingAdmin" - Returns the pending admin of CToken contract - * E.g. "CToken cZRX PendingAdmin" - Returns cZRX's pending admin - `, - "PendingAdmin", - [ - new Arg("cToken", getCTokenV) - ], - (world, { cToken }) => getCTokenPendingAdmin(world, cToken), - { namePos: 1 } - ), - - new Fetcher<{ cToken: CToken }, AddressV>(` - #### Underlying - - * "CToken Underlying" - Returns the underlying asset (if applicable) - * E.g. "CToken cZRX Underlying" - `, - "Underlying", - [ - new Arg("cToken", getCTokenV) - ], - async (world, { cToken }) => new AddressV(await cToken.methods.underlying().call()), - { namePos: 1 } - ), - - new Fetcher<{ cToken: CToken, address: AddressV }, NumberV>(` - #### UnderlyingBalance - - * "CToken UnderlyingBalance " - Returns a user's underlying balance (based on given exchange rate) - * E.g. "CToken cZRX UnderlyingBalance Geoff" - `, - "UnderlyingBalance", - [ - new Arg("cToken", getCTokenV), - new Arg("address", getAddressV) - ], - (world, { cToken, address }) => balanceOfUnderlying(world, cToken, address.val), - { namePos: 1 } - ), - - new Fetcher<{ cToken: CToken, address: AddressV }, NumberV>(` - #### BorrowBalance - - * "CToken BorrowBalance " - Returns a user's borrow balance (including interest) - * E.g. "CToken cZRX BorrowBalance Geoff" - `, - "BorrowBalance", - [ - new Arg("cToken", getCTokenV), - new Arg("address", getAddressV) - ], - (world, { cToken, address }) => getBorrowBalance(world, cToken, address.val), - { namePos: 1 } - ), - - new Fetcher<{ cToken: CToken, address: AddressV }, NumberV>(` - #### BorrowBalanceStored - - * "CToken BorrowBalanceStored " - Returns a user's borrow balance (without specifically re-accruing interest) - * E.g. "CToken cZRX BorrowBalanceStored Geoff" - `, - "BorrowBalanceStored", - [ - new Arg("cToken", getCTokenV), - new Arg("address", getAddressV) - ], - (world, { cToken, address }) => getBorrowBalanceStored(world, cToken, address.val), - { namePos: 1 } - ), - - new Fetcher<{ cToken: CToken }, NumberV>(` - #### TotalBorrows - - * "CToken TotalBorrows" - Returns the cToken's total borrow balance - * E.g. "CToken cZRX TotalBorrows" - `, - "TotalBorrows", - [ - new Arg("cToken", getCTokenV) - ], - (world, { cToken }) => getTotalBorrows(world, cToken), - { namePos: 1 } - ), - - new Fetcher<{ cToken: CToken }, NumberV>(` - #### TotalBorrowsCurrent - - * "CToken TotalBorrowsCurrent" - Returns the cToken's total borrow balance with interest - * E.g. "CToken cZRX TotalBorrowsCurrent" - `, - "TotalBorrowsCurrent", - [ - new Arg("cToken", getCTokenV) - ], - (world, { cToken }) => getTotalBorrowsCurrent(world, cToken), - { namePos: 1 } - ), - - new Fetcher<{ cToken: CToken }, NumberV>(` - #### Reserves - - * "CToken Reserves" - Returns the cToken's total reserves - * E.g. "CToken cZRX Reserves" - `, - "Reserves", - [ - new Arg("cToken", getCTokenV) - ], - (world, { cToken }) => getTotalReserves(world, cToken), - { namePos: 1 } - ), - - new Fetcher<{ cToken: CToken }, NumberV>(` - #### ReserveFactor - - * "CToken ReserveFactor" - Returns reserve factor of CToken contract - * E.g. "CToken cZRX ReserveFactor" - Returns cZRX's reserve factor - `, - "ReserveFactor", - [ - new Arg("cToken", getCTokenV) - ], - (world, { cToken }) => getReserveFactor(world, cToken), - { namePos: 1 } - ), - - new Fetcher<{ cToken: CToken }, AddressV>(` - #### Comptroller - - * "CToken Comptroller" - Returns the cToken's comptroller - * E.g. "CToken cZRX Comptroller" - `, - "Comptroller", - [ - new Arg("cToken", getCTokenV) - ], - (world, { cToken }) => getComptroller(world, cToken), - { namePos: 1 } - ), - - new Fetcher<{ cToken: CToken }, NumberV>(` - #### ExchangeRateStored - - * "CToken ExchangeRateStored" - Returns the cToken's exchange rate (based on balances stored) - * E.g. "CToken cZRX ExchangeRateStored" - `, - "ExchangeRateStored", - [ - new Arg("cToken", getCTokenV) - ], - (world, { cToken }) => getExchangeRateStored(world, cToken), - { namePos: 1 } - ), - - new Fetcher<{ cToken: CToken }, NumberV>(` - #### ExchangeRate - - * "CToken ExchangeRate" - Returns the cToken's current exchange rate - * E.g. "CToken cZRX ExchangeRate" - `, - "ExchangeRate", - [ - new Arg("cToken", getCTokenV) - ], - (world, { cToken }) => getExchangeRate(world, cToken), - { namePos: 1 } - ), - - new Fetcher<{ cToken: CToken }, NumberV>(` - #### Cash - - * "CToken Cash" - Returns the cToken's current cash - * E.g. "CToken cZRX Cash" - `, - "Cash", - [ - new Arg("cToken", getCTokenV) - ], - (world, { cToken }) => getCash(world, cToken), - { namePos: 1 } - ), - - new Fetcher<{ cToken: CToken }, NumberV>(` - #### InterestRate - - * "CToken InterestRate" - Returns the cToken's current interest rate - * E.g. "CToken cZRX InterestRate" - `, - "InterestRate", - [ - new Arg("cToken", getCTokenV) - ], - (world, {cToken}) => getInterestRate(world, cToken), - {namePos: 1} - ), - new Fetcher<{cToken: CToken, signature: StringV}, NumberV>(` - #### CallNum - - * "CToken Call " - Simple direct call method, for now with no parameters - * E.g. "CToken cZRX Call \"borrowIndex()\"" - `, - "CallNum", - [ - new Arg("cToken", getCTokenV), - new Arg("signature", getStringV), - ], - async (world, {cToken, signature}) => { - const res = await world.web3.eth.call({ - to: cToken._address, - data: world.web3.eth.abi.encodeFunctionSignature(signature.val) - }) - const resNum : any = world.web3.eth.abi.decodeParameter('uint256',res); - return new NumberV(resNum); - } - , - {namePos: 1} - ), - new Fetcher<{ cToken: CToken }, AddressV>(` - #### Implementation - - * "CToken Implementation" - Returns the cToken's current implementation - * E.g. "CToken cDAI Implementation" - `, - "Implementation", - [ - new Arg("cToken", getCTokenV) - ], - (world, { cToken }) => getImplementation(world, cToken), - { namePos: 1 } - ) - ]; -} - -export async function getCTokenValue(world: World, event: Event): Promise { - return await getFetcherValue("cToken", cTokenFetchers(), world, event); -} diff --git a/scenario/src/Value/CompValue.ts b/scenario/src/Value/CompValue.ts deleted file mode 100644 index d95672434..000000000 --- a/scenario/src/Value/CompValue.ts +++ /dev/null @@ -1,202 +0,0 @@ -import { Event } from '../Event'; -import { World } from '../World'; -import { Comp } from '../Contract/Comp'; -import { - getAddressV, - getNumberV -} from '../CoreValue'; -import { - AddressV, - ListV, - NumberV, - StringV, - Value -} from '../Value'; -import { Arg, Fetcher, getFetcherValue } from '../Command'; -import { getComp } from '../ContractLookup'; - -export function compFetchers() { - return [ - new Fetcher<{ comp: Comp }, AddressV>(` - #### Address - - * " Address" - Returns the address of Comp token - * E.g. "Comp Address" - `, - "Address", - [ - new Arg("comp", getComp, { implicit: true }) - ], - async (world, { comp }) => new AddressV(comp._address) - ), - - new Fetcher<{ comp: Comp }, StringV>(` - #### Name - - * " Name" - Returns the name of the Comp token - * E.g. "Comp Name" - `, - "Name", - [ - new Arg("comp", getComp, { implicit: true }) - ], - async (world, { comp }) => new StringV(await comp.methods.name().call()) - ), - - new Fetcher<{ comp: Comp }, StringV>(` - #### Symbol - - * " Symbol" - Returns the symbol of the Comp token - * E.g. "Comp Symbol" - `, - "Symbol", - [ - new Arg("comp", getComp, { implicit: true }) - ], - async (world, { comp }) => new StringV(await comp.methods.symbol().call()) - ), - - new Fetcher<{ comp: Comp }, NumberV>(` - #### Decimals - - * " Decimals" - Returns the number of decimals of the Comp token - * E.g. "Comp Decimals" - `, - "Decimals", - [ - new Arg("comp", getComp, { implicit: true }) - ], - async (world, { comp }) => new NumberV(await comp.methods.decimals().call()) - ), - - new Fetcher<{ comp: Comp }, NumberV>(` - #### TotalSupply - - * "Comp TotalSupply" - Returns Comp token's total supply - `, - "TotalSupply", - [ - new Arg("comp", getComp, { implicit: true }) - ], - async (world, { comp }) => new NumberV(await comp.methods.totalSupply().call()) - ), - - new Fetcher<{ comp: Comp, address: AddressV }, NumberV>(` - #### TokenBalance - - * "Comp TokenBalance
" - Returns the Comp token balance of a given address - * E.g. "Comp TokenBalance Geoff" - Returns Geoff's Comp balance - `, - "TokenBalance", - [ - new Arg("comp", getComp, { implicit: true }), - new Arg("address", getAddressV) - ], - async (world, { comp, address }) => new NumberV(await comp.methods.balanceOf(address.val).call()) - ), - - new Fetcher<{ comp: Comp, owner: AddressV, spender: AddressV }, NumberV>(` - #### Allowance - - * "Comp Allowance owner:
spender:
" - Returns the Comp allowance from owner to spender - * E.g. "Comp Allowance Geoff Torrey" - Returns the Comp allowance of Geoff to Torrey - `, - "Allowance", - [ - new Arg("comp", getComp, { implicit: true }), - new Arg("owner", getAddressV), - new Arg("spender", getAddressV) - ], - async (world, { comp, owner, spender }) => new NumberV(await comp.methods.allowance(owner.val, spender.val).call()) - ), - - new Fetcher<{ comp: Comp, account: AddressV }, NumberV>(` - #### GetCurrentVotes - - * "Comp GetCurrentVotes account:
" - Returns the current Comp votes balance for an account - * E.g. "Comp GetCurrentVotes Geoff" - Returns the current Comp vote balance of Geoff - `, - "GetCurrentVotes", - [ - new Arg("comp", getComp, { implicit: true }), - new Arg("account", getAddressV), - ], - async (world, { comp, account }) => new NumberV(await comp.methods.getCurrentVotes(account.val).call()) - ), - - new Fetcher<{ comp: Comp, account: AddressV, blockNumber: NumberV }, NumberV>(` - #### GetPriorVotes - - * "Comp GetPriorVotes account:
blockBumber:" - Returns the current Comp votes balance at given block - * E.g. "Comp GetPriorVotes Geoff 5" - Returns the Comp vote balance for Geoff at block 5 - `, - "GetPriorVotes", - [ - new Arg("comp", getComp, { implicit: true }), - new Arg("account", getAddressV), - new Arg("blockNumber", getNumberV), - ], - async (world, { comp, account, blockNumber }) => new NumberV(await comp.methods.getPriorVotes(account.val, blockNumber.encode()).call()) - ), - - new Fetcher<{ comp: Comp, account: AddressV }, NumberV>(` - #### GetCurrentVotesBlock - - * "Comp GetCurrentVotesBlock account:
" - Returns the current Comp votes checkpoint block for an account - * E.g. "Comp GetCurrentVotesBlock Geoff" - Returns the current Comp votes checkpoint block for Geoff - `, - "GetCurrentVotesBlock", - [ - new Arg("comp", getComp, { implicit: true }), - new Arg("account", getAddressV), - ], - async (world, { comp, account }) => { - const numCheckpoints = Number(await comp.methods.numCheckpoints(account.val).call()); - const checkpoint = await comp.methods.checkpoints(account.val, numCheckpoints - 1).call(); - - return new NumberV(checkpoint.fromBlock); - } - ), - - new Fetcher<{ comp: Comp, account: AddressV }, NumberV>(` - #### VotesLength - - * "Comp VotesLength account:
" - Returns the Comp vote checkpoint array length - * E.g. "Comp VotesLength Geoff" - Returns the Comp vote checkpoint array length of Geoff - `, - "VotesLength", - [ - new Arg("comp", getComp, { implicit: true }), - new Arg("account", getAddressV), - ], - async (world, { comp, account }) => new NumberV(await comp.methods.numCheckpoints(account.val).call()) - ), - - new Fetcher<{ comp: Comp, account: AddressV }, ListV>(` - #### AllVotes - - * "Comp AllVotes account:
" - Returns information about all votes an account has had - * E.g. "Comp AllVotes Geoff" - Returns the Comp vote checkpoint array - `, - "AllVotes", - [ - new Arg("comp", getComp, { implicit: true }), - new Arg("account", getAddressV), - ], - async (world, { comp, account }) => { - const numCheckpoints = Number(await comp.methods.numCheckpoints(account.val).call()); - const checkpoints = await Promise.all(new Array(numCheckpoints).fill(undefined).map(async (_, i) => { - const {fromBlock, votes} = await comp.methods.checkpoints(account.val, i).call(); - - return new StringV(`Block ${fromBlock}: ${votes} vote${votes !== 1 ? "s" : ""}`); - })); - - return new ListV(checkpoints); - } - ) - ]; -} - -export async function getCompValue(world: World, event: Event): Promise { - return await getFetcherValue("Comp", compFetchers(), world, event); -} diff --git a/scenario/src/Value/ComptrollerValue.ts b/scenario/src/Value/ComptrollerValue.ts index a8b809a8c..3c1eda2af 100644 --- a/scenario/src/Value/ComptrollerValue.ts +++ b/scenario/src/Value/ComptrollerValue.ts @@ -1,7 +1,7 @@ import {Event} from '../Event'; import {World} from '../World'; import {Comptroller} from '../Contract/Comptroller'; -import {CToken} from '../Contract/CToken'; +import {SLToken} from '../Contract/SLToken'; import { getAddressV, getCoreValue, @@ -19,7 +19,7 @@ import { import {Arg, Fetcher, getFetcherValue} from '../Command'; import {getComptroller} from '../ContractLookup'; import {encodedNumber} from '../Encoding'; -import {getCTokenV} from '../Value/CTokenValue'; +import {getSLTokenV} from './SLTokenValue'; import { encodeParameters, encodeABI } from '../Utils'; export async function getComptrollerAddress(world: World, comptroller: Comptroller): Promise { @@ -74,8 +74,8 @@ async function getPendingAdmin(world: World, comptroller: Comptroller): Promise< return new AddressV(await comptroller.methods.pendingAdmin().call()); } -async function getCollateralFactor(world: World, comptroller: Comptroller, cToken: CToken): Promise { - let {0: _isListed, 1: collateralFactorMantissa} = await comptroller.methods.markets(cToken._address).call(); +async function getCollateralFactor(world: World, comptroller: Comptroller, slToken: SLToken): Promise { + let {0: _isListed, 1: collateralFactorMantissa} = await comptroller.methods.markets(slToken._address).call(); return new NumberV(collateralFactorMantissa, 1e18); } @@ -83,8 +83,8 @@ async function membershipLength(world: World, comptroller: Comptroller, user: st return new NumberV(await comptroller.methods.membershipLength(user).call()); } -async function checkMembership(world: World, comptroller: Comptroller, user: string, cToken: CToken): Promise { - return new BoolV(await comptroller.methods.checkMembership(user, cToken._address).call()); +async function checkMembership(world: World, comptroller: Comptroller, user: string, slToken: SLToken): Promise { + return new BoolV(await comptroller.methods.checkMembership(user, slToken._address).call()); } async function getAssetsIn(world: World, comptroller: Comptroller, user: string): Promise { @@ -93,21 +93,21 @@ async function getAssetsIn(world: World, comptroller: Comptroller, user: string) return new ListV(assetsList.map((a) => new AddressV(a))); } -async function getCompMarkets(world: World, comptroller: Comptroller): Promise { - let mkts = await comptroller.methods.getCompMarkets().call(); +async function getSashimiMarkets(world: World, comptroller: Comptroller): Promise { + let mkts = await comptroller.methods.getSashimiMarkets().call(); return new ListV(mkts.map((a) => new AddressV(a))); } -async function checkListed(world: World, comptroller: Comptroller, cToken: CToken): Promise { - let {0: isListed, 1: _collateralFactorMantissa} = await comptroller.methods.markets(cToken._address).call(); +async function checkListed(world: World, comptroller: Comptroller, slToken: SLToken): Promise { + let {0: isListed, 1: _collateralFactorMantissa} = await comptroller.methods.markets(slToken._address).call(); return new BoolV(isListed); } -async function checkIsComped(world: World, comptroller: Comptroller, cToken: CToken): Promise { - let {0: isListed, 1: _collateralFactorMantissa, 2: isComped} = await comptroller.methods.markets(cToken._address).call(); - return new BoolV(isComped); +async function checkIsSashimied(world: World, comptroller: Comptroller, slToken: SLToken): Promise { + let {0: isListed, 1: _collateralFactorMantissa, 2: isSashimied} = await comptroller.methods.markets(slToken._address).call(); + return new BoolV(isSashimied); } @@ -135,12 +135,12 @@ export function comptrollerFetchers() { ], (world, {comptroller, account}) => getLiquidity(world, comptroller, account.val) ), - new Fetcher<{comptroller: Comptroller, account: AddressV, action: StringV, amount: NumberV, cToken: CToken}, NumberV>(` + new Fetcher<{comptroller: Comptroller, account: AddressV, action: StringV, amount: NumberV, slToken: SLToken}, NumberV>(` #### Hypothetical * "Comptroller Hypothetical " - Returns a given user's trued up liquidity given a hypothetical change in asset with redeeming a certain number of tokens and/or borrowing a given amount. - * E.g. "Comptroller Hypothetical Geoff Redeems 6.0 cZRX" - * E.g. "Comptroller Hypothetical Geoff Borrows 5.0 cZRX" + * E.g. "Comptroller Hypothetical Geoff Redeems 6.0 slZRX" + * E.g. "Comptroller Hypothetical Geoff Borrows 5.0 slZRX" `, "Hypothetical", [ @@ -148,9 +148,9 @@ export function comptrollerFetchers() { new Arg("account", getAddressV), new Arg("action", getStringV), new Arg("amount", getNumberV), - new Arg("cToken", getCTokenV) + new Arg("slToken", getSLTokenV) ], - async (world, {comptroller, account, action, cToken, amount}) => { + async (world, {comptroller, account, action, slToken, amount}) => { let redeemTokens: NumberV; let borrowAmount: NumberV; @@ -167,7 +167,7 @@ export function comptrollerFetchers() { throw new Error(`Unknown hypothetical: ${action.val}`); } - return await getHypotheticalLiquidity(world, comptroller, account.val, cToken._address, redeemTokens.encode(), borrowAmount.encode()); + return await getHypotheticalLiquidity(world, comptroller, account.val, slToken._address, redeemTokens.encode(), borrowAmount.encode()); } ), new Fetcher<{comptroller: Comptroller}, AddressV>(` @@ -252,18 +252,18 @@ export function comptrollerFetchers() { [new Arg("comptroller", getComptroller, {implicit: true})], (world, {comptroller}) => getBlockNumber(world, comptroller) ), - new Fetcher<{comptroller: Comptroller, cToken: CToken}, NumberV>(` + new Fetcher<{comptroller: Comptroller, slToken: SLToken}, NumberV>(` #### CollateralFactor - * "Comptroller CollateralFactor " - Returns the collateralFactor associated with a given asset - * E.g. "Comptroller CollateralFactor cZRX" + * "Comptroller CollateralFactor " - Returns the collateralFactor associated with a given asset + * E.g. "Comptroller CollateralFactor slZRX" `, "CollateralFactor", [ new Arg("comptroller", getComptroller, {implicit: true}), - new Arg("cToken", getCTokenV) + new Arg("slToken", getSLTokenV) ], - (world, {comptroller, cToken}) => getCollateralFactor(world, comptroller, cToken) + (world, {comptroller, slToken}) => getCollateralFactor(world, comptroller, slToken) ), new Fetcher<{comptroller: Comptroller, account: AddressV}, NumberV>(` #### MembershipLength @@ -278,19 +278,19 @@ export function comptrollerFetchers() { ], (world, {comptroller, account}) => membershipLength(world, comptroller, account.val) ), - new Fetcher<{comptroller: Comptroller, account: AddressV, cToken: CToken}, BoolV>(` + new Fetcher<{comptroller: Comptroller, account: AddressV, slToken: SLToken}, BoolV>(` #### CheckMembership - * "Comptroller CheckMembership " - Returns one if user is in asset, zero otherwise. - * E.g. "Comptroller CheckMembership Geoff cZRX" + * "Comptroller CheckMembership " - Returns one if user is in asset, zero otherwise. + * E.g. "Comptroller CheckMembership Geoff slZRX" `, "CheckMembership", [ new Arg("comptroller", getComptroller, {implicit: true}), new Arg("account", getAddressV), - new Arg("cToken", getCTokenV) + new Arg("slToken", getSLTokenV) ], - (world, {comptroller, account, cToken}) => checkMembership(world, comptroller, account.val, cToken) + (world, {comptroller, account, slToken}) => checkMembership(world, comptroller, account.val, slToken) ), new Fetcher<{comptroller: Comptroller, account: AddressV}, ListV>(` #### AssetsIn @@ -305,31 +305,31 @@ export function comptrollerFetchers() { ], (world, {comptroller, account}) => getAssetsIn(world, comptroller, account.val) ), - new Fetcher<{comptroller: Comptroller, cToken: CToken}, BoolV>(` + new Fetcher<{comptroller: Comptroller, slToken: SLToken}, BoolV>(` #### CheckListed - * "Comptroller CheckListed " - Returns true if market is listed, false otherwise. - * E.g. "Comptroller CheckListed cZRX" + * "Comptroller CheckListed " - Returns true if market is listed, false otherwise. + * E.g. "Comptroller CheckListed slZRX" `, "CheckListed", [ new Arg("comptroller", getComptroller, {implicit: true}), - new Arg("cToken", getCTokenV) + new Arg("slToken", getSLTokenV) ], - (world, {comptroller, cToken}) => checkListed(world, comptroller, cToken) + (world, {comptroller, slToken}) => checkListed(world, comptroller, slToken) ), - new Fetcher<{comptroller: Comptroller, cToken: CToken}, BoolV>(` - #### CheckIsComped + new Fetcher<{comptroller: Comptroller, slToken: SLToken}, BoolV>(` + #### CheckIsSashimied - * "Comptroller CheckIsComped " - Returns true if market is listed, false otherwise. - * E.g. "Comptroller CheckIsComped cZRX" + * "Comptroller CheckIsSashimied " - Returns true if market is listed, false otherwise. + * E.g. "Comptroller CheckIsSashimied slZRX" `, - "CheckIsComped", + "CheckIsSashimied", [ new Arg("comptroller", getComptroller, {implicit: true}), - new Arg("cToken", getCTokenV) + new Arg("slToken", getSLTokenV) ], - (world, {comptroller, cToken}) => checkIsComped(world, comptroller, cToken) + (world, {comptroller, slToken}) => checkIsSashimied(world, comptroller, slToken) ), new Fetcher<{comptroller: Comptroller}, AddressV>(` #### PauseGuardian @@ -386,60 +386,60 @@ export function comptrollerFetchers() { async (world, {comptroller}) => new BoolV(await comptroller.methods.seizeGuardianPaused().call()) ), - new Fetcher<{comptroller: Comptroller, cToken: CToken}, BoolV>(` + new Fetcher<{comptroller: Comptroller, slToken: SLToken}, BoolV>(` #### MintGuardianMarketPaused * "MintGuardianMarketPaused" - Returns the Comptrollers's Mint paused status in market - * E.g. "Comptroller MintGuardianMarketPaused cREP" + * E.g. "Comptroller MintGuardianMarketPaused slREP" `, "MintGuardianMarketPaused", [ new Arg("comptroller", getComptroller, {implicit: true}), - new Arg("cToken", getCTokenV) + new Arg("slToken", getSLTokenV) ], - async (world, {comptroller, cToken}) => new BoolV(await comptroller.methods.mintGuardianPaused(cToken._address).call()) + async (world, {comptroller, slToken}) => new BoolV(await comptroller.methods.mintGuardianPaused(slToken._address).call()) ), - new Fetcher<{comptroller: Comptroller, cToken: CToken}, BoolV>(` + new Fetcher<{comptroller: Comptroller, slToken: SLToken}, BoolV>(` #### BorrowGuardianMarketPaused * "BorrowGuardianMarketPaused" - Returns the Comptrollers's Borrow paused status in market - * E.g. "Comptroller BorrowGuardianMarketPaused cREP" + * E.g. "Comptroller BorrowGuardianMarketPaused slREP" `, "BorrowGuardianMarketPaused", [ new Arg("comptroller", getComptroller, {implicit: true}), - new Arg("cToken", getCTokenV) + new Arg("slToken", getSLTokenV) ], - async (world, {comptroller, cToken}) => new BoolV(await comptroller.methods.borrowGuardianPaused(cToken._address).call()) + async (world, {comptroller, slToken}) => new BoolV(await comptroller.methods.borrowGuardianPaused(slToken._address).call()) ), new Fetcher<{comptroller: Comptroller}, ListV>(` - #### GetCompMarkets + #### GetSashimiMarkets - * "GetCompMarkets" - Returns an array of the currently enabled Comp markets. To use the auto-gen array getter compMarkets(uint), use CompMarkets - * E.g. "Comptroller GetCompMarkets" + * "GetSashimiMarkets" - Returns an array of the currently enabled Sashimi markets. To use the auto-gen array getter sashimiMarkets(uint), use SashimiMarkets + * E.g. "Comptroller GetSashimiMarkets" `, - "GetCompMarkets", + "GetSashimiMarkets", [new Arg("comptroller", getComptroller, {implicit: true})], - async(world, {comptroller}) => await getCompMarkets(world, comptroller) + async(world, {comptroller}) => await getSashimiMarkets(world, comptroller) ), new Fetcher<{comptroller: Comptroller}, NumberV>(` - #### CompRate + #### SashimiRate - * "CompRate" - Returns the current comp rate. - * E.g. "Comptroller CompRate" + * "SashimiRate" - Returns the current sashimi rate. + * E.g. "Comptroller SashimiRate" `, - "CompRate", + "SashimiRate", [new Arg("comptroller", getComptroller, {implicit: true})], - async(world, {comptroller}) => new NumberV(await comptroller.methods.compRate().call()) + async(world, {comptroller}) => new NumberV(await comptroller.methods.sashimiRate().call()) ), new Fetcher<{comptroller: Comptroller, signature: StringV, callArgs: StringV[]}, NumberV>(` #### CallNum * "CallNum signature: ...callArgs" - Simple direct call method - * E.g. "Comptroller CallNum \"compSpeeds(address)\" (Address Coburn)" + * E.g. "Comptroller CallNum \"sashimiSpeeds(address)\" (Address Coburn)" `, "CallNum", [ @@ -457,95 +457,95 @@ export function comptrollerFetchers() { return new NumberV(resNum); } ), - new Fetcher<{comptroller: Comptroller, CToken: CToken, key: StringV}, NumberV>(` - #### CompSupplyState(address) + new Fetcher<{comptroller: Comptroller, SLToken: SLToken, key: StringV}, NumberV>(` + #### SashimiSupplyState(address) - * "Comptroller CompBorrowState cZRX "index" + * "Comptroller SashimiBorrowState slZRX "index" `, - "CompSupplyState", + "SashimiSupplyState", [ new Arg("comptroller", getComptroller, {implicit: true}), - new Arg("CToken", getCTokenV), + new Arg("SLToken", getSLTokenV), new Arg("key", getStringV), ], - async (world, {comptroller, CToken, key}) => { - const result = await comptroller.methods.compSupplyState(CToken._address).call(); + async (world, {comptroller, SLToken, key}) => { + const result = await comptroller.methods.sashimiSupplyState(SLToken._address).call(); return new NumberV(result[key.val]); } ), - new Fetcher<{comptroller: Comptroller, CToken: CToken, key: StringV}, NumberV>(` - #### CompBorrowState(address) + new Fetcher<{comptroller: Comptroller, SLToken: SLToken, key: StringV}, NumberV>(` + #### SashimiBorrowState(address) - * "Comptroller CompBorrowState cZRX "index" + * "Comptroller SashimiBorrowState slZRX "index" `, - "CompBorrowState", + "SashimiBorrowState", [ new Arg("comptroller", getComptroller, {implicit: true}), - new Arg("CToken", getCTokenV), + new Arg("SLToken", getSLTokenV), new Arg("key", getStringV), ], - async (world, {comptroller, CToken, key}) => { - const result = await comptroller.methods.compBorrowState(CToken._address).call(); + async (world, {comptroller, SLToken, key}) => { + const result = await comptroller.methods.sashimiBorrowState(SLToken._address).call(); return new NumberV(result[key.val]); } ), new Fetcher<{comptroller: Comptroller, account: AddressV, key: StringV}, NumberV>(` - #### CompAccrued(address) + #### SashimiAccrued(address) - * "Comptroller CompAccrued Coburn + * "Comptroller SashimiAccrued Coburn `, - "CompAccrued", + "SashimiAccrued", [ new Arg("comptroller", getComptroller, {implicit: true}), new Arg("account", getAddressV), ], async (world, {comptroller,account}) => { - const result = await comptroller.methods.compAccrued(account.val).call(); + const result = await comptroller.methods.sashimiAccrued(account.val).call(); return new NumberV(result); } ), - new Fetcher<{comptroller: Comptroller, CToken: CToken, account: AddressV}, NumberV>(` - #### compSupplierIndex + new Fetcher<{comptroller: Comptroller, SLToken: SLToken, account: AddressV}, NumberV>(` + #### sashimiSupplierIndex - * "Comptroller CompSupplierIndex cZRX Coburn + * "Comptroller SashimiSupplierIndex slZRX Coburn `, - "CompSupplierIndex", + "SashimiSupplierIndex", [ new Arg("comptroller", getComptroller, {implicit: true}), - new Arg("CToken", getCTokenV), + new Arg("SLToken", getSLTokenV), new Arg("account", getAddressV), ], - async (world, {comptroller, CToken, account}) => { - return new NumberV(await comptroller.methods.compSupplierIndex(CToken._address, account.val).call()); + async (world, {comptroller, SLToken, account}) => { + return new NumberV(await comptroller.methods.sashimiSupplierIndex(SLToken._address, account.val).call()); } ), - new Fetcher<{comptroller: Comptroller, CToken: CToken, account: AddressV}, NumberV>(` - #### CompBorrowerIndex + new Fetcher<{comptroller: Comptroller, SLToken: SLToken, account: AddressV}, NumberV>(` + #### SashimiBorrowerIndex - * "Comptroller CompBorrowerIndex cZRX Coburn + * "Comptroller SashimiBorrowerIndex slZRX Coburn `, - "CompBorrowerIndex", + "SashimiBorrowerIndex", [ new Arg("comptroller", getComptroller, {implicit: true}), - new Arg("CToken", getCTokenV), + new Arg("SLToken", getSLTokenV), new Arg("account", getAddressV), ], - async (world, {comptroller, CToken, account}) => { - return new NumberV(await comptroller.methods.compBorrowerIndex(CToken._address, account.val).call()); + async (world, {comptroller, SLToken, account}) => { + return new NumberV(await comptroller.methods.sashimiBorrowerIndex(SLToken._address, account.val).call()); } ), - new Fetcher<{comptroller: Comptroller, CToken: CToken}, NumberV>(` - #### CompSpeed + new Fetcher<{comptroller: Comptroller, SLToken: SLToken}, NumberV>(` + #### SashimiSpeed - * "Comptroller CompSpeed cZRX + * "Comptroller SashimiSpeed slZRX `, - "CompSpeed", + "SashimiSpeed", [ new Arg("comptroller", getComptroller, {implicit: true}), - new Arg("CToken", getCTokenV), + new Arg("SLToken", getSLTokenV), ], - async (world, {comptroller, CToken}) => { - return new NumberV(await comptroller.methods.compSpeeds(CToken._address).call()); + async (world, {comptroller, SLToken}) => { + return new NumberV(await comptroller.methods.sashimiSpeeds(SLToken._address).call()); } ), new Fetcher<{comptroller: Comptroller}, AddressV>(` @@ -560,18 +560,18 @@ export function comptrollerFetchers() { ], async (world, {comptroller}) => new AddressV(await comptroller.methods.borrowCapGuardian().call()) ), - new Fetcher<{comptroller: Comptroller, CToken: CToken}, NumberV>(` + new Fetcher<{comptroller: Comptroller, SLToken: SLToken}, NumberV>(` #### BorrowCaps - * "Comptroller BorrowCaps cZRX + * "Comptroller BorrowCaps slZRX `, "BorrowCaps", [ new Arg("comptroller", getComptroller, {implicit: true}), - new Arg("CToken", getCTokenV), + new Arg("SLToken", getSLTokenV), ], - async (world, {comptroller, CToken}) => { - return new NumberV(await comptroller.methods.borrowCaps(CToken._address).call()); + async (world, {comptroller, SLToken}) => { + return new NumberV(await comptroller.methods.borrowCaps(SLToken._address).call()); } ) ]; diff --git a/scenario/src/Value/Erc20Value.ts b/scenario/src/Value/Erc20Value.ts index 8f31716b0..e079ce464 100644 --- a/scenario/src/Value/Erc20Value.ts +++ b/scenario/src/Value/Erc20Value.ts @@ -110,7 +110,7 @@ export function erc20Fetchers() { * "Erc20 TotalSupply" - Returns the ERC-20 token's total supply * E.g. "Erc20 ZRX TotalSupply" - * E.g. "Erc20 cZRX TotalSupply" + * E.g. "Erc20 slZRX TotalSupply" `, "TotalSupply", [ @@ -124,8 +124,8 @@ export function erc20Fetchers() { * "Erc20 TokenBalance
" - Returns the ERC-20 token balance of a given address * E.g. "Erc20 ZRX TokenBalance Geoff" - Returns a user's ZRX balance - * E.g. "Erc20 cZRX TokenBalance Geoff" - Returns a user's cZRX balance - * E.g. "Erc20 ZRX TokenBalance cZRX" - Returns cZRX's ZRX balance + * E.g. "Erc20 slZRX TokenBalance Geoff" - Returns a user's slZRX balance + * E.g. "Erc20 ZRX TokenBalance slZRX" - Returns slZRX's ZRX balance `, "TokenBalance", [ @@ -140,8 +140,8 @@ export function erc20Fetchers() { * "Erc20 Allowance owner:
spender:
" - Returns the ERC-20 allowance from owner to spender * E.g. "Erc20 ZRX Allowance Geoff Torrey" - Returns the ZRX allowance of Geoff to Torrey - * E.g. "Erc20 cZRX Allowance Geoff Coburn" - Returns the cZRX allowance of Geoff to Coburn - * E.g. "Erc20 ZRX Allowance Geoff cZRX" - Returns the ZRX allowance of Geoff to the cZRX cToken + * E.g. "Erc20 slZRX Allowance Geoff Coburn" - Returns the slZRX allowance of Geoff to Coburn + * E.g. "Erc20 ZRX Allowance Geoff slZRX" - Returns the ZRX allowance of Geoff to the slZRX slToken `, "Allowance", [ diff --git a/scenario/src/Value/GovernorValue.ts b/scenario/src/Value/GovernorValue.ts deleted file mode 100644 index c7352b500..000000000 --- a/scenario/src/Value/GovernorValue.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { Event } from '../Event'; -import { World } from '../World'; -import { Governor } from '../Contract/Governor'; -import { - getCoreValue, - getEventV, - mapValue -} from '../CoreValue'; -import { - AddressV, - EventV, - Value -} from '../Value'; -import { Arg, Fetcher, getFetcherValue } from '../Command'; -import { getProposalValue } from './ProposalValue'; -import { getGovernorAddress, getWorldContractByAddress } from '../ContractLookup'; - -export async function getGovernorV(world: World, event: Event): Promise { - const address = await mapValue( - world, - event, - (str) => new AddressV(getGovernorAddress(world, str)), - getCoreValue, - AddressV - ); - - return getWorldContractByAddress(world, address.val); -} - -export async function governorAddress(world: World, governor: Governor): Promise { - return new AddressV(governor._address); -} - -export async function getGovernorGuardian(world: World, governor: Governor): Promise { - return new AddressV(await governor.methods.guardian().call()); -} - -export function governorFetchers() { - return [ - new Fetcher<{ governor: Governor }, AddressV>(` - #### Address - - * "Governor Address" - Returns the address of governor contract - * E.g. "Governor GovernorScenario Address" - `, - "Address", - [ - new Arg("governor", getGovernorV) - ], - (world, { governor }) => governorAddress(world, governor), - { namePos: 1 } - ), - - new Fetcher<{ governor: Governor }, AddressV>(` - #### Guardian - - * "Governor Guardian" - Returns the address of governor guardian - * E.g. "Governor GovernorScenario Guardian" - `, - "Guardian", - [ - new Arg("governor", getGovernorV) - ], - (world, { governor }) => getGovernorGuardian(world, governor), - { namePos: 1 } - ), - - new Fetcher<{ governor: Governor, params: EventV }, Value>(` - #### Proposal - - * "Governor Proposal <...proposalValue>" - Returns information about a proposal - * E.g. "Governor GovernorScenario Proposal LastProposal Id" - `, - "Proposal", - [ - new Arg("governor", getGovernorV), - new Arg("params", getEventV, { variadic: true }) - ], - (world, { governor, params }) => getProposalValue(world, governor, params.val), - { namePos: 1 } - ), - ]; -} - -export async function getGovernorValue(world: World, event: Event): Promise { - return await getFetcherValue("Governor", governorFetchers(), world, event); -} diff --git a/scenario/src/Value/MCDValue.ts b/scenario/src/Value/MCDValue.ts index e970226c6..04409e05d 100644 --- a/scenario/src/Value/MCDValue.ts +++ b/scenario/src/Value/MCDValue.ts @@ -22,7 +22,7 @@ export function mcdFetchers() { #### PotAt * "MCD PotAt " - * E.g. "MCD PotAt "0xPotAddress" "pie" (CToken cDai Address)" + * E.g. "MCD PotAt "0xPotAddress" "pie" (SLToken cDai Address)" `, "PotAt", [ @@ -42,7 +42,7 @@ export function mcdFetchers() { #### VatAt * "MCD VatAt " - * E.g. "MCD VatAt "0xVatAddress" "dai" (CToken cDai Address)" + * E.g. "MCD VatAt "0xVatAddress" "dai" (SLToken cDai Address)" `, "VatAt", [ diff --git a/scenario/src/Value/ProposalValue.ts b/scenario/src/Value/ProposalValue.ts deleted file mode 100644 index c97fad212..000000000 --- a/scenario/src/Value/ProposalValue.ts +++ /dev/null @@ -1,195 +0,0 @@ -import { Event } from '../Event'; -import { World } from '../World'; -import { Governor, proposalStateEnums } from '../Contract/Governor'; -import { getAddress } from '../ContractLookup'; -import { - getAddressV, - getArrayV, - getEventV, - getNumberV, - getStringV -} from '../CoreValue'; -import { - AddressV, - BoolV, - EventV, - NumberV, - StringV, - Value -} from '../Value'; -import { Arg, Fetcher, getFetcherValue } from '../Command'; -import { encodedNumber } from '../Encoding'; - -export async function getProposalId(world: World, governor: Governor, proposalIdent: Event): Promise { - if (typeof proposalIdent === 'string' && proposalIdent === 'LastProposal') { - return Number(await governor.methods.proposalCount().call()); - } else if (Array.isArray(proposalIdent) && proposalIdent[0] === 'ActiveProposal' && typeof proposalIdent[1] === 'string') { - let proposer = getAddress(world, proposalIdent[1]); - - return Number(await governor.methods.latestProposalIds(proposer).call()); - } else { - try { - return (await getNumberV(world, proposalIdent)).toNumber(); - } catch (e) { - throw new Error(`Unknown proposal identifier \`${proposalIdent}\`, expected Number or "LastProposal"`); - } - } -} - -async function getProposal(world: World, governor: Governor, proposalIdent: Event, getter: (govener: Governor, number: encodedNumber) => Promise): Promise { - return await getter(governor, new NumberV(await getProposalId(world, governor, proposalIdent)).encode()); -} - -async function getProposalState(world: World, governor: Governor, proposalIdent: Event): Promise { - const proposalId = await getProposalId(world, governor, proposalIdent); - const stateEnum = await governor.methods.state(proposalId).call(); - return new StringV(proposalStateEnums[stateEnum]); -} - -function capitalize(s) { - return s.charAt(0).toUpperCase() + s.slice(1); -} - -export function proposalFetchers(governor: Governor) { - const fields = { - id: getNumberV, - proposer: getAddressV, - eta: getNumberV, - targets: { - constructor: getArrayV(getStringV), - getter: async (governor, proposalId) => (await governor.methods.getActions(proposalId).call())[0] - }, - values: { - constructor: getArrayV(getNumberV), - getter: async (governor, proposalId) => (await governor.methods.getActions(proposalId).call())[1] - }, - signatures: { - constructor: getArrayV(getStringV), - getter: async (governor, proposalId) => (await governor.methods.getActions(proposalId).call())[2] - }, - calldatas: { - constructor: getArrayV(getStringV), - getter: async (governor, proposalId) => (await governor.methods.getActions(proposalId).call())[3] - }, - startBlock: getNumberV, - endBlock: getNumberV, - forVotes: getNumberV, - againstVotes: getNumberV - }; - - const defaultedFields = Object.entries(fields).map(([field, values]) => { - let givenValues; - - if (typeof values === 'object') { - givenValues = values; - } else { - givenValues = { - constructor: values - } - }; - - return { - field: field, - event: capitalize(field.toString()), - getter: async (governor, proposalId) => (await governor.methods.proposals(proposalId).call())[field], - constructor: values, - name: field.toString(), - ...givenValues - }; - }); - - const baseFetchers = []>defaultedFields.map(({ field, constructor, event, name, getter }) => { - return new Fetcher<{ proposalIdent: EventV }, Value>(` - #### ${event} - - * "Governor Proposal ${event}" - Returns the ${name || field} of given proposal - * E.g. "Governor GovernorScenario Proposal 5 ${event}" - * E.g. "Governor GovernorScenario Proposal LastProposal ${event}" - `, - event, - [ - new Arg("proposalIdent", getEventV) - ], - async (world, { proposalIdent }) => await constructor(world, await getProposal(world, governor, proposalIdent.val, getter)), - { namePos: 1 } - ) - }); - - const otherFetchers = []>[ - new Fetcher<{ proposalIdent: EventV, voter: AddressV }, BoolV>(` - #### HasVoted - - * "Governor Proposal HasVoted " - Returns true if the given address has voted on given proposal - * E.g. "Governor GovernorScenario Proposal 5 HasVoted Geoff" - * E.g. "Governor GovernorScenario Proposal LastProposal HasVoted Geoff" - `, - "HasVoted", - [ - new Arg("proposalIdent", getEventV), - new Arg("voter", getAddressV) - ], - async (world, { proposalIdent, voter }) => { - const receipt = await governor.methods.getReceipt(await getProposalId(world, governor, proposalIdent.val), voter.val).call(); - return new BoolV(receipt.hasVoted); - }, - { namePos: 1 } - ), - new Fetcher<{ proposalIdent: EventV, voter: AddressV }, BoolV>(` - #### Supported - - * "Governor Proposal Supported " - Returns true if the given address has voted on given proposal - * E.g. "Governor GovernorScenario Proposal 5 Supported Geoff" - * E.g. "Governor GovernorScenario Proposal LastProposal Supported Geoff" - `, - "Supported", - [ - new Arg("proposalIdent", getEventV), - new Arg("voter", getAddressV) - ], - async (world, { proposalIdent, voter }) => { - const receipt = await governor.methods.getReceipt(await getProposalId(world, governor, proposalIdent.val), voter.val).call(); - return new BoolV(receipt.support); - }, - { namePos: 1 } - ), - new Fetcher<{ proposalIdent: EventV, voter: AddressV }, NumberV>(` - #### VotesCast - - * "Governor Proposal VotesCast " - Returns true if the given address has voted on given proposal - * E.g. "Governor GovernorScenario Proposal 5 VotesCast Geoff" - * E.g. "Governor GovernorScenario Proposal LastProposal VotesCast Geoff" - `, - "VotesCast", - [ - new Arg("proposalIdent", getEventV), - new Arg("voter", getAddressV) - ], - async (world, { proposalIdent, voter }) => { - const receipt = await governor.methods.getReceipt(await getProposalId(world, governor, proposalIdent.val), voter.val).call(); - return new NumberV(receipt.votes); - }, - { namePos: 1 } - ), - new Fetcher<{ proposalIdent: EventV }, StringV>(` - #### State - - * "Governor Proposal State" - Returns a string of a proposal's current state - * E.g. "Governor GovernorScenario Proposal LastProposal State" - `, - "State", - [ - new Arg("proposalIdent", getEventV), - ], - async (world, { proposalIdent }) => { - return await getProposalState(world, governor, proposalIdent.val); - }, - { namePos: 1 } - ) - ]; - - return baseFetchers.concat(otherFetchers); -} - -export async function getProposalValue(world: World, governor: Governor, event: Event): Promise { - return await getFetcherValue("Proposal", proposalFetchers(governor), world, event); -} diff --git a/scenario/src/Value/SLTokenDelegateValue.ts b/scenario/src/Value/SLTokenDelegateValue.ts new file mode 100644 index 000000000..c296420df --- /dev/null +++ b/scenario/src/Value/SLTokenDelegateValue.ts @@ -0,0 +1,51 @@ +import { Event } from '../Event'; +import { World } from '../World'; +import { SLErc20Delegate } from '../Contract/SLErc20Delegate'; +import { + getCoreValue, + mapValue +} from '../CoreValue'; +import { Arg, Fetcher, getFetcherValue } from '../Command'; +import { + AddressV, + Value, +} from '../Value'; +import { getWorldContractByAddress, getSLTokenDelegateAddress } from '../ContractLookup'; + +export async function getSLTokenDelegateV(world: World, event: Event): Promise { + const address = await mapValue( + world, + event, + (str) => new AddressV(getSLTokenDelegateAddress(world, str)), + getCoreValue, + AddressV + ); + + return getWorldContractByAddress(world, address.val); +} + +async function slTokenDelegateAddress(world: World, slTokenDelegate: SLErc20Delegate): Promise { + return new AddressV(slTokenDelegate._address); +} + +export function slTokenDelegateFetchers() { + return [ + new Fetcher<{ slTokenDelegate: SLErc20Delegate }, AddressV>(` + #### Address + + * "SLTokenDelegate Address" - Returns address of SLTokenDelegate contract + * E.g. "SLTokenDelegate slDaiDelegate Address" - Returns slDaiDelegate's address + `, + "Address", + [ + new Arg("slTokenDelegate", getSLTokenDelegateV) + ], + (world, { slTokenDelegate }) => slTokenDelegateAddress(world, slTokenDelegate), + { namePos: 1 } + ), + ]; +} + +export async function getSLTokenDelegateValue(world: World, event: Event): Promise { + return await getFetcherValue("SLTokenDelegate", slTokenDelegateFetchers(), world, event); +} diff --git a/scenario/src/Value/SLTokenValue.ts b/scenario/src/Value/SLTokenValue.ts new file mode 100644 index 000000000..2f77a91e1 --- /dev/null +++ b/scenario/src/Value/SLTokenValue.ts @@ -0,0 +1,395 @@ +import { Event } from '../Event'; +import { World } from '../World'; +import { SLToken } from '../Contract/SLToken'; +import { SLErc20Delegator } from '../Contract/SLErc20Delegator'; +import { Erc20 } from '../Contract/Erc20'; +import { + getAddressV, + getCoreValue, + getStringV, + mapValue +} from '../CoreValue'; +import { Arg, Fetcher, getFetcherValue } from '../Command'; +import { + AddressV, + NumberV, + Value, + StringV +} from '../Value'; +import { getWorldContractByAddress, getSLTokenAddress } from '../ContractLookup'; + +export async function getSLTokenV(world: World, event: Event): Promise { + const address = await mapValue( + world, + event, + (str) => new AddressV(getSLTokenAddress(world, str)), + getCoreValue, + AddressV + ); + + return getWorldContractByAddress(world, address.val); +} + +export async function getSLErc20DelegatorV(world: World, event: Event): Promise { + const address = await mapValue( + world, + event, + (str) => new AddressV(getSLTokenAddress(world, str)), + getCoreValue, + AddressV + ); + + return getWorldContractByAddress(world, address.val); +} + +async function getInterestRateModel(world: World, slToken: SLToken): Promise { + return new AddressV(await slToken.methods.interestRateModel().call()); +} + +async function slTokenAddress(world: World, slToken: SLToken): Promise { + return new AddressV(slToken._address); +} + +async function getSLTokenAdmin(world: World, slToken: SLToken): Promise { + return new AddressV(await slToken.methods.admin().call()); +} + +async function getSLTokenPendingAdmin(world: World, slToken: SLToken): Promise { + return new AddressV(await slToken.methods.pendingAdmin().call()); +} + +async function balanceOfUnderlying(world: World, slToken: SLToken, user: string): Promise { + return new NumberV(await slToken.methods.balanceOfUnderlying(user).call()); +} + +async function getBorrowBalance(world: World, slToken: SLToken, user): Promise { + return new NumberV(await slToken.methods.borrowBalanceCurrent(user).call()); +} + +async function getBorrowBalanceStored(world: World, slToken: SLToken, user): Promise { + return new NumberV(await slToken.methods.borrowBalanceStored(user).call()); +} + +async function getTotalBorrows(world: World, slToken: SLToken): Promise { + return new NumberV(await slToken.methods.totalBorrows().call()); +} + +async function getTotalBorrowsCurrent(world: World, slToken: SLToken): Promise { + return new NumberV(await slToken.methods.totalBorrowsCurrent().call()); +} + +async function getReserveFactor(world: World, slToken: SLToken): Promise { + return new NumberV(await slToken.methods.reserveFactorMantissa().call(), 1.0e18); +} + +async function getTotalReserves(world: World, slToken: SLToken): Promise { + return new NumberV(await slToken.methods.totalReserves().call()); +} + +async function getComptroller(world: World, slToken: SLToken): Promise { + return new AddressV(await slToken.methods.comptroller().call()); +} + +async function getExchangeRateStored(world: World, slToken: SLToken): Promise { + return new NumberV(await slToken.methods.exchangeRateStored().call()); +} + +async function getExchangeRate(world: World, slToken: SLToken): Promise { + return new NumberV(await slToken.methods.exchangeRateCurrent().call(), 1e18); +} + +async function getCash(world: World, slToken: SLToken): Promise { + return new NumberV(await slToken.methods.getCash().call()); +} + +async function getInterestRate(world: World, slToken: SLToken): Promise { + return new NumberV(await slToken.methods.borrowRatePerBlock().call(), 1.0e18 / 2102400); +} + +async function getImplementation(world: World, slToken: SLToken): Promise { + return new AddressV(await (slToken as SLErc20Delegator).methods.implementation().call()); +} + +export function slTokenFetchers() { + return [ + new Fetcher<{ slToken: SLToken }, AddressV>(` + #### Address + + * "SLToken Address" - Returns address of SLToken contract + * E.g. "SLToken slZRX Address" - Returns slZRX's address + `, + "Address", + [ + new Arg("slToken", getSLTokenV) + ], + (world, { slToken }) => slTokenAddress(world, slToken), + { namePos: 1 } + ), + + new Fetcher<{ slToken: SLToken }, AddressV>(` + #### InterestRateModel + + * "SLToken InterestRateModel" - Returns the interest rate model of SLToken contract + * E.g. "SLToken slZRX InterestRateModel" - Returns slZRX's interest rate model + `, + "InterestRateModel", + [ + new Arg("slToken", getSLTokenV) + ], + (world, { slToken }) => getInterestRateModel(world, slToken), + { namePos: 1 } + ), + + new Fetcher<{ slToken: SLToken }, AddressV>(` + #### Admin + + * "SLToken Admin" - Returns the admin of SLToken contract + * E.g. "SLToken slZRX Admin" - Returns slZRX's admin + `, + "Admin", + [ + new Arg("slToken", getSLTokenV) + ], + (world, { slToken }) => getSLTokenAdmin(world, slToken), + { namePos: 1 } + ), + + new Fetcher<{ slToken: SLToken }, AddressV>(` + #### PendingAdmin + + * "SLToken PendingAdmin" - Returns the pending admin of SLToken contract + * E.g. "SLToken slZRX PendingAdmin" - Returns slZRX's pending admin + `, + "PendingAdmin", + [ + new Arg("slToken", getSLTokenV) + ], + (world, { slToken }) => getSLTokenPendingAdmin(world, slToken), + { namePos: 1 } + ), + + new Fetcher<{ slToken: SLToken }, AddressV>(` + #### Underlying + + * "SLToken Underlying" - Returns the underlying asset (if applicable) + * E.g. "SLToken slZRX Underlying" + `, + "Underlying", + [ + new Arg("slToken", getSLTokenV) + ], + async (world, { slToken }) => new AddressV(await slToken.methods.underlying().call()), + { namePos: 1 } + ), + + new Fetcher<{ slToken: SLToken, address: AddressV }, NumberV>(` + #### UnderlyingBalance + + * "SLToken UnderlyingBalance " - Returns a user's underlying balance (based on given exchange rate) + * E.g. "SLToken slZRX UnderlyingBalance Geoff" + `, + "UnderlyingBalance", + [ + new Arg("slToken", getSLTokenV), + new Arg("address", getAddressV) + ], + (world, { slToken, address }) => balanceOfUnderlying(world, slToken, address.val), + { namePos: 1 } + ), + + new Fetcher<{ slToken: SLToken, address: AddressV }, NumberV>(` + #### BorrowBalance + + * "SLToken BorrowBalance " - Returns a user's borrow balance (including interest) + * E.g. "SLToken slZRX BorrowBalance Geoff" + `, + "BorrowBalance", + [ + new Arg("slToken", getSLTokenV), + new Arg("address", getAddressV) + ], + (world, { slToken, address }) => getBorrowBalance(world, slToken, address.val), + { namePos: 1 } + ), + + new Fetcher<{ slToken: SLToken, address: AddressV }, NumberV>(` + #### BorrowBalanceStored + + * "SLToken BorrowBalanceStored " - Returns a user's borrow balance (without specifically re-accruing interest) + * E.g. "SLToken slZRX BorrowBalanceStored Geoff" + `, + "BorrowBalanceStored", + [ + new Arg("slToken", getSLTokenV), + new Arg("address", getAddressV) + ], + (world, { slToken, address }) => getBorrowBalanceStored(world, slToken, address.val), + { namePos: 1 } + ), + + new Fetcher<{ slToken: SLToken }, NumberV>(` + #### TotalBorrows + + * "SLToken TotalBorrows" - Returns the slToken's total borrow balance + * E.g. "SLToken slZRX TotalBorrows" + `, + "TotalBorrows", + [ + new Arg("slToken", getSLTokenV) + ], + (world, { slToken }) => getTotalBorrows(world, slToken), + { namePos: 1 } + ), + + new Fetcher<{ slToken: SLToken }, NumberV>(` + #### TotalBorrowsCurrent + + * "SLToken TotalBorrowsCurrent" - Returns the slToken's total borrow balance with interest + * E.g. "SLToken slZRX TotalBorrowsCurrent" + `, + "TotalBorrowsCurrent", + [ + new Arg("slToken", getSLTokenV) + ], + (world, { slToken }) => getTotalBorrowsCurrent(world, slToken), + { namePos: 1 } + ), + + new Fetcher<{ slToken: SLToken }, NumberV>(` + #### Reserves + + * "SLToken Reserves" - Returns the slToken's total reserves + * E.g. "SLToken slZRX Reserves" + `, + "Reserves", + [ + new Arg("slToken", getSLTokenV) + ], + (world, { slToken }) => getTotalReserves(world, slToken), + { namePos: 1 } + ), + + new Fetcher<{ slToken: SLToken }, NumberV>(` + #### ReserveFactor + + * "SLToken ReserveFactor" - Returns reserve factor of SLToken contract + * E.g. "SLToken slZRX ReserveFactor" - Returns slZRX's reserve factor + `, + "ReserveFactor", + [ + new Arg("slToken", getSLTokenV) + ], + (world, { slToken }) => getReserveFactor(world, slToken), + { namePos: 1 } + ), + + new Fetcher<{ slToken: SLToken }, AddressV>(` + #### Comptroller + + * "SLToken Comptroller" - Returns the slToken's comptroller + * E.g. "SLToken slZRX Comptroller" + `, + "Comptroller", + [ + new Arg("slToken", getSLTokenV) + ], + (world, { slToken }) => getComptroller(world, slToken), + { namePos: 1 } + ), + + new Fetcher<{ slToken: SLToken }, NumberV>(` + #### ExchangeRateStored + + * "SLToken ExchangeRateStored" - Returns the slToken's exchange rate (based on balances stored) + * E.g. "SLToken slZRX ExchangeRateStored" + `, + "ExchangeRateStored", + [ + new Arg("slToken", getSLTokenV) + ], + (world, { slToken }) => getExchangeRateStored(world, slToken), + { namePos: 1 } + ), + + new Fetcher<{ slToken: SLToken }, NumberV>(` + #### ExchangeRate + + * "SLToken ExchangeRate" - Returns the slToken's current exchange rate + * E.g. "SLToken slZRX ExchangeRate" + `, + "ExchangeRate", + [ + new Arg("slToken", getSLTokenV) + ], + (world, { slToken }) => getExchangeRate(world, slToken), + { namePos: 1 } + ), + + new Fetcher<{ slToken: SLToken }, NumberV>(` + #### Cash + + * "SLToken Cash" - Returns the slToken's current cash + * E.g. "SLToken slZRX Cash" + `, + "Cash", + [ + new Arg("slToken", getSLTokenV) + ], + (world, { slToken }) => getCash(world, slToken), + { namePos: 1 } + ), + + new Fetcher<{ slToken: SLToken }, NumberV>(` + #### InterestRate + + * "SLToken InterestRate" - Returns the slToken's current interest rate + * E.g. "SLToken slZRX InterestRate" + `, + "InterestRate", + [ + new Arg("slToken", getSLTokenV) + ], + (world, {slToken}) => getInterestRate(world, slToken), + {namePos: 1} + ), + new Fetcher<{slToken: SLToken, signature: StringV}, NumberV>(` + #### CallNum + + * "SLToken Call " - Simple direct call method, for now with no parameters + * E.g. "SLToken slZRX Call \"borrowIndex()\"" + `, + "CallNum", + [ + new Arg("slToken", getSLTokenV), + new Arg("signature", getStringV), + ], + async (world, {slToken, signature}) => { + const res = await world.web3.eth.call({ + to: slToken._address, + data: world.web3.eth.abi.encodeFunctionSignature(signature.val) + }) + const resNum : any = world.web3.eth.abi.decodeParameter('uint256',res); + return new NumberV(resNum); + } + , + {namePos: 1} + ), + new Fetcher<{ slToken: SLToken }, AddressV>(` + #### Implementation + + * "SLToken Implementation" - Returns the slToken's current implementation + * E.g. "SLToken slDAI Implementation" + `, + "Implementation", + [ + new Arg("slToken", getSLTokenV) + ], + (world, { slToken }) => getImplementation(world, slToken), + { namePos: 1 } + ) + ]; +} + +export async function getSLTokenValue(world: World, event: Event): Promise { + return await getFetcherValue("slToken", slTokenFetchers(), world, event); +} diff --git a/script/saddle/flywheelInit.js b/script/saddle/flywheelInit.js index eeaa6b6cf..304d3ef01 100644 --- a/script/saddle/flywheelInit.js +++ b/script/saddle/flywheelInit.js @@ -51,13 +51,13 @@ let getConfig = (configArgs) => { return res; }; -let getCTokenAddresses = (cTokenArgs) => { +let getSLTokenAddresses = (cTokenArgs) => { let all = [ 'cUSDC', 'cDAI', 'cUSDT', 'cBAT', - 'cETH', + 'slETH', 'cSAI', 'cREP', 'cZRX', @@ -140,14 +140,14 @@ let accountRequest = async (network, opts) => { return JSON.parse(res).accounts; }; -let filterInitialized = async (borrowersByCToken) => { +let filterInitialized = async (borrowersBySLToken) => { let res = {} let batchSize = 75; console.log(`Calling compBorrowerIndex for borrowers in batches of ${batchSize}...\n`); - for(let cTokenAddr of Object.keys(borrowersByCToken)) { + for(let cTokenAddr of Object.keys(borrowersBySLToken)) { let speed = await call(Comptroller, 'compSpeeds', [cTokenAddr]); if (Number(speed) != 0){ - for (let borrowerChunk of getChunks(borrowersByCToken[cTokenAddr], batchSize)) { + for (let borrowerChunk of getChunks(borrowersBySLToken[cTokenAddr], batchSize)) { try { let indices = await Promise.all(borrowerChunk.map( async(borrower) => { @@ -169,9 +169,9 @@ let filterInitialized = async (borrowersByCToken) => { let filterBorrowers = (apiAccounts, cTokenList) => { return apiAccounts.reduce((acc, account) => { let validBorrowers = account.tokens.filter( - (accountCToken) => - cTokenList.includes(accountCToken.address) && - accountCToken.borrow_balance_underlying.value > 0 + (accountSLToken) => + cTokenList.includes(accountSLToken.address) && + accountSLToken.borrow_balance_underlying.value > 0 ); for (let borrower of validBorrowers) { let ctokenAddr = borrower.address; @@ -183,9 +183,9 @@ let filterBorrowers = (apiAccounts, cTokenList) => { }, {}); }; -let claimCompBatch = async (borrowersByCToken, opts) => { - for (let cTokenAddr of Object.keys(borrowersByCToken)) { - let borrowers = borrowersByCToken[cTokenAddr]; +let claimCompBatch = async (borrowersBySLToken, opts) => { + for (let cTokenAddr of Object.keys(borrowersBySLToken)) { + let borrowers = borrowersBySLToken[cTokenAddr]; for (let chunk of getChunks(borrowers, opts.batch)) { if (chunk.length == 0) { console.log(`No borrowers to claim for ${cTokenAddr}`); @@ -214,25 +214,25 @@ let claimCompBatch = async (borrowersByCToken, opts) => { }; (async () => { - let borrowersByCToken; + let borrowersBySLToken; let cTokenMap; // symbol => addrs let opts = getConfig(args[0]); if (network == 'development') { - borrowersByCToken = getTestData(); + borrowersBySLToken = getTestData(); } else if (isKnownNetwork(network)) { let apiAccounts = opts.readFixture ? await readFixture() : await accountRequest(network, opts); - let cTokenAddresses = Object.values(getCTokenAddresses(opts.cTokens)); - borrowersByCToken = filterBorrowers(apiAccounts, cTokenAddresses); + let cTokenAddresses = Object.values(getSLTokenAddresses(opts.cTokens)); + borrowersBySLToken = filterBorrowers(apiAccounts, cTokenAddresses); if (opts.writeFixture) await writeFixture(apiAccounts); } else { printUsage(); } - let unInit = await filterInitialized(borrowersByCToken); + let unInit = await filterInitialized(borrowersBySLToken); print('Uninitialized accounts before: ', unInit); await claimCompBatch(unInit, opts); - unInit = await filterInitialized(borrowersByCToken); + unInit = await filterInitialized(borrowersBySLToken); print('Uninitialized accounts after: ', unInit); })(); diff --git a/script/scen/deploy.scen b/script/scen/deploy.scen index d9a66a506..59e3e954c 100755 --- a/script/scen/deploy.scen +++ b/script/scen/deploy.scen @@ -18,14 +18,14 @@ Gate (Erc20 REP Address) (Erc20 Deploy Standard REP "Augur") Gate (Erc20 USDC Address) (Erc20 Deploy Standard USDC "USD Coin" 6) -- Now deploy our cTokens -Gate (CToken cZRX Address) (CToken Deploy CErc20 cZRX "Test 0x 📈" (Erc20 ZRX Address) (Comptroller Address) (InterestRateModel InterestRateModel Address) 0.2e9 8) -Gate (CToken cBAT Address) (CToken Deploy CErc20 cBAT "Test Basic Attention Token 📈" (Erc20 BAT Address) (Comptroller Address) (InterestRateModel InterestRateModel Address) 0.2e9 8) -Gate (CToken cDAI Address) (CToken Deploy CErc20 cDAI "Test Dai 📈" (Erc20 DAI Address) (Comptroller Address) (InterestRateModel InterestRateModel Address) 0.2e9 8) -Gate (CToken cREP Address) (CToken Deploy CErc20 cREP "Test Augur 📈" (Erc20 REP Address) (Comptroller Address) (InterestRateModel InterestRateModel Address) 0.2e9 8) -Gate (CToken cETH Address) (CToken Deploy CEther cETH "Test Ether 📈" (Comptroller Address) (InterestRateModel InterestRateModel Address) 0.2e9 8) -Gate (CToken cUSDC Address) (CToken Deploy CErc20 cUSDC "Test USD Coin 📈" (Erc20 USDC Address) (Comptroller Address) (InterestRateModel InterestRateModel Address) 2e-4 8) +Gate (SLToken slZRX Address) (SLToken Deploy CErc20 slZRX "Test 0x 📈" (Erc20 ZRX Address) (Comptroller Address) (InterestRateModel InterestRateModel Address) 0.2e9 8) +Gate (SLToken slBAT Address) (SLToken Deploy CErc20 slBAT "Test Basic Attention Token 📈" (Erc20 BAT Address) (Comptroller Address) (InterestRateModel InterestRateModel Address) 0.2e9 8) +Gate (SLToken slDAI Address) (SLToken Deploy CErc20 slDAI "Test Dai 📈" (Erc20 DAI Address) (Comptroller Address) (InterestRateModel InterestRateModel Address) 0.2e9 8) +Gate (SLToken slREP Address) (SLToken Deploy CErc20 slREP "Test Augur 📈" (Erc20 REP Address) (Comptroller Address) (InterestRateModel InterestRateModel Address) 0.2e9 8) +Gate (SLToken slETH Address) (SLToken Deploy CEther slETH "Test Ether 📈" (Comptroller Address) (InterestRateModel InterestRateModel Address) 0.2e9 8) +Gate (SLToken slUSDC Address) (SLToken Deploy CErc20 slUSDC "Test USD Coin 📈" (Erc20 USDC Address) (Comptroller Address) (InterestRateModel InterestRateModel Address) 2e-4 8) -- Deploy Maximillion -Gate (Maximillion Address) (Maximillion Deploy cETH) +Gate (Maximillion Address) (Maximillion Deploy slETH) -Print "Deployed Comptroller and cTokens: cETH, cBAT, cDAI, cREP, cUSDC and cZRX" +Print "Deployed Comptroller and cTokens: slETH, slBAT, slDAI, slREP, slUSDC and slZRX" diff --git a/script/scen/scriptFlywheel.scen b/script/scen/scriptFlywheel.scen index 7cbb6282f..5ce3e5cdc 100755 --- a/script/scen/scriptFlywheel.scen +++ b/script/scen/scriptFlywheel.scen @@ -13,43 +13,43 @@ Comptroller SetPriceOracle (PriceOracleProxy Address) Comptroller SetMaxAssets 20 Comptroller SetCloseFactor 0.5 Comptroller LiquidationIncentive 1.1 -NewCToken ZRX cZRX -NewCToken BAT cBAT -Support cZRX collateralFactor:0.5 -Support cBAT collateralFactor:0.5 +NewSLToken ZRX slZRX +NewSLToken BAT slBAT +Support slZRX collateralFactor:0.5 +Support slBAT collateralFactor:0.5 -- final ComptrollerImpl Deploy Scenario ComptrollerScen Unitroller SetPendingImpl ComptrollerScen -Prep Geoff 100e18 ZRX cZRX -Mint Geoff 50e18 cZRX--tokenbalance = 50e18 / 2e9 = 2.5e10 +Prep Geoff 100e18 ZRX slZRX +Mint Geoff 50e18 slZRX--tokenbalance = 50e18 / 2e9 = 2.5e10 -Prep Fourth Some BAT cBAT -Mint Fourth 6e18 cBAT -EnterMarkets Fourth cBAT -Borrow Fourth 1e18 cZRX +Prep Fourth Some BAT slBAT +Mint Fourth 6e18 slBAT +EnterMarkets Fourth slBAT +Borrow Fourth 1e18 slZRX -Prep Fifth Some BAT cBAT -Mint Fifth 6e18 cBAT -EnterMarkets Fifth cBAT -Borrow Fifth 1e18 cZRX +Prep Fifth Some BAT slBAT +Mint Fifth 6e18 slBAT +EnterMarkets Fifth slBAT +Borrow Fifth 1e18 slZRX -Prep Sixth Some BAT cBAT -Mint Sixth 6e18 cBAT -EnterMarkets Sixth cBAT -Borrow Sixth 1e18 cZRX +Prep Sixth Some BAT slBAT +Mint Sixth 6e18 slBAT +EnterMarkets Sixth slBAT +Borrow Sixth 1e18 slZRX -Prep Seventh Some BAT cBAT -Mint Seventh 6e18 cBAT -EnterMarkets Seventh cBAT -Borrow Seventh 1e18 cZRX +Prep Seventh Some BAT slBAT +Mint Seventh 6e18 slBAT +EnterMarkets Seventh slBAT +Borrow Seventh 1e18 slZRX -ComptrollerImpl ComptrollerScen Become 1e18 [cZRX cBAT] -Erc20 Deploy Standard COMP "COMP Token" 18 -Give (Address Comptroller) 5000000e18 COMP -Comptroller Send "setCompAddress(address)" (Address COMP) +ComptrollerImpl ComptrollerScen Become 1e18 [slZRX slBAT] +Erc20 Deploy Standard SASHIMI "SASHIMI Token" 18 +Give (Address Comptroller) 5000000e18 SASHIMI +Comptroller Send "setSashimiAddress(address)" (Address SASHIMI) -Comptroller RefreshCompSpeeds +Comptroller RefreshSashimiSpeeds FastForward 300000 Blocks Read (Comptroller Address) diff --git a/spec/certora/contracts/ComptrollerCertora.sol b/spec/certora/contracts/ComptrollerCertora.sol index 5f78d1691..96b32e3b1 100644 --- a/spec/certora/contracts/ComptrollerCertora.sol +++ b/spec/certora/contracts/ComptrollerCertora.sol @@ -8,7 +8,7 @@ contract ComptrollerCertora is Comptroller { function getHypotheticalAccountLiquidityInternal( address account, - CToken cTokenModify, + SLToken slTokenModify, uint redeemTokens, uint borrowAmount) internal view returns (Error, uint, uint) { if (switcher == 0) diff --git a/spec/certora/contracts/MaximillionCertora.sol b/spec/certora/contracts/MaximillionCertora.sol index c178836b0..868c9c6e3 100644 --- a/spec/certora/contracts/MaximillionCertora.sol +++ b/spec/certora/contracts/MaximillionCertora.sol @@ -3,10 +3,10 @@ pragma solidity ^0.5.16; import "../../../contracts/Maximillion.sol"; contract MaximillionCertora is Maximillion { - constructor(CEther cEther_) public Maximillion(cEther_) {} + constructor(SLEther slEther_) public Maximillion(slEther_) {} function borrowBalance(address account) external returns (uint) { - return cEther.borrowBalanceCurrent(account); + return slEther.borrowBalanceCurrent(account); } function etherBalance(address account) external returns (uint) { diff --git a/spec/certora/contracts/PriceOracleModel.sol b/spec/certora/contracts/PriceOracleModel.sol index 030c73e69..4119c0bb4 100644 --- a/spec/certora/contracts/PriceOracleModel.sol +++ b/spec/certora/contracts/PriceOracleModel.sol @@ -9,7 +9,7 @@ contract PriceOracleModel is PriceOracle { return true; } - function getUnderlyingPrice(CToken cToken) external view returns (uint) { + function getUnderlyingPrice(SLToken slToken) external view returns (uint) { return dummy; } } \ No newline at end of file diff --git a/spec/certora/contracts/CDaiDelegateCertora.sol b/spec/certora/contracts/SLDaiDelegateCertora.sol similarity index 63% rename from spec/certora/contracts/CDaiDelegateCertora.sol rename to spec/certora/contracts/SLDaiDelegateCertora.sol index 6a8c2b977..572260fe4 100644 --- a/spec/certora/contracts/CDaiDelegateCertora.sol +++ b/spec/certora/contracts/SLDaiDelegateCertora.sol @@ -1,8 +1,8 @@ pragma solidity ^0.5.16; -import "../../../contracts/CDaiDelegate.sol"; +import "../../../contracts/SLDaiDelegate.sol"; -contract CDaiDelegateCertora is CDaiDelegate { +contract SLDaiDelegateCertora is SLDaiDelegate { function getCashOf(address account) public view returns (uint) { return EIP20Interface(underlying).balanceOf(account); } diff --git a/spec/certora/contracts/CErc20DelegateCertora.sol b/spec/certora/contracts/SLErc20DelegateCertora.sol similarity index 85% rename from spec/certora/contracts/CErc20DelegateCertora.sol rename to spec/certora/contracts/SLErc20DelegateCertora.sol index ee3ec3ec9..f60004ded 100644 --- a/spec/certora/contracts/CErc20DelegateCertora.sol +++ b/spec/certora/contracts/SLErc20DelegateCertora.sol @@ -1,12 +1,12 @@ pragma solidity ^0.5.16; -import "../../../contracts/CErc20Delegate.sol"; +import "../../../contracts/SLErc20Delegate.sol"; import "../../../contracts/EIP20Interface.sol"; -import "./CTokenCollateral.sol"; +import "./SLTokenCollateral.sol"; -contract CErc20DelegateCertora is CErc20Delegate { - CTokenCollateral public otherToken; +contract SLErc20DelegateCertora is SLErc20Delegate { + SLTokenCollateral public otherToken; function mintFreshPub(address minter, uint mintAmount) public returns (uint) { (uint error,) = mintFresh(minter, mintAmount); diff --git a/spec/certora/contracts/CErc20DelegatorCertora.sol b/spec/certora/contracts/SLErc20DelegatorCertora.sol similarity index 88% rename from spec/certora/contracts/CErc20DelegatorCertora.sol rename to spec/certora/contracts/SLErc20DelegatorCertora.sol index 87394538c..18b2ac545 100644 --- a/spec/certora/contracts/CErc20DelegatorCertora.sol +++ b/spec/certora/contracts/SLErc20DelegatorCertora.sol @@ -1,12 +1,12 @@ pragma solidity ^0.5.16; -import "../../../contracts/CErc20Delegator.sol"; +import "../../../contracts/SLErc20Delegator.sol"; import "../../../contracts/EIP20Interface.sol"; -import "./CTokenCollateral.sol"; +import "./SLTokenCollateral.sol"; -contract CErc20DelegatorCertora is CErc20Delegator { - CTokenCollateral public otherToken; +contract SLErc20DelegatorCertora is SLErc20Delegator { + SLTokenCollateral public otherToken; constructor(address underlying_, ComptrollerInterface comptroller_, @@ -17,7 +17,7 @@ contract CErc20DelegatorCertora is CErc20Delegator { uint8 decimals_, address payable admin_, address implementation_, - bytes memory becomeImplementationData) public CErc20Delegator(underlying_, comptroller_, interestRateModel_, initialExchangeRateMantissa_, name_, symbol_, decimals_, admin_, implementation_, becomeImplementationData) { + bytes memory becomeImplementationData) public SLErc20Delegator(underlying_, comptroller_, interestRateModel_, initialExchangeRateMantissa_, name_, symbol_, decimals_, admin_, implementation_, becomeImplementationData) { comptroller; // touch for Certora slot deduction interestRateModel; // touch for Certora slot deduction } diff --git a/spec/certora/contracts/CErc20ImmutableCertora.sol b/spec/certora/contracts/SLErc20ImmutableCertora.sol similarity index 87% rename from spec/certora/contracts/CErc20ImmutableCertora.sol rename to spec/certora/contracts/SLErc20ImmutableCertora.sol index 1b345086f..39d9bb48c 100644 --- a/spec/certora/contracts/CErc20ImmutableCertora.sol +++ b/spec/certora/contracts/SLErc20ImmutableCertora.sol @@ -1,12 +1,12 @@ pragma solidity ^0.5.16; -import "../../../contracts/CErc20Immutable.sol"; +import "../../../contracts/SLErc20Immutable.sol"; import "../../../contracts/EIP20Interface.sol"; -import "./CTokenCollateral.sol"; +import "./SLTokenCollateral.sol"; -contract CErc20ImmutableCertora is CErc20Immutable { - CTokenCollateral public otherToken; +contract SLErc20ImmutableCertora is SLErc20Immutable { + SLTokenCollateral public otherToken; constructor(address underlying_, ComptrollerInterface comptroller_, @@ -15,7 +15,7 @@ contract CErc20ImmutableCertora is CErc20Immutable { string memory name_, string memory symbol_, uint8 decimals_, - address payable admin_) public CErc20Immutable(underlying_, comptroller_, interestRateModel_, initialExchangeRateMantissa_, name_, symbol_, decimals_, admin_) { + address payable admin_) public SLErc20Immutable(underlying_, comptroller_, interestRateModel_, initialExchangeRateMantissa_, name_, symbol_, decimals_, admin_) { } function balanceOfInOther(address account) public view returns (uint) { diff --git a/spec/certora/contracts/CEtherCertora.sol b/spec/certora/contracts/SLEtherCertora.sol similarity index 56% rename from spec/certora/contracts/CEtherCertora.sol rename to spec/certora/contracts/SLEtherCertora.sol index 6ac66c429..33c92a299 100644 --- a/spec/certora/contracts/CEtherCertora.sol +++ b/spec/certora/contracts/SLEtherCertora.sol @@ -1,14 +1,14 @@ pragma solidity ^0.5.16; -import "../../../contracts/CEther.sol"; +import "../../../contracts/SLEther.sol"; -contract CEtherCertora is CEther { +contract SLEtherCertora is SLEther { constructor(ComptrollerInterface comptroller_, InterestRateModel interestRateModel_, uint initialExchangeRateMantissa_, string memory name_, string memory symbol_, uint8 decimals_, - address payable admin_) public CEther(comptroller_, interestRateModel_, initialExchangeRateMantissa_, name_, symbol_, decimals_, admin_) { + address payable admin_) public SLEther(comptroller_, interestRateModel_, initialExchangeRateMantissa_, name_, symbol_, decimals_, admin_) { } } diff --git a/spec/certora/contracts/CTokenCollateral.sol b/spec/certora/contracts/SLTokenCollateral.sol similarity index 65% rename from spec/certora/contracts/CTokenCollateral.sol rename to spec/certora/contracts/SLTokenCollateral.sol index c36105432..30cc3eaff 100644 --- a/spec/certora/contracts/CTokenCollateral.sol +++ b/spec/certora/contracts/SLTokenCollateral.sol @@ -1,9 +1,9 @@ pragma solidity ^0.5.16; -import "../../../contracts/CErc20Immutable.sol"; +import "../../../contracts/SLErc20Immutable.sol"; import "../../../contracts/EIP20Interface.sol"; -contract CTokenCollateral is CErc20Immutable { +contract SLTokenCollateral is SLErc20Immutable { constructor(address underlying_, ComptrollerInterface comptroller_, InterestRateModel interestRateModel_, @@ -11,7 +11,7 @@ contract CTokenCollateral is CErc20Immutable { string memory name_, string memory symbol_, uint8 decimals_, - address payable admin_) public CErc20Immutable(underlying_, comptroller_, interestRateModel_, initialExchangeRateMantissa_, name_, symbol_, decimals_, admin_) { + address payable admin_) public SLErc20Immutable(underlying_, comptroller_, interestRateModel_, initialExchangeRateMantissa_, name_, symbol_, decimals_, admin_) { } function getCashOf(address account) public view returns (uint) { diff --git a/spec/scenario/AddReserves.scen b/spec/scenario/AddReserves.scen index 57f9ca822..7c026a926 100644 --- a/spec/scenario/AddReserves.scen +++ b/spec/scenario/AddReserves.scen @@ -1,133 +1,133 @@ Test "Add all reserves and verify effects" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff 50e18 ZRX cZRX - Mint Geoff 50e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 500e8) -- 50e18 / 1e9 - Assert Equal (CToken cZRX UnderlyingBalance Geoff) (Exactly 50e18) - Assert Equal (CToken cZRX ExchangeRate) (Exactly 1e9) + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff 50e18 ZRX slZRX + Mint Geoff 50e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 500e8) -- 50e18 / 1e9 + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) (Exactly 50e18) + Assert Equal (SLToken slZRX ExchangeRate) (Exactly 1e9) -- Get some brah to borrow then repay - BorrowAndRepayWithInterest ZRX cZRX 10e18 5e18 interestRate:0.000001 blocks:500000 reserveRate:0.2 + BorrowAndRepayWithInterest ZRX slZRX 10e18 5e18 interestRate:0.000001 blocks:500000 reserveRate:0.2 -- We've accrued .0001% interest for 500000 blocks, or 50% of the principal (10e18), -- thus, we should have accrued 5e18 of interest for the protocol -- The reserves should get 20% of this, or 1e18, and the rest -- is due pro-rata to all suppliers. We just have one, so -- let's check that account is given correct new balance. - Assert Equal (Erc20 ZRX TokenBalance cZRX) (Exactly 55e18) + Assert Equal (Erc20 ZRX TokenBalance slZRX) (Exactly 55e18) Assert Equal (Erc20 ZRX TokenBalance Root) (Exactly 0e18) - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 500e8) - Assert Equal (CToken cZRX Reserves) (Exactly 1e18) - Assert Equal (CToken cZRX UnderlyingBalance Geoff) (Exactly 54e18) + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 500e8) + Assert Equal (SLToken slZRX Reserves) (Exactly 1e18) + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) (Exactly 54e18) -- (55.0e18+0.0e18-1.0e18)/500.0e8 - Assert Equal (CToken cZRX ExchangeRate) (Exactly 1.08e9) + Assert Equal (SLToken slZRX ExchangeRate) (Exactly 1.08e9) -- Now, let's pull out add some our reserves (1e18) Erc20 ZRX Faucet Root 3e18 - From Root (Erc20 ZRX Approve cZRX 6e18) - AddReserves 1e18 cZRX - Assert Equal (Erc20 ZRX TokenBalance cZRX) (Exactly 56e18) + From Root (Erc20 ZRX Approve slZRX 6e18) + AddReserves 1e18 slZRX + Assert Equal (Erc20 ZRX TokenBalance slZRX) (Exactly 56e18) Assert Equal (Erc20 ZRX TokenBalance Root) (Exactly 2e18) - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 500e8) - Assert Equal (CToken cZRX Reserves) (Exactly 2e18) - Assert Equal (CToken cZRX UnderlyingBalance Geoff) (Exactly 54e18) + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 500e8) + Assert Equal (SLToken slZRX Reserves) (Exactly 2e18) + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) (Exactly 54e18) -- (54.0e18+0.0e18-0.0e18)/500.0e8 -- unchanged - Assert Equal (CToken cZRX ExchangeRate) (Exactly 1.08e9) + Assert Equal (SLToken slZRX ExchangeRate) (Exactly 1.08e9) Test "Remove and re add reserves and remove again" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff 50e18 ZRX cZRX - Mint Geoff 50e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 500e8) - Assert Equal (CToken cZRX UnderlyingBalance Geoff) (Exactly 50e18) - Assert Equal (CToken cZRX ExchangeRate) (Exactly 1e9) + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff 50e18 ZRX slZRX + Mint Geoff 50e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 500e8) + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) (Exactly 50e18) + Assert Equal (SLToken slZRX ExchangeRate) (Exactly 1e9) -- Get some brah to borrow then repay - BorrowAndRepayWithInterest ZRX cZRX 10e18 5e18 interestRate:0.000001 blocks:500000 reserveRate:0.2 + BorrowAndRepayWithInterest ZRX slZRX 10e18 5e18 interestRate:0.000001 blocks:500000 reserveRate:0.2 -- We've accrued .0001% interest for 500000 blocks, or 50% of the principal (10e18), -- thus, we should have accrued 5e18 of interest for the protocol -- The reserves should get 20% of this, or 1e18, and the rest -- is due pro-rata to all suppliers. We just have one, so -- let's check that account is given correct new balance. - Assert Equal (Erc20 ZRX TokenBalance cZRX) (Exactly 55e18) + Assert Equal (Erc20 ZRX TokenBalance slZRX) (Exactly 55e18) Assert Equal (Erc20 ZRX TokenBalance Root) (Exactly 0e18) - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 500e8) - Assert Equal (CToken cZRX Reserves) (Exactly 1e18) - Assert Equal (CToken cZRX UnderlyingBalance Geoff) (Exactly 54e18) + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 500e8) + Assert Equal (SLToken slZRX Reserves) (Exactly 1e18) + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) (Exactly 54e18) -- (55.0e18+0.0e18-1.0e18)/500.0e8 - Assert Equal (CToken cZRX ExchangeRate) (Exactly 1.08e9) + Assert Equal (SLToken slZRX ExchangeRate) (Exactly 1.08e9) -- Now, let's pull out half of reserves (0.5e18) - ReduceReserves 0.5e18 cZRX - Assert Equal (Erc20 ZRX TokenBalance cZRX) (Exactly 54.5e18) + ReduceReserves 0.5e18 slZRX + Assert Equal (Erc20 ZRX TokenBalance slZRX) (Exactly 54.5e18) Assert Equal (Erc20 ZRX TokenBalance Root) (Exactly 0.5e18) - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 500e8) - Assert Equal (CToken cZRX Reserves) (Exactly 0.5e18) - Assert Equal (CToken cZRX UnderlyingBalance Geoff) (Exactly 54e18) + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 500e8) + Assert Equal (SLToken slZRX Reserves) (Exactly 0.5e18) + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) (Exactly 54e18) -- (54.5e18+0.5e18-0.0e18)/500.0e8 - Assert Equal (CToken cZRX ExchangeRate) (Exactly 1.08e9) + Assert Equal (SLToken slZRX ExchangeRate) (Exactly 1.08e9) -- Now, let's put back reserves (1e18) - From Root (Erc20 ZRX Approve cZRX 6e18) - AddReserves 0.5e18 cZRX - Assert Equal (Erc20 ZRX TokenBalance cZRX) (Exactly 55e18) + From Root (Erc20 ZRX Approve slZRX 6e18) + AddReserves 0.5e18 slZRX + Assert Equal (Erc20 ZRX TokenBalance slZRX) (Exactly 55e18) Assert Equal (Erc20 ZRX TokenBalance Root) (Exactly 0e18) - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 500e8) - Assert Equal (CToken cZRX Reserves) (Exactly 1e18) - Assert Equal (CToken cZRX UnderlyingBalance Geoff) (Exactly 54e18) + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 500e8) + Assert Equal (SLToken slZRX Reserves) (Exactly 1e18) + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) (Exactly 54e18) -- (54.5e18+0.5e18-0.0e18)/500.0e8 - Assert Equal (CToken cZRX ExchangeRate) (Exactly 1.08e9) + Assert Equal (SLToken slZRX ExchangeRate) (Exactly 1.08e9) Test "add reserves to empty contract" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Assert Equal (CToken cZRX ExchangeRate) (Exactly 1e9) + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Assert Equal (SLToken slZRX ExchangeRate) (Exactly 1e9) Erc20 ZRX Faucet Root 3e18 - From Root (Erc20 ZRX Approve cZRX 6e18) - AddReserves 2e18 cZRX - Assert Equal (Erc20 ZRX TokenBalance cZRX) (Exactly 2e18) + From Root (Erc20 ZRX Approve slZRX 6e18) + AddReserves 2e18 slZRX + Assert Equal (Erc20 ZRX TokenBalance slZRX) (Exactly 2e18) Assert Equal (Erc20 ZRX TokenBalance Root) (Exactly 1e18) - Assert Equal (CToken cZRX Reserves) (Exactly 2e18) + Assert Equal (SLToken slZRX Reserves) (Exactly 2e18) -- unchanged - Assert Equal (CToken cZRX ExchangeRate) (Exactly 1e9) + Assert Equal (SLToken slZRX ExchangeRate) (Exactly 1e9) Test "add reserves failures" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Assert Equal (CToken cZRX ExchangeRate) (Exactly 1e9) - Assert Equal (CToken cZRX Reserves) (Exactly 0e18) + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Assert Equal (SLToken slZRX ExchangeRate) (Exactly 1e9) + Assert Equal (SLToken slZRX Reserves) (Exactly 0e18) Erc20 ZRX Faucet Root 2e18 AllowFailures - AddReserves 2e18 cZRX + AddReserves 2e18 slZRX Assert Revert "revert Insufficient allowance" - Assert Equal (Erc20 ZRX TokenBalance cZRX) (Exactly 0e18) + Assert Equal (Erc20 ZRX TokenBalance slZRX) (Exactly 0e18) Assert Equal (Erc20 ZRX TokenBalance Root) (Exactly 2e18) - Assert Equal (CToken cZRX Reserves) (Exactly 0e18) + Assert Equal (SLToken slZRX Reserves) (Exactly 0e18) -- unchanged - Assert Equal (CToken cZRX ExchangeRate) (Exactly 1e9) + Assert Equal (SLToken slZRX ExchangeRate) (Exactly 1e9) Test "Add reserves WBTC when paused" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:1e9 tokenType:WBTC - Prep Geoff 50e18 WBTC cWBTC - Mint Geoff 50e18 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) (Exactly 500e8) - Assert Equal (CToken cWBTC UnderlyingBalance Geoff) (Exactly 50e18) - Assert Equal (CToken cWBTC ExchangeRate) (Exactly 1e9) + ListedSLToken WBTC slWBTC initialExchangeRate:1e9 tokenType:WBTC + Prep Geoff 50e18 WBTC slWBTC + Mint Geoff 50e18 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) (Exactly 500e8) + Assert Equal (SLToken slWBTC UnderlyingBalance Geoff) (Exactly 50e18) + Assert Equal (SLToken slWBTC ExchangeRate) (Exactly 1e9) -- Get some brah to borrow then repay - BorrowAndRepayWithInterest WBTC cWBTC 10e18 5e18 interestRate:0.000001 blocks:500000 reserveRate:0.2 + BorrowAndRepayWithInterest WBTC slWBTC 10e18 5e18 interestRate:0.000001 blocks:500000 reserveRate:0.2 -- We've accrued .0001% interest for 500000 blocks, or 50% of the principal (10e18), -- thus, we should have accrued 5e18 of interest for the protocol -- The reserves should get 20% of this, or 1e18, and the rest -- is due pro-rata to all suppliers. We just have one, so -- let's check that account is given correct new balance. Erc20 WBTC Faucet Root 3e18 - Invariant Remains (Erc20 WBTC TokenBalance cWBTC) (Exactly 55e18) + Invariant Remains (Erc20 WBTC TokenBalance slWBTC) (Exactly 55e18) Invariant Remains (Erc20 WBTC TokenBalance Root) (Exactly 3e18) - Invariant Remains (Erc20 cWBTC TokenBalance Geoff) (Exactly 500e8) - Invariant Remains (CToken cWBTC Reserves) (Exactly 1e18) - Invariant Remains (CToken cWBTC UnderlyingBalance Geoff) (Exactly 54e18) + Invariant Remains (Erc20 slWBTC TokenBalance Geoff) (Exactly 500e8) + Invariant Remains (SLToken slWBTC Reserves) (Exactly 1e18) + Invariant Remains (SLToken slWBTC UnderlyingBalance Geoff) (Exactly 54e18) -- (55.0e18+0.0e18-1.0e18)/500.0e8 - Invariant Remains (CToken cWBTC ExchangeRate) (Exactly 1.08e9) - From Root (Erc20 WBTC Approve cWBTC 6e18) + Invariant Remains (SLToken slWBTC ExchangeRate) (Exactly 1.08e9) + From Root (Erc20 WBTC Approve slWBTC 6e18) Erc20 WBTC Pause AllowFailures - AddReserves 1e18 cWBTC + AddReserves 1e18 slWBTC Assert Revert diff --git a/spec/scenario/Borrow.scen b/spec/scenario/Borrow.scen index 8d7f5cbb2..c5fe32679 100644 --- a/spec/scenario/Borrow.scen +++ b/spec/scenario/Borrow.scen @@ -1,117 +1,117 @@ Test "Borrow some BAT and enters BAT if BAT not entered" NewComptroller price:1.0 - NewCToken ZRX cZRX - NewCToken BAT cBAT - Give cBAT 10e18 BAT -- Faucet some bat to borrow - Support cZRX collateralFactor:0.5 - Support cBAT collateralFactor:0.5 - Prep Geoff Some ZRX cZRX - Mint Geoff 100e18 cZRX - EnterMarkets Geoff cZRX - Borrow Geoff 1e18 cBAT - Assert Equal (cToken cBAT BorrowBalance Geoff) (Exactly 1e18) + NewSLToken ZRX slZRX + NewSLToken BAT slBAT + Give slBAT 10e18 BAT -- Faucet some bat to borrow + Support slZRX collateralFactor:0.5 + Support slBAT collateralFactor:0.5 + Prep Geoff Some ZRX slZRX + Mint Geoff 100e18 slZRX + EnterMarkets Geoff slZRX + Borrow Geoff 1e18 slBAT + Assert Equal (slToken slBAT BorrowBalance Geoff) (Exactly 1e18) Assert Equal (Erc20 BAT TokenBalance Geoff) (Exactly 1e18) - Assert Equal (Erc20 BAT TokenBalance cBAT) (Exactly 9e18) + Assert Equal (Erc20 BAT TokenBalance slBAT) (Exactly 9e18) Assert Equal (Comptroller MembershipLength Geoff) (Exactly 2) - Assert True (Comptroller CheckMembership Geoff cZRX) - Assert True (Comptroller CheckMembership Geoff cBAT) + Assert True (Comptroller CheckMembership Geoff slZRX) + Assert True (Comptroller CheckMembership Geoff slBAT) Test "Borrow some BAT fails, but user still entered" NewComptroller price:1.0 - NewCToken ZRX cZRX - NewCToken BAT cBAT - Support cZRX collateralFactor:0.5 - Support cBAT collateralFactor:0.5 - Prep Geoff Some ZRX cZRX - Mint Geoff 100e18 cZRX - EnterMarkets Geoff cZRX + NewSLToken ZRX slZRX + NewSLToken BAT slBAT + Support slZRX collateralFactor:0.5 + Support slBAT collateralFactor:0.5 + Prep Geoff Some ZRX slZRX + Mint Geoff 100e18 slZRX + EnterMarkets Geoff slZRX Invariant Static (Erc20 BAT TokenBalance Geoff) - Invariant Static (Erc20 BAT TokenBalance cBAT) + Invariant Static (Erc20 BAT TokenBalance slBAT) AllowFailures - Borrow Geoff 1e18 cBAT + Borrow Geoff 1e18 slBAT Assert Failure TOKEN_INSUFFICIENT_CASH BORROW_CASH_NOT_AVAILABLE Assert Equal (Comptroller MembershipLength Geoff) (Exactly 2) - Assert True (Comptroller CheckMembership Geoff cZRX) - Assert True (Comptroller CheckMembership Geoff cBAT) + Assert True (Comptroller CheckMembership Geoff slZRX) + Assert True (Comptroller CheckMembership Geoff slBAT) Test "Borrow some BAT fails when no BAT available" NewComptroller price:1.0 - NewCToken ZRX cZRX - NewCToken BAT cBAT - Support cZRX collateralFactor:0.5 - Support cBAT collateralFactor:0.5 - Prep Geoff Some ZRX cZRX - Mint Geoff 100e18 cZRX - EnterMarkets Geoff cZRX cBAT - Invariant Static (CToken cZRX ExchangeRateStored) + NewSLToken ZRX slZRX + NewSLToken BAT slBAT + Support slZRX collateralFactor:0.5 + Support slBAT collateralFactor:0.5 + Prep Geoff Some ZRX slZRX + Mint Geoff 100e18 slZRX + EnterMarkets Geoff slZRX slBAT + Invariant Static (SLToken slZRX ExchangeRateStored) AllowFailures - Borrow Geoff 1e18 cBAT + Borrow Geoff 1e18 slBAT Assert Failure TOKEN_INSUFFICIENT_CASH BORROW_CASH_NOT_AVAILABLE Test "Borrow some BAT fails when already entered max assets" NewComptroller price:1.0 maxAssets:1 - NewCToken ZRX cZRX - NewCToken BAT cBAT - Give cBAT 10e18 BAT -- Faucet some bat to borrow - Support cZRX collateralFactor:0.5 - Support cBAT collateralFactor:0.5 - Prep Geoff Some ZRX cZRX - Mint Geoff 100e18 cZRX - EnterMarkets Geoff cZRX + NewSLToken ZRX slZRX + NewSLToken BAT slBAT + Give slBAT 10e18 BAT -- Faucet some bat to borrow + Support slZRX collateralFactor:0.5 + Support slBAT collateralFactor:0.5 + Prep Geoff Some ZRX slZRX + Mint Geoff 100e18 slZRX + EnterMarkets Geoff slZRX AllowFailures - Borrow Geoff 1e18 cBAT + Borrow Geoff 1e18 slBAT Assert Failure COMPTROLLER_REJECTION BORROW_COMPTROLLER_REJECTION TOO_MANY_ASSETS Test "Borrow fails if market not listed" NewComptroller price:1.0 - NewCToken ZRX cZRX - NewCToken BAT cBAT - Give cBAT 10e18 BAT -- Faucet some bat to borrow - Support cZRX collateralFactor:0.5 - Prep Geoff Some ZRX cZRX - Mint Geoff 100e18 cZRX - EnterMarkets Geoff cZRX + NewSLToken ZRX slZRX + NewSLToken BAT slBAT + Give slBAT 10e18 BAT -- Faucet some bat to borrow + Support slZRX collateralFactor:0.5 + Prep Geoff Some ZRX slZRX + Mint Geoff 100e18 slZRX + EnterMarkets Geoff slZRX AllowFailures - Borrow Geoff 1e18 cBAT + Borrow Geoff 1e18 slBAT Assert Failure COMPTROLLER_REJECTION BORROW_COMPTROLLER_REJECTION MARKET_NOT_LISTED Test "Borrow some BAT from Excess Cash" Invariant Success NewComptroller price:1.0 - NewCToken ZRX cZRX - NewCToken BAT cBAT - Give cBAT 10e18 BAT -- Faucet some bat to borrow - Support cZRX collateralFactor:0.5 - Support cBAT collateralFactor:0.5 - Prep Geoff Some ZRX cZRX - Mint Geoff 100e18 cZRX - EnterMarkets Geoff cZRX cBAT - Borrow Geoff 1e18 cBAT - Assert Equal (cToken cBAT BorrowBalance Geoff) (Exactly 1e18) + NewSLToken ZRX slZRX + NewSLToken BAT slBAT + Give slBAT 10e18 BAT -- Faucet some bat to borrow + Support slZRX collateralFactor:0.5 + Support slBAT collateralFactor:0.5 + Prep Geoff Some ZRX slZRX + Mint Geoff 100e18 slZRX + EnterMarkets Geoff slZRX slBAT + Borrow Geoff 1e18 slBAT + Assert Equal (slToken slBAT BorrowBalance Geoff) (Exactly 1e18) Assert Equal (Erc20 BAT TokenBalance Geoff) (Exactly 1e18) - Assert Equal (Erc20 BAT TokenBalance cBAT) (Exactly 9e18) + Assert Equal (Erc20 BAT TokenBalance slBAT) (Exactly 9e18) Test "Borrow some BAT reverts if borrow is paused" NewComptroller price:1.0 Comptroller SetPauseGuardian Coburn - NewCToken ZRX cZRX - NewCToken BAT cBAT - Give cBAT 10e18 BAT -- Faucet some bat to borrow - Support cZRX collateralFactor:0.5 - Support cBAT collateralFactor:0.5 - Prep Geoff Some ZRX cZRX - Mint Geoff 100e18 cZRX - EnterMarkets Geoff cZRX cBAT - From Coburn (Comptroller SetGuardianMarketPaused cBAT "Borrow" True) + NewSLToken ZRX slZRX + NewSLToken BAT slBAT + Give slBAT 10e18 BAT -- Faucet some bat to borrow + Support slZRX collateralFactor:0.5 + Support slBAT collateralFactor:0.5 + Prep Geoff Some ZRX slZRX + Mint Geoff 100e18 slZRX + EnterMarkets Geoff slZRX slBAT + From Coburn (Comptroller SetGuardianMarketPaused slBAT "Borrow" True) AllowFailures - Borrow Geoff 1e18 cBAT + Borrow Geoff 1e18 slBAT Assert Revert "revert borrow is paused" - Assert Equal (cToken cBAT BorrowBalance Geoff) 0 + Assert Equal (slToken slBAT BorrowBalance Geoff) 0 Assert Equal (Erc20 BAT TokenBalance Geoff) 0 - Assert Equal (Erc20 BAT TokenBalance cBAT) (Exactly 10e18) - Comptroller SetGuardianMarketPaused cBAT "Borrow" False - Borrow Geoff 1e18 cBAT - Assert Equal (cToken cBAT BorrowBalance Geoff) (Exactly 1e18) + Assert Equal (Erc20 BAT TokenBalance slBAT) (Exactly 10e18) + Comptroller SetGuardianMarketPaused slBAT "Borrow" False + Borrow Geoff 1e18 slBAT + Assert Equal (slToken slBAT BorrowBalance Geoff) (Exactly 1e18) Assert Equal (Erc20 BAT TokenBalance Geoff) (Exactly 1e18) - Assert Equal (Erc20 BAT TokenBalance cBAT) (Exactly 9e18) + Assert Equal (Erc20 BAT TokenBalance slBAT) (Exactly 9e18) diff --git a/spec/scenario/BorrowBalance.scen b/spec/scenario/BorrowBalance.scen index 4ba070485..4b4dfc019 100644 --- a/spec/scenario/BorrowBalance.scen +++ b/spec/scenario/BorrowBalance.scen @@ -2,83 +2,83 @@ Macro NewBorrow borrowAmount borrowRate user=Geoff NewComptroller price:1.0 -- TODO: This should really be a price for a specific asset - NewCToken ZRX cZRX - NewCToken BAT cBAT borrowRate -- note: cannot use macros with named args right now - Give cBAT 10e18 BAT -- Faucet some bat to borrow - Support cZRX collateralFactor:0.5 - Support cBAT collateralFactor:0.5 + NewSLToken ZRX slZRX + NewSLToken BAT slBAT borrowRate -- note: cannot use macros with named args right now + Give slBAT 10e18 BAT -- Faucet some bat to borrow + Support slZRX collateralFactor:0.5 + Support slBAT collateralFactor:0.5 SimpleBorrow user borrowAmount Macro SimpleBorrow user borrowAmount - Prep user Some ZRX cZRX - Mint user 100e18 cZRX - EnterMarkets user cZRX cBAT - Borrow user borrowAmount cBAT + Prep user Some ZRX slZRX + Mint user 100e18 slZRX + EnterMarkets user slZRX slBAT + Borrow user borrowAmount slBAT Test "Borrow Balance after 300000 blocks" NewBorrow borrowAmount:1e18 borrowRate:0.000005 - Assert Equal (cToken cBAT BorrowBalance Geoff) (Exactly 1e18) - Assert Equal (cToken cBAT TotalBorrowsCurrent) (Exactly 1e18) + Assert Equal (slToken slBAT BorrowBalance Geoff) (Exactly 1e18) + Assert Equal (slToken slBAT TotalBorrowsCurrent) (Exactly 1e18) Assert Equal (Erc20 BAT TokenBalance Geoff) (Exactly 1e18) - Assert Equal (Erc20 BAT TokenBalance cBAT) (Exactly 9e18) + Assert Equal (Erc20 BAT TokenBalance slBAT) (Exactly 9e18) -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- 1e18 * (1 + 300000 * 0.000005) - Assert Equal (cToken cBAT BorrowBalance Geoff) (Exactly 2.5e18) - Assert Equal (cToken cBAT TotalBorrowsCurrent) (Exactly 2.5e18) + Assert Equal (slToken slBAT BorrowBalance Geoff) (Exactly 2.5e18) + Assert Equal (slToken slBAT TotalBorrowsCurrent) (Exactly 2.5e18) Test "Borrow Balance after 300000 blocks and then 600000 blocks" NewBorrow borrowAmount:1e18 borrowRate:0.000005 - Assert Equal (cToken cBAT BorrowBalance Geoff) (Exactly 1e18) - Assert Equal (cToken cBAT TotalBorrowsCurrent) (Exactly 1e18) + Assert Equal (slToken slBAT BorrowBalance Geoff) (Exactly 1e18) + Assert Equal (slToken slBAT TotalBorrowsCurrent) (Exactly 1e18) Assert Equal (Erc20 BAT TokenBalance Geoff) (Exactly 1e18) - Assert Equal (Erc20 BAT TokenBalance cBAT) (Exactly 9e18) + Assert Equal (Erc20 BAT TokenBalance slBAT) (Exactly 9e18) -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- 1e18 * (1 + 300000 * 0.000005) - AccrueInterest cBAT - Assert Equal (cToken cBAT BorrowBalance Geoff) (Exactly 2.5e18) - Assert Equal (cToken cBAT TotalBorrowsCurrent) (Exactly 2.5e18) + AccrueInterest slBAT + Assert Equal (slToken slBAT BorrowBalance Geoff) (Exactly 2.5e18) + Assert Equal (slToken slBAT TotalBorrowsCurrent) (Exactly 2.5e18) FastForward 600000 Blocks -- 1e18 * (1 + 300000 * 0.000005) * (1 + 600000 * 0.000005) - Assert Equal (cToken cBAT BorrowBalance Geoff) (Exactly 10e18) - Assert Equal (cToken cBAT TotalBorrowsCurrent) (Exactly 10e18) + Assert Equal (slToken slBAT BorrowBalance Geoff) (Exactly 10e18) + Assert Equal (slToken slBAT TotalBorrowsCurrent) (Exactly 10e18) Test "Borrow Balance after accrual then changed interest rate" NewBorrow borrowAmount:1e18 borrowRate:0.000005 - Assert Equal (cToken cBAT BorrowBalance Geoff) (Exactly 1e18) - Assert Equal (cToken cBAT TotalBorrowsCurrent) (Exactly 1e18) + Assert Equal (slToken slBAT BorrowBalance Geoff) (Exactly 1e18) + Assert Equal (slToken slBAT TotalBorrowsCurrent) (Exactly 1e18) Assert Equal (Erc20 BAT TokenBalance Geoff) (Exactly 1e18) - Assert Equal (Erc20 BAT TokenBalance cBAT) (Exactly 9e18) + Assert Equal (Erc20 BAT TokenBalance slBAT) (Exactly 9e18) -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- Current: 1e18 * (1 + 300000 * 0.000005) -- Note: this should accrue interest InterestRateModel Deploy Fixed Std 0.000004 - CToken cBAT SetInterestRateModel (InterestRateModel Std Address) + SLToken slBAT SetInterestRateModel (InterestRateModel Std Address) -- Check borrow balance still based on old figure (with previous interest accrual) - Assert Equal (cToken cBAT BorrowBalance Geoff) (Exactly 2.5e18) - Assert Equal (cToken cBAT TotalBorrowsCurrent) (Exactly 2.5e18) + Assert Equal (slToken slBAT BorrowBalance Geoff) (Exactly 2.5e18) + Assert Equal (slToken slBAT TotalBorrowsCurrent) (Exactly 2.5e18) -- Now accrue with new rate FastForward 800000 Blocks -- 1e18 * (1 + 300000 * 0.000005) * (1 + 800000 * 0.000004) - Assert Equal (cToken cBAT BorrowBalance Geoff) (Exactly 10.5e18) - Assert Equal (cToken cBAT TotalBorrowsCurrent) (Exactly 10.5e18) + Assert Equal (slToken slBAT BorrowBalance Geoff) (Exactly 10.5e18) + Assert Equal (slToken slBAT TotalBorrowsCurrent) (Exactly 10.5e18) Test "Total Borrow Balance with Two Borrowers" NewBorrow borrowAmount:1e18 borrowRate:0.000005 user:Geoff FastForward 300000 Blocks InterestRateModel Deploy Fixed Std 0.000004 - CToken cBAT SetInterestRateModel (InterestRateModel Std Address) + SLToken slBAT SetInterestRateModel (InterestRateModel Std Address) -- Check borrow balance still based on old figure (with previous interest accrual) - Assert Equal (cToken cBAT BorrowBalance Geoff) (Exactly 2.5e18) - Assert Equal (cToken cBAT TotalBorrowsCurrent) (Exactly 2.5e18) + Assert Equal (slToken slBAT BorrowBalance Geoff) (Exactly 2.5e18) + Assert Equal (slToken slBAT TotalBorrowsCurrent) (Exactly 2.5e18) SimpleBorrow user:Torrey borrowAmount:5e18 -- Now accrue with new rate FastForward 800000 Blocks -- Geoff: 1e18 * (1 + 300000 * 0.000005) * (1 + 800000 * 0.000004) - Assert Equal (cToken cBAT BorrowBalance Geoff) (Exactly 10.5e18) + Assert Equal (slToken slBAT BorrowBalance Geoff) (Exactly 10.5e18) -- Torrey: 5e18 * (1 + 800000 * 0.000004) - Assert Equal (cToken cBAT BorrowBalance Torrey) (Exactly 21e18) - Assert Equal (cToken cBAT TotalBorrowsCurrent) (Exactly 31.5e18) + Assert Equal (slToken slBAT BorrowBalance Torrey) (Exactly 21e18) + Assert Equal (slToken slBAT TotalBorrowsCurrent) (Exactly 31.5e18) -- And test some repayment - From Torrey (Erc20 BAT Approve cBAT 2.0e18) - RepayBorrow Torrey 2.0e18 cBAT - Assert Equal (cToken cBAT BorrowBalance Geoff) (Exactly 10.5e18) - Assert Equal (cToken cBAT BorrowBalance Torrey) (Exactly 19e18) - Assert Equal (cToken cBAT TotalBorrowsCurrent) (Exactly 29.5e18) + From Torrey (Erc20 BAT Approve slBAT 2.0e18) + RepayBorrow Torrey 2.0e18 slBAT + Assert Equal (slToken slBAT BorrowBalance Geoff) (Exactly 10.5e18) + Assert Equal (slToken slBAT BorrowBalance Torrey) (Exactly 19e18) + Assert Equal (slToken slBAT TotalBorrowsCurrent) (Exactly 29.5e18) diff --git a/spec/scenario/BorrowCap.scen b/spec/scenario/BorrowCap.scen index 26c73f807..ee8148cfb 100644 --- a/spec/scenario/BorrowCap.scen +++ b/spec/scenario/BorrowCap.scen @@ -1,137 +1,137 @@ Test "Attempt to borrow over set cap ERC20" NewComptroller price:1.0 - NewCToken ZRX cZRX - NewCToken BAT cBAT - Comptroller SetMarketBorrowCaps (cBAT) (0.5e18) - Assert Equal (Comptroller BorrowCaps cBAT) (Exactly 0.5e18) - Give cBAT 10e18 BAT -- Faucet some bat to borrow - Support cZRX collateralFactor:0.5 - Support cBAT collateralFactor:0.5 - Prep Geoff Some ZRX cZRX - Mint Geoff 100e18 cZRX - EnterMarkets Geoff cZRX + NewSLToken ZRX slZRX + NewSLToken BAT slBAT + Comptroller SetMarketBorrowCaps (slBAT) (0.5e18) + Assert Equal (Comptroller BorrowCaps slBAT) (Exactly 0.5e18) + Give slBAT 10e18 BAT -- Faucet some bat to borrow + Support slZRX collateralFactor:0.5 + Support slBAT collateralFactor:0.5 + Prep Geoff Some ZRX slZRX + Mint Geoff 100e18 slZRX + EnterMarkets Geoff slZRX AllowFailures - Borrow Geoff 1e18 cBAT + Borrow Geoff 1e18 slBAT Assert Revert - Assert Equal (cToken cBAT BorrowBalance Geoff) (Exactly 0) + Assert Equal (slToken slBAT BorrowBalance Geoff) (Exactly 0) Assert Equal (Erc20 BAT TokenBalance Geoff) (Exactly 0) - Assert Equal (Erc20 BAT TokenBalance cBAT) (Exactly 10e18) + Assert Equal (Erc20 BAT TokenBalance slBAT) (Exactly 10e18) Test "Attempt to borrow at set cap ERC20" NewComptroller price:1.0 - NewCToken ZRX cZRX - NewCToken BAT cBAT - Comptroller SetMarketBorrowCaps (cBAT) (1000000000000000001) - Give cBAT 10e18 BAT -- Faucet some bat to borrow - Support cZRX collateralFactor:0.5 - Support cBAT collateralFactor:0.5 - Prep Geoff Some ZRX cZRX - Mint Geoff 100e18 cZRX - EnterMarkets Geoff cZRX - Borrow Geoff 1e18 cBAT - Assert Equal (cToken cBAT BorrowBalance Geoff) (Exactly 1e18) + NewSLToken ZRX slZRX + NewSLToken BAT slBAT + Comptroller SetMarketBorrowCaps (slBAT) (1000000000000000001) + Give slBAT 10e18 BAT -- Faucet some bat to borrow + Support slZRX collateralFactor:0.5 + Support slBAT collateralFactor:0.5 + Prep Geoff Some ZRX slZRX + Mint Geoff 100e18 slZRX + EnterMarkets Geoff slZRX + Borrow Geoff 1e18 slBAT + Assert Equal (slToken slBAT BorrowBalance Geoff) (Exactly 1e18) Assert Equal (Erc20 BAT TokenBalance Geoff) (Exactly 1e18) - Assert Equal (Erc20 BAT TokenBalance cBAT) (Exactly 9e18) + Assert Equal (Erc20 BAT TokenBalance slBAT) (Exactly 9e18) Assert Equal (Comptroller MembershipLength Geoff) (Exactly 2) - Assert True (Comptroller CheckMembership Geoff cZRX) - Assert True (Comptroller CheckMembership Geoff cBAT) + Assert True (Comptroller CheckMembership Geoff slZRX) + Assert True (Comptroller CheckMembership Geoff slBAT) Test "Attempt to borrow below set cap ERC20" NewComptroller price:1.0 - NewCToken ZRX cZRX - NewCToken BAT cBAT - Comptroller SetMarketBorrowCaps (cBAT) (10e18) - Give cBAT 10e18 BAT -- Faucet some bat to borrow - Support cZRX collateralFactor:0.5 - Support cBAT collateralFactor:0.5 - Prep Geoff Some ZRX cZRX - Mint Geoff 100e18 cZRX - EnterMarkets Geoff cZRX - Borrow Geoff 1e18 cBAT - Assert Equal (cToken cBAT BorrowBalance Geoff) (Exactly 1e18) + NewSLToken ZRX slZRX + NewSLToken BAT slBAT + Comptroller SetMarketBorrowCaps (slBAT) (10e18) + Give slBAT 10e18 BAT -- Faucet some bat to borrow + Support slZRX collateralFactor:0.5 + Support slBAT collateralFactor:0.5 + Prep Geoff Some ZRX slZRX + Mint Geoff 100e18 slZRX + EnterMarkets Geoff slZRX + Borrow Geoff 1e18 slBAT + Assert Equal (slToken slBAT BorrowBalance Geoff) (Exactly 1e18) Assert Equal (Erc20 BAT TokenBalance Geoff) (Exactly 1e18) - Assert Equal (Erc20 BAT TokenBalance cBAT) (Exactly 9e18) + Assert Equal (Erc20 BAT TokenBalance slBAT) (Exactly 9e18) Assert Equal (Comptroller MembershipLength Geoff) (Exactly 2) - Assert True (Comptroller CheckMembership Geoff cZRX) - Assert True (Comptroller CheckMembership Geoff cBAT) + Assert True (Comptroller CheckMembership Geoff slZRX) + Assert True (Comptroller CheckMembership Geoff slBAT) Test "Borrow some Eth over cap" NewComptroller price:1.0 - ListedCToken ZRX cZRX - ListedEtherToken cETH initialExchangeRate:0.005e9 - SetCollateralFactor cZRX collateralFactor:0.5 - SetCollateralFactor cETH collateralFactor:0.5 - Comptroller SetMarketBorrowCaps (cETH) (0.0001e18) - Donate cETH 0.003e18 - Prep Geoff Some ZRX cZRX - Mint Geoff 1e18 cZRX - EnterMarkets Geoff cZRX + ListedSLToken ZRX slZRX + ListedEtherToken slETH initialExchangeRate:0.005e9 + SetCollateralFactor slZRX collateralFactor:0.5 + SetCollateralFactor slETH collateralFactor:0.5 + Comptroller SetMarketBorrowCaps (slETH) (0.0001e18) + Donate slETH 0.003e18 + Prep Geoff Some ZRX slZRX + Mint Geoff 1e18 slZRX + EnterMarkets Geoff slZRX AllowFailures - BorrowEth Geoff 0.001e18 cETH + BorrowEth Geoff 0.001e18 slETH Assert Revert - Assert Equal (EtherBalance cETH) 0.003e18 + Assert Equal (EtherBalance slETH) 0.003e18 Test "Borrow some Eth enters Eth and succeeds when Eth not entered. At borrow cap" NewComptroller price:1.0 - ListedCToken ZRX cZRX - ListedEtherToken cETH initialExchangeRate:0.005e9 - SetCollateralFactor cZRX collateralFactor:0.5 - SetCollateralFactor cETH collateralFactor:0.5 - Comptroller SetMarketBorrowCaps (cETH) (1000000000000001) - Donate cETH 0.003e18 - Prep Geoff Some ZRX cZRX - Mint Geoff 1e18 cZRX - EnterMarkets Geoff cZRX + ListedSLToken ZRX slZRX + ListedEtherToken slETH initialExchangeRate:0.005e9 + SetCollateralFactor slZRX collateralFactor:0.5 + SetCollateralFactor slETH collateralFactor:0.5 + Comptroller SetMarketBorrowCaps (slETH) (1000000000000001) + Donate slETH 0.003e18 + Prep Geoff Some ZRX slZRX + Mint Geoff 1e18 slZRX + EnterMarkets Geoff slZRX Expect Changes (EtherBalance Geoff) +0.001e18 - BorrowEth Geoff 0.001e18 cETH - Assert Equal (EtherBalance cETH) 0.002e18 + BorrowEth Geoff 0.001e18 slETH + Assert Equal (EtherBalance slETH) 0.002e18 Assert Equal (Comptroller Liquidity Geoff) 4.99e17 Assert Equal (Comptroller MembershipLength Geoff) (Exactly 2) - Assert True (Comptroller CheckMembership Geoff cETH) + Assert True (Comptroller CheckMembership Geoff slETH) Test "Borrow some Eth enters Eth and succeeds when Eth not entered. At under borrow cap" NewComptroller price:1.0 - ListedCToken ZRX cZRX - ListedEtherToken cETH initialExchangeRate:0.005e9 - SetCollateralFactor cZRX collateralFactor:0.5 - SetCollateralFactor cETH collateralFactor:0.5 - Comptroller SetMarketBorrowCaps (cETH) (0.01e18) - Donate cETH 0.003e18 - Prep Geoff Some ZRX cZRX - Mint Geoff 1e18 cZRX - EnterMarkets Geoff cZRX + ListedSLToken ZRX slZRX + ListedEtherToken slETH initialExchangeRate:0.005e9 + SetCollateralFactor slZRX collateralFactor:0.5 + SetCollateralFactor slETH collateralFactor:0.5 + Comptroller SetMarketBorrowCaps (slETH) (0.01e18) + Donate slETH 0.003e18 + Prep Geoff Some ZRX slZRX + Mint Geoff 1e18 slZRX + EnterMarkets Geoff slZRX Expect Changes (EtherBalance Geoff) +0.001e18 - BorrowEth Geoff 0.001e18 cETH - Assert Equal (EtherBalance cETH) 0.002e18 + BorrowEth Geoff 0.001e18 slETH + Assert Equal (EtherBalance slETH) 0.002e18 Assert Equal (Comptroller Liquidity Geoff) 4.99e17 Assert Equal (Comptroller MembershipLength Geoff) (Exactly 2) - Assert True (Comptroller CheckMembership Geoff cETH) + Assert True (Comptroller CheckMembership Geoff slETH) Test "Setting borrow cap restricted to admin" NewComptroller price:1.0 - ListedCToken ZRX cZRX - ListedEtherToken cETH initialExchangeRate:0.005e9 - SetCollateralFactor cZRX collateralFactor:0.5 - SetCollateralFactor cETH collateralFactor:0.5 + ListedSLToken ZRX slZRX + ListedEtherToken slETH initialExchangeRate:0.005e9 + SetCollateralFactor slZRX collateralFactor:0.5 + SetCollateralFactor slETH collateralFactor:0.5 AllowFailures - From Robert (Comptroller SetMarketBorrowCaps (cETH) (0.01e18)) + From Robert (Comptroller SetMarketBorrowCaps (slETH) (0.01e18)) Assert Revert Test "Borrow cap guardian can set borrow caps" NewComptroller price:1.0 - ListedCToken ZRX cZRX - ListedEtherToken cETH initialExchangeRate:0.005e9 - SetCollateralFactor cZRX collateralFactor:0.5 - SetCollateralFactor cETH collateralFactor:0.5 + ListedSLToken ZRX slZRX + ListedEtherToken slETH initialExchangeRate:0.005e9 + SetCollateralFactor slZRX collateralFactor:0.5 + SetCollateralFactor slETH collateralFactor:0.5 Comptroller SetBorrowCapGuardian Geoff - From Geoff (Comptroller SetMarketBorrowCaps (cZRX) (0.5e18)) + From Geoff (Comptroller SetMarketBorrowCaps (slZRX) (0.5e18)) AllowFailures - From Robert (Comptroller SetMarketBorrowCaps (cZRX) (0.01e18)) -- Robert still can't... + From Robert (Comptroller SetMarketBorrowCaps (slZRX) (0.01e18)) -- Robert still can't... Assert Revert - From Robert (Comptroller SetMarketBorrowCaps (cZRX) (0.01e18)) + From Robert (Comptroller SetMarketBorrowCaps (slZRX) (0.01e18)) Assert Revert - Assert Equal (Comptroller BorrowCaps cZRX) (Exactly 0.5e18) + Assert Equal (Comptroller BorrowCaps slZRX) (Exactly 0.5e18) Assert Equal (Comptroller BorrowCapGuardian) (User Geoff Address) Test "Only admin can set Borrow Cap Guardian" @@ -142,29 +142,29 @@ Test "Only admin can set Borrow Cap Guardian" Test "SetBorrowCaps works correctly too" NewComptroller price:1.0 - NewCToken ZRX cZRX - NewCToken BAT cBAT - NewCToken USDC cUSDC - Comptroller SetMarketBorrowCaps (cBAT cUSDC) (0.5e18 1000001) - Assert Equal (Comptroller BorrowCaps cBAT) (Exactly 0.5e18) - Assert Equal (Comptroller BorrowCaps cUSDC) (Exactly 1000001) - Give cBAT 10e18 BAT -- Faucet some bat to borrow - Give cUSDC 20e6 USDC - Support cZRX collateralFactor:0.5 - Support cBAT collateralFactor:0.5 - Support cUSDC collateralFactor:0.5 - Prep Geoff Some ZRX cZRX - Mint Geoff 100e18 cZRX - EnterMarkets Geoff cZRX + NewSLToken ZRX slZRX + NewSLToken BAT slBAT + NewSLToken USDC slUSDC + Comptroller SetMarketBorrowCaps (slBAT slUSDC) (0.5e18 1000001) + Assert Equal (Comptroller BorrowCaps slBAT) (Exactly 0.5e18) + Assert Equal (Comptroller BorrowCaps slUSDC) (Exactly 1000001) + Give slBAT 10e18 BAT -- Faucet some bat to borrow + Give slUSDC 20e6 USDC + Support slZRX collateralFactor:0.5 + Support slBAT collateralFactor:0.5 + Support slUSDC collateralFactor:0.5 + Prep Geoff Some ZRX slZRX + Mint Geoff 100e18 slZRX + EnterMarkets Geoff slZRX AllowFailures - Borrow Geoff 1e18 cBAT + Borrow Geoff 1e18 slBAT Assert Revert - Borrow Geoff 2e6 cUSDC + Borrow Geoff 2e6 slUSDC Assert Revert Successfully - Borrow Geoff 1e6 cUSDC - Assert Equal (cToken cBAT BorrowBalance Geoff) (Exactly 0) + Borrow Geoff 1e6 slUSDC + Assert Equal (slToken slBAT BorrowBalance Geoff) (Exactly 0) Assert Equal (Erc20 BAT TokenBalance Geoff) (Exactly 0) - Assert Equal (Erc20 BAT TokenBalance cBAT) (Exactly 10e18) + Assert Equal (Erc20 BAT TokenBalance slBAT) (Exactly 10e18) Assert Equal (Erc20 USDC TokenBalance Geoff) (Exactly 1e6) diff --git a/spec/scenario/BorrowEth.scen b/spec/scenario/BorrowEth.scen index 5b95182f7..57f7b3c59 100644 --- a/spec/scenario/BorrowEth.scen +++ b/spec/scenario/BorrowEth.scen @@ -1,49 +1,49 @@ Test "Borrow some Eth enters Eth and succeeds when Eth not entered" NewComptroller price:1.0 - ListedCToken ZRX cZRX - ListedEtherToken cETH initialExchangeRate:0.005e9 - SetCollateralFactor cZRX collateralFactor:0.5 - SetCollateralFactor cETH collateralFactor:0.5 - Donate cETH 0.003e18 - Prep Geoff Some ZRX cZRX - Mint Geoff 1e18 cZRX - EnterMarkets Geoff cZRX + ListedSLToken ZRX slZRX + ListedEtherToken slETH initialExchangeRate:0.005e9 + SetCollateralFactor slZRX collateralFactor:0.5 + SetCollateralFactor slETH collateralFactor:0.5 + Donate slETH 0.003e18 + Prep Geoff Some ZRX slZRX + Mint Geoff 1e18 slZRX + EnterMarkets Geoff slZRX Expect Changes (EtherBalance Geoff) +0.001e18 - BorrowEth Geoff 0.001e18 cETH - Assert Equal (EtherBalance cETH) 0.002e18 + BorrowEth Geoff 0.001e18 slETH + Assert Equal (EtherBalance slETH) 0.002e18 Assert Equal (Comptroller Liquidity Geoff) 4.99e17 Assert Equal (Comptroller MembershipLength Geoff) (Exactly 2) - Assert True (Comptroller CheckMembership Geoff cETH) + Assert True (Comptroller CheckMembership Geoff slETH) Test "Borrow some ETH fails when no ETH available" NewComptroller price:1.0 - ListedCToken ZRX cZRX - ListedEtherToken cETH initialExchangeRate:0.005e9 - SetCollateralFactor cZRX collateralFactor:0.5 - SetCollateralFactor cETH collateralFactor:0.5 - Prep Geoff Some ZRX cZRX - Mint Geoff 100e18 cZRX - EnterMarkets Geoff cZRX cETH + ListedSLToken ZRX slZRX + ListedEtherToken slETH initialExchangeRate:0.005e9 + SetCollateralFactor slZRX collateralFactor:0.5 + SetCollateralFactor slETH collateralFactor:0.5 + Prep Geoff Some ZRX slZRX + Mint Geoff 100e18 slZRX + EnterMarkets Geoff slZRX slETH AllowFailures - Invariant Static (CToken cZRX ExchangeRateStored) - Invariant Static (CToken cETH ExchangeRateStored) + Invariant Static (SLToken slZRX ExchangeRateStored) + Invariant Static (SLToken slETH ExchangeRateStored) Invariant Static (Comptroller Liquidity Geoff) Invariant Static (EtherBalance Geoff) - BorrowEth Geoff 1e18 cETH + BorrowEth Geoff 1e18 slETH Assert Failure TOKEN_INSUFFICIENT_CASH BORROW_CASH_NOT_AVAILABLE Test "Borrow some ETH from excess cash" NewComptroller price:1.0 - ListedCToken ZRX cZRX - ListedEtherToken cETH initialExchangeRate:0.005e9 - SetCollateralFactor cZRX collateralFactor:0.5 - SetCollateralFactor cETH collateralFactor:0.5 - Donate cETH 0.003e18 - Prep Geoff Some ZRX cZRX - Mint Geoff 1e18 cZRX - EnterMarkets Geoff cZRX cETH + ListedSLToken ZRX slZRX + ListedEtherToken slETH initialExchangeRate:0.005e9 + SetCollateralFactor slZRX collateralFactor:0.5 + SetCollateralFactor slETH collateralFactor:0.5 + Donate slETH 0.003e18 + Prep Geoff Some ZRX slZRX + Mint Geoff 1e18 slZRX + EnterMarkets Geoff slZRX slETH Expect Changes (EtherBalance Geoff) +0.001e18 - BorrowEth Geoff 0.001e18 cETH - Assert Equal (EtherBalance cETH) 0.002e18 + BorrowEth Geoff 0.001e18 slETH + Assert Equal (EtherBalance slETH) 0.002e18 Assert Equal (Comptroller Liquidity Geoff) 4.99e17 diff --git a/spec/scenario/BorrowWBTC.scen b/spec/scenario/BorrowWBTC.scen index ae7d79df4..d9cddb2b3 100644 --- a/spec/scenario/BorrowWBTC.scen +++ b/spec/scenario/BorrowWBTC.scen @@ -2,62 +2,62 @@ Test "Borrow some WBTC enters WBTC and succeeds when not entered" Invariant Success NewComptroller price:1.0 - NewCToken ZRX cZRX - NewCToken WBTC cWBTC tokenType:WBTC - Give cWBTC 10e8 WBTC -- Faucet some WBTC to borrow - Support cZRX collateralFactor:0.5 - Support cWBTC collateralFactor:0.5 - Prep Geoff Some ZRX cZRX - Mint Geoff 100e18 cZRX - EnterMarkets Geoff cZRX - Borrow Geoff 1e8 cWBTC - Assert Equal (cToken cWBTC BorrowBalance Geoff) (Exactly 1e8) + NewSLToken ZRX slZRX + NewSLToken WBTC slWBTC tokenType:WBTC + Give slWBTC 10e8 WBTC -- Faucet some WBTC to borrow + Support slZRX collateralFactor:0.5 + Support slWBTC collateralFactor:0.5 + Prep Geoff Some ZRX slZRX + Mint Geoff 100e18 slZRX + EnterMarkets Geoff slZRX + Borrow Geoff 1e8 slWBTC + Assert Equal (slToken slWBTC BorrowBalance Geoff) (Exactly 1e8) Assert Equal (Erc20 WBTC TokenBalance Geoff) (Exactly 1e8) - Assert Equal (Erc20 WBTC TokenBalance cWBTC) (Exactly 9e8) + Assert Equal (Erc20 WBTC TokenBalance slWBTC) (Exactly 9e8) Test "Borrow some WBTC fails when no WBTC available" NewComptroller price:1.0 - NewCToken ZRX cZRX - NewCToken WBTC cWBTC tokenType:WBTC - Support cZRX collateralFactor:0.5 - Support cWBTC collateralFactor:0.5 - Prep Geoff Some ZRX cZRX - Mint Geoff 100e18 cZRX - EnterMarkets Geoff cZRX cWBTC - Invariant Static (CToken cZRX ExchangeRateStored) + NewSLToken ZRX slZRX + NewSLToken WBTC slWBTC tokenType:WBTC + Support slZRX collateralFactor:0.5 + Support slWBTC collateralFactor:0.5 + Prep Geoff Some ZRX slZRX + Mint Geoff 100e18 slZRX + EnterMarkets Geoff slZRX slWBTC + Invariant Static (SLToken slZRX ExchangeRateStored) AllowFailures - Borrow Geoff 1e8 cWBTC + Borrow Geoff 1e8 slWBTC Assert Failure TOKEN_INSUFFICIENT_CASH BORROW_CASH_NOT_AVAILABLE Test "Borrow some WBTC fails when WBTC paused" NewComptroller price:1.0 - NewCToken ZRX cZRX - NewCToken WBTC cWBTC tokenType:WBTC - Give cWBTC 10e8 WBTC -- Faucet some WBTC to borrow - Support cZRX collateralFactor:0.5 - Support cWBTC collateralFactor:0.5 - Prep Geoff Some ZRX cZRX - Mint Geoff 100e18 cZRX - EnterMarkets Geoff cZRX cWBTC - Invariant Static (CToken cZRX ExchangeRateStored) + NewSLToken ZRX slZRX + NewSLToken WBTC slWBTC tokenType:WBTC + Give slWBTC 10e8 WBTC -- Faucet some WBTC to borrow + Support slZRX collateralFactor:0.5 + Support slWBTC collateralFactor:0.5 + Prep Geoff Some ZRX slZRX + Mint Geoff 100e18 slZRX + EnterMarkets Geoff slZRX slWBTC + Invariant Static (SLToken slZRX ExchangeRateStored) Erc20 WBTC Pause AllowFailures - Borrow Geoff 1e8 cWBTC + Borrow Geoff 1e8 slWBTC Assert Revert Test "Borrow some WBTC from Excess Cash" Invariant Success NewComptroller price:1.0 - NewCToken ZRX cZRX - NewCToken WBTC cWBTC tokenType:WBTC - Give cWBTC 10e8 WBTC -- Faucet some WBTC to borrow - Support cZRX collateralFactor:0.5 - Support cWBTC collateralFactor:0.5 - Prep Geoff Some ZRX cZRX - Mint Geoff 100e18 cZRX - EnterMarkets Geoff cZRX cWBTC - Borrow Geoff 1e8 cWBTC - EnterMarkets Geoff cZRX cWBTC - Assert Equal (cToken cWBTC BorrowBalance Geoff) (Exactly 1e8) + NewSLToken ZRX slZRX + NewSLToken WBTC slWBTC tokenType:WBTC + Give slWBTC 10e8 WBTC -- Faucet some WBTC to borrow + Support slZRX collateralFactor:0.5 + Support slWBTC collateralFactor:0.5 + Prep Geoff Some ZRX slZRX + Mint Geoff 100e18 slZRX + EnterMarkets Geoff slZRX slWBTC + Borrow Geoff 1e8 slWBTC + EnterMarkets Geoff slZRX slWBTC + Assert Equal (slToken slWBTC BorrowBalance Geoff) (Exactly 1e8) Assert Equal (Erc20 WBTC TokenBalance Geoff) (Exactly 1e8) - Assert Equal (Erc20 WBTC TokenBalance cWBTC) (Exactly 9e8) + Assert Equal (Erc20 WBTC TokenBalance slWBTC) (Exactly 9e8) diff --git a/spec/scenario/BreakLiquidate.scen b/spec/scenario/BreakLiquidate.scen index 1dc0e9c8c..78f0dedbc 100644 --- a/spec/scenario/BreakLiquidate.scen +++ b/spec/scenario/BreakLiquidate.scen @@ -2,20 +2,20 @@ Macro NewBorrow borrowAmount mintAmount borrowRate=0.000005 user=Geoff collateralPrice=1.0 borrowPrice=1.0 liquidationIncentive=1.1 PricedComptroller closeFactor:0.9 -- Set the close factor high to reduce number of steps to demonstrate Comptroller LiquidationIncentive liquidationIncentive - NewCToken ZRX cZRX - NewCToken BAT cBAT borrowRate - Give cBAT 10e18 BAT -- Faucet some bat to borrow - PriceOracle SetPrice cZRX collateralPrice - Support cZRX collateralFactor:0.7 - PriceOracle SetPrice cBAT borrowPrice - Support cBAT collateralFactor:0 + NewSLToken ZRX slZRX + NewSLToken BAT slBAT borrowRate + Give slBAT 10e18 BAT -- Faucet some bat to borrow + PriceOracle SetPrice slZRX collateralPrice + Support slZRX collateralFactor:0.7 + PriceOracle SetPrice slBAT borrowPrice + Support slBAT collateralFactor:0 SimpleBorrow user borrowAmount mintAmount Macro SimpleBorrow user borrowAmount mintAmount - Prep user mintAmount ZRX cZRX - Mint user mintAmount cZRX - EnterMarkets user cZRX cBAT - Borrow user borrowAmount cBAT + Prep user mintAmount ZRX slZRX + Mint user mintAmount slZRX + EnterMarkets user slZRX slBAT + Borrow user borrowAmount slBAT Test "When account goes further underwater than the liquidation incentive and cannot pay down debt fully" -- Happens whenever collateral ratio > liquidation discount (i.e. 1 / liquidation incentive) @@ -24,23 +24,23 @@ Test "When account goes further underwater than the liquidation incentive and ca NewBorrow borrowAmount:1e18 mintAmount:1.43e18 liquidationIncentive:1.1 -- -- Verify that the borrow results in the correct state - Assert Equal (CToken cBAT BorrowBalance Geoff) 1e18 - Assert Equal (CToken cZRX UnderlyingBalance Geoff) 1.43e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 1e18 + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) 1.43e18 -- -- Put the account underwater s.t. 0.91 < Borrow/Supply -- i.e. (1 / liquidationIncentive) < Borrow/Supply - PriceOracle SetPrice cZRX 0.76 + PriceOracle SetPrice slZRX 0.76 -- -- Pay back a bunch of debt by liquidating - Prep Jared 10e18 BAT cBAT - Liquidate Jared "->" Geoff 0.9e18 cBAT "Seizing" cZRX - Assert Equal (CToken cBAT BorrowBalance Geoff) 0.1e18 - Assert Equal (CToken cZRX UnderlyingBalance Geoff) 0.127368422e18 + Prep Jared 10e18 BAT slBAT + Liquidate Jared "->" Geoff 0.9e18 slBAT "Seizing" slZRX + Assert Equal (SLToken slBAT BorrowBalance Geoff) 0.1e18 + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) 0.127368422e18 -- Do it again, and note that the collateral is gone but borrows remain -- if we had set the close factor lower, it would just take more steps - Liquidate Jared "->" Geoff 0.0880000008e18 cBAT "Seizing" cZRX - Assert Equal (CToken cBAT BorrowBalance Geoff) 0.0119999992e18 - Assert Equal (CToken cZRX UnderlyingBalance Geoff) 0 + Liquidate Jared "->" Geoff 0.0880000008e18 slBAT "Seizing" slZRX + Assert Equal (SLToken slBAT BorrowBalance Geoff) 0.0119999992e18 + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) 0 Test "When liquidation incentive is too high to be effective" -- Happens whenever liquidation discount < collateral factor @@ -49,17 +49,17 @@ Test "When liquidation incentive is too high to be effective" NewBorrow borrowAmount:1e18 mintAmount:1.43e18 liquidationIncentive:1.5 -- -- Verify that the borrow results in the correct state - Assert Equal (CToken cBAT BorrowBalance Geoff) 1e18 - Assert Equal (CToken cZRX UnderlyingBalance Geoff) 1.43e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 1e18 + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) 1.43e18 -- -- Put the account underwater s.t. 0.7 < Borrow/Supply -- i.e. collateral factor < Borrow/Supply - PriceOracle SetPrice cZRX 0.87 + PriceOracle SetPrice slZRX 0.87 -- -- Now any amount of debt that we pay back by liquidating will make liquidity worse -- -- First, prepare to liquidate - Prep Jared 10e18 BAT cBAT + Prep Jared 10e18 BAT slBAT Expect Changes (Comptroller Liquidity Geoff) -0.024999999076e18 -- Note that the account collateral ratio will become worse than before -- although shortfall decreases in absolute terms @@ -67,11 +67,11 @@ Test "When liquidation incentive is too high to be effective" -- now Supply/Borrow = 0.567931036 * 0.87 / 0.5 = 1.135862072 -- -- Now perform the liquidation - Liquidate Jared "->" Geoff 0.5e18 cBAT "Seizing" cZRX + Liquidate Jared "->" Geoff 0.5e18 slBAT "Seizing" slZRX -- -- Verify that the liquidation went through - Assert Equal (CToken cBAT BorrowBalance Geoff) 0.5e18 - Assert Equal (CToken cZRX UnderlyingBalance Geoff) 0.567931036e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 0.5e18 + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) 0.567931036e18 -- -- Test succeeded which means our expectation was correct -- liquidity went down after a liquidation! @@ -79,4 +79,4 @@ Test "When liquidation incentive is too high to be effective" -- Now lets see that lowering the incentive and liquidating improves the situation Comptroller LiquidationIncentive 1.2 Expect Changes (Comptroller Liquidity Geoff) 0.016000000294e18 - Liquidate Jared "->" Geoff 0.1e18 cBAT "Seizing" cZRX + Liquidate Jared "->" Geoff 0.1e18 slBAT "Seizing" slZRX diff --git a/spec/scenario/CTokenAdmin.scen b/spec/scenario/CTokenAdmin.scen deleted file mode 100644 index e658ae1dd..000000000 --- a/spec/scenario/CTokenAdmin.scen +++ /dev/null @@ -1,43 +0,0 @@ - -Test "Set admin" - NewComptroller - NewCToken ZRX cZRX - Assert Equal (CToken cZRX Admin) (Address Root) - Assert Equal (CToken cZRX PendingAdmin) (Address Zero) - From Root (CToken cZRX SetPendingAdmin Geoff) - Assert Equal (CToken cZRX Admin) (Address Root) - Assert Equal (CToken cZRX PendingAdmin) (Address Geoff) - From Geoff (CToken cZRX AcceptAdmin) - Assert Equal (CToken cZRX Admin) (Address Geoff) - Assert Equal (CToken cZRX PendingAdmin) (Address Zero) - -Test "Set admin to contructor argument" - NewComptroller - NewCToken ZRX cZRX admin:Torrey - Assert Equal (CToken cZRX Admin) (Address Torrey) - Assert Equal (CToken cZRX PendingAdmin) (Address Zero) - From Torrey (CToken cZRX SetPendingAdmin Geoff) - Assert Equal (CToken cZRX Admin) (Address Torrey) - Assert Equal (CToken cZRX PendingAdmin) (Address Geoff) - From Geoff (CToken cZRX AcceptAdmin) - Assert Equal (CToken cZRX Admin) (Address Geoff) - Assert Equal (CToken cZRX PendingAdmin) (Address Zero) - - -Test "Fail to set pending admin" - NewComptroller - NewCToken ZRX cZRX - Invariant Remains (CToken cZRX Admin) (Address Root) - Invariant Remains (CToken cZRX PendingAdmin) (Address Zero) - AllowFailures - From Geoff (CToken cZRX SetPendingAdmin Geoff) - Assert Failure UNAUTHORIZED SET_PENDING_ADMIN_OWNER_CHECK - -Test "Fail to accept admin" - NewComptroller - NewCToken ZRX cZRX - Invariant Remains (CToken cZRX Admin) (Address Root) - Invariant Remains (CToken cZRX PendingAdmin) (Address Zero) - AllowFailures - From Geoff (CToken cZRX AcceptAdmin) - Assert Failure UNAUTHORIZED ACCEPT_ADMIN_PENDING_ADMIN_CHECK diff --git a/spec/scenario/ChangeDelegate.scen b/spec/scenario/ChangeDelegate.scen index 08dbbc919..af550dca1 100644 --- a/spec/scenario/ChangeDelegate.scen +++ b/spec/scenario/ChangeDelegate.scen @@ -2,10 +2,10 @@ Test "Change the delegate" NewComptroller - NewCToken DEL cDEL - Support cDEL collateralFactor:0.5 - Prep Jared Some DEL cDEL - Mint Jared 100e18 cDEL - CTokenDelegate Deploy CErc20Delegate cErc20Delegate2 - CToken cDEL SetImplementation (CTokenDelegate cErc20Delegate2 Address) True "0x0" - Redeem Jared 50e9 cDEL + NewSLToken DEL slDEL + Support slDEL collateralFactor:0.5 + Prep Jared Some DEL slDEL + Mint Jared 100e18 slDEL + SLTokenDelegate Deploy SLErc20Delegate slErc20Delegate2 + SLToken slDEL SetImplementation (SLTokenDelegate slErc20Delegate2 Address) True "0x0" + Redeem Jared 50e9 slDEL diff --git a/spec/scenario/Comp/Comp.scen b/spec/scenario/Comp/Comp.scen deleted file mode 100644 index db51ee9f1..000000000 --- a/spec/scenario/Comp/Comp.scen +++ /dev/null @@ -1,300 +0,0 @@ - -Test "Check Name" - Comp Deploy Geoff - Assert Equal (Comp Name) "Compound" - -Test "Check Symbol" - Comp Deploy Geoff - Assert Equal (Comp Symbol) "COMP" - -Test "Check Decimals" - Comp Deploy Geoff - Assert Equal (Comp Decimals) 18 - -Test "Check Total Supply" - Comp Deploy Geoff - Assert Equal (Comp TotalSupply) 10000000e18 - -Test "Check account receives Total Supply after deploy and emits Transfer event" - Comp Deploy Geoff - Assert Equal (Comp TokenBalance Geoff) 10000000e18 - Assert Log Transfer (from (Address Zero)) (to (Address Geoff)) (amount "10000000000000000000000000") - -Test "Check approve sets correct approval and emits Approval event" - Comp Deploy Geoff - From Geoff (Comp Approve Jared 10) - Assert Equal (Comp Allowance Geoff Jared) 10 - Assert Log Approval (owner (Address Geoff)) (spender (Address Jared)) (amount "10") - -Test "Check approve with bad allowance reverts" - Comp Deploy Geoff - AllowFailures - From Geoff (Comp Approve Jared 1e70) - Assert Revert "revert Comp::approve: amount exceeds 96 bits" - -Test "Check transfer updates balances correctly, emits Transfer event, and returns true" - Comp Deploy Geoff - From Geoff (Comp Transfer Jared 10) - Assert Equal (Comp TokenBalance Geoff) 9999999999999999999999990 - Assert Equal (Comp TokenBalance Jared) 10 - Assert Log Transfer (from (Address Geoff)) (to (Address Jared)) (amount "10") - -Test "Check self-transfer updates balances correctly, emits Transfer event, and returns true" - Comp Deploy Geoff - Expect Changes (Comp VotesLength Geoff) Zero - Expect Changes (Comp TokenBalance Geoff) Zero - From Geoff (Comp Transfer Geoff 10) - Assert Log Transfer (from (Address Geoff)) (to (Address Geoff)) (amount "10") - Expect Changes (Comp VotesLength Geoff) Zero - Expect Changes (Comp TokenBalance Geoff) Zero - From Geoff (Comp Transfer Geoff 0) - Assert Log Transfer (from (Address Geoff)) (to (Address Geoff)) (amount "0") - -Test "Check transferFrom with unlimited allowance updates balances correctly, emits Transfer event, and returns true" - Comp Deploy Geoff - From Geoff (Comp Approve Jared UInt256Max) - From Jared (Comp TransferFrom Geoff Jared 10) - Assert Equal (Comp TokenBalance Geoff) 9999999999999999999999990 - Assert Equal (Comp TokenBalance Jared) 10 - Assert Equal (Comp Allowance Geoff Jared) UInt96Max - Assert Log Transfer (from (Address Geoff)) (to (Address Jared)) (amount "10") - -Test "Check transferFrom with unlimited allowance updates balances correctly, emits Transfer event, and returns true" - Comp Deploy Geoff - From Geoff (Comp Approve Jared UInt96Max) - From Jared (Comp TransferFrom Geoff Jared 10) - Assert Equal (Comp TokenBalance Geoff) 9999999999999999999999990 - Assert Equal (Comp TokenBalance Jared) 10 - Assert Equal (Comp Allowance Geoff Jared) UInt96Max - Assert Log Transfer (from (Address Geoff)) (to (Address Jared)) (amount "10") - -Test "Check transferFrom with allowance updates balances correctly, emits Transfer event, and returns true" - Comp Deploy Geoff - From Geoff (Comp Approve Jared 10) - From Jared (Comp TransferFrom Geoff Jared 9) - Assert Equal (Comp TokenBalance Geoff) 9999999999999999999999991 - Assert Equal (Comp TokenBalance Jared) 9 - Assert Equal (Comp Allowance Geoff Jared) 1 - Assert Log Transfer (from (Address Geoff)) (to (Address Jared)) (amount "9") - Assert Log Approval (owner (Address Geoff)) (spender (Address Jared)) (amount "1") - -Test "Check transferFrom reverts with not sufficient allowance" - Comp Deploy Geoff - From Geoff (Comp Approve Jared 10) - AllowFailures - From Jared (Comp TransferFrom Geoff Jared 11) - Assert Revert "revert Comp::transferFrom: transfer amount exceeds spender allowance" - -Test "Check transfer reverts when transferring too much" - Comp Deploy Geoff - AllowFailures - From Geoff (Comp Transfer Jared 10000001e18) - Assert Revert "revert Comp::_transferTokens: transfer amount exceeds balance" - -Test "Check transfer reverts when transferring to address 0" - Comp Deploy Geoff - AllowFailures - From Geoff (Comp Transfer (Address Zero) 10000000e18) - Assert Revert "revert Comp::_transferTokens: cannot transfer to the zero address" - -Test "Delegate with zero balance doesn't change votes checkpoints" - Comp Deploy Geoff - Assert Equal (Comp VotesLength Geoff) 0 - From Jared (Comp Delegate Geoff) - Assert Equal (Comp VotesLength Geoff) 0 - Assert Log DelegateChanged (delegator (Address Jared)) (fromDelegate (Address Zero)) (toDelegate (Address Geoff)) - -Test "Delegate from address(0) to account with zero checkpoints" - Comp Deploy Geoff - From Geoff (Comp Transfer Jared 10) - Assert Equal (Comp VotesLength Geoff) 0 - From Jared (Comp Delegate Geoff) - Assert Equal (Comp VotesLength Geoff) 1 - Assert Equal (Comp GetCurrentVotes Geoff) 10 - Assert Equal (Comp GetCurrentVotesBlock Geoff) LastBlock - Assert Equal (Comp VotesLength Zero) 0 - Assert Log DelegateChanged (delegator (Address Jared)) (fromDelegate (Address Zero)) (toDelegate (Address Geoff)) - Assert Log DelegateVotesChanged (delegate (Address Geoff)) (previousBalance "0") (newBalance "10") - -Test "Delegate from address(0) to account with existing checkpoints" - Comp Deploy Geoff - From Geoff (Comp Transfer Jared 10) - From Geoff (Comp Transfer Torrey 14) - Assert Equal (Comp VotesLength Geoff) 0 - From Jared (Comp Delegate Geoff) - Assert Equal (Comp VotesLength Geoff) 1 - Assert Equal (Comp GetCurrentVotes Geoff) 10 - Assert Equal (Comp GetCurrentVotesBlock Geoff) LastBlock - Assert Log DelegateChanged (delegator (Address Jared)) (fromDelegate (Address Zero)) (toDelegate (Address Geoff)) - Assert Log DelegateVotesChanged (delegate (Address Geoff)) (previousBalance "0") (newBalance "10") - From Torrey (Comp Delegate Geoff) - Assert Equal (Comp VotesLength Geoff) 2 - Assert Equal (Comp GetCurrentVotes Geoff) 24 - Assert Equal (Comp GetCurrentVotesBlock Geoff) LastBlock - Assert Equal (Comp VotesLength Zero) 0 - Assert Log DelegateChanged (delegator (Address Torrey)) (fromDelegate (Address Zero)) (toDelegate (Address Geoff)) - Assert Log DelegateVotesChanged (delegate (Address Geoff)) (previousBalance "10") (newBalance "24") - -Test "Delegate to address(0)" - Comp Deploy Geoff - From Geoff (Comp Transfer Jared 10) - From Geoff (Comp Transfer Torrey 14) - Assert Equal (Comp VotesLength Geoff) 0 - From Jared (Comp Delegate Geoff) - Assert Equal (Comp VotesLength Geoff) 1 - Assert Equal (Comp GetCurrentVotes Geoff) 10 - Assert Equal (Comp GetCurrentVotesBlock Geoff) LastBlock - Assert Log DelegateChanged (delegator (Address Jared)) (fromDelegate (Address Zero)) (toDelegate (Address Geoff)) - Assert Log DelegateVotesChanged (delegate (Address Geoff)) (previousBalance "0") (newBalance "10") - From Torrey (Comp Delegate Geoff) - Assert Equal (Comp VotesLength Geoff) 2 - Assert Equal (Comp GetCurrentVotes Geoff) 24 - Assert Equal (Comp GetCurrentVotesBlock Geoff) LastBlock - Assert Log DelegateChanged (delegator (Address Torrey)) (fromDelegate (Address Zero)) (toDelegate (Address Geoff)) - Assert Log DelegateVotesChanged (delegate (Address Geoff)) (previousBalance "10") (newBalance "24") - From Torrey (Comp Delegate Zero) - Assert Equal (Comp VotesLength Geoff) 3 - Assert Equal (Comp GetCurrentVotes Geoff) 10 - Assert Equal (Comp GetCurrentVotesBlock Geoff) LastBlock - Assert Log DelegateChanged (delegator (Address Torrey)) (fromDelegate (Address Geoff)) (toDelegate (Address Zero)) - Assert Log DelegateVotesChanged (delegate (Address Geoff)) (previousBalance "24") (newBalance "10") - Assert Equal (Comp VotesLength Zero) 0 - -Test "Delegate from one account to another account with zero checkpoints" - Comp Deploy Geoff - From Geoff (Comp Transfer Jared 10) - From Geoff (Comp Transfer Torrey 14) - Assert Equal (Comp VotesLength Geoff) 0 - From Jared (Comp Delegate Geoff) - Assert Equal (Comp VotesLength Geoff) 1 - Assert Equal (Comp GetCurrentVotes Geoff) 10 - Assert Equal (Comp GetCurrentVotesBlock Geoff) LastBlock - Assert Log DelegateChanged (delegator (Address Jared)) (fromDelegate (Address Zero)) (toDelegate (Address Geoff)) - Assert Log DelegateVotesChanged (delegate (Address Geoff)) (previousBalance "0") (newBalance "10") - From Torrey (Comp Delegate Geoff) - Assert Equal (Comp VotesLength Geoff) 2 - Assert Equal (Comp GetCurrentVotes Geoff) 24 - Assert Equal (Comp GetCurrentVotesBlock Geoff) LastBlock - Assert Equal (Comp VotesLength Coburn) 0 - Assert Log DelegateChanged (delegator (Address Torrey)) (fromDelegate (Address Zero)) (toDelegate (Address Geoff)) - Assert Log DelegateVotesChanged (delegate (Address Geoff)) (previousBalance "10") (newBalance "24") - From Torrey (Comp Delegate Coburn) - Assert Equal (Comp VotesLength Coburn) 1 - Assert Equal (Comp GetCurrentVotes Coburn) 14 - Assert Equal (Comp GetCurrentVotesBlock Coburn) LastBlock - Assert Equal (Comp VotesLength Geoff) 3 - Assert Equal (Comp GetCurrentVotes Geoff) 10 - Assert Equal (Comp GetCurrentVotesBlock Geoff) LastBlock - Assert Log DelegateChanged (delegator (Address Torrey)) (fromDelegate (Address Geoff)) (toDelegate (Address Coburn)) - Assert Log DelegateVotesChanged (delegate (Address Geoff)) (previousBalance "24") (newBalance "10") - Assert Log DelegateVotesChanged (delegate (Address Coburn)) (previousBalance "0") (newBalance "14") - -Test "Delegate from one account to another account with multiple checkpoints" - Comp Deploy Geoff - From Geoff (Comp Transfer Jared 10) - From Geoff (Comp Transfer Torrey 14) - From Geoff (Comp Transfer Coburn 2) - Assert Equal (Comp VotesLength Geoff) 0 - From Jared (Comp Delegate Geoff) - Assert Equal (Comp VotesLength Geoff) 1 - Assert Equal (Comp GetCurrentVotes Geoff) 10 - Assert Equal (Comp GetCurrentVotesBlock Geoff) LastBlock - Assert Log DelegateChanged (delegator (Address Jared)) (fromDelegate (Address Zero)) (toDelegate (Address Geoff)) - Assert Log DelegateVotesChanged (delegate (Address Geoff)) (previousBalance "0") (newBalance "10") - From Torrey (Comp Delegate Geoff) - Assert Equal (Comp VotesLength Geoff) 2 - Assert Equal (Comp GetCurrentVotes Geoff) 24 - Assert Equal (Comp GetCurrentVotesBlock Geoff) LastBlock - Assert Equal (Comp VotesLength Coburn) 0 - Assert Log DelegateChanged (delegator (Address Torrey)) (fromDelegate (Address Zero)) (toDelegate (Address Geoff)) - Assert Log DelegateVotesChanged (delegate (Address Geoff)) (previousBalance "10") (newBalance "24") - From Coburn (Comp Delegate Coburn) - Assert Equal (Comp VotesLength Coburn) 1 - Assert Equal (Comp GetCurrentVotes Coburn) 2 - Assert Equal (Comp GetCurrentVotesBlock Coburn) LastBlock - Assert Log DelegateChanged (delegator (Address Coburn)) (fromDelegate (Address Zero)) (toDelegate (Address Coburn)) - Assert Log DelegateVotesChanged (delegate (Address Coburn)) (previousBalance "0") (newBalance "2") - From Torrey (Comp Delegate Coburn) - Assert Equal (Comp VotesLength Coburn) 2 - Assert Equal (Comp GetCurrentVotes Coburn) 16 - Assert Equal (Comp GetCurrentVotesBlock Coburn) LastBlock - Assert Equal (Comp VotesLength Geoff) 3 - Assert Equal (Comp GetCurrentVotes Geoff) 10 - Assert Equal (Comp GetCurrentVotesBlock Geoff) LastBlock - Assert Log DelegateChanged (delegator (Address Torrey)) (fromDelegate (Address Geoff)) (toDelegate (Address Coburn)) - Assert Log DelegateVotesChanged (delegate (Address Geoff)) (previousBalance "24") (newBalance "10") - Assert Log DelegateVotesChanged (delegate (Address Coburn)) (previousBalance "2") (newBalance "16") - -Test "Vote checkpoints don't change on transfer when to and from accounts delegate to same account" - Comp Deploy Geoff - From Geoff (Comp Transfer Jared 10) - From Geoff (Comp Transfer Torrey 14) - Assert Equal (Comp VotesLength Geoff) 0 - From Jared (Comp Delegate Geoff) - Assert Equal (Comp VotesLength Geoff) 1 - Assert Equal (Comp GetCurrentVotes Geoff) 10 - Assert Equal (Comp GetCurrentVotesBlock Geoff) LastBlock - Assert Log DelegateChanged (delegator (Address Jared)) (fromDelegate (Address Zero)) (toDelegate (Address Geoff)) - Assert Log DelegateVotesChanged (delegate (Address Geoff)) (previousBalance "0") (newBalance "10") - From Torrey (Comp Delegate Geoff) - Assert Equal (Comp VotesLength Geoff) 2 - Assert Equal (Comp GetCurrentVotes Geoff) 24 - Assert Equal (Comp GetCurrentVotesBlock Geoff) LastBlock - Assert Log DelegateChanged (delegator (Address Torrey)) (fromDelegate (Address Zero)) (toDelegate (Address Geoff)) - Assert Log DelegateVotesChanged (delegate (Address Geoff)) (previousBalance "10") (newBalance "24") - Invariant Static (Comp VotesLength Geoff) - Invariant Static (Comp GetCurrentVotes Geoff) - Invariant Static (Comp GetCurrentVotesBlock Geoff) - From Torrey (Comp Transfer Jared 14) - -Test "Only one checkpoint is added per block for multiple increased balance updates" - Comp Deploy Scenario Geoff - Assert Equal (Comp VotesLength Geoff) 0 - Assert Equal (Comp GetCurrentVotes Geoff) 0 - From Jared (Comp Delegate Geoff) - Assert Log DelegateChanged (delegator (Address Jared)) (fromDelegate (Address Zero)) (toDelegate (Address Geoff)) - From Torrey (Comp Delegate Geoff) - Assert Log DelegateChanged (delegator (Address Torrey)) (fromDelegate (Address Zero)) (toDelegate (Address Geoff)) - From Geoff (Comp TransferScenario (Jared Torrey) 10) - Assert Equal (Comp VotesLength Geoff) 1 - Assert Equal (Comp GetCurrentVotes Geoff) 20 - Assert Equal (Comp GetCurrentVotesBlock Geoff) LastBlock - Assert Equal (Comp VotesLength Zero) 0 - Assert Log DelegateVotesChanged (delegate (Address Geoff)) (previousBalance "0") (newBalance "10") - Assert Log DelegateVotesChanged (delegate (Address Geoff)) (previousBalance "10") (newBalance "20") - -Test "Only one checkpoint is added per block for multiple decreased balance updates" - Comp Deploy Scenario Geoff - From Geoff (Comp Transfer Jared 10) - From Geoff (Comp Transfer Torrey 10) - Assert Equal (Comp VotesLength Geoff) 0 - Assert Equal (Comp GetCurrentVotes Geoff) 0 - From Jared (Comp Delegate Geoff) - Assert Equal (Comp VotesLength Geoff) 1 - Assert Equal (Comp GetCurrentVotes Geoff) 10 - Assert Equal (Comp GetCurrentVotesBlock Geoff) LastBlock - Assert Log DelegateChanged (delegator (Address Jared)) (fromDelegate (Address Zero)) (toDelegate (Address Geoff)) - Assert Log DelegateVotesChanged (delegate (Address Geoff)) (previousBalance "0") (newBalance "10") - From Torrey (Comp Delegate Geoff) - Assert Equal (Comp VotesLength Geoff) 2 - Assert Equal (Comp GetCurrentVotes Geoff) 20 - Assert Equal (Comp GetCurrentVotesBlock Geoff) LastBlock - Assert Log DelegateChanged (delegator (Address Torrey)) (fromDelegate (Address Zero)) (toDelegate (Address Geoff)) - Assert Log DelegateVotesChanged (delegate (Address Geoff)) (previousBalance "10") (newBalance "20") - From Jared (Comp Approve Geoff 10) - From Torrey (Comp Approve Geoff 10) - From Geoff (Comp TransferFromScenario (Jared Torrey) 10) - Assert Equal (Comp VotesLength Geoff) 3 - Assert Equal (Comp GetCurrentVotes Geoff) 0 - Assert Equal (Comp GetCurrentVotesBlock Geoff) LastBlock - Assert Equal (Comp VotesLength Zero) 0 - Assert Log DelegateVotesChanged (delegate (Address Geoff)) (previousBalance "20") (newBalance "10") - Assert Log DelegateVotesChanged (delegate (Address Geoff)) (previousBalance "10") (newBalance "0") - -Test "Check transfer reverts when block number exceeds 32 bits" - Comp Deploy Geoff - From Jared (Comp Delegate Geoff) - AllowFailures - SetBlockNumber 5000000000 - From Geoff (Comp Transfer Jared 10000000e18) - Assert Revert "revert Comp::_writeCheckpoint: block number exceeds 32 bits" diff --git a/spec/scenario/CoreMacros b/spec/scenario/CoreMacros index 904afaf42..02650be4f 100644 --- a/spec/scenario/CoreMacros +++ b/spec/scenario/CoreMacros @@ -11,7 +11,7 @@ Macro PricedComptroller closeFactor=0.1 maxAssets=20 PriceOracle Deploy Simple ComptrollerImpl Deploy ScenarioG1 ScenComptrollerG1 Unitroller SetPendingImpl ScenComptrollerG1 - PriceOracleProxy Deploy Admin (PriceOracle Address) (Address Zero) (Address Zero) (Address Zero) (Address Zero) (Address Zero) -- if listing cEther use ListedEtherToken to replace proxy + PriceOracleProxy Deploy Admin (PriceOracle Address) (Address Zero) (Address Zero) (Address Zero) (Address Zero) (Address Zero) -- if listing slEther use ListedEtherToken to replace proxy ComptrollerImpl ScenComptrollerG1 BecomeG1 (PriceOracleProxy Address) closeFactor maxAssets ComptrollerImpl Deploy Scenario ScenComptroller Unitroller SetPendingImpl ScenComptroller @@ -23,7 +23,7 @@ Macro NewComptroller price=1.0 closeFactor=0.1 maxAssets=20 PriceOracle Deploy Fixed price ComptrollerImpl Deploy ScenarioG1 ScenComptrollerG1 Unitroller SetPendingImpl ScenComptrollerG1 - PriceOracleProxy Deploy Admin (PriceOracle Address) (Address Zero) (Address Zero) (Address Zero) (Address Zero) (Address Zero) -- if listing cEther use ListedEtherToken to replace proxy + PriceOracleProxy Deploy Admin (PriceOracle Address) (Address Zero) (Address Zero) (Address Zero) (Address Zero) (Address Zero) -- if listing slEther use ListedEtherToken to replace proxy ComptrollerImpl ScenComptrollerG1 BecomeG1 (PriceOracleProxy Address) closeFactor maxAssets --g2 ComptrollerImpl Deploy StandardG2 ComptrollerG2 @@ -38,135 +38,135 @@ Macro NewComptroller price=1.0 closeFactor=0.1 maxAssets=20 Unitroller SetPendingImpl ScenComptroller ComptrollerImpl ScenComptroller Become -Macro NewCToken erc20 cToken borrowRate=0.000005 initialExchangeRate=2e9 decimals=8 tokenType=Standard delegatorType=CErc20DelegatorScenario cTokenType=CErc20DelegateScenario admin=Admin becomeImplementationData="0x0" +Macro NewSLToken erc20 slToken borrowRate=0.000005 initialExchangeRate=2e9 decimals=8 tokenType=Standard delegatorType=SLErc20DelegatorScenario slTokenType=SLErc20DelegateScenario admin=Admin becomeImplementationData="0x0" Erc20 Deploy tokenType erc20 erc20 InterestRateModel Deploy Fixed StdInterest borrowRate -- Note: interest rate model probably shouldn't be global - CTokenDelegate Deploy cTokenType cErc20Delegate - CToken Deploy delegatorType cToken cToken (Erc20 erc20 Address) (Comptroller Address) (InterestRateModel StdInterest Address) initialExchangeRate decimals admin (CTokenDelegate cErc20Delegate Address) becomeImplementationData + SLTokenDelegate Deploy slTokenType slErc20Delegate + SLToken Deploy delegatorType slToken slToken (Erc20 erc20 Address) (Comptroller Address) (InterestRateModel StdInterest Address) initialExchangeRate decimals admin (SLTokenDelegate slErc20Delegate Address) becomeImplementationData --- Same as NewCToken but does not deploy an ERC20. Used for special ERC20s that are initialized differently -Macro NewCTokenBringERC20 erc20 cToken borrowRate=0.000005 initialExchangeRate=2e9 decimals=8 delegatorType=CErc20DelegatorScenario cTokenType=CErc20DelegateScenario admin=Admin becomeImplementationData="0x0" +-- Same as NewSLToken but does not deploy an ERC20. Used for special ERC20s that are initialized differently +Macro NewSLTokenBringERC20 erc20 slToken borrowRate=0.000005 initialExchangeRate=2e9 decimals=8 delegatorType=SLErc20DelegatorScenario slTokenType=SLErc20DelegateScenario admin=Admin becomeImplementationData="0x0" InterestRateModel Deploy Fixed StdInterest borrowRate -- Note: interest rate model probably shouldn't be global - CTokenDelegate Deploy cTokenType cErc20Delegate - CToken Deploy delegatorType cToken cToken (Erc20 erc20 Address) (Comptroller Address) (InterestRateModel StdInterest Address) initialExchangeRate decimals admin (CTokenDelegate cErc20Delegate Address) becomeImplementationData + SLTokenDelegate Deploy slTokenType slErc20Delegate + SLToken Deploy delegatorType slToken slToken (Erc20 erc20 Address) (Comptroller Address) (InterestRateModel StdInterest Address) initialExchangeRate decimals admin (SLTokenDelegate slErc20Delegate Address) becomeImplementationData -Macro NewCTokenImmutable erc20 cToken borrowRate=0.000005 initialExchangeRate=2e9 decimals=8 tokenType=Standard cTokenType=Scenario admin=Admin +Macro NewSLTokenImmutable erc20 slToken borrowRate=0.000005 initialExchangeRate=2e9 decimals=8 tokenType=Standard slTokenType=Scenario admin=Admin Erc20 Deploy tokenType erc20 erc20 InterestRateModel Deploy Fixed StdInterest borrowRate -- Note: interest rate model probably shouldn't be global - CToken Deploy cTokenType cToken cToken (Erc20 erc20 Address) (Comptroller Address) (InterestRateModel StdInterest Address) initialExchangeRate decimals admin + SLToken Deploy slTokenType slToken slToken (Erc20 erc20 Address) (Comptroller Address) (InterestRateModel StdInterest Address) initialExchangeRate decimals admin -Macro NewEtherToken cToken borrowRate=0.000005 initialExchangeRate=2e9 decimals=8 admin=Admin +Macro NewEtherToken slToken borrowRate=0.000005 initialExchangeRate=2e9 decimals=8 admin=Admin InterestRateModel Deploy Fixed StdInterest borrowRate -- Note: interest rate model probably shouldn't be global - CToken Deploy CEtherScenario cToken cToken (Comptroller Address) (InterestRateModel StdInterest Address) initialExchangeRate decimals admin + SLToken Deploy slEtherScenario slToken slToken (Comptroller Address) (InterestRateModel StdInterest Address) initialExchangeRate decimals admin -Macro ListedCToken erc20 cToken borrowRate=0.000005 initialExchangeRate=2e9 decimals=8 tokenType=Standard delegatorType=CErc20DelegatorScenario cTokenType=CErc20DelegateScenario admin=Admin - NewCToken erc20 cToken borrowRate initialExchangeRate decimals tokenType delegatorType cTokenType admin - Comptroller SupportMarket cToken +Macro ListedSLToken erc20 slToken borrowRate=0.000005 initialExchangeRate=2e9 decimals=8 tokenType=Standard delegatorType=SLErc20DelegatorScenario slTokenType=SLErc20DelegateScenario admin=Admin + NewSLToken erc20 slToken borrowRate initialExchangeRate decimals tokenType delegatorType slTokenType admin + Comptroller SupportMarket slToken -Macro ListedCTokenImmutable erc20 cToken borrowRate=0.000005 initialExchangeRate=2e9 decimals=8 tokenType=Standard cTokenType=Scenario admin=Admin - NewCTokenImmutable erc20 cToken borrowRate initialExchangeRate decimals tokenType cTokenType admin - Comptroller SupportMarket cToken +Macro ListedSLTokenImmutable erc20 slToken borrowRate=0.000005 initialExchangeRate=2e9 decimals=8 tokenType=Standard slTokenType=Scenario admin=Admin + NewSLTokenImmutable erc20 slToken borrowRate initialExchangeRate decimals tokenType slTokenType admin + Comptroller SupportMarket slToken -Macro ListedEtherToken cToken borrowRate=0.000005 initialExchangeRate=2e9 decimals=8 admin=Admin - NewEtherToken cToken borrowRate initialExchangeRate decimals admin - Comptroller SupportMarket cToken - PriceOracleProxy Deploy Admin (PriceOracle Address) (Address cETH) (Address Zero) (Address Zero) (Address Zero) (Address Zero) +Macro ListedEtherToken slToken borrowRate=0.000005 initialExchangeRate=2e9 decimals=8 admin=Admin + NewEtherToken slToken borrowRate initialExchangeRate decimals admin + Comptroller SupportMarket slToken + PriceOracleProxy Deploy Admin (PriceOracle Address) (Address slETH) (Address Zero) (Address Zero) (Address Zero) (Address Zero) Comptroller SetPriceOracle (PriceOracleProxy Address) -Macro ListedEtherTokenMinted cToken borrowRate=0.000005 initialExchangeRate=2e9 decimals=8 admin=Admin - NewEtherToken cToken borrowRate initialExchangeRate decimals admin - Comptroller SupportMarket cToken - CallMintEth Root 1e18 cToken +Macro ListedEtherTokenMinted slToken borrowRate=0.000005 initialExchangeRate=2e9 decimals=8 admin=Admin + NewEtherToken slToken borrowRate initialExchangeRate decimals admin + Comptroller SupportMarket slToken + CallMintEth Root 1e18 slToken -Macro SetPriceCF cToken price collateralFactor - PriceOracle SetPrice cToken price - Comptroller SetCollateralFactor cToken collateralFactor +Macro SetPriceCF slToken price collateralFactor + PriceOracle SetPrice slToken price + Comptroller SetCollateralFactor slToken collateralFactor Macro Give user amount erc20 Erc20 erc20 Faucet user amount Macro Donate token amount - (Trx Value amount (CToken token Donate)) + (Trx Value amount (SLToken token Donate)) Macro Prep user amount erc20 token allowanceAmount=Nothing Erc20 erc20 Faucet user amount From user (Erc20 erc20 Approve token (Default allowanceAmount amount)) Macro Allow user token - From user (Erc20 (CToken token Underlying) Approve token UInt256Max) + From user (Erc20 (SLToken token Underlying) Approve token UInt256Max) Macro AccrueInterest token - CToken token AccrueInterest + SLToken token AccrueInterest Macro Mint user amount token - From user (CToken token Mint amount) + From user (SLToken token Mint amount) Macro SendMintEth user amount token From user (Trx GasPrice 0 (Trx Value amount (Send token amount))) Macro CallMintEth user amount token - From user (Trx GasPrice 0 (Trx Value amount (CToken token Mint))) + From user (Trx GasPrice 0 (Trx Value amount (SLToken token Mint))) Macro Redeem user amount token - From user (CToken token Redeem amount) + From user (SLToken token Redeem amount) Macro RedeemEth user amount token - Trx GasPrice 0 (From user (CToken token Redeem amount)) + Trx GasPrice 0 (From user (SLToken token Redeem amount)) Macro RedeemUnderlying user amount token - From user (CToken token RedeemUnderlying amount) + From user (SLToken token RedeemUnderlying amount) Macro RedeemUnderlyingEth user amount token - Trx GasPrice 0 (From user (CToken token RedeemUnderlying amount)) + Trx GasPrice 0 (From user (SLToken token RedeemUnderlying amount)) Macro BorrowEth user amount token - Trx GasPrice 0 (From user (CToken token Borrow amount)) + Trx GasPrice 0 (From user (SLToken token Borrow amount)) Macro Borrow user amount token - From user (CToken token Borrow amount) + From user (SLToken token Borrow amount) Macro RepayBorrow user amount token - From user (CToken token RepayBorrow amount) + From user (SLToken token RepayBorrow amount) Macro RepayBorrowEth user amount token - From user (Trx GasPrice 0 (Trx Value amount (CToken token RepayBorrow))) + From user (Trx GasPrice 0 (Trx Value amount (SLToken token RepayBorrow))) Macro RepayBorrowEthMax user amount token From user (Trx GasPrice 0 (Trx Value amount (Maximillion RepayBehalf user))) Macro RepayBorrowBehalf user behalf amount token - From user (CToken token RepayBorrowBehalf behalf amount) + From user (SLToken token RepayBorrowBehalf behalf amount) Macro RepayBorrowEthBehalf user behalf amount token - From user (Trx GasPrice 0 (Trx Value amount (CToken token RepayBorrowBehalf behalf))) + From user (Trx GasPrice 0 (Trx Value amount (SLToken token RepayBorrowBehalf behalf))) Macro Liquidate liquidator _ borrower amount token _ collateral - From liquidator (CToken token Liquidate borrower collateral amount) + From liquidator (SLToken token Liquidate borrower collateral amount) Macro LiquidateEthColl liquidator _ borrower amount token _ collateral - From liquidator (Trx GasPrice 0 (CToken token Liquidate borrower collateral amount)) + From liquidator (Trx GasPrice 0 (SLToken token Liquidate borrower collateral amount)) Macro LiquidateEthBorrow liquidator _ borrower amount token _ collateral - From liquidator (Trx GasPrice 0 (Trx Value amount (CToken token Liquidate borrower collateral))) + From liquidator (Trx GasPrice 0 (Trx Value amount (SLToken token Liquidate borrower collateral))) Macro Seize amount token caller liquidator borrower - From caller (CToken token Seize liquidator borrower amount) + From caller (SLToken token Seize liquidator borrower amount) Macro EvilSeize token amount treasure seizer seizee - CToken token EvilSeize treasure seizer seizee amount + SLToken token EvilSeize treasure seizer seizee amount -Macro Support cToken collateralFactor=0.5 - Comptroller SupportMarket cToken - Comptroller SetCollateralFactor cToken collateralFactor +Macro Support slToken collateralFactor=0.5 + Comptroller SupportMarket slToken + Comptroller SetCollateralFactor slToken collateralFactor -Macro SetCollateralFactor cToken collateralFactor=0.5 - Comptroller SetCollateralFactor cToken collateralFactor +Macro SetCollateralFactor slToken collateralFactor=0.5 + Comptroller SetCollateralFactor slToken collateralFactor Macro AddReserves amount token user=Root - From user (CToken token AddReserves amount) + From user (SLToken token AddReserves amount) Macro ReduceReserves amount token - CToken token ReduceReserves amount + SLToken token ReduceReserves amount Macro FastForward n blocks Comptroller FastForward n blocks @@ -180,64 +180,64 @@ Macro ExitMarket user market Macro Transfer from to amount token From from (Erc20 token Transfer to amount) -Macro Cash cToken - Read Erc20 (CToken cToken Underlying) TokenBalance cToken +Macro Cash slToken + Read Erc20 (SLToken slToken Underlying) TokenBalance slToken -Macro QuickMint amount cToken from=Me - Give from amount (CToken cToken Underlying) - Allow from cToken - From from (CToken cToken Mint amount) +Macro QuickMint amount slToken from=Me + Give from amount (SLToken slToken Underlying) + Allow from slToken + From from (SLToken slToken Mint amount) -Macro QuickBorrow amount cToken ...collateral +Macro QuickBorrow amount slToken ...collateral From Me (Comptroller EnterMarkets collateral) - From Me (Comptroller EnterMarkets (cToken)) - From Me (CToken cToken Borrow amount) + From Me (Comptroller EnterMarkets (slToken)) + From Me (SLToken slToken Borrow amount) -- Macro for performing a borrow with the sole -- purpose of adding interest to the erc20 market -Macro BorrowAndRepayWithInterest erc20 cToken amount interestAmount interestRate blocks reserveRate=0 +Macro BorrowAndRepayWithInterest erc20 slToken amount interestAmount interestRate blocks reserveRate=0 -- TODO: Make invariant success for these? -- TODO: Named args as macros InterestRateModel Deploy Fixed Std interestRate - CToken cToken SetInterestRateModel (InterestRateModel Std Address) - CToken cToken SetReserveFactor reserveRate - ListedCToken COLLAT cCOLLAT - Comptroller SetCollateralFactor cCOLLAT 0.9 - Prep Torrey 1e30 COLLAT cCOLLAT - Mint Torrey 1e30 cCOLLAT - EnterMarkets Torrey cCOLLAT cToken - Assert True (Comptroller CheckMembership Torrey cCOLLAT) - Assert True (Comptroller CheckMembership Torrey cToken) - Borrow Torrey amount cToken + SLToken slToken SetInterestRateModel (InterestRateModel Std Address) + SLToken slToken SetReserveFactor reserveRate + ListedSLToken COLLAT slCOLLAT + Comptroller SetCollateralFactor slCOLLAT 0.9 + Prep Torrey 1e30 COLLAT slCOLLAT + Mint Torrey 1e30 slCOLLAT + EnterMarkets Torrey slCOLLAT slToken + Assert True (Comptroller CheckMembership Torrey slCOLLAT) + Assert True (Comptroller CheckMembership Torrey slToken) + Borrow Torrey amount slToken -- Cool, we've borrowed, now let's accrue interest then repay all FastForward blocks Blocks - -- RepayBorrow Torrey (CToken BorrowBalance Torrey) cToken - From Torrey (Erc20 erc20 Approve cToken amount) - RepayBorrow Torrey amount cToken - From Torrey (Erc20 erc20 Approve cToken interestAmount) + -- RepayBorrow Torrey (SLToken BorrowBalance Torrey) slToken + From Torrey (Erc20 erc20 Approve slToken amount) + RepayBorrow Torrey amount slToken + From Torrey (Erc20 erc20 Approve slToken interestAmount) Give Torrey interestAmount erc20 - RepayBorrow Torrey interestAmount cToken - Assert Equal (CToken cToken BorrowBalance Torrey) Zero + RepayBorrow Torrey interestAmount slToken + Assert Equal (SLToken slToken BorrowBalance Torrey) Zero -- Macro for performing a borrow with the sole -- purpose of adding interest to the ether market -Macro BorrowAndRepayEthWithInterest cEther amount interestAmount interestRate blocks reserveRate=0 +Macro BorrowAndRepayEthWithInterest slEther amount interestAmount interestRate blocks reserveRate=0 -- TODO: Make invariant success for these? -- TODO: Named args as macros InterestRateModel Deploy Fixed Std interestRate - CToken cEther SetInterestRateModel (InterestRateModel Std Address) - CToken cEther SetReserveFactor reserveRate - ListedCToken COLLAT cCOLLAT - Comptroller SetCollateralFactor cCOLLAT 0.9 - Prep Torrey 1e30 COLLAT cCOLLAT - Mint Torrey 1e30 cCOLLAT - EnterMarkets Torrey cCOLLAT cEther - Assert True (Comptroller CheckMembership Torrey cCOLLAT) - Assert True (Comptroller CheckMembership Torrey cEther) - Borrow Torrey amount cEther + SLToken slEther SetInterestRateModel (InterestRateModel Std Address) + SLToken slEther SetReserveFactor reserveRate + ListedSLToken COLLAT slCOLLAT + Comptroller SetCollateralFactor slCOLLAT 0.9 + Prep Torrey 1e30 COLLAT slCOLLAT + Mint Torrey 1e30 slCOLLAT + EnterMarkets Torrey slCOLLAT slEther + Assert True (Comptroller CheckMembership Torrey slCOLLAT) + Assert True (Comptroller CheckMembership Torrey slEther) + Borrow Torrey amount slEther -- Cool, we've borrowed, now let's accrue interest then repay all FastForward blocks Blocks - -- RepayBorrow Torrey (CToken BorrowBalance Torrey) cEther - RepayBorrowEth Torrey amount cEther - RepayBorrowEth Torrey interestAmount cEther - Assert Equal (CToken cEther BorrowBalance Torrey) Zero + -- RepayBorrow Torrey (SLToken BorrowBalance Torrey) slEther + RepayBorrowEth Torrey amount slEther + RepayBorrowEth Torrey interestAmount slEther + Assert Equal (SLToken slEther BorrowBalance Torrey) Zero diff --git a/spec/scenario/EnterExitMarkets.scen b/spec/scenario/EnterExitMarkets.scen index ad8217a81..6bab5eeda 100644 --- a/spec/scenario/EnterExitMarkets.scen +++ b/spec/scenario/EnterExitMarkets.scen @@ -4,148 +4,148 @@ Test "Enter Markets Idempotent" NewComptroller Assert Equal (Comptroller MembershipLength Geoff) Zero Assert Equal (Comptroller AssetsIn Geoff) [] - ListedCToken ZRX cZRX - EnterMarkets Geoff cZRX - Assert Log MarketEntered (cToken (Address cZRX)) (account (Address Geoff)) + ListedSLToken ZRX slZRX + EnterMarkets Geoff slZRX + Assert Log MarketEntered (slToken (Address slZRX)) (account (Address Geoff)) Assert Equal (Comptroller MembershipLength Geoff) (Exactly 1) - Assert True (Comptroller CheckMembership Geoff cZRX) - ListedCToken OMG cOMG - EnterMarkets Geoff cZRX cOMG + Assert True (Comptroller CheckMembership Geoff slZRX) + ListedSLToken OMG slOMG + EnterMarkets Geoff slZRX slOMG Assert Equal (Comptroller MembershipLength Geoff) (Exactly 2) - Assert True (Comptroller CheckMembership Geoff cZRX) - Assert True (Comptroller CheckMembership Geoff cOMG) - Assert Equal (Comptroller AssetsIn Geoff) [(Address cZRX) (Address cOMG)] + Assert True (Comptroller CheckMembership Geoff slZRX) + Assert True (Comptroller CheckMembership Geoff slOMG) + Assert Equal (Comptroller AssetsIn Geoff) [(Address slZRX) (Address slOMG)] Test "Entered Market Must Be Supported" NewComptroller Assert Equal (Comptroller MembershipLength Geoff) Zero - ListedCToken ZRX cZRX - EnterMarkets Geoff cZRX + ListedSLToken ZRX slZRX + EnterMarkets Geoff slZRX Assert Equal (Comptroller MembershipLength Geoff) (Exactly 1) - NewCToken OMG cOMG - EnterMarkets Geoff cZRX cOMG + NewSLToken OMG slOMG + EnterMarkets Geoff slZRX slOMG Assert Equal (Comptroller MembershipLength Geoff) (Exactly 1) - Assert True (Comptroller CheckMembership Geoff cZRX) - Assert False (Comptroller CheckMembership Geoff cOMG) - Support cOMG - EnterMarkets Geoff cZRX cOMG + Assert True (Comptroller CheckMembership Geoff slZRX) + Assert False (Comptroller CheckMembership Geoff slOMG) + Support slOMG + EnterMarkets Geoff slZRX slOMG Assert Equal (Comptroller MembershipLength Geoff) (Exactly 2) - Assert True (Comptroller CheckMembership Geoff cZRX) - Assert True (Comptroller CheckMembership Geoff cOMG) + Assert True (Comptroller CheckMembership Geoff slZRX) + Assert True (Comptroller CheckMembership Geoff slOMG) Test "Cannot enter Markets beyond max assets" NewComptroller Comptroller SetMaxAssets 1 Assert Equal (Comptroller MembershipLength Geoff) Zero - ListedCToken ZRX cZRX - ListedCToken OMG cOMG - EnterMarkets Geoff cZRX cOMG + ListedSLToken ZRX slZRX + ListedSLToken OMG slOMG + EnterMarkets Geoff slZRX slOMG Assert Equal (Comptroller MembershipLength Geoff) (Exactly 1) - Assert True (Comptroller CheckMembership Geoff cZRX) - Assert False (Comptroller CheckMembership Geoff cOMG) + Assert True (Comptroller CheckMembership Geoff slZRX) + Assert False (Comptroller CheckMembership Geoff slOMG) Test "Exit single market" NewComptroller - ListedCToken ZRX cZRX - EnterMarkets Geoff cZRX - Assert Equal (Comptroller AssetsIn Geoff) [(Address cZRX)] - ExitMarket Geoff cZRX + ListedSLToken ZRX slZRX + EnterMarkets Geoff slZRX + Assert Equal (Comptroller AssetsIn Geoff) [(Address slZRX)] + ExitMarket Geoff slZRX Assert Equal (Comptroller AssetsIn Geoff) [] Test "Exit non-entered market" NewComptroller - ListedCToken ZRX cZRX - ExitMarket Geoff cZRX + ListedSLToken ZRX slZRX + ExitMarket Geoff slZRX Assert Equal (Comptroller AssetsIn Geoff) [] Test "Exit one of two market from the front" NewComptroller - ListedCToken ZRX cZRX - ListedCToken OMG cOMG - EnterMarkets Geoff cZRX cOMG - Assert Equal (Comptroller AssetsIn Geoff) [(Address cZRX) (Address cOMG)] - ExitMarket Geoff cZRX - Assert Equal (Comptroller AssetsIn Geoff) [(Address cOMG)] + ListedSLToken ZRX slZRX + ListedSLToken OMG slOMG + EnterMarkets Geoff slZRX slOMG + Assert Equal (Comptroller AssetsIn Geoff) [(Address slZRX) (Address slOMG)] + ExitMarket Geoff slZRX + Assert Equal (Comptroller AssetsIn Geoff) [(Address slOMG)] Test "Exit one of two market from the back" NewComptroller - ListedCToken ZRX cZRX - ListedCToken OMG cOMG - EnterMarkets Geoff cZRX cOMG - Assert Equal (Comptroller AssetsIn Geoff) [(Address cZRX) (Address cOMG)] - ExitMarket Geoff cOMG - Assert Equal (Comptroller AssetsIn Geoff) [(Address cZRX)] + ListedSLToken ZRX slZRX + ListedSLToken OMG slOMG + EnterMarkets Geoff slZRX slOMG + Assert Equal (Comptroller AssetsIn Geoff) [(Address slZRX) (Address slOMG)] + ExitMarket Geoff slOMG + Assert Equal (Comptroller AssetsIn Geoff) [(Address slZRX)] Test "Exit multiple markets" NewComptroller - ListedCToken ZRX cZRX - ListedCToken OMG cOMG - ListedCToken BAT cBAT - ListedCToken REP cREP - ListedCToken DAI cDAI - EnterMarkets Geoff cZRX cOMG cBAT cREP cDAI - Assert Equal (Comptroller AssetsIn Geoff) [(Address cZRX) (Address cOMG) (Address cBAT) (Address cREP) (Address cDAI)] - ExitMarket Geoff cZRX - Assert Equal (Comptroller AssetsIn Geoff) [(Address cDAI) (Address cOMG) (Address cBAT) (Address cREP)] - ExitMarket Geoff cREP - Assert Equal (Comptroller AssetsIn Geoff) [(Address cDAI) (Address cOMG) (Address cBAT)] - ExitMarket Geoff cOMG - Assert Equal (Comptroller AssetsIn Geoff) [(Address cDAI) (Address cBAT)] - ExitMarket Geoff cDAI - Assert Equal (Comptroller AssetsIn Geoff) [(Address cBAT)] - ExitMarket Geoff cBAT + ListedSLToken ZRX slZRX + ListedSLToken OMG slOMG + ListedSLToken BAT slBAT + ListedSLToken REP slREP + ListedSLToken DAI slDAI + EnterMarkets Geoff slZRX slOMG slBAT slREP slDAI + Assert Equal (Comptroller AssetsIn Geoff) [(Address slZRX) (Address slOMG) (Address slBAT) (Address slREP) (Address slDAI)] + ExitMarket Geoff slZRX + Assert Equal (Comptroller AssetsIn Geoff) [(Address slDAI) (Address slOMG) (Address slBAT) (Address slREP)] + ExitMarket Geoff slREP + Assert Equal (Comptroller AssetsIn Geoff) [(Address slDAI) (Address slOMG) (Address slBAT)] + ExitMarket Geoff slOMG + Assert Equal (Comptroller AssetsIn Geoff) [(Address slDAI) (Address slBAT)] + ExitMarket Geoff slDAI + Assert Equal (Comptroller AssetsIn Geoff) [(Address slBAT)] + ExitMarket Geoff slBAT Assert Equal (Comptroller AssetsIn Geoff) [] Test "Realistic Market Scenario" PricedComptroller - ListedCToken ZRX cZRX - SetPriceCF cZRX 0.002 0.4 - ListedEtherToken cETH - Comptroller SetCollateralFactor cEth 0.8 - ListedCToken BAT cBAT - SetPriceCF cBAT 0.0015 0.3 - -- Mint some cZRX and cETH - Prep Geoff 1250e18 ZRX cZRX - Mint Geoff 1250e18 cZRX -- Liquidity -> 0.4 * 0.002 * 1250e18 = 1.0e18 - SendMintEth Geoff 2.5e18 cETH -- Liqiuidity -> 0.8 * 1.0 * 2.5e18 = 2.0e18 + ListedSLToken ZRX slZRX + SetPriceCF slZRX 0.002 0.4 + ListedEtherToken slETH + Comptroller SetCollateralFactor slETH 0.8 + ListedSLToken BAT slBAT + SetPriceCF slBAT 0.0015 0.3 + -- Mint some slZRX and slETH + Prep Geoff 1250e18 ZRX slZRX + Mint Geoff 1250e18 slZRX -- Liquidity -> 0.4 * 0.002 * 1250e18 = 1.0e18 + SendMintEth Geoff 2.5e18 slETH -- Liqiuidity -> 0.8 * 1.0 * 2.5e18 = 2.0e18 -- Check liquidity is zero when not in any markets Assert Equal (Comptroller Liquidity Geoff) Zero -- Enter ZRX and check liquidity - EnterMarkets Geoff cZRX + EnterMarkets Geoff slZRX Assert Equal (Comptroller Liquidity Geoff) 1.0e18 -- Fail to borrow BAT due to liquidity - Give cBAT 1000e18 BAT + Give slBAT 1000e18 BAT HoldInvariants - Borrow Geoff 1000e18 cBAT -- 1000e18 * 0.0015 = 1.5e18 required liquidity + Borrow Geoff 1000e18 slBAT -- 1000e18 * 0.0015 = 1.5e18 required liquidity -- But since we're only in ZRX, we only have 1.0e18 liquidity Assert Failure COMPTROLLER_REJECTION BORROW_COMPTROLLER_REJECTION INSUFFICIENT_LIQUIDITY - -- Enter cETH and check liquidity - EnterMarkets Geoff cETH - Assert Equal (Comptroller Liquidity Geoff) 3.0e18 -- Sum of cETH and cZRX liquidity from above + -- Enter slETH and check liquidity + EnterMarkets Geoff slETH + Assert Equal (Comptroller Liquidity Geoff) 3.0e18 -- Sum of slETH and slZRX liquidity from above -- Borrow previous BAT amount given liquidity - Borrow Geoff 1000e18 cBAT + Borrow Geoff 1000e18 slBAT Assert Equal (Comptroller Liquidity Geoff) 1.5e18 -- Less the borrow amount's toll -- Try to exit a eth market but fail due to given borrow requiring eth as collateral HoldInvariants - ExitMarket Geoff cETH + ExitMarket Geoff slETH Assert Failure REJECTION EXIT_MARKET_REJECTION INSUFFICIENT_LIQUIDITY -- Liquidity check fails - Assert Equal (Comptroller AssetsIn Geoff) [(Address cZRX) (Address cBAT) (Address cETH)] + Assert Equal (Comptroller AssetsIn Geoff) [(Address slZRX) (Address slBAT) (Address slETH)] -- Repay some borrow and exit market OMG - Allow Geoff cBAT - RepayBorrow Geoff 500e18 cBAT + Allow Geoff slBAT + RepayBorrow Geoff 500e18 slBAT Assert Equal (Comptroller Liquidity Geoff) 2.25e18 -- With 0.75e18 repaid - ExitMarket Geoff cETH - Assert Equal (Comptroller AssetsIn Geoff) [(Address cZRX) (Address cBAT)] + ExitMarket Geoff slETH + Assert Equal (Comptroller AssetsIn Geoff) [(Address slZRX) (Address slBAT)] Assert Equal (Comptroller Liquidity Geoff) 0.25e18 -- Less Eth's 2.0e18 collateral weight - -- Try and exit cBAT (firist without, then after, repaying) + -- Try and exit slBAT (firist without, then after, repaying) HoldInvariants - ExitMarket Geoff cBAT + ExitMarket Geoff slBAT Assert Failure NONZERO_BORROW_BALANCE EXIT_MARKET_BALANCE_OWED - RepayBorrow Geoff UInt256Max cBAT - ExitMarket Geoff cBAT - Assert Equal (Comptroller AssetsIn Geoff) [(Address cZRX)] - Assert Equal (Comptroller Liquidity Geoff) 1.0e18 -- Back to just cZRX - -- Exit cZRX - ExitMarket Geoff cZRX + RepayBorrow Geoff UInt256Max slBAT + ExitMarket Geoff slBAT + Assert Equal (Comptroller AssetsIn Geoff) [(Address slZRX)] + Assert Equal (Comptroller Liquidity Geoff) 1.0e18 -- Back to just slZRX + -- Exit slZRX + ExitMarket Geoff slZRX Assert Equal (Comptroller AssetsIn Geoff) [] Assert Equal (Comptroller Liquidity Geoff) 0e18 -- Back to nothing diff --git a/spec/scenario/ExchangeRate.scen b/spec/scenario/ExchangeRate.scen index 2db30838b..65c90264a 100644 --- a/spec/scenario/ExchangeRate.scen +++ b/spec/scenario/ExchangeRate.scen @@ -1,73 +1,73 @@ Test "Initial Exchange Rate" NewComptroller - NewCToken ZRX cZRX initialExchangeRate:2e9 - Assert Equal (CToken cZRX ExchangeRateStored) (Exp 2e9) + NewSLToken ZRX slZRX initialExchangeRate:2e9 + Assert Equal (SLToken slZRX ExchangeRateStored) (Exp 2e9) Test "Initial Exchange Rate with Mint" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:5e9 + ListedSLToken ZRX slZRX initialExchangeRate:5e9 -- Check initial exchange holds - Invariant Remains (CToken cZRX ExchangeRateStored) (Exp 5e9) + Invariant Remains (SLToken slZRX ExchangeRateStored) (Exp 5e9) -- Mint some tokens and verify invariant still holds - Prep Geoff Some ZRX cZRX - Mint Geoff 50e18 cZRX + Prep Geoff Some ZRX slZRX + Mint Geoff 50e18 slZRX -- Also, verify token was minted at given exchange rate - Assert Equal (Erc20 cZRX TotalSupply) (Exactly 10e9) - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 10e9) + Assert Equal (Erc20 slZRX TotalSupply) (Exactly 10e9) + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 10e9) -- Let's mint again and verify it's still good. - Prep Torrey Some ZRX cZRX - Mint Torrey 50e18 cZRX + Prep Torrey Some ZRX slZRX + Mint Torrey 50e18 slZRX -- Also, verify token was minted at given exchange rate - Assert Equal (Erc20 cZRX TotalSupply) (Exactly 20e9) - Assert Equal (Erc20 cZRX TokenBalance Torrey) (Exactly 10e9) + Assert Equal (Erc20 slZRX TotalSupply) (Exactly 20e9) + Assert Equal (Erc20 slZRX TokenBalance Torrey) (Exactly 10e9) Test "ZRX: Exch. Rate:2e9, Cash(51e18) + Borrows(2.0e18) - Reserves(0.5e18) / Tokens(2.5e10)" NewComptroller -- Decimals You=18, Decimals Us=8 -> 2e9 Exchange Rate - ListedCToken ZRX cZRX initialExchangeRate:2e9 decimals:8 - Assert Equal (CToken cZRX ExchangeRateStored) (Exp 2e9) + ListedSLToken ZRX slZRX initialExchangeRate:2e9 decimals:8 + Assert Equal (SLToken slZRX ExchangeRateStored) (Exp 2e9) -- Mint 50.0 ZRX at given exchange rate - Prep Geoff Some ZRX cZRX - Assert Equal (Erc20 cZRX TotalSupply) Zero - Mint Geoff 50e18 cZRX + Prep Geoff Some ZRX slZRX + Assert Equal (Erc20 slZRX TotalSupply) Zero + Mint Geoff 50e18 slZRX -- 50e18 / 2e9 = 2.5e10 - Assert Equal (Erc20 cZRX TotalSupply) (Exactly 2.5e10) - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 2.5e10) + Assert Equal (Erc20 slZRX TotalSupply) (Exactly 2.5e10) + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 2.5e10) -- Set cash - Erc20 ZRX Faucet cZRX 1.0e18 - Assert Equal (Erc20 ZRX TokenBalance cZRX) (Exactly 51.0e18) + Erc20 ZRX Faucet slZRX 1.0e18 + Assert Equal (Erc20 ZRX TokenBalance slZRX) (Exactly 51.0e18) -- Mock total borrows - CToken cZRX Mock totalBorrows 2.0e18 - Assert Equal (CToken cZRX TotalBorrows) (Exactly 2.0e18) + SLToken slZRX Mock totalBorrows 2.0e18 + Assert Equal (SLToken slZRX TotalBorrows) (Exactly 2.0e18) -- Mock total reserves - CToken cZRX Mock totalReserves 0.5e18 - Assert Equal (CToken cZRX Reserves) (Exactly 0.5e18) + SLToken slZRX Mock totalReserves 0.5e18 + Assert Equal (SLToken slZRX Reserves) (Exactly 0.5e18) -- Okay, we're all set, let's check the exchange rate -- (51+2-0.5)e18/2.5e10 = 52.5e18/2.5e10 = 21e8 -> 21e26 (Exp) - Assert Equal (CToken cZRX ExchangeRateStored) (Exp 2.1e9) + Assert Equal (SLToken slZRX ExchangeRateStored) (Exp 2.1e9) Test "USDC: Exch. Rate:2e-3, Cash(51e18) + Borrows(2.0e18) - Reserves(0.5e18) / Tokens(2.5e10)" NewComptroller -- Decimals You=6, Decimals Us=8 -> 2e-3 Exchange Rate - ListedCToken USDC cUSDC initialExchangeRate:2e-3 decimals:8 - Assert Equal (CToken cUSDC ExchangeRateStored) (Exp 2e-3) + ListedSLToken USDC slUSDC initialExchangeRate:2e-3 decimals:8 + Assert Equal (SLToken slUSDC ExchangeRateStored) (Exp 2e-3) -- Mint 50.0 USDC at given exchange rate - Prep Geoff Little USDC cUSDC - Assert Equal (Erc20 cUSDC TotalSupply) (Exactly 0.0) - Mint Geoff 50e6 cUSDC + Prep Geoff Little USDC slUSDC + Assert Equal (Erc20 slUSDC TotalSupply) (Exactly 0.0) + Mint Geoff 50e6 slUSDC -- 5.0e7 / 2e-3 = 2.5e10 - Assert Equal (Erc20 cUSDC TotalSupply) (Exactly 2.5e10) - Assert Equal (Erc20 cUSDC TokenBalance Geoff) (Exactly 2.5e10) + Assert Equal (Erc20 slUSDC TotalSupply) (Exactly 2.5e10) + Assert Equal (Erc20 slUSDC TokenBalance Geoff) (Exactly 2.5e10) -- Set cash - Erc20 USDC Faucet cUSDC 2.0e6 - Assert Equal (Erc20 USDC TokenBalance cUSDC) (Exactly 52.0e6) + Erc20 USDC Faucet slUSDC 2.0e6 + Assert Equal (Erc20 USDC TokenBalance slUSDC) (Exactly 52.0e6) -- Mock total borrows - CToken cUSDC Mock totalBorrows 5.0e6 - Assert Equal (CToken cUSDC TotalBorrows) (Exactly 5.0e6) + SLToken slUSDC Mock totalBorrows 5.0e6 + Assert Equal (SLToken slUSDC TotalBorrows) (Exactly 5.0e6) -- Mock total reserves - CToken cUSDC Mock totalReserves 1.5e6 - Assert Equal (CToken cUSDC Reserves) (Exactly 1.5e6) + SLToken slUSDC Mock totalReserves 1.5e6 + Assert Equal (SLToken slUSDC Reserves) (Exactly 1.5e6) -- Okay, we're all set, let's check the exchange rate -- (52+5-1.5)e6/2.5e10 = 55.5e6/2.5e10 = 2.22e-3 -> 2.22e15 (Exp) - Assert Equal (CToken cUSDC ExchangeRateStored) (Exp 2.22e-3) + Assert Equal (SLToken slUSDC ExchangeRateStored) (Exp 2.22e-3) diff --git a/spec/scenario/Fee.scen b/spec/scenario/Fee.scen index 87f6eba67..25402763f 100644 --- a/spec/scenario/Fee.scen +++ b/spec/scenario/Fee.scen @@ -10,86 +10,86 @@ Test "Transfer fee goes to admin" Test "Mint should work and not change exchange rate" NewComptroller price:1.0 Erc20 Deploy Fee USDT USDT 18 100 Admin - NewCTokenBringERC20 USDT cUSDT - Support cUSDT collateralFactor:0.5 - Invariant Static (CToken cUSDT ExchangeRate) - Prep Torrey 1e18 USDT cUSDT - Mint Torrey 1e18 cUSDT - Assert Equal (ERC20 USDT TokenBalance cUSDT) 0.99e18 + NewSLTokenBringERC20 USDT slUSDT + Support slUSDT collateralFactor:0.5 + Invariant Static (SLToken slUSDT ExchangeRate) + Prep Torrey 1e18 USDT slUSDT + Mint Torrey 1e18 slUSDT + Assert Equal (ERC20 USDT TokenBalance slUSDT) 0.99e18 Test "Repay borrow should work and not change exchange rate" PricedComptroller Erc20 Deploy Fee USDT USDT 18 100 Admin - NewCTokenBringERC20 USDT cUSDT - NewCToken ZRX cZRX 0.000005 2e9 8 Standard - PriceOracle SetPrice cZRX 1.0 - PriceOracle SetPrice cUSDT 1.0 - Support cZRX 0.5 - Support cUSDT 0.5 - Give cUSDT 10e18 USDT -- Faucet some Tether to borrow - Invariant Static (CToken cUSDT ExchangeRate) - Prep Torrey 100e18 ZRX cZRX - Mint Torrey 100e18 cZRX - EnterMarkets Torrey cUSDT - EnterMarkets Torrey cZRX - Borrow Torrey 1e18 cUSDT -- we only received 0.99 tether bc of fee + NewSLTokenBringERC20 USDT slUSDT + NewSLToken ZRX slZRX 0.000005 2e9 8 Standard + PriceOracle SetPrice slZRX 1.0 + PriceOracle SetPrice slUSDT 1.0 + Support slZRX 0.5 + Support slUSDT 0.5 + Give slUSDT 10e18 USDT -- Faucet some Tether to borrow + Invariant Static (SLToken slUSDT ExchangeRate) + Prep Torrey 100e18 ZRX slZRX + Mint Torrey 100e18 slZRX + EnterMarkets Torrey slUSDT + EnterMarkets Torrey slZRX + Borrow Torrey 1e18 slUSDT -- we only received 0.99 tether bc of fee Assert Equal (ERC20 USDT TokenBalance Torrey) 0.99e18 FastForward 196000 Blocks -- 1e18 * 196000 * 0.000005 = 0.98e18 interest accrued - Assert Equal (CToken cUSDT TotalBorrowsCurrent) 1.98e18 - Prep Torrey 1.01e18 USDT cUSDT 2e18 -- so give 2 - 0.99 = 1.01, and approve 2e18 - RepayBorrow Torrey 2e18 cUSDT -- repay more than we owe to account for fee - Assert Equal (CToken cUSDT BorrowBalance Torrey) 0 - Assert Equal (CToken cUSDT TotalBorrowsCurrent) 0 + Assert Equal (SLToken slUSDT TotalBorrowsCurrent) 1.98e18 + Prep Torrey 1.01e18 USDT slUSDT 2e18 -- so give 2 - 0.99 = 1.01, and approve 2e18 + RepayBorrow Torrey 2e18 slUSDT -- repay more than we owe to account for fee + Assert Equal (SLToken slUSDT BorrowBalance Torrey) 0 + Assert Equal (SLToken slUSDT TotalBorrowsCurrent) 0 Assert Equal (ERC20 USDT TokenBalance Torrey) 0 Test "Should be able to liquidate fee token borrow" PricedComptroller Comptroller LiquidationIncentive 1.1 Erc20 Deploy Fee USDT USDT 18 100 Admin - NewCTokenBringERC20 USDT cUSDT - NewCToken ZRX cZRX 0.000005 2e9 8 Standard - PriceOracle SetPrice cZRX 1.0 - PriceOracle SetPrice cUSDT 1.0 - Support cZRX 0.5 - Support cUSDT 0.5 - Give cUSDT 10e18 USDT -- Faucet some Tether to borrow - Invariant Static (CToken cUSDT ExchangeRate) - Invariant Static (CToken cZRX ExchangeRate) - Prep Torrey 2e18 ZRX cZRX - Mint Torrey 2e18 cZRX - EnterMarkets Torrey cUSDT - EnterMarkets Torrey cZRX - Borrow Torrey 1e18 cUSDT -- we only received 0.99 tether bc of fee + NewSLTokenBringERC20 USDT slUSDT + NewSLToken ZRX slZRX 0.000005 2e9 8 Standard + PriceOracle SetPrice slZRX 1.0 + PriceOracle SetPrice slUSDT 1.0 + Support slZRX 0.5 + Support slUSDT 0.5 + Give slUSDT 10e18 USDT -- Faucet some Tether to borrow + Invariant Static (SLToken slUSDT ExchangeRate) + Invariant Static (SLToken slZRX ExchangeRate) + Prep Torrey 2e18 ZRX slZRX + Mint Torrey 2e18 slZRX + EnterMarkets Torrey slUSDT + EnterMarkets Torrey slZRX + Borrow Torrey 1e18 slUSDT -- we only received 0.99 tether bc of fee Assert Equal (ERC20 USDT TokenBalance Torrey) 0.99e18 FastForward 196000 Blocks -- 1e18 * 196000 * 0.000005 = 0.98e18 interest accrued - Assert Equal (CToken cUSDT TotalBorrowsCurrent) 1.98e18 + Assert Equal (SLToken slUSDT TotalBorrowsCurrent) 1.98e18 -- OK! should be ready to liquidate, so lets do that - Prep Coburn 2e18 USDT cUSDT - Liquidate Coburn "->" Torrey 0.1e18 cUSDT "Seizing" cZRX + Prep Coburn 2e18 USDT slUSDT + Liquidate Coburn "->" Torrey 0.1e18 slUSDT "Seizing" slZRX -- 5.445e7 = 0.1 (amount liquidated) * 1.1 (liq discount) * .99 (fee) / 2e9 (exchange rate) - Assert Equal (Erc20 cZRX TokenBalance Coburn) 5.445e7 - Assert Equal (CToken cUSDT BorrowBalance Torrey) 1.881e18 -- 1.98 - (0.1 * .99) was liquidated + Assert Equal (Erc20 slZRX TokenBalance Coburn) 5.445e7 + Assert Equal (SLToken slUSDT BorrowBalance Torrey) 1.881e18 -- 1.98 - (0.1 * .99) was liquidated Assert Equal (Erc20 USDT TokenBalance Coburn) 1.9e18 -Test "Should be able to redeem a fee CToken, exchange Rate should not change" +Test "Should be able to redeem a fee SLToken, exchange Rate should not change" NewComptroller price:1.0 Erc20 Deploy Fee USDT USDT 18 100 Admin - NewCTokenBringERC20 USDT cUSDT - Support cUSDT collateralFactor:0.5 - Invariant Static (CToken cUSDT ExchangeRate) - Prep Torrey 1e18 USDT cUSDT - Mint Torrey 1e18 cUSDT - Redeem Torrey (Erc20 cUSDT TokenBalance Torrey) cUSDT + NewSLTokenBringERC20 USDT slUSDT + Support slUSDT collateralFactor:0.5 + Invariant Static (SLToken slUSDT ExchangeRate) + Prep Torrey 1e18 USDT slUSDT + Mint Torrey 1e18 slUSDT + Redeem Torrey (Erc20 slUSDT TokenBalance Torrey) slUSDT Test "Order of redeems should not matter if no interest accrued" NewComptroller price:1.0 Erc20 Deploy Fee USDT USDT 18 100 Admin - NewCTokenBringERC20 USDT cUSDT - Support cUSDT collateralFactor:0.5 - Invariant Static (CToken cUSDT ExchangeRate) - Prep Torrey 1e18 USDT cUSDT - Mint Torrey 1e18 cUSDT - Prep Coburn 1e18 USDT cUSDT - Mint Coburn 1e18 cUSDT - Redeem Torrey (Erc20 cUSDT TokenBalance Torrey) cUSDT - Redeem Coburn (Erc20 cUSDT TokenBalance Coburn) cUSDT + NewSLTokenBringERC20 USDT slUSDT + Support slUSDT collateralFactor:0.5 + Invariant Static (SLToken slUSDT ExchangeRate) + Prep Torrey 1e18 USDT slUSDT + Mint Torrey 1e18 slUSDT + Prep Coburn 1e18 USDT slUSDT + Mint Coburn 1e18 slUSDT + Redeem Torrey (Erc20 slUSDT TokenBalance Torrey) slUSDT + Redeem Coburn (Erc20 slUSDT TokenBalance Coburn) slUSDT diff --git a/spec/scenario/Flywheel/Flywheel.scen b/spec/scenario/Flywheel/Flywheel.scen index ef498ec12..f07ae0fae 100644 --- a/spec/scenario/Flywheel/Flywheel.scen +++ b/spec/scenario/Flywheel/Flywheel.scen @@ -1,5 +1,5 @@ -- NewComptroller, but with markets listed so that we can make them comp markets in constructor -Macro FlywheelComptroller price=1.0 borrowRate=0.000005 compInitAmount=5000000e18 +Macro FlywheelComptroller price=1.0 borrowRate=0.000005 sashimiInitAmount=5000000e18 Unitroller Deploy PriceOracle Deploy Fixed price PriceOracleProxy Deploy Admin (PriceOracle Address) (Address Zero) (Address Zero) (Address Zero) (Address Zero) (Address Zero) @@ -12,210 +12,210 @@ Macro FlywheelComptroller price=1.0 borrowRate=0.000005 compInitAmount=5000000e1 Comptroller SetMaxAssets 20 Comptroller SetCloseFactor 0.5 Comptroller LiquidationIncentive 1.1 - NewCToken ZRX cZRX - NewCToken BAT cBAT - Support cZRX collateralFactor:0.5 - Support cBAT collateralFactor:0.5 + NewSLToken ZRX slZRX + NewSLToken BAT slBAT + Support slZRX collateralFactor:0.5 + Support slBAT collateralFactor:0.5 -- final ComptrollerImpl Deploy ScenarioG3 ComptrollerScen Unitroller SetPendingImpl ComptrollerScen - ComptrollerImpl ComptrollerScen BecomeG3 1e18 [cZRX cBAT] - Erc20 Deploy Standard COMP "COMP Token" 18 - Give (Address Comptroller) compInitAmount COMP - Comptroller Send "setCompAddress(address)" (Address COMP) + ComptrollerImpl ComptrollerScen BecomeG3 1e18 [slZRX slBAT] + Erc20 Deploy Standard SASHIMI "SASHIMI Token" 18 + Give (Address Comptroller) sashimiInitAmount SASHIMI + Comptroller Send "setSashimiAddress(address)" (Address SASHIMI) Macro InitSpeeds - Prep Geoff 100e18 ZRX cZRX - Mint Geoff 50e18 cZRX--tokenbalance = 50e18 / 2e9 = 2.5e10 - Prep Coburn Some BAT cBAT - Mint Coburn 6e18 cBAT--tokenbalance = 6e18 / 2e9 = 3e9 - EnterMarkets Coburn cBAT - Borrow Coburn 1e18 cZRX - Comptroller RefreshCompSpeeds + Prep Geoff 100e18 ZRX slZRX + Mint Geoff 50e18 slZRX--tokenbalance = 50e18 / 2e9 = 2.5e10 + Prep Coburn Some BAT slBAT + Mint Coburn 6e18 slBAT--tokenbalance = 6e18 / 2e9 = 3e9 + EnterMarkets Coburn slBAT + Borrow Coburn 1e18 slZRX + Comptroller RefreshSashimiSpeeds -Test "Accrue COMP during a mint" +Test "Accrue SASHIMI during a mint" FlywheelComptroller InitSpeeds FastForward 300000 Blocks - Assert Equal (Comptroller CompAccrued Geoff) 0 - Mint Geoff 1e18 cZRX + Assert Equal (Comptroller SashimiAccrued Geoff) 0 + Mint Geoff 1e18 slZRX -- new index = initVal + deltaBlocks * supplySpeed * 1e36 / totalSupply -- new index = 1e36 + 300000 * 1e18 * 1e36 / 2.5e10 = 1.2000000000001e49 - Assert Equal (Comptroller CompAccrued Geoff) 0 - Assert Equal (Comptroller CompSupplyState cZRX "index") 1.2000000000001e49 - Assert Equal (Comptroller CompSupplyState cZRX "block") 300000 - Assert Equal (Erc20 COMP TokenBalance Geoff) 300000e18 - Assert Equal (Comptroller CompSupplierIndex cZRX Geoff) 1.2000000000001e49 + Assert Equal (Comptroller SashimiAccrued Geoff) 0 + Assert Equal (Comptroller SashimiSupplyState slZRX "index") 1.2000000000001e49 + Assert Equal (Comptroller SashimiSupplyState slZRX "block") 300000 + Assert Equal (Erc20 SASHIMI TokenBalance Geoff) 300000e18 + Assert Equal (Comptroller SashimiSupplierIndex slZRX Geoff) 1.2000000000001e49 -Test "Accrue COMP during a borrow" +Test "Accrue SASHIMI during a borrow" FlywheelComptroller InitSpeeds Comptroller FastForward 300000 Blocks - Assert Equal (Comptroller CompAccrued Coburn) 0 - Borrow Coburn 0.1e18 cZRX + Assert Equal (Comptroller SashimiAccrued Coburn) 0 + Borrow Coburn 0.1e18 slZRX -- new index = initVal + deltaBlocks * borrowSpeed * 1e36 / totalBorrows -- new index = 1e36 + 300000 * 1e18 * 1e36 / 1e18 = 3.00001e41 - Assert Equal (Comptroller CompAccrued Coburn) 0 - Assert Equal (Comptroller CompBorrowState cZRX "index") 3.00001e41 - Assert Equal (Comptroller CompBorrowState cZRX "block") 300000 - Assert Equal (Erc20 COMP TokenBalance Coburn) 300000e18 - Assert Equal (Comptroller CompBorrowerIndex cZRX Coburn) 3.00001e41 + Assert Equal (Comptroller SashimiAccrued Coburn) 0 + Assert Equal (Comptroller SashimiBorrowState slZRX "index") 3.00001e41 + Assert Equal (Comptroller SashimiBorrowState slZRX "block") 300000 + Assert Equal (Erc20 SASHIMI TokenBalance Coburn) 300000e18 + Assert Equal (Comptroller SashimiBorrowerIndex slZRX Coburn) 3.00001e41 -Test "Accrue COMP during a redeem" +Test "Accrue SASHIMI during a redeem" FlywheelComptroller InitSpeeds FastForward 300000 Blocks - Assert Equal (Comptroller CompAccrued Geoff) 0 - Redeem Geoff 1e9 cZRX + Assert Equal (Comptroller SashimiAccrued Geoff) 0 + Redeem Geoff 1e9 slZRX -- new index = initVal + deltaBlocks * supplySpeed * 1e36 / totalSupply -- new index = 1e36 + 300000 * 1e18 * 1e36 / 2.5e10 = 1.2000000000001e49 - Assert Equal (Comptroller CompAccrued Geoff) 0 - Assert Equal (Comptroller CompSupplyState cZRX "index") 1.2000000000001e49 - Assert Equal (Comptroller CompSupplyState cZRX "block") 300000 - Assert Equal (Erc20 COMP TokenBalance Geoff) 300000e18 - Assert Equal (Comptroller CompSupplierIndex cZRX Geoff) 1.2000000000001e49 + Assert Equal (Comptroller SashimiAccrued Geoff) 0 + Assert Equal (Comptroller SashimiSupplyState slZRX "index") 1.2000000000001e49 + Assert Equal (Comptroller SashimiSupplyState slZRX "block") 300000 + Assert Equal (Erc20 SASHIMI TokenBalance Geoff) 300000e18 + Assert Equal (Comptroller SashimiSupplierIndex slZRX Geoff) 1.2000000000001e49 -Test "Accrue COMP during a repayBorrow" +Test "Accrue SASHIMI during a repayBorrow" FlywheelComptroller InitSpeeds FastForward 300000 Blocks - Assert Equal (Comptroller CompAccrued Geoff) 0 - Prep Coburn 0.5e18 ZRX cZRX - RepayBorrow Coburn 0.5e18 cZRX + Assert Equal (Comptroller SashimiAccrued Geoff) 0 + Prep Coburn 0.5e18 ZRX slZRX + RepayBorrow Coburn 0.5e18 slZRX -- new index = initVal + deltaBlocks * borrowSpeed * 1e36 / totalBorrows -- new index = 1e36 + 300000 * 1e18 * 1e36 / 1e18 = 3.00001e41 - Assert Equal (Comptroller CompAccrued Coburn) 0 - Assert Equal (Comptroller CompBorrowState cZRX "index") 3.00001e41 - Assert Equal (Comptroller CompBorrowState cZRX "block") 300000 - Assert Equal (Erc20 COMP TokenBalance Coburn) 300000e18 - Assert Equal (Comptroller CompBorrowerIndex cZRX Coburn) 3.00001e41 + Assert Equal (Comptroller SashimiAccrued Coburn) 0 + Assert Equal (Comptroller SashimiBorrowState slZRX "index") 3.00001e41 + Assert Equal (Comptroller SashimiBorrowState slZRX "block") 300000 + Assert Equal (Erc20 SASHIMI TokenBalance Coburn) 300000e18 + Assert Equal (Comptroller SashimiBorrowerIndex slZRX Coburn) 3.00001e41 -Test "Accrue COMP during a repayBorrowBehalf of 0" +Test "Accrue SASHIMI during a repayBorrowBehalf of 0" FlywheelComptroller InitSpeeds FastForward 300000 Blocks - Assert Equal (Comptroller CompAccrued Geoff) 0 + Assert Equal (Comptroller SashimiAccrued Geoff) 0 -- confirm we can init all flywheel accounts for free - RepayBorrowBehalf Jared Coburn 0 cZRX + RepayBorrowBehalf Jared Coburn 0 slZRX -- new index = initVal + deltaBlocks * borrowSpeed * 1e36 / totalBorrows -- new index = 1e36 + 300000 * 1e18 * 1e36 / 1e18 = 3.00001e41 - Assert Equal (Comptroller CompAccrued Coburn) 0 - Assert Equal (Comptroller CompBorrowState cZRX "index") 3.00001e41 - Assert Equal (Comptroller CompBorrowState cZRX "block") 300000 - Assert Equal (Erc20 COMP TokenBalance Coburn) 300000e18 - Assert Equal (Comptroller CompBorrowerIndex cZRX Coburn) 3.00001e41 + Assert Equal (Comptroller SashimiAccrued Coburn) 0 + Assert Equal (Comptroller SashimiBorrowState slZRX "index") 3.00001e41 + Assert Equal (Comptroller SashimiBorrowState slZRX "block") 300000 + Assert Equal (Erc20 SASHIMI TokenBalance Coburn) 300000e18 + Assert Equal (Comptroller SashimiBorrowerIndex slZRX Coburn) 3.00001e41 -Test "Accrue COMP during a liquidation" +Test "Accrue SASHIMI during a liquidation" FlywheelComptroller InitSpeeds - Assert Equal (Comptroller CompSpeed cZRX) 1e18 - Assert Equal (Comptroller CompSpeed cBAT) 0 + Assert Equal (Comptroller SashimiSpeed slZRX) 1e18 + Assert Equal (Comptroller SashimiSpeed slBAT) 0 --coburn zrx borrow, bat supply. geoff zrx supply FastForward 600000 Blocks--1e18 borrow * (1 + 600000 * 0.000005) = 3.5e18 borrow > 6e18 collateral * 0.5 CF - Prep Geoff Some ZRX cZRX - From Geoff (CToken cZRX Liquidate Coburn cBAT 0.5e18) + Prep Geoff Some ZRX slZRX + From Geoff (SLToken slZRX Liquidate Coburn slBAT 0.5e18) -- zrx borrow index is updated and comp distributed -- * new index = initVal + deltaBlocks * borrowSpeed * 1e36 / totalBorrows -- * new index = 1e36 + 600000 * 1e18 * 1e36 / 1e18 = 6.00001E41 - Assert Equal (Comptroller CompBorrowState cZRX "index") 6.00001e41 - Assert Equal (Comptroller CompBorrowState cZRX "block") 600000 + Assert Equal (Comptroller SashimiBorrowState slZRX "index") 6.00001e41 + Assert Equal (Comptroller SashimiBorrowState slZRX "block") 600000 -- zrx supply index isnt updated and comp isnt distributed for zrx supply - Assert Equal (Comptroller CompSupplyState cZRX "index") 1e36 - Assert Equal (Comptroller CompSupplyState cZRX "block") 0 - Assert Equal (Comptroller CompSupplierIndex cZRX Geoff) 1e36--no change, minted in init + Assert Equal (Comptroller SashimiSupplyState slZRX "index") 1e36 + Assert Equal (Comptroller SashimiSupplyState slZRX "block") 0 + Assert Equal (Comptroller SashimiSupplierIndex slZRX Geoff) 1e36--no change, minted in init -- bat supply/borrow index is not updated, since there is no comp speed - Assert Equal (Comptroller CompSupplyState cBAT "index") 1e36 - Assert Equal (Comptroller CompSupplyState cBAT "block") 600000 + Assert Equal (Comptroller SashimiSupplyState slBAT "index") 1e36 + Assert Equal (Comptroller SashimiSupplyState slBAT "block") 600000 -- neither is borrow state. block is 0 because update fn is never even called - Assert Equal (Comptroller CompBorrowState cBAT "index") 1e36 - Assert Equal (Comptroller CompBorrowState cBAT "block") 0 + Assert Equal (Comptroller SashimiBorrowState slBAT "index") 1e36 + Assert Equal (Comptroller SashimiBorrowState slBAT "block") 0 -- - Assert Equal (Comptroller CompSupplierIndex cBAT Coburn) 1e36 - Assert Equal (Comptroller CompBorrowerIndex cZRX Coburn) 6.00001e41 - Assert Equal (Erc20 COMP TokenBalance Coburn) 600000e18 - Assert Equal (Comptroller CompAccrued Coburn) 0 + Assert Equal (Comptroller SashimiSupplierIndex slBAT Coburn) 1e36 + Assert Equal (Comptroller SashimiBorrowerIndex slZRX Coburn) 6.00001e41 + Assert Equal (Erc20 SASHIMI TokenBalance Coburn) 600000e18 + Assert Equal (Comptroller SashimiAccrued Coburn) 0 -- - Assert Equal (Comptroller CompSupplierIndex cBAT Geoff) 1e36 - Assert Equal (Erc20 COMP TokenBalance Geoff) 0 - Assert Equal (Comptroller CompAccrued Geoff) 0 + Assert Equal (Comptroller SashimiSupplierIndex slBAT Geoff) 1e36 + Assert Equal (Erc20 SASHIMI TokenBalance Geoff) 0 + Assert Equal (Comptroller SashimiAccrued Geoff) 0 -Test "Accrue COMP during a transfer" +Test "Accrue SASHIMI during a transfer" FlywheelComptroller InitSpeeds FastForward 300000 Blocks - Assert Equal (Erc20 COMP TokenBalance Geoff) 0 - Assert Equal (Comptroller CompSupplierIndex cZRX Geoff) 1e36 - Transfer Geoff Jared 2.5e10 cZRX + Assert Equal (Erc20 SASHIMI TokenBalance Geoff) 0 + Assert Equal (Comptroller SashimiSupplierIndex slZRX Geoff) 1e36 + Transfer Geoff Jared 2.5e10 slZRX -- new index = initVal + deltaBlocks * supplySpeed * 1e36 / totalSupply -- new index = 1e36 + 300000 * 1e18 * 1e36 / 2.5e10 = 1.2000000000001e49 - Assert Equal (Erc20 COMP TokenBalance Geoff) 300000e18 - Assert Equal (Comptroller CompAccrued Geoff) 0 - Assert Equal (Comptroller CompSupplyState cZRX "index") 1.2000000000001e49 - Assert Equal (Comptroller CompSupplyState cZRX "block") 300000 - Assert Equal (Comptroller CompSupplierIndex cZRX Geoff) 1.2000000000001e49 + Assert Equal (Erc20 SASHIMI TokenBalance Geoff) 300000e18 + Assert Equal (Comptroller SashimiAccrued Geoff) 0 + Assert Equal (Comptroller SashimiSupplyState slZRX "index") 1.2000000000001e49 + Assert Equal (Comptroller SashimiSupplyState slZRX "block") 300000 + Assert Equal (Comptroller SashimiSupplierIndex slZRX Geoff) 1.2000000000001e49 -- - Assert Equal (Comptroller CompAccrued Jared) 0 - Assert Equal (Comptroller CompSupplyState cZRX "index") 1.2000000000001e49 - Assert Equal (Comptroller CompSupplyState cZRX "block") 300000 - Assert Equal (Comptroller CompSupplierIndex cZRX Jared) 1.2000000000001e49 + Assert Equal (Comptroller SashimiAccrued Jared) 0 + Assert Equal (Comptroller SashimiSupplyState slZRX "index") 1.2000000000001e49 + Assert Equal (Comptroller SashimiSupplyState slZRX "block") 300000 + Assert Equal (Comptroller SashimiSupplierIndex slZRX Jared) 1.2000000000001e49 Test "Accrues correctly when market is added, deactivated, and activated again" FlywheelComptroller InitSpeeds - NewCToken DAI cDAI + NewSLToken DAI slDAI -- - Support cDAI collateralFactor:0.5 - Comptroller AddCompMarkets cDAI - Assert Equal (Comptroller GetCompMarkets) [(Address cZRX) (Address cBAT) (Address cDAI)] - Prep Jared Some DAI cDAI - Mint Jared 6e18 cDAI - EnterMarkets Geoff cZRX - Borrow Geoff 0.5e18 cDAI - Borrow Coburn 0.5e18 cDAI - Comptroller RefreshCompSpeeds - Assert Equal (Comptroller CompSpeed cZRX) 0.5e18 - Assert Equal (Comptroller CompSpeed cDAI) 0.5e18 + Support slDAI collateralFactor:0.5 + Comptroller AddSashimiMarkets slDAI + Assert Equal (Comptroller GetSashimiMarkets) [(Address slZRX) (Address slBAT) (Address slDAI)] + Prep Jared Some DAI slDAI + Mint Jared 6e18 slDAI + EnterMarkets Geoff slZRX + Borrow Geoff 0.5e18 slDAI + Borrow Coburn 0.5e18 slDAI + Comptroller RefreshSashimiSpeeds + Assert Equal (Comptroller SashimiSpeed slZRX) 0.5e18 + Assert Equal (Comptroller SashimiSpeed slDAI) 0.5e18 -- FastForward 100 Blocks - Comptroller DropCompMarket cDAI - Comptroller ClaimComp Geoff - Assert Equal (Erc20 COMP TokenBalance Geoff) 75e18--half of cdai, all of zrx(.25e18 + .5e18) * 100 - Assert Equal (Comptroller GetCompMarkets) [(Address cZRX) (Address cBAT)] - Assert Equal (Comptroller CompSpeed cZRX) 1e18 - Assert Equal (Comptroller CompSpeed cDAI) 0 + Comptroller DropSashimiMarket slDAI + Comptroller ClaimSashimi Geoff + Assert Equal (Erc20 SASHIMI TokenBalance Geoff) 75e18--half of sldai, all of zrx(.25e18 + .5e18) * 100 + Assert Equal (Comptroller GetSashimiMarkets) [(Address slZRX) (Address slBAT)] + Assert Equal (Comptroller SashimiSpeed slZRX) 1e18 + Assert Equal (Comptroller SashimiSpeed slDAI) 0 -- FastForward 100 Blocks - Comptroller ClaimComp Geoff - Assert Equal (Erc20 COMP TokenBalance Geoff) 175e18-- += 1e18 * 100 - Assert Equal (Comptroller CompAccrued Geoff) 0 + Comptroller ClaimSashimi Geoff + Assert Equal (Erc20 SASHIMI TokenBalance Geoff) 175e18-- += 1e18 * 100 + Assert Equal (Comptroller SashimiAccrued Geoff) 0 -- - Comptroller AddCompMarkets cDAI + Comptroller AddSashimiMarkets slDAI FastForward 100 Blocks - Comptroller ClaimComp Geoff - Assert Equal (Erc20 COMP TokenBalance Geoff) 250e18--half of cdai, all of zrx. += (.25 + .5) * 100 - Assert Equal (Comptroller CompAccrued Geoff) 0 + Comptroller ClaimSashimi Geoff + Assert Equal (Erc20 SASHIMI TokenBalance Geoff) 250e18--half of sldai, all of zrx. += (.25 + .5) * 100 + Assert Equal (Comptroller SashimiAccrued Geoff) 0 -Test "TransferComp handles running out of COMP in Comptroller correctly" - FlywheelComptroller price:1.0 borrowRate:0.000005 compInitAmount:1e18 +Test "TransferComp handles running out of SASHIMI in Comptroller correctly" + FlywheelComptroller price:1.0 borrowRate:0.000005 sashimiInitAmount:1e18 InitSpeeds FastForward 2 Blocks - Comptroller ClaimComp Geoff - Assert Equal (Comptroller CompAccrued Geoff) 2e18 - Assert Equal (Erc20 COMP TokenBalance Geoff) 0 - Give (Address Comptroller) 1e18 COMP - Comptroller ClaimComp Geoff - Assert Equal (Comptroller CompAccrued Geoff) 0 - Assert Equal (Erc20 COMP TokenBalance Geoff) 2e18 + Comptroller ClaimSashimi Geoff + Assert Equal (Comptroller SashimiAccrued Geoff) 2e18 + Assert Equal (Erc20 SASHIMI TokenBalance Geoff) 0 + Give (Address Comptroller) 1e18 SASHIMI + Comptroller ClaimSashimi Geoff + Assert Equal (Comptroller SashimiAccrued Geoff) 0 + Assert Equal (Erc20 SASHIMI TokenBalance Geoff) 2e18 -Test "Changing COMP rate continues to distribute at the correct speed" +Test "Changing SASHIMI rate continues to distribute at the correct speed" FlywheelComptroller InitSpeeds -- - Assert Equal (Comptroller CompSpeed cZRX) 1e18 + Assert Equal (Comptroller SashimiSpeed slZRX) 1e18 FastForward 10 Blocks - Comptroller SetCompRate 2e18 - Assert Equal (Comptroller CompSpeed cZRX) 2e18 + Comptroller SetSashimiRate 2e18 + Assert Equal (Comptroller SashimiSpeed slZRX) 2e18 FastForward 10 Blocks - Comptroller ClaimComp Geoff - Assert Equal (Comptroller CompAccrued Geoff) 0 - Assert Equal (Erc20 COMP TokenBalance Geoff) 30e18 + Comptroller ClaimSashimi Geoff + Assert Equal (Comptroller SashimiAccrued Geoff) 0 + Assert Equal (Erc20 SASHIMI TokenBalance Geoff) 30e18 diff --git a/spec/scenario/Flywheel/Reservoir.scen b/spec/scenario/Flywheel/Reservoir.scen deleted file mode 100644 index 9e8785853..000000000 --- a/spec/scenario/Flywheel/Reservoir.scen +++ /dev/null @@ -1,84 +0,0 @@ - -Test "Reservoir is initialized correctly" - Comp Deploy Admin - Block 100 (Reservoir Deploy 5e18 Comp Bank) - Assert Equal (Reservoir Dripped) 0 - Assert Equal (Reservoir DripStart) 100 - Assert Equal (Reservoir DripRate) 5e18 - Assert Equal (Reservoir Token) (Comp Address) - Assert Equal (Reservoir Target) (Address Bank) - -Test "Reservoir properly drips first drip" - Comp Deploy Admin - Block 100 (Reservoir Deploy 5e18 Comp Bank) - Comp Transfer Reservoir 5000e18 - SetBlockNumber 200 - Assert Equal (Reservoir Drip) 500e18 - Assert Equal (Reservoir Dripped) 0 - Block 200 (Reservoir Drip) - Assert Equal (Reservoir Dripped) 500e18 - Assert Equal (Comp TokenBalance Bank) 500e18 - Assert Equal (Comp TokenBalance Reservoir) 4500e18 - -Test "Reservoir properly drips second drip" - Comp Deploy Admin - Block 100 (Reservoir Deploy 5e18 Comp Bank) - Comp Transfer Reservoir 5000e18 - Block 200 (Reservoir Drip) - Assert Equal (Reservoir Dripped) 500e18 - SetBlockNumber 250 - Assert Equal (Reservoir Drip) 250e18 - Block 250 (Reservoir Drip) - Assert Equal (Reservoir Dripped) 750e18 - Assert Equal (Comp TokenBalance Bank) 750e18 - Assert Equal (Comp TokenBalance Reservoir) 4250e18 - -Test "Reservoir properly drips zero sequentially" - Comp Deploy Admin - Block 100 (Reservoir Deploy 5e18 Comp Bank) - Comp Transfer Reservoir 5000e18 - Block 100 (Reservoir Drip) - Assert Equal (Reservoir Dripped) 0 - Block 200 (Reservoir Drip) - Assert Equal (Reservoir Dripped) 500e18 - Block 200 (Reservoir Drip) - Assert Equal (Reservoir Dripped) 500e18 - -Test "Reservoir handles not having enough to drip" - Comp Deploy Admin - Block 100 (Reservoir Deploy 5e18 Comp Bank) - Comp Transfer Reservoir 200e18 - Block 200 (Reservoir Drip) - Assert Equal (Reservoir Dripped) 200e18 - Assert Equal (Comp TokenBalance Bank) 200e18 - Assert Equal (Comp TokenBalance Reservoir) 0 - Block 200 (Reservoir Drip) - Assert Equal (Reservoir Dripped) 200e18 - Assert Equal (Comp TokenBalance Bank) 200e18 - Assert Equal (Comp TokenBalance Reservoir) 0 - Comp Transfer Reservoir 4800e18 - Block 200 (Reservoir Drip) - Assert Equal (Reservoir Dripped) 500e18 - Assert Equal (Comp TokenBalance Bank) 500e18 - Assert Equal (Comp TokenBalance Reservoir) 4500e18 - Block 250 (Reservoir Drip) - Assert Equal (Reservoir Dripped) 750e18 - Assert Equal (Comp TokenBalance Bank) 750e18 - Assert Equal (Comp TokenBalance Reservoir) 4250e18 - -Test "Revert on dripTotal overflow" - Comp Deploy Admin - Block 100 (Reservoir Deploy 10e77 Comp Bank) - AllowFailures - Block 200 (Reservoir Drip) - Assert Revert "revert dripTotal overflow" - -Test "Revert on deltaDrip underflow - reverses block!" - Comp Deploy Admin - Block 100 (Reservoir Deploy 5e18 Comp Bank) - Comp Transfer Reservoir 5000e18 - Assert Equal (Reservoir DripStart) 100 - Block 200 (Reservoir Drip) - AllowFailures - Block 100 (Reservoir Drip) -- Going back in time! - Assert Revert "revert deltaDrip underflow" diff --git a/spec/scenario/Governor/Cancel.scen b/spec/scenario/Governor/Cancel.scen deleted file mode 100644 index 088ce4d3a..000000000 --- a/spec/scenario/Governor/Cancel.scen +++ /dev/null @@ -1,99 +0,0 @@ -Macro DeployGov - SetBlockNumber 1 - Counter Deploy CNT1 - Timelock Deploy Scenario Jared 604800 - Comp Deploy Bank - Governor Deploy Alpha LegitGov (Address Timelock) (Address Comp) Guardian - Timelock SetAdmin (Address LegitGov) - Enfranchise Root 200001e18 - Enfranchise Jared 200000e18 - -Macro Enfranchise user amount - From Bank (Comp Transfer user amount) - From user (Comp Delegate user) - -Macro GivenPendingProposal - DeployGov - MineBlock - MineBlock - Governor LegitGov Propose "Add and sub" [(Address CNT1) (Address CNT1)] [0 0] ["increment(uint256,uint256)" "decrement(uint256)"] [["7" "4"] ["2"]] - Assert Equal ("Pending") (Governor LegitGov Proposal LastProposal State) - -Macro GivenActiveProposal - GivenPendingProposal - MineBlock - MineBlock - Assert Equal ("Active") (Governor LegitGov Proposal LastProposal State) - -Macro GivenSucceededProposal - GivenActiveProposal - Governor LegitGov Proposal LastProposal Vote For - From Jared (Governor LegitGov Proposal LastProposal Vote For) - AdvanceBlocks 20000 - Assert Equal ("Succeeded") (Governor LegitGov Proposal LastProposal State) - -Macro GivenQueuedProposal - GivenSucceededProposal - FreezeTime 100 - Governor LegitGov Proposal LastProposal Queue - Assert Log ProposalQueued (id 1) - Assert Equal ("Queued") (Governor LegitGov Proposal LastProposal State) - -Macro GivenExecutedProposal - GivenQueuedProposal - FreezeTime 604901 - Governor LegitGov Proposal LastProposal Execute - Assert Equal ("Executed") (Governor LegitGov Proposal LastProposal State) - -Test "Cancel a Pending proposal" - GivenPendingProposal - From Root (Comp Delegate Geoff) - Assert Equal ("Pending") (Governor LegitGov Proposal LastProposal State) - --sending away delegates takes a block, so proposal will be "Active" by time it is cancelable - Governor LegitGov Proposal LastProposal Cancel - Assert Log ProposalCanceled (id 1) - Assert Equal ("Canceled") (Governor LegitGov Proposal LastProposal State) - -Test "Cancel an Active proposal" - GivenActiveProposal - From Root (Comp Delegate Geoff) - Governor LegitGov Proposal LastProposal Cancel - Assert Log ProposalCanceled (id 1) - Assert Equal ("Canceled") (Governor LegitGov Proposal LastProposal State) - -Test "Cancel a Succeded proposal" - GivenSucceededProposal - From Root (Comp Delegate Geoff) - Governor LegitGov Proposal LastProposal Cancel - Assert Log ProposalCanceled (id 1) - Assert Equal ("Canceled") (Governor LegitGov Proposal LastProposal State) - -Test "Cancel a queued proposal" - GivenQueuedProposal - Assert True (Timelock QueuedTransaction (Timelock TxHash (Address CNT1) 0 (Governor LegitGov Proposal LastProposal Eta) "increment(uint256,uint256)" 7 4)) - Assert True (Timelock QueuedTransaction (Timelock TxHash (Address CNT1) 0 (Governor LegitGov Proposal LastProposal Eta) "decrement(uint256)" 2)) - From Root (Comp Delegate Geoff) - Governor LegitGov Proposal LastProposal Cancel - Assert Log ProposalCanceled (id 1) - Assert False (Timelock QueuedTransaction (Timelock TxHash (Address CNT1) 0 (Governor LegitGov Proposal LastProposal Eta) "increment(uint256,uint256)" 7 4)) - Assert False (Timelock QueuedTransaction (Timelock TxHash (Address CNT1) 0 (Governor LegitGov Proposal LastProposal Eta) "decrement(uint256)" 2)) - Assert Equal ("Canceled") (Governor LegitGov Proposal LastProposal State) - -Test "Revert when trying to cancel an executed proposal" - GivenExecutedProposal - From Root (Comp Delegate Geoff) - AllowFailures - Governor LegitGov Proposal LastProposal Cancel - Assert Revert "revert GovernorAlpha::cancel: cannot cancel executed proposal" - -Test "Revert when canceling if proposer has votes" - GivenPendingProposal - AllowFailures - Governor LegitGov Proposal LastProposal Cancel - Assert Revert "revert GovernorAlpha::cancel: proposer above threshold" - -Test "Guardian can cancel any proposal" - GivenActiveProposal - From Guardian (Governor LegitGov Proposal LastProposal Cancel) - Assert Log ProposalCanceled (id 1) - Assert Equal (Governor LegitGov Proposal LastProposal State) "Canceled" diff --git a/spec/scenario/Governor/Defeat.scen b/spec/scenario/Governor/Defeat.scen deleted file mode 100644 index b7dae5c19..000000000 --- a/spec/scenario/Governor/Defeat.scen +++ /dev/null @@ -1,55 +0,0 @@ -Macro DeployGov - SetBlockNumber 1 - Counter Deploy CNT1 - Timelock Deploy Scenario Jared 604800 - Comp Deploy Bank - Governor Deploy Alpha LegitGov (Address Timelock) (Address Comp) Guardian - Timelock SetAdmin (Address LegitGov) - Enfranchise Root 100001e18 - Enfranchise Jared 200000e18 - Enfranchise Torrey 600001e18 - Enfranchise Geoff 700001e18 - -Macro Enfranchise user amount - From Bank (Comp Transfer user amount) - From user (Comp Delegate user) - -Macro GivenPendingProposal - DeployGov - MineBlock - MineBlock - Governor LegitGov Propose "Add and sub" [(Address CNT1) (Address CNT1)] [0 0] ["increment(uint256,uint256)" "decrement(uint256)"] [["7" "4"] ["2"]] - Assert Equal ("Pending") (Governor LegitGov Proposal LastProposal State) - -Macro GivenActiveProposal - GivenPendingProposal - MineBlock - MineBlock - Assert Equal ("Active") (Governor LegitGov Proposal LastProposal State) - -Test "Defeat when for votes do not reach quorum" - GivenActiveProposal - Governor LegitGov Proposal LastProposal Vote For - AdvanceBlocks 20000 - Assert Equal ("Defeated") (Governor LegitGov Proposal LastProposal State) - -Test "Defeat when more against votes than for votes" - GivenActiveProposal - From Torrey (Governor LegitGov Proposal LastProposal Vote For ) - From Geoff (Governor LegitGov Proposal LastProposal Vote Against ) - AdvanceBlocks 20000 - Assert Equal ("Defeated") (Governor LegitGov Proposal LastProposal State) - -Test "(not defeat) when vote is ongoing" - GivenActiveProposal - From Torrey (Governor LegitGov Proposal LastProposal Vote For ) - From Geoff (Governor LegitGov Proposal LastProposal Vote For ) - Assert Equal ("Active") (Governor LegitGov Proposal LastProposal State) - -Test "(not defeat) when fors pass quorum and nays" - GivenActiveProposal - From Torrey (Governor LegitGov Proposal LastProposal Vote For ) - From Geoff (Governor LegitGov Proposal LastProposal Vote For ) - From Jared (Governor LegitGov Proposal LastProposal Vote Against ) - AdvanceBlocks 20000 - Assert Equal ("Succeeded") (Governor LegitGov Proposal LastProposal State) diff --git a/spec/scenario/Governor/Execute.scen b/spec/scenario/Governor/Execute.scen deleted file mode 100644 index b2ba4b485..000000000 --- a/spec/scenario/Governor/Execute.scen +++ /dev/null @@ -1,96 +0,0 @@ -Macro DeployGov - SetBlockNumber 1 - IncreaseTime 100 - Counter Deploy CNT1 - Timelock Deploy Jared 604800 - Comp Deploy Bank - Enfranchise Root 200001e18 - Enfranchise Jared 200000e18 - Governor Deploy Alpha LegitGov (Address Timelock) (Address Comp) Guardian - Timelock SetAdmin (Address LegitGov) - -Macro Enfranchise user amount - From Bank (Comp Transfer user amount) - From user (Comp Delegate user) - -Macro SucceedProposal - MineBlock - Governor LegitGov Proposal LastProposal Vote For - From Jared (Governor LegitGov Proposal LastProposal Vote For) - AdvanceBlocks 20000 - Assert Equal ("Succeeded") (Governor LegitGov Proposal LastProposal State) - -Macro GivenSucceededProposal - DeployGov - Governor LegitGov Propose "Add 2" [(Address CNT1)] [0] ["increment(uint256)"] [["2"]] - SucceedProposal - -Macro GivenQueuedProposal - GivenSucceededProposal - Governor LegitGov Proposal LastProposal Queue - -Test "Execute a simple queued proposal with value" - GivenQueuedProposal - Assert Equal ("Queued") (Governor LegitGov Proposal LastProposal State) - IncreaseTime 605000 - Governor LegitGov Proposal LastProposal Execute - Assert Equal ("Executed") (Governor LegitGov Proposal LastProposal State) - Assert Log ProposalExecuted (id 1) - Assert Equal (Counter CNT1 Count) 2 - -Test "Execute a complex queued proposal with value" - DeployGov - Governor LegitGov Propose "Add and sub" [(Address CNT1) (Address CNT1)] [1 1] ["increment(uint256,uint256)" "decrement(uint256)"] [["7" "4"] ["2"]] - SucceedProposal - Governor LegitGov Proposal LastProposal Queue - IncreaseTime 604910 - Assert Equal (Counter CNT1 Count) 0 - Assert Equal (Counter CNT1 Count2) 0 - Trx Value 2 (Governor LegitGov Proposal LastProposal Execute) - Assert Equal ("Executed") (Governor LegitGov Proposal LastProposal State) - Assert Equal (Counter CNT1 Count) 5 - Assert Equal (Counter CNT1 Count2) 4 - -Test "Revert when trying to execute a succeeded but unqueued proposal" - DeployGov - Governor LegitGov Propose "Add 5" [(Address CNT1)] [0] ["increment(uint256)"] [["2"]] - SucceedProposal - AllowFailures - Governor LegitGov Proposal LastProposal Execute - Assert Revert "revert GovernorAlpha::execute: proposal can only be executed if it is queued" - -Test "Revert when executing a proposal that reverts" - DeployGov - Governor LegitGov Propose "Add 1 and revert" [(Address CNT1) (Address CNT1)] [0 0] ["increment(uint256)" "doRevert()"] [["1"] []] - SucceedProposal - Governor LegitGov Proposal LastProposal Queue - IncreaseTime 604905 - AllowFailures - Governor LegitGov Proposal LastProposal Execute - Assert Revert "revert Timelock::executeTransaction: Transaction execution reverted." - -Test "Revert when executing an expired proposal" - GivenQueuedProposal - -- eta + grace period (2 weeks) + 1 - -- 604900 + 1209600 + 1 = - IncreaseTime 1814505 - Assert Equal ("Expired") (Governor LegitGov Proposal LastProposal State) - AllowFailures - Governor LegitGov Proposal LastProposal Execute - Assert Revert "revert GovernorAlpha::execute: proposal can only be executed if it is queued" - -Test "Assert execution order" - DeployGov - Governor LegitGov Propose "Increment and require not zero" [(Address CNT1) (Address CNT1)] [0 0] ["increment(uint256)" "notZero()"] [["1"] []] - SucceedProposal - Governor LegitGov Proposal LastProposal Queue - IncreaseTime 604905 - Governor LegitGov Proposal LastProposal Execute - -Test "Cannot execute cancelled proposal" - GivenQueuedProposal - IncreaseTime 604905 - From Guardian (Governor LegitGov Proposal LastProposal Cancel) - AllowFailures - Governor LegitGov Proposal LastProposal Execute - Assert Revert "revert GovernorAlpha::execute: proposal can only be executed if it is queued" diff --git a/spec/scenario/Governor/Guardian.scen b/spec/scenario/Governor/Guardian.scen deleted file mode 100644 index f3b840fd8..000000000 --- a/spec/scenario/Governor/Guardian.scen +++ /dev/null @@ -1,68 +0,0 @@ -Macro GivenGov - Counter Deploy - SetTime 10 - Timelock Deploy Jared 604800 - Comp Deploy Bank - Governor Deploy Alpha LegitGov (Address Timelock) (Address Comp) Guardian - Timelock SetAdmin (Address LegitGov) - -Test "Guardian can switch to a new governor" - GivenGov - From Guardian (Governor LegitGov Guardian QueueSetTimelockPendingAdmin (Address Geoff) 604900) - SetTime 604901 - From Guardian (Governor LegitGov Guardian ExecuteSetTimelockPendingAdmin (Address Geoff) 604900) - From Geoff (Timelock AcceptAdmin) - Assert Equal (Timelock Admin) (Address Geoff) - -Test "Only guardian can queue" - GivenGov - AllowFailures - Governor LegitGov Guardian QueueSetTimelockPendingAdmin Geoff 604900 - Assert Revert "revert GovernorAlpha::__queueSetTimelockPendingAdmin: sender must be gov guardian" - -Test "Only guardian can execute" - GivenGov - From Guardian (Governor LegitGov Guardian QueueSetTimelockPendingAdmin Geoff 604900) - AllowFailures - IncreaseTime 604901 - Governor LegitGov Guardian ExecuteSetTimelockPendingAdmin Geoff 604900 - Assert Revert "revert GovernorAlpha::__executeSetTimelockPendingAdmin: sender must be gov guardian" - -Test "Guardian can abdicate" - GivenGov - Assert Equal (Governor LegitGov Guardian) (Address Guardian) - From Guardian (Governor LegitGov Guardian Abdicate) - Assert Equal (Governor LegitGov Guardian) (Address Zero) - -Test "Only guardian can abdicate" - GivenGov - AllowFailures - Governor LegitGov Guardian Abdicate - Assert Revert "revert GovernorAlpha::__abdicate: sender must be gov guardian" - -Test "Guardian can accept admin" - Timelock Deploy Jared 604800 - Comp Deploy Bank - Governor Deploy Alpha LegitGov (Address Timelock) (Address Comp) Guardian - From Jared (Timelock QueueTransaction (Timelock Address) 0 604900 "setPendingAdmin(address)" (Governor LegitGov Address)) - IncreaseTime 604901 - From Jared (Timelock ExecuteTransaction (Timelock Address) 0 604900 "setPendingAdmin(address)" (Governor LegitGov Address)) - Assert Equal (Timelock Admin) (Address Jared) - Assert Equal (Timelock PendingAdmin) (Governor LegitGov Address) - From Guardian (Governor LegitGov Guardian AcceptAdmin) - Assert Equal (Timelock Admin) (Governor LegitGov Address) - Assert Equal (Timelock PendingAdmin) (Address Zero) - -Test "Only guardian can accept admin" - SetTime 10 - Timelock Deploy Jared 604800 - Comp Deploy Bank - Governor Deploy Alpha LegitGov (Address Timelock) (Address Comp) Guardian - From Jared (Timelock QueueTransaction (Timelock Address) 0 604900 "setPendingAdmin(address)" (Governor LegitGov Address)) - IncreaseTime 604901 - From Jared (Timelock ExecuteTransaction (Timelock Address) 0 604900 "setPendingAdmin(address)" (Governor LegitGov Address)) - Assert Equal (Timelock Admin) (Address Jared) - Assert Equal (Timelock PendingAdmin) (Governor LegitGov Address) - AllowFailures - Governor LegitGov Guardian AcceptAdmin - Assert Revert "revert GovernorAlpha::__acceptAdmin: sender must be gov guardian" diff --git a/spec/scenario/Governor/Propose.scen b/spec/scenario/Governor/Propose.scen deleted file mode 100644 index d0ca6d2ac..000000000 --- a/spec/scenario/Governor/Propose.scen +++ /dev/null @@ -1,109 +0,0 @@ - -Macro DeployGov - Comp Deploy Bank - Timelock Deploy Jared 604800 - Governor Deploy Alpha LegitGov (Address Timelock) (Address Comp) Guardian - Timelock SetAdmin (Address LegitGov) - Enfranchise Root 100001e18 - -Macro Enfranchise user amount - From Bank (Comp Transfer user amount) - From user (Comp Delegate user) - -Test "Propose 💍 [1 Action]" - DeployGov - Counter Deploy - Governor LegitGov Propose "Add 5" [(Address Counter)] [1] ["increment(uint256)"] [["5"]] - Assert Log ProposalCreated (id 1) - Assert Log ProposalCreated (description "Add 5") - Assert Log ProposalCreated (targets [(Address Counter)]) - Assert Log ProposalCreated (values [1]) - Assert Log ProposalCreated (signatures ["increment(uint256)"]) - Assert Log ProposalCreated (startBlock 9) - Assert Log ProposalCreated (endBlock 17289) - Assert Log ProposalCreated (calldatas ["0x0000000000000000000000000000000000000000000000000000000000000005"]) - Assert Log ProposalCreated (proposer (Address Root)) - Assert Equal (Governor LegitGov Proposal LastProposal Id) 1 - Assert Equal (Governor LegitGov Proposal LastProposal Proposer) (Address Root) - Assert Equal (Governor LegitGov Proposal LastProposal StartBlock) 9 - Assert Equal (Governor LegitGov Proposal LastProposal EndBlock) 17289 - Assert Equal (Governor LegitGov Proposal LastProposal ForVotes) 0 - Assert Equal (Governor LegitGov Proposal LastProposal AgainstVotes) 0 - Assert Equal (Governor LegitGov Proposal LastProposal Eta) 0 - Assert Equal (Governor LegitGov Proposal LastProposal Targets) [(Address Counter)] - Assert Equal (Governor LegitGov Proposal LastProposal Values) [1] - Assert Equal (Governor LegitGov Proposal LastProposal Signatures) ["increment(uint256)"] - Assert Equal (Governor LegitGov Proposal LastProposal Calldatas) ["0x0000000000000000000000000000000000000000000000000000000000000005"] - Assert False (Governor LegitGov Proposal LastProposal HasVoted Geoff) - -Test "Propose 💍💍 [2 Actions]" - DeployGov - Counter Deploy CounterA - Counter Deploy CounterB - Governor LegitGov Propose "Add 5, Sub 3" [(Address CounterA) (Address CounterB)] [1 2] ["increment(uint256)" "decrement(uint256)"] [["5"] ["3"]] - Assert Log ProposalCreated (description "Add 5, Sub 3") - Assert Log ProposalCreated (targets [(Address CounterA) (Address CounterB)]) - Assert Log ProposalCreated (values [1 2]) - Assert Log ProposalCreated (signatures ["increment(uint256)" "decrement(uint256)"]) - Assert Log ProposalCreated (calldatas ["0x0000000000000000000000000000000000000000000000000000000000000005" "0x0000000000000000000000000000000000000000000000000000000000000003"]) - Assert Log ProposalCreated (proposer (Address Root)) - Assert Equal (Governor LegitGov Proposal LastProposal Targets) [(Address CounterA) (Address CounterB)] - Assert Equal (Governor LegitGov Proposal LastProposal Values) [1 2] - Assert Equal (Governor LegitGov Proposal LastProposal Signatures) ["increment(uint256)" "decrement(uint256)"] - Assert Equal (Governor LegitGov Proposal LastProposal Calldatas) ["0x0000000000000000000000000000000000000000000000000000000000000005" "0x0000000000000000000000000000000000000000000000000000000000000003"] - -Test "Propose fails when insufficient sender votes" - DeployGov - Counter Deploy - AllowFailures - From Geoff (Governor LegitGov Propose "Add 5" [(Address Counter)] [1] ["increment(uint256)"] [["5"]]) - Assert Revert "revert GovernorAlpha::propose: proposer votes below proposal threshold" - -Test "Propose fails when no actions given" - DeployGov - Counter Deploy - AllowFailures - Governor LegitGov Propose "Add 5" [] [] [] [[]] - Assert Revert "revert GovernorAlpha::propose: must provide actions" - -Test "Propose fails when too many actions given" - DeployGov - Counter Deploy - AllowFailures - Governor LegitGov Propose "Add 5" [(Address LegitGov) (Address LegitGov) (Address LegitGov) (Address LegitGov) (Address LegitGov) (Address LegitGov) (Address LegitGov) (Address LegitGov) (Address LegitGov) (Address LegitGov) (Address LegitGov)] [0 1 2 3 4 5 6 7 8 9 10] ["0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "10"] [[] [] [] [] [] [] [] [] [] [] []] - Assert Revert "revert GovernorAlpha::propose: too many actions" - -Test "Propose fails when actions mismatch length" - DeployGov - Counter Deploy - AllowFailures - Governor LegitGov Propose "Add 5" [(Address Counter)] [1 2] ["increment(uint256)"] [["5"]] - Assert Revert "revert GovernorAlpha::propose: proposal function information arity mismatch" - -Test "Propose fails when proposer has active proposal" - DeployGov - Counter Deploy - Governor LegitGov Propose "Add 5" [(Address Counter)] [1] ["increment(uint256)"] [["5"]] - AllowFailures - Governor LegitGov Propose "Add 5" [(Address Counter)] [1] ["increment(uint256)"] [["5"]] - Assert Revert "revert GovernorAlpha::propose: one live proposal per proposer, found an already pending proposal" - -Test "Can re-propose after vote completes" - DeployGov - Counter Deploy - Governor LegitGov Propose "Add 5" [(Address Counter)] [1] ["increment(uint256)"] [["5"]] - Assert Equal (Governor LegitGov Proposal (ActiveProposal Root) Id) 1 - AdvanceBlocks 20000 - Governor LegitGov Propose "Add 7" [(Address Counter)] [1] ["increment(uint256)"] [["7"]] - Assert Equal (Governor LegitGov Proposal (ActiveProposal Root) Id) 2 - -Test "Can re-propose after vote is canceled" - DeployGov - Counter Deploy - Governor LegitGov Propose "Add 5" [(Address Counter)] [1] ["increment(uint256)"] [["5"]] - Assert Equal (Governor LegitGov Proposal (ActiveProposal Root) Id) 1 - From Root (Comp Delegate Geoff) - Governor LegitGov Proposal (ActiveProposal Root) Cancel - From Root (Comp Delegate Root) - Governor LegitGov Propose "Add 7" [(Address Counter)] [1] ["increment(uint256)"] [["7"]] - Assert Equal (Governor LegitGov Proposal (ActiveProposal Root) Id) 2 diff --git a/spec/scenario/Governor/Queue.scen b/spec/scenario/Governor/Queue.scen deleted file mode 100644 index 0b660009b..000000000 --- a/spec/scenario/Governor/Queue.scen +++ /dev/null @@ -1,135 +0,0 @@ -Macro DeployGov - Counter Deploy CNT1 - Timelock Deploy Jared 604800 - Comp Deploy Bank - Governor Deploy Alpha LegitGov (Address Timelock) (Address Comp) Guardian - Timelock SetAdmin (Address LegitGov) - Enfranchise Root 400001e18 - MineBlock - -Macro Enfranchise user amount - From Bank (Comp Transfer user amount) - From user (Comp Delegate user) - MineBlock - -Macro QueueLastProposal - --anyone should be able to queue, set time to 100 for predictable eta's - SetTime 100 - From Torrey (Governor LegitGov Proposal LastProposal Queue) - -Macro GivenPendingProposal - DeployGov - MineBlock - Governor LegitGov Propose "Add and sub" [(Address CNT1) (Address CNT1)] [0 0] ["increment(uint256,uint256)" "decrement(uint256)"] [["7" "4"] ["2"]] - Assert Equal ("Pending") (Governor LegitGov Proposal LastProposal State) - -Macro GivenActiveProposal - GivenPendingProposal - MineBlock - MineBlock - Assert Equal ("Active") (Governor LegitGov Proposal LastProposal State) - -Macro GivenSucceededProposal - GivenActiveProposal - SucceedProposal - -Macro SucceedProposal - Governor LegitGov Proposal LastProposal Vote For - AdvanceBlocks 20000 - Assert Equal ("Succeeded") (Governor LegitGov Proposal LastProposal State) - -Test "Queue simple action" - DeployGov - Enfranchise Geoff 100 - Governor LegitGov Propose "Add 5" [(Address CNT1)] [1] ["increment(uint256)"] [["2"]] - MineBlock - SucceedProposal - --anyone should be able to queue - From Torrey (Governor LegitGov Proposal LastProposal Queue) - Assert True (Timelock QueuedTransaction (Timelock TxHash (Address CNT1) 1 (Governor LegitGov Proposal LastProposal Eta) "increment(uint256)" 2)) - Assert Log ProposalQueued (id 1) - Assert Log ProposalQueued (eta (Governor LegitGov Proposal LastProposal Eta)) - Assert True (Timelock QueuedTransaction (Timelock TxHash (Address CNT1) 1 (Governor LegitGov Proposal LastProposal Eta) "increment(uint256)" 2)) - -Test "Queue 2 actions with multiple params" - GivenActiveProposal - Governor LegitGov Proposal LastProposal Vote For - AdvanceBlocks 20000 - QueueLastProposal - Assert Log ProposalQueued (id 1) - Assert Log ProposalQueued (eta (Governor LegitGov Proposal LastProposal Eta)) - Assert True (Timelock QueuedTransaction (Timelock TxHash (Address CNT1) 0 (Governor LegitGov Proposal LastProposal Eta) "increment(uint256,uint256)" 7 4)) - Assert True (Timelock QueuedTransaction (Timelock TxHash (Address CNT1) 0 (Governor LegitGov Proposal LastProposal Eta) "decrement(uint256)" 2)) - -Test "Revert on repeated proposal items" - DeployGov - Governor LegitGov Propose "Add 1 and Add 1" [(Address CNT1) (Address CNT1)] [0 0] ["increment(uint256)" "increment(uint256)"] [["1"] ["1"]] - MineBlock - SucceedProposal - AllowFailures - Governor LegitGov Proposal LastProposal Queue - Assert Revert "revert GovernorAlpha::_queueOrRevert: proposal action already queued at eta" - -Test "Revert queue when proposal Id is Invalid" - DeployGov - AllowFailures - Governor LegitGov Proposal LastProposal Queue - Assert Revert "revert GovernorAlpha::state: invalid proposal id" - -Test "Revert queue when proposal is Pending" - DeployGov - Governor LegitGov Propose "Add 5" [(Address CNT1)] [1] ["increment(uint256)"] [["2"]] - Assert Equal ("Pending") (Governor LegitGov Proposal LastProposal State) - AllowFailures - Governor LegitGov Proposal LastProposal Queue - Assert Revert "revert GovernorAlpha::queue: proposal can only be queued if it is succeeded" - -Test "Revert queue proposal is Active" - GivenActiveProposal - AllowFailures - Governor LegitGov Proposal LastProposal Queue - Assert Revert "revert GovernorAlpha::queue: proposal can only be queued if it is succeeded" - -Test "Revert queue when proposal is Defeated" - GivenActiveProposal - Governor LegitGov Proposal LastProposal Vote Against - AdvanceBlocks 20000 - AllowFailures - Assert Equal ("Defeated") (Governor LegitGov Proposal LastProposal State) - Governor LegitGov Proposal LastProposal Queue - Assert Revert "revert GovernorAlpha::queue: proposal can only be queued if it is succeeded" - -Test "Revert queue when proposal is Queued" - GivenSucceededProposal - Governor LegitGov Proposal LastProposal Queue - Assert Equal ("Queued") (Governor LegitGov Proposal LastProposal State) - AllowFailures - Governor LegitGov Proposal LastProposal Queue - Assert Revert "revert GovernorAlpha::queue: proposal can only be queued if it is succeeded" - -Test "Revert when queuing an already executed proposal" - GivenSucceededProposal - QueueLastProposal - SetTime 604902 - Governor LegitGov Proposal LastProposal Execute - AllowFailures - Governor LegitGov Proposal LastProposal Queue - Assert Revert "revert GovernorAlpha::queue: proposal can only be queued if it is succeeded" - -Test "Revert when queuing on invalid Timelock" - Comp Deploy Bank - Enfranchise Root 600001e18 - Counter Deploy CNT1 - Governor Deploy Alpha LegitGov (Address Zero) (Address Comp) Guardian - Governor LegitGov Propose "Add 5" [(Address CNT1)] [1] ["increment(uint256)"] [["2"]] - MineBlock - Governor LegitGov Proposal LastProposal Vote For - AllowFailures - Governor LegitGov Proposal LastProposal Queue - Assert Revert "revert" - ---TODO: - ---Test "Dont queue when cancelled" ---deploy => propose => cancel ---Assert revert on queue diff --git a/spec/scenario/Governor/Upgrade.scen b/spec/scenario/Governor/Upgrade.scen deleted file mode 100644 index 80f822414..000000000 --- a/spec/scenario/Governor/Upgrade.scen +++ /dev/null @@ -1,63 +0,0 @@ - -Macro DeployGov - SetBlockNumber 1 - SetTime 10 - Counter Deploy CNT1 - Comp Deploy Bank - Enfranchise Root 400001e18 - Timelock Deploy Jared 604800 - Governor Deploy Alpha Alpha (Address Timelock) (Address Comp) Guardian - Timelock SetAdmin (Address Alpha) - Assert Equal (Timelock Admin) (Address Alpha) - -Macro SucceedQueueExecuteLastProposal gov - MineBlock - Governor gov Proposal LastProposal Vote For - AdvanceBlocks 20000 - MineBlock - Enfranchise Root 600001e18 - Assert Equal ("Succeeded") (Governor gov Proposal LastProposal State) - Governor gov Proposal LastProposal Queue - Assert Equal ("Queued") (Governor gov Proposal LastProposal State) - IncreaseTime 604905 - Governor gov Proposal LastProposal Execute - Assert Equal ("Executed") (Governor gov Proposal LastProposal State) - -Macro Enfranchise user amount - From Bank (Comp Transfer user amount) - From user (Comp Delegate user) - -Test "Governor can switch to a new governor" - DeployGov - Governor Deploy Alpha Beta (Address Timelock) (Address Comp) Guardian - Governor Alpha Propose "Upgrade Governor" [(Address Timelock)] [0] ["setPendingAdmin(address)"] [[(Address Beta)]] - SucceedQueueExecuteLastProposal Alpha - Assert Equal (Timelock PendingAdmin) (Address Beta) - From Guardian (Governor Beta Guardian AcceptAdmin) - Assert Equal (Timelock Admin) (Address Beta) - Assert Equal (Timelock PendingAdmin) (Address Zero) - Governor Beta Propose "Add 2" [(Address CNT1)] [0] ["increment(uint256)"] [["2"]] - SucceedQueueExecuteLastProposal Beta - Assert Log ProposalExecuted (id 1) - Assert Equal (Counter CNT1 Count) 2 - -Test "Guardian can switch to a new governor" - DeployGov - Governor Deploy Alpha Beta (Address Timelock) (Address Comp) Guardian - From Guardian (Governor Alpha Guardian QueueSetTimelockPendingAdmin (Address Beta) 604902) - IncreaseTime 604905 - From Guardian (Governor Alpha Guardian ExecuteSetTimelockPendingAdmin (Address Beta) 604902) - From Guardian (Governor Beta Guardian AcceptAdmin) - Assert Equal (Timelock Admin) (Address Beta) - Assert Equal (Timelock PendingAdmin) (Address Zero) - Governor Beta Propose "Add 2" [(Address CNT1)] [0] ["increment(uint256)"] [["2"]] - IncreaseTime 604901 - From Root (Governor Beta Proposal LastProposal Vote For) - AdvanceBlocks 20000 - Governor Beta Proposal LastProposal Queue - Assert Equal ("Queued") (Governor Beta Proposal LastProposal State) - IncreaseTime 604901 - Governor Beta Proposal LastProposal Execute - Assert Equal ("Executed") (Governor Beta Proposal LastProposal State) - Assert Log ProposalExecuted (id 1) - Assert Equal (Counter CNT1 Count) 2 diff --git a/spec/scenario/Governor/Vote.scen b/spec/scenario/Governor/Vote.scen deleted file mode 100644 index d4ae5dbdf..000000000 --- a/spec/scenario/Governor/Vote.scen +++ /dev/null @@ -1,72 +0,0 @@ - -Macro GivenProposal - Counter Deploy - Comp Deploy Bank - Timelock Deploy Jared 604800 - Governor Deploy Alpha LegitGov (Address Timelock) (Address Comp) Guardian - Timelock SetAdmin (Address LegitGov) - Enfranchise Root 100001e18 - Enfranchise Geoff 100 - Governor LegitGov Propose "Add 5" [(Address Counter)] [1] ["increment(uint256)"] [["0x5"]] - MineBlock - -Macro Enfranchise user amount - From Bank (Comp Transfer user amount) - From user (Comp Delegate user) - -Test "Successfully Cast For Vote" - GivenProposal - From Geoff (Governor LegitGov Proposal LastProposal Vote For) - Assert Log VoteCast (voter (Address Geoff)) (proposalId 1) (support true) (votes 100) - Assert Equal (Governor LegitGov Proposal LastProposal ForVotes) 100 - Assert Equal (Governor LegitGov Proposal LastProposal AgainstVotes) 0 - Assert True (Governor LegitGov Proposal LastProposal HasVoted Geoff) - -Test "Successfully Cast Against Vote" - GivenProposal - From Geoff (Governor LegitGov Proposal LastProposal Vote Against) - Assert Log VoteCast (support false) (votes 100) - Assert Equal (Governor LegitGov Proposal LastProposal ForVotes) 0 - Assert Equal (Governor LegitGov Proposal LastProposal AgainstVotes) 100 - Assert True (Governor LegitGov Proposal LastProposal HasVoted Geoff) - -Test "Successfully Cast Zero Vote" - GivenProposal - From Torrey (Governor LegitGov Proposal LastProposal Vote For) - Assert Log VoteCast (support true) (votes 0) - Assert Equal (Governor LegitGov Proposal LastProposal ForVotes) 0 - Assert Equal (Governor LegitGov Proposal LastProposal AgainstVotes) 0 - Assert True (Governor LegitGov Proposal LastProposal HasVoted Torrey) - -Test "Fail to vote twice" - GivenProposal - Governor LegitGov Proposal LastProposal Vote For - AllowFailures - Governor LegitGov Proposal LastProposal Vote For - Assert Revert "revert GovernorAlpha::_castVote: voter already voted" - Governor LegitGov Proposal LastProposal Vote Against - Assert Revert "revert GovernorAlpha::_castVote: voter already voted" - Assert Equal (Governor LegitGov Proposal LastProposal ForVotes) 100001e18 - Assert Equal (Governor LegitGov Proposal LastProposal AgainstVotes) 0 - Assert False (Governor LegitGov Proposal LastProposal HasVoted Geoff) - -Test "Cannot vote before vote starts" - GivenProposal - AllowFailures - SetBlockNumber 7 - Governor LegitGov Proposal LastProposal Vote For - Assert Revert "revert GovernorAlpha::_castVote: voting is closed" - -Test "Cannot vote after vote ends" - GivenProposal - AllowFailures - AdvanceBlocks 20000 - Governor LegitGov Proposal LastProposal Vote For - Assert Revert "revert GovernorAlpha::_castVote: voting is closed" - -Test "Cannot vote on cancelled vote" - GivenProposal - From Guardian (Governor LegitGov Proposal LastProposal Cancel) - AllowFailures - Governor LegitGov Proposal LastProposal Vote For - Assert Revert "revert GovernorAlpha::_castVote: voting is closed" diff --git a/spec/scenario/HypotheticalAccountLiquidity.scen b/spec/scenario/HypotheticalAccountLiquidity.scen index 0028795fc..21848bce9 100644 --- a/spec/scenario/HypotheticalAccountLiquidity.scen +++ b/spec/scenario/HypotheticalAccountLiquidity.scen @@ -2,48 +2,48 @@ Test "Calculates hypothetical account liquidity" -- Note, this comes a bit from `EnterExitMarkets` Scenario PricedComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - SetPriceCF cZRX 0.002 0.4 - ListedEtherToken cETH initialExchangeRate:1e9 - Comptroller SetCollateralFactor cEth 0.8 - ListedCToken BAT cBAT initialExchangeRate:1e9 - SetPriceCF cBAT 0.0015 0.3 - ListedCToken OMG cOMG initialExchangeRate:1e9 - NewCToken REP cREP - -- Mint some cZRX and cETH - Prep Geoff 1250e18 ZRX cZRX - Mint Geoff 1250e18 cZRX -- Liquidity -> 0.4 * 0.002 * 1250e18 = 1.0e18 - SendMintEth Geoff 2.5e18 cETH -- Liqiuidity -> 0.8 * 1.0 * 2.5e18 = 2.0e18 + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + SetPriceCF slZRX 0.002 0.4 + ListedEtherToken slETH initialExchangeRate:1e9 + Comptroller SetCollateralFactor slETH 0.8 + ListedSLToken BAT slBAT initialExchangeRate:1e9 + SetPriceCF slBAT 0.0015 0.3 + ListedSLToken OMG slOMG initialExchangeRate:1e9 + NewSLToken REP slREP + -- Mint some slZRX and slETH + Prep Geoff 1250e18 ZRX slZRX + Mint Geoff 1250e18 slZRX -- Liquidity -> 0.4 * 0.002 * 1250e18 = 1.0e18 + SendMintEth Geoff 2.5e18 slETH -- Liqiuidity -> 0.8 * 1.0 * 2.5e18 = 2.0e18 -- Check liquidity is zero when not in any markets Assert Equal (Comptroller Liquidity Geoff) Zero -- Enter ZRX and check liquidity - EnterMarkets Geoff cZRX + EnterMarkets Geoff slZRX Assert Equal (Comptroller Liquidity Geoff) 1.0e18 -- Now let's look at some hypotheticals - Assert Equal (Comptroller Hypothetical Geoff Redeems 1000e9 cZRX) 0.2e18 -- 0.4 * 0.002 * -1000e18 = -0.8e18 - Assert Equal (Comptroller Hypothetical Geoff Borrows 1000e18 cZRX) -1e18 -- 0.002 * -1000e18 = -2e18 + Assert Equal (Comptroller Hypothetical Geoff Redeems 1000e9 slZRX) 0.2e18 -- 0.4 * 0.002 * -1000e18 = -0.8e18 + Assert Equal (Comptroller Hypothetical Geoff Borrows 1000e18 slZRX) -1e18 -- 0.002 * -1000e18 = -2e18 -- Note, if you're not in an asset, this function returns no effect - Assert Equal (Comptroller Hypothetical Geoff Redeems 0.002e9 cETH) 1.0e18 -- 0.8 * 1000.0 * -0.002e18 = -1.6e18 - Assert Equal (Comptroller Hypothetical Geoff Borrows 0.002e18 cETH) 1.0e18 -- 1000.0 * -0.002e18 = -2e18 - EnterMarkets Geoff cETH + Assert Equal (Comptroller Hypothetical Geoff Redeems 0.002e9 slETH) 1.0e18 -- 0.8 * 1000.0 * -0.002e18 = -1.6e18 + Assert Equal (Comptroller Hypothetical Geoff Borrows 0.002e18 slETH) 1.0e18 -- 1000.0 * -0.002e18 = -2e18 + EnterMarkets Geoff slETH Assert Equal (Comptroller Liquidity Geoff) 3.0e18 - Assert Equal (Comptroller Hypothetical Geoff Redeems 1000e9 cZRX) 2.2e18 -- 0.4 * 0.002 * -1000e18 = -0.8e18 - Assert Equal (Comptroller Hypothetical Geoff Borrows 1000e18 cZRX) 1e18 -- 0.002 * -1000e18 = -2e18 - Assert Equal (Comptroller Hypothetical Geoff Redeems 2e9 cETH) 1.4e18 -- 0.8 * 1.0 * -2e18 = -1.6e18 - Assert Equal (Comptroller Hypothetical Geoff Borrows 2e18 cETH) 1.0e18 -- 1.0 * -2e18 = -2e18 - EnterMarkets Geoff cBAT - Assert Equal (Comptroller Hypothetical Geoff Redeems 1000e9 cBAT) 2.55e18 -- 0.3 * 0.0015 * -1000e18 = -0.45e18e18 - Assert Equal (Comptroller Hypothetical Geoff Borrows 1000e18 cBAT) 1.5e18 -- 0.0015 * -1000e18 = -1.5e18 - EnterMarkets Geoff cOMG + Assert Equal (Comptroller Hypothetical Geoff Redeems 1000e9 slZRX) 2.2e18 -- 0.4 * 0.002 * -1000e18 = -0.8e18 + Assert Equal (Comptroller Hypothetical Geoff Borrows 1000e18 slZRX) 1e18 -- 0.002 * -1000e18 = -2e18 + Assert Equal (Comptroller Hypothetical Geoff Redeems 2e9 slETH) 1.4e18 -- 0.8 * 1.0 * -2e18 = -1.6e18 + Assert Equal (Comptroller Hypothetical Geoff Borrows 2e18 slETH) 1.0e18 -- 1.0 * -2e18 = -2e18 + EnterMarkets Geoff slBAT + Assert Equal (Comptroller Hypothetical Geoff Redeems 1000e9 slBAT) 2.55e18 -- 0.3 * 0.0015 * -1000e18 = -0.45e18e18 + Assert Equal (Comptroller Hypothetical Geoff Borrows 1000e18 slBAT) 1.5e18 -- 0.0015 * -1000e18 = -1.5e18 + EnterMarkets Geoff slOMG -- Fails if the given asset doesn't have a price - Assert ReadError (Comptroller Hypothetical Geoff Redeems 1e20 cOMG) "Failed to compute account hypothetical liquidity: error code = 13" - Assert ReadError (Comptroller Hypothetical Geoff Borrows 1e20 cOMG) "Failed to compute account hypothetical liquidity: error code = 13" - PriceOracle SetPrice cOMG 0.01 + Assert ReadError (Comptroller Hypothetical Geoff Redeems 1e20 slOMG) "Failed to compute account hypothetical liquidity: error code = 13" + Assert ReadError (Comptroller Hypothetical Geoff Borrows 1e20 slOMG) "Failed to compute account hypothetical liquidity: error code = 13" + PriceOracle SetPrice slOMG 0.01 -- Has a price and now is listed - Assert Equal (Comptroller Hypothetical Geoff Redeems 100e9 cOMG) 3.0e18 -- No collateral factor - Assert Equal (Comptroller Hypothetical Geoff Borrows 100e18 cOMG) 2.0e18 -- 0.01 * -100e18 = -1e18 + Assert Equal (Comptroller Hypothetical Geoff Redeems 100e9 slOMG) 3.0e18 -- No collateral factor + Assert Equal (Comptroller Hypothetical Geoff Borrows 100e18 slOMG) 2.0e18 -- 0.01 * -100e18 = -1e18 -- For a token has no price and isn't listed -- Note: we can't actually enter the unlisted market without some harness function -- we could consider testing this, but it would be out of the scope of scenarios - Assert Equal (Comptroller Hypothetical Geoff Redeems 100e18 cREP) 3.0e18 -- No effect - Assert Equal (Comptroller Hypothetical Geoff Borrows 100e18 cREP) 3.0e18 -- No effect + Assert Equal (Comptroller Hypothetical Geoff Redeems 100e18 slREP) 3.0e18 -- No effect + Assert Equal (Comptroller Hypothetical Geoff Borrows 100e18 slREP) 3.0e18 -- No effect diff --git a/spec/scenario/InKindLiquidation.scen b/spec/scenario/InKindLiquidation.scen index 20dfac5f1..a1f7be88b 100644 --- a/spec/scenario/InKindLiquidation.scen +++ b/spec/scenario/InKindLiquidation.scen @@ -2,24 +2,24 @@ Macro InKindBorrow borrowAmount borrowRate user=Geoff borrowPrice=1.0 mintAmount=100e18 giveAmount=0e18 borrowTokenType=Standard PricedComptroller Comptroller LiquidationIncentive 1.1 - NewCToken BAT cBAT borrowRate 2e9 8 borrowTokenType -- note: cannot use macros with named args right now - Give cBAT giveAmount BAT -- Faucet some bat - PriceOracle SetPrice cBAT borrowPrice - Support cBAT collateralFactor:0.5 - Prep user mintAmount BAT cBAT - Mint user mintAmount cBAT - EnterMarkets user cBAT - Borrow user borrowAmount cBAT + NewSLToken BAT slBAT borrowRate 2e9 8 borrowTokenType -- note: cannot use macros with named args right now + Give slBAT giveAmount BAT -- Faucet some bat + PriceOracle SetPrice slBAT borrowPrice + Support slBAT collateralFactor:0.5 + Prep user mintAmount BAT slBAT + Mint user mintAmount slBAT + EnterMarkets user slBAT + Borrow user borrowAmount slBAT Test "Insufficient in-kind shortfall" InKindBorrow borrowAmount:1e18 borrowRate:0.000005 - Assert Equal (CToken cBAT BorrowBalance Geoff) 1e18 - Assert Equal (CToken cBAT TotalBorrows) 1e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 1e18 + Assert Equal (SLToken slBAT TotalBorrows) 1e18 Assert Equal (Erc20 BAT TokenBalance Geoff) 1e18 - Assert Equal (Erc20 BAT TokenBalance cBAT) 99e18 + Assert Equal (Erc20 BAT TokenBalance slBAT) 99e18 Assert Equal (Comptroller Liquidity Geoff) 49e18 -- ( ( 1.0 * 100e18 * 0.5 ) - ( 1.0 * 51e18 ) ) / 1e18 -- Prices are 1:1 (in-kind) and collateral factor is 0.5, - -- thus supplying 100e18 cBAT gives the user 50e18 + -- thus supplying 100e18 slBAT gives the user 50e18 -- capacity of BAT. User only borrowed 1BAT, but after -- a lot blocks at a 0.0005% interest rate, he'll be -- underwater. Note: with a reserve rate of zero, that @@ -28,27 +28,27 @@ Test "Insufficient in-kind shortfall" -- Thus, we will need to accumulate for twice as many blocks -- to end up where we'd usually be underwater FastForward 19600000 Blocks -- 1e18 * (1 + 19600000 * 0.000005) - AccrueInterest cBAT -- Note: we have to accrue interest + AccrueInterest slBAT -- Note: we have to accrue interest -- since it's not automatic for liquidity - Assert Equal (CToken cBAT BorrowBalanceStored Geoff) 99e18 - Assert Equal (CToken cBAT TotalBorrows) 99e18 + Assert Equal (SLToken slBAT BorrowBalanceStored Geoff) 99e18 + Assert Equal (SLToken slBAT TotalBorrows) 99e18 -- Check user liquidity and verify equals 0 Assert Equal (Comptroller Liquidity Geoff) 0e18 -- ( ( 1.0 * ( 100e18 + 98e18 ) * 0.5 ) - ( ( 98 + 1 ) * 1e18 ) ) / 1e18 -- At exactly zero, should not be able to liquidate - Prep Torrey 10e18 BAT cBAT + Prep Torrey 10e18 BAT slBAT AllowFailures - Liquidate Torrey "->" Geoff 10e18 cBAT "Seizing" cBAT + Liquidate Torrey "->" Geoff 10e18 slBAT "Seizing" slBAT Assert Failure COMPTROLLER_REJECTION LIQUIDATE_COMPTROLLER_REJECTION INSUFFICIENT_SHORTFALL Test "Cannot self-in-kind-liquidate" InKindBorrow borrowAmount:1e18 borrowRate:0.000005 - Assert Equal (CToken cBAT BorrowBalance Geoff) 1e18 - Assert Equal (CToken cBAT TotalBorrows) 1e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 1e18 + Assert Equal (SLToken slBAT TotalBorrows) 1e18 Assert Equal (Erc20 BAT TokenBalance Geoff) 1e18 - Assert Equal (Erc20 BAT TokenBalance cBAT) 99e18 + Assert Equal (Erc20 BAT TokenBalance slBAT) 99e18 Assert Equal (Comptroller Liquidity Geoff) 49e18 -- ( ( 1.0 * 100e18 * 0.5 ) - ( 1.0 * 51e18 ) ) / 1e18 -- Prices are 1:1 (in-kind) and collateral factor is 0.5, - -- thus supplying 100e18 cBAT gives the user 50e18 + -- thus supplying 100e18 slBAT gives the user 50e18 -- capacity of BAT. User only borrowed 1BAT, but after -- a lot blocks at a 0.0005% interest rate, he'll be -- underwater. Note: with a reserve rate of zero, that @@ -57,27 +57,27 @@ Test "Cannot self-in-kind-liquidate" -- Thus, we will need to accumulate for twice as many blocks -- to end up where we'd usually be underwater FastForward 20000000 Blocks -- 1e18 * (1 + 20000000 * 0.000005) - AccrueInterest cBAT -- Note: we have to accrue interest + AccrueInterest slBAT -- Note: we have to accrue interest -- since it's not automatic for liquidity - Assert Equal (CToken cBAT BorrowBalanceStored Geoff) 101e18 - Assert Equal (CToken cBAT TotalBorrows) 101e18 + Assert Equal (SLToken slBAT BorrowBalanceStored Geoff) 101e18 + Assert Equal (SLToken slBAT TotalBorrows) 101e18 -- Check user liquidity and verify < 0 Assert Equal (Comptroller Liquidity Geoff) -1e18 -- Okay, so we should be able to liquidate, so let's do that. - Prep Geoff 10e18 BAT cBAT + Prep Geoff 10e18 BAT slBAT AllowFailures - Liquidate Geoff "->" Geoff 2e18 cBAT "Seizing" cBAT + Liquidate Geoff "->" Geoff 2e18 slBAT "Seizing" slBAT Assert Failure INVALID_ACCOUNT_PAIR LIQUIDATE_LIQUIDATOR_IS_BORROWER Test "Liqidate in-kind beyond max close" InKindBorrow borrowAmount:1e18 borrowRate:0.000005 - Assert Equal (CToken cBAT BorrowBalance Geoff) 1e18 - Assert Equal (CToken cBAT TotalBorrows) 1e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 1e18 + Assert Equal (SLToken slBAT TotalBorrows) 1e18 Assert Equal (Erc20 BAT TokenBalance Geoff) 1e18 - Assert Equal (Erc20 BAT TokenBalance cBAT) 99e18 + Assert Equal (Erc20 BAT TokenBalance slBAT) 99e18 Assert Equal (Comptroller Liquidity Geoff) 49e18 -- ( ( 1.0 * 100e18 * 0.5 ) - ( 1.0 * 51e18 ) ) / 1e18 -- Prices are 1:1 (in-kind) and collateral factor is 0.5, - -- thus supplying 100e18 cBAT gives the user 50e18 + -- thus supplying 100e18 slBAT gives the user 50e18 -- capacity of BAT. User only borrowed 1BAT, but after -- a lot blocks at a 0.0005% interest rate, he'll be -- underwater. Note: with a reserve rate of zero, that @@ -86,27 +86,27 @@ Test "Liqidate in-kind beyond max close" -- Thus, we will need to accumulate for twice as many blocks -- to end up where we'd usually be underwater FastForward 20000000 Blocks -- 1e18 * (1 + 20000000 * 0.000005) - AccrueInterest cBAT -- Note: we have to accrue interest + AccrueInterest slBAT -- Note: we have to accrue interest -- since it's not automatic for liquidity - Assert Equal (CToken cBAT BorrowBalanceStored Geoff) 101e18 - Assert Equal (CToken cBAT TotalBorrows) 101e18 + Assert Equal (SLToken slBAT BorrowBalanceStored Geoff) 101e18 + Assert Equal (SLToken slBAT TotalBorrows) 101e18 -- Check user liquidity and verify < 0 Assert Equal (Comptroller Liquidity Geoff) -1e18 -- Okay, so we should be able to liquidate, so let's do that. - Prep Torrey 20e18 BAT cBAT + Prep Torrey 20e18 BAT slBAT AllowFailures - Liquidate Torrey "->" Geoff 20e18 cBAT "Seizing" cBAT + Liquidate Torrey "->" Geoff 20e18 slBAT "Seizing" slBAT Assert Failure COMPTROLLER_REJECTION LIQUIDATE_COMPTROLLER_REJECTION TOO_MUCH_REPAY Test "Proper In-Kind Liquidation" InKindBorrow borrowAmount:1e18 borrowRate:0.000005 - Assert Equal (CToken cBAT BorrowBalance Geoff) 1e18 - Assert Equal (CToken cBAT TotalBorrows) 1e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 1e18 + Assert Equal (SLToken slBAT TotalBorrows) 1e18 Assert Equal (Erc20 BAT TokenBalance Geoff) 1e18 - Assert Equal (Erc20 BAT TokenBalance cBAT) 99e18 + Assert Equal (Erc20 BAT TokenBalance slBAT) 99e18 Assert Equal (Comptroller Liquidity Geoff) 49e18 -- ( ( 1.0 * 100e18 * 0.5 ) - ( 1.0 * 1e18 ) ) / 1e18 -- Prices are 1:1 (in-kind) and collateral factor is 0.5, - -- thus supplying 100e18 cBAT gives the user 50e18 + -- thus supplying 100e18 slBAT gives the user 50e18 -- capacity of BAT. User only borrowed 1BAT, but after -- a lot blocks at a 0.0005% interest rate, he'll be -- underwater. Note: with a reserve rate of zero, that @@ -115,37 +115,37 @@ Test "Proper In-Kind Liquidation" -- Thus, we will need to accumulate for twice as many blocks -- to end up where we'd usually be underwater FastForward 20000000 Blocks -- 1e18 * (1 + 20000000 * 0.000005) - AccrueInterest cBAT -- Note: we have to accrue interest + AccrueInterest slBAT -- Note: we have to accrue interest -- since it's not automatic for liquidity - Assert Equal (CToken cBAT BorrowBalanceStored Geoff) 101e18 - Assert Equal (CToken cBAT TotalBorrows) 101e18 + Assert Equal (SLToken slBAT BorrowBalanceStored Geoff) 101e18 + Assert Equal (SLToken slBAT TotalBorrows) 101e18 -- Check user liquidity and verify < 0 Assert Equal (Comptroller Liquidity Geoff) -1e18 -- ( ( 1.0 * ( 100e18 + 100e18 ) * 0.5 ) - ( 101 * 1e18 ) ) / 1e18 -- Okay, so we should be able to liquidate, so let's do that. - Prep Torrey 2e18 BAT cBAT + Prep Torrey 2e18 BAT slBAT -- -- Let's check how values start before liquidation -- Note: we're going to be some-what exhausive in what we check Invariant Remains (Erc20 BAT TokenBalance Geoff) 1e18 -- all was minted, this is what was borrowed Assert Equal (Erc20 BAT TokenBalance Torrey) 2e18 -- from prep above - Assert Equal (Erc20 BAT TokenBalance cBAT) 99e18 -- from minting minus 1e18 lent to geoff - Assert Equal (Erc20 cBAT TokenBalance Geoff) 50e9 -- from minting - Assert Equal (Erc20 cBAT TokenBalance Torrey) 0e9 -- never had any + Assert Equal (Erc20 BAT TokenBalance slBAT) 99e18 -- from minting minus 1e18 lent to geoff + Assert Equal (Erc20 slBAT TokenBalance Geoff) 50e9 -- from minting + Assert Equal (Erc20 slBAT TokenBalance Torrey) 0e9 -- never had any Invariant Remains (Erc20 BAT TokenBalance Geoff) 1e18 -- original amount borrowed - Assert Equal (CToken cBAT BorrowBalanceStored Geoff) 101e18 -- all that interest - Assert Equal (CToken cBAT TotalBorrows) 101e18 -- all those borrowers - Assert Equal (CToken cBAT ExchangeRate) 4e9 --- XXX: Verify this + Assert Equal (SLToken slBAT BorrowBalanceStored Geoff) 101e18 -- all that interest + Assert Equal (SLToken slBAT TotalBorrows) 101e18 -- all those borrowers + Assert Equal (SLToken slBAT ExchangeRate) 4e9 --- XXX: Verify this -- Do the liquidation - Liquidate Torrey "->" Geoff 2e18 cBAT "Seizing" cBAT -- should now take twice as much collateral + Liquidate Torrey "->" Geoff 2e18 slBAT "Seizing" slBAT -- should now take twice as much collateral -- -- And see what they are now - Assert Equal (CToken cBAT ExchangeRate) 4e9 --- XXX: Verify this - Assert Equal (Erc20 cBAT TokenBalance Geoff) 49.45e9 -- 1:1 -> 1 x 2e18 x 1.1 ÷ 4e9 [exchange rate] = 0.55e9 -> Torrey - Assert Equal (Erc20 cBAT TokenBalance Torrey) 0.55e9 -- didn't have any beforehand + Assert Equal (SLToken slBAT ExchangeRate) 4e9 --- XXX: Verify this + Assert Equal (Erc20 slBAT TokenBalance Geoff) 49.45e9 -- 1:1 -> 1 x 2e18 x 1.1 ÷ 4e9 [exchange rate] = 0.55e9 -> Torrey + Assert Equal (Erc20 slBAT TokenBalance Torrey) 0.55e9 -- didn't have any beforehand Assert Equal (Erc20 BAT TokenBalance Torrey) 0e18 -- repaid - Assert Equal (Erc20 BAT TokenBalance cBAT) 101e18 -- had 100e18, lent 1e18 to geoff, repaid 2 - Assert Equal (CToken cBAT BorrowBalanceStored Geoff) 99e18 -- less closed amount - Assert Equal (CToken cBAT TotalBorrows) 99e18 -- + Assert Equal (Erc20 BAT TokenBalance slBAT) 101e18 -- had 100e18, lent 1e18 to geoff, repaid 2 + Assert Equal (SLToken slBAT BorrowBalanceStored Geoff) 99e18 -- less closed amount + Assert Equal (SLToken slBAT TotalBorrows) 99e18 -- -- Prices are 1:1 and collateral factor is 0.5 -- User now has 49.45e9 outstanding supply (yielding 98.9 borrowing capacity due -- to the collateral factor (0.5) and exchange rate (4e9)). @@ -155,13 +155,13 @@ Test "Proper In-Kind Liquidation" Test "Liquidate exactly zero" InKindBorrow borrowAmount:1e18 borrowRate:0.000005 - Assert Equal (CToken cBAT BorrowBalance Geoff) 1e18 - Assert Equal (CToken cBAT TotalBorrows) 1e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 1e18 + Assert Equal (SLToken slBAT TotalBorrows) 1e18 Assert Equal (Erc20 BAT TokenBalance Geoff) 1e18 - Assert Equal (Erc20 BAT TokenBalance cBAT) 99e18 + Assert Equal (Erc20 BAT TokenBalance slBAT) 99e18 Assert Equal (Comptroller Liquidity Geoff) 49e18 -- ( ( 1.0 * 100e18 * 0.5 ) - ( 1.0 * 1e18 ) ) / 1e18 -- Prices are 1:1 (in-kind) and collateral factor is 0.5, - -- thus supplying 100e18 cBAT gives the user 50e18 + -- thus supplying 100e18 slBAT gives the user 50e18 -- capacity of BAT. User only borrowed 1BAT, but after -- a lot blocks at a 0.0005% interest rate, he'll be -- underwater. Note: with a reserve rate of zero, that @@ -170,27 +170,27 @@ Test "Liquidate exactly zero" -- Thus, we will need to accumulate for twice as many blocks -- to end up where we'd usually be underwater FastForward 20000000 Blocks -- 1e18 * (1 + 20000000 * 0.000005) - AccrueInterest cBAT -- Note: we have to accrue interest + AccrueInterest slBAT -- Note: we have to accrue interest -- since it's not automatic for liquidity - Invariant Remains (CToken cBAT BorrowBalanceStored Geoff) 101e18 - Invariant Remains (CToken cBAT TotalBorrows) 101e18 + Invariant Remains (SLToken slBAT BorrowBalanceStored Geoff) 101e18 + Invariant Remains (SLToken slBAT TotalBorrows) 101e18 -- Check user liquidity and verify < 0 Invariant Remains (Comptroller Liquidity Geoff) -1e18 -- Okay, so we should be able to liquidate, so let's do that. - Prep Torrey 10e18 BAT cBAT + Prep Torrey 10e18 BAT slBAT AllowFailures - Liquidate Torrey "->" Geoff 0e18 cBAT "Seizing" cBAT + Liquidate Torrey "->" Geoff 0e18 slBAT "Seizing" slBAT Assert Failure INVALID_CLOSE_AMOUNT_REQUESTED LIQUIDATE_CLOSE_AMOUNT_IS_ZERO Test "When price oracle for collateral token is zero" InKindBorrow borrowAmount:1e18 borrowRate:0.000005 - Assert Equal (CToken cBAT BorrowBalance Geoff) 1e18 - Assert Equal (CToken cBAT TotalBorrows) 1e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 1e18 + Assert Equal (SLToken slBAT TotalBorrows) 1e18 Assert Equal (Erc20 BAT TokenBalance Geoff) 1e18 - Assert Equal (Erc20 BAT TokenBalance cBAT) 99e18 + Assert Equal (Erc20 BAT TokenBalance slBAT) 99e18 Assert Equal (Comptroller Liquidity Geoff) 49e18 -- ( ( 1.0 * 100e18 * 0.5 ) - ( 1.0 * 1e18 ) ) / 1e18 -- Prices are 1:1 (in-kind) and collateral factor is 0.5, - -- thus supplying 100e18 cBAT gives the user 50e18 + -- thus supplying 100e18 slBAT gives the user 50e18 -- capacity of BAT. User only borrowed 1BAT, but after -- a lot blocks at a 0.0005% interest rate, he'll be -- underwater. Note: with a reserve rate of zero, that @@ -199,28 +199,28 @@ Test "When price oracle for collateral token is zero" -- Thus, we will need to accumulate for twice as many blocks -- to end up where we'd usually be underwater FastForward 20000000 Blocks -- 1e18 * (1 + 20000000 * 0.000005) - AccrueInterest cBAT -- Note: we have to accrue interest + AccrueInterest slBAT -- Note: we have to accrue interest -- since it's not automatic for liquidity - Invariant Remains (CToken cBAT BorrowBalanceStored Geoff) 101e18 - Invariant Remains (CToken cBAT TotalBorrows) 101e18 + Invariant Remains (SLToken slBAT BorrowBalanceStored Geoff) 101e18 + Invariant Remains (SLToken slBAT TotalBorrows) 101e18 -- Check user liquidity and verify < 0 Assert Equal (Comptroller Liquidity Geoff) -1e18 -- Okay, so we should be able to liquidate, so let's do that. - Prep Torrey 10e18 BAT cBAT - PriceOracle SetPrice cBAT 0 + Prep Torrey 10e18 BAT slBAT + PriceOracle SetPrice slBAT 0 AllowFailures - Liquidate Torrey "->" Geoff 2e18 cBAT "Seizing" cBAT + Liquidate Torrey "->" Geoff 2e18 slBAT "Seizing" slBAT Assert Failure COMPTROLLER_REJECTION LIQUIDATE_COMPTROLLER_REJECTION PRICE_ERROR Test "When price oracle for collateral token is whack" InKindBorrow borrowAmount:1e18 borrowRate:0.000005 - Assert Equal (CToken cBAT BorrowBalance Geoff) 1e18 - Assert Equal (CToken cBAT TotalBorrows) 1e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 1e18 + Assert Equal (SLToken slBAT TotalBorrows) 1e18 Assert Equal (Erc20 BAT TokenBalance Geoff) 1e18 - Assert Equal (Erc20 BAT TokenBalance cBAT) 99e18 + Assert Equal (Erc20 BAT TokenBalance slBAT) 99e18 Assert Equal (Comptroller Liquidity Geoff) 49e18 -- ( ( 1.0 * 100e18 * 0.5 ) - ( 1.0 * 1e18 ) ) / 1e18 -- Prices are 1:1 (in-kind) and collateral factor is 0.5, - -- thus supplying 100e18 cBAT gives the user 50e18 + -- thus supplying 100e18 slBAT gives the user 50e18 -- capacity of BAT. User only borrowed 1BAT, but after -- a lot blocks at a 0.0005% interest rate, he'll be -- underwater. Note: with a reserve rate of zero, that @@ -229,28 +229,28 @@ Test "When price oracle for collateral token is whack" -- Thus, we will need to accumulate for twice as many blocks -- to end up where we'd usually be underwater FastForward 20000000 Blocks -- 1e18 * (1 + 20000000 * 0.000005) - AccrueInterest cBAT -- Note: we have to accrue interest + AccrueInterest slBAT -- Note: we have to accrue interest -- since it's not automatic for liquidity - Invariant Remains (CToken cBAT BorrowBalanceStored Geoff) 101e18 - Invariant Remains (CToken cBAT TotalBorrows) 101e18 + Invariant Remains (SLToken slBAT BorrowBalanceStored Geoff) 101e18 + Invariant Remains (SLToken slBAT TotalBorrows) 101e18 -- Check user liquidity and verify < 0 Assert Equal (Comptroller Liquidity Geoff) -1e18 -- Okay, so we should be able to liquidate, so let's do that. - Prep Torrey 10e18 BAT cBAT - PriceOracle SetPrice cBAT UInt256Max + Prep Torrey 10e18 BAT slBAT + PriceOracle SetPrice slBAT UInt256Max AllowFailures - Liquidate Torrey "->" Geoff 2e18 cBAT "Seizing" cBAT + Liquidate Torrey "->" Geoff 2e18 slBAT "Seizing" slBAT Assert Failure COMPTROLLER_REJECTION LIQUIDATE_COMPTROLLER_REJECTION MATH_ERROR Test "When repay borrow fails" InKindBorrow borrowAmount:1e18 borrowRate:0.000005 - Assert Equal (CToken cBAT BorrowBalance Geoff) 1e18 - Assert Equal (CToken cBAT TotalBorrows) 1e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 1e18 + Assert Equal (SLToken slBAT TotalBorrows) 1e18 Assert Equal (Erc20 BAT TokenBalance Geoff) 1e18 - Assert Equal (Erc20 BAT TokenBalance cBAT) 99e18 + Assert Equal (Erc20 BAT TokenBalance slBAT) 99e18 Assert Equal (Comptroller Liquidity Geoff) 49e18 -- ( ( 1.0 * 100e18 * 0.5 ) - ( 1.0 * 1e18 ) ) / 1e18 -- Prices are 1:1 (in-kind) and collateral factor is 0.5, - -- thus supplying 100e18 cBAT gives the user 50e18 + -- thus supplying 100e18 slBAT gives the user 50e18 -- capacity of BAT. User only borrowed 1BAT, but after -- a lot blocks at a 0.0005% interest rate, he'll be -- underwater. Note: with a reserve rate of zero, that @@ -259,27 +259,27 @@ Test "When repay borrow fails" -- Thus, we will need to accumulate for twice as many blocks -- to end up where we'd usually be underwater FastForward 20000000 Blocks -- 1e18 * (1 + 20000000 * 0.000005) - AccrueInterest cBAT -- Note: we have to accrue interest + AccrueInterest slBAT -- Note: we have to accrue interest -- since it's not automatic for liquidity - Invariant Remains (CToken cBAT BorrowBalanceStored Geoff) 101e18 - Invariant Remains (CToken cBAT TotalBorrows) 101e18 + Invariant Remains (SLToken slBAT BorrowBalanceStored Geoff) 101e18 + Invariant Remains (SLToken slBAT TotalBorrows) 101e18 -- Check user liquidity and verify < 0 Invariant Remains (Comptroller Liquidity Geoff) -1e18 -- Okay, so we should be able to liquidate, so let's do that. - Prep Torrey 10e18 BAT cBAT allowanceAmount:0.1e18 + Prep Torrey 10e18 BAT slBAT allowanceAmount:0.1e18 AllowFailures - Liquidate Torrey "->" Geoff 2e18 cBAT "Seizing" cBAT + Liquidate Torrey "->" Geoff 2e18 slBAT "Seizing" slBAT Assert Revert "revert Insufficient allowance" Test "Proper liquidation of paused WBTC as collateral" InKindBorrow borrowAmount:1e18 borrowRate:0.000005 borrowTokenType:WBTC - Assert Equal (CToken cBAT BorrowBalance Geoff) 1e18 - Assert Equal (CToken cBAT TotalBorrows) 1e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 1e18 + Assert Equal (SLToken slBAT TotalBorrows) 1e18 Assert Equal (Erc20 BAT TokenBalance Geoff) 1e18 - Assert Equal (Erc20 BAT TokenBalance cBAT) 99e18 + Assert Equal (Erc20 BAT TokenBalance slBAT) 99e18 Assert Equal (Comptroller Liquidity Geoff) 49e18 -- ( ( 1.0 * 100e18 * 0.5 ) - ( 1.0 * 1e18 ) ) / 1e18 -- Prices are 1:1 (in-kind) and collateral factor is 0.5, - -- thus supplying 100e18 cBAT gives the user 50e18 + -- thus supplying 100e18 slBAT gives the user 50e18 -- capacity of BAT. User only borrowed 1BAT, but after -- a lot blocks at a 0.0005% interest rate, he'll be -- underwater. Note: with a reserve rate of zero, that @@ -288,43 +288,43 @@ Test "Proper liquidation of paused WBTC as collateral" -- Thus, we will need to accumulate for twice as many blocks -- to end up where we'd usually be underwater FastForward 20000000 Blocks -- 1e18 * (1 + 20000000 * 0.000005) - AccrueInterest cBAT -- Note: we have to accrue interest + AccrueInterest slBAT -- Note: we have to accrue interest -- since it's not automatic for liquidity - Assert Equal (CToken cBAT BorrowBalanceStored Geoff) 101e18 - Assert Equal (CToken cBAT TotalBorrows) 101e18 + Assert Equal (SLToken slBAT BorrowBalanceStored Geoff) 101e18 + Assert Equal (SLToken slBAT TotalBorrows) 101e18 -- Check user liquidity and verify < 0 Assert Equal (Comptroller Liquidity Geoff) -1e18 -- recheck -- Okay, so we should be able to liquidate, so let's do that. - Prep Torrey 2e18 BAT cBAT + Prep Torrey 2e18 BAT slBAT -- -- Let's check how values start before liquidation -- Note: we're going to be some-what exhausive in what we check Invariant Remains (Erc20 BAT TokenBalance Geoff) 1e18 -- all was minted, this is what was borrowed Assert Equal (Erc20 BAT TokenBalance Torrey) 2e18 -- from prep above - Assert Equal (Erc20 BAT TokenBalance cBAT) 99e18 -- from minting minus 1e18 lent to geoff - Assert Equal (Erc20 cBAT TokenBalance Geoff) 50e9 -- from minting - Assert Equal (Erc20 cBAT TokenBalance Torrey) 0e9 -- never had any + Assert Equal (Erc20 BAT TokenBalance slBAT) 99e18 -- from minting minus 1e18 lent to geoff + Assert Equal (Erc20 slBAT TokenBalance Geoff) 50e9 -- from minting + Assert Equal (Erc20 slBAT TokenBalance Torrey) 0e9 -- never had any Invariant Remains (Erc20 BAT TokenBalance Geoff) 1e18 -- original amount borrowed - Assert Equal (CToken cBAT BorrowBalanceStored Geoff) 101e18 -- all that interest - Assert Equal (CToken cBAT TotalBorrows) 101e18 -- all those borrowers - Assert Equal (CToken cBAT ExchangeRate) 4e9 --- XXX: Verify this + Assert Equal (SLToken slBAT BorrowBalanceStored Geoff) 101e18 -- all that interest + Assert Equal (SLToken slBAT TotalBorrows) 101e18 -- all those borrowers + Assert Equal (SLToken slBAT ExchangeRate) 4e9 --- XXX: Verify this -- -- Pause "WBTC" Erc20 BAT Pause -- Actually a WBTC token -- Do the liquidation AllowFailures - Liquidate Torrey "->" Geoff 2e18 cBAT "Seizing" cBAT -- should now take twice as much collateral + Liquidate Torrey "->" Geoff 2e18 slBAT "Seizing" slBAT -- should now take twice as much collateral Assert Revert -- Reverts since we can't transfer the BAT in due to pause Test "When seize not allowed due to unlisted collateral" InKindBorrow borrowAmount:1e18 borrowRate:0.000005 - Assert Equal (CToken cBAT BorrowBalance Geoff) 1e18 - Assert Equal (CToken cBAT TotalBorrows) 1e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 1e18 + Assert Equal (SLToken slBAT TotalBorrows) 1e18 Assert Equal (Erc20 BAT TokenBalance Geoff) 1e18 - Assert Equal (Erc20 BAT TokenBalance cBAT) 99e18 + Assert Equal (Erc20 BAT TokenBalance slBAT) 99e18 Assert Equal (Comptroller Liquidity Geoff) 49e18 -- ( ( 1.0 * 100e18 * 0.5 ) - ( 1.0 * 1e18 ) ) / 1e18 -- Prices are 1:1 (in-kind) and collateral factor is 0.5, - -- thus supplying 100e18 cBAT gives the user 50e18 + -- thus supplying 100e18 slBAT gives the user 50e18 -- capacity of BAT. User only borrowed 1BAT, but after -- a lot blocks at a 0.0005% interest rate, he'll be -- underwater. Note: with a reserve rate of zero, that @@ -333,26 +333,26 @@ Test "When seize not allowed due to unlisted collateral" -- Thus, we will need to accumulate for twice as many blocks -- to end up where we'd usually be underwater FastForward 20000000 Blocks -- 1e18 * (1 + 20000000 * 0.000005) - AccrueInterest cBAT -- Note: we have to accrue interest + AccrueInterest slBAT -- Note: we have to accrue interest -- since it's not automatic for liquidity - Invariant Remains (CToken cBAT BorrowBalanceStored Geoff) 101e18 - Invariant Remains (CToken cBAT TotalBorrows) 101e18 + Invariant Remains (SLToken slBAT BorrowBalanceStored Geoff) 101e18 + Invariant Remains (SLToken slBAT TotalBorrows) 101e18 -- Okay, so we should be able to liquidate, so let's do that. - Prep Torrey 10e18 BAT cBAT - Comptroller UnList cBAT -- Mock unlist collateral + Prep Torrey 10e18 BAT slBAT + Comptroller UnList slBAT -- Mock unlist collateral AllowFailures - Liquidate Torrey "->" Geoff 2e18 cBAT "Seizing" cBAT + Liquidate Torrey "->" Geoff 2e18 slBAT "Seizing" slBAT Assert Failure COMPTROLLER_REJECTION LIQUIDATE_COMPTROLLER_REJECTION MARKET_NOT_LISTED Test "When seize not allowed due to unlisted borrow" InKindBorrow borrowAmount:1e18 borrowRate:0.000005 - Assert Equal (CToken cBAT BorrowBalance Geoff) 1e18 - Assert Equal (CToken cBAT TotalBorrows) 1e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 1e18 + Assert Equal (SLToken slBAT TotalBorrows) 1e18 Assert Equal (Erc20 BAT TokenBalance Geoff) 1e18 - Assert Equal (Erc20 BAT TokenBalance cBAT) 99e18 + Assert Equal (Erc20 BAT TokenBalance slBAT) 99e18 Assert Equal (Comptroller Liquidity Geoff) 49e18 -- ( ( 1.0 * 100e18 * 0.5 ) - ( 1.0 * 1e18 ) ) / 1e18 -- Prices are 1:1 (in-kind) and collateral factor is 0.5, - -- thus supplying 100e18 cBAT gives the user 50e18 + -- thus supplying 100e18 slBAT gives the user 50e18 -- capacity of BAT. User only borrowed 1BAT, but after -- a lot blocks at a 0.0005% interest rate, he'll be -- underwater. Note: with a reserve rate of zero, that @@ -361,28 +361,28 @@ Test "When seize not allowed due to unlisted borrow" -- Thus, we will need to accumulate for twice as many blocks -- to end up where we'd usually be underwater FastForward 20000000 Blocks -- 1e18 * (1 + 20000000 * 0.000005) - AccrueInterest cBAT -- Note: we have to accrue interest + AccrueInterest slBAT -- Note: we have to accrue interest -- since it's not automatic for liquidity - Invariant Remains (CToken cBAT BorrowBalanceStored Geoff) 101e18 - Invariant Remains (CToken cBAT TotalBorrows) 101e18 + Invariant Remains (SLToken slBAT BorrowBalanceStored Geoff) 101e18 + Invariant Remains (SLToken slBAT TotalBorrows) 101e18 -- Okay, so we should be able to liquidate, so let's do that. - Prep Torrey 10e18 BAT cBAT - Comptroller UnList cBAT -- Mock unlist borrow + Prep Torrey 10e18 BAT slBAT + Comptroller UnList slBAT -- Mock unlist borrow AllowFailures - Liquidate Torrey "->" Geoff 2e18 cBAT "Seizing" cBAT + Liquidate Torrey "->" Geoff 2e18 slBAT "Seizing" slBAT Assert Failure COMPTROLLER_REJECTION LIQUIDATE_COMPTROLLER_REJECTION MARKET_NOT_LISTED Test "When there's insufficient collateral" InKindBorrow borrowAmount:1e18 borrowRate:0.000005 Comptroller SetCloseFactor 0.9 Comptroller LiquidationIncentive 1.5 - Assert Equal (CToken cBAT BorrowBalance Geoff) 1e18 - Assert Equal (CToken cBAT TotalBorrows) 1e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 1e18 + Assert Equal (SLToken slBAT TotalBorrows) 1e18 Assert Equal (Erc20 BAT TokenBalance Geoff) 1e18 - Assert Equal (Erc20 BAT TokenBalance cBAT) 99e18 + Assert Equal (Erc20 BAT TokenBalance slBAT) 99e18 Assert Equal (Comptroller Liquidity Geoff) 49e18 -- ( ( 1.0 * 100e18 * 0.5 ) - ( 1.0 * 1e18 ) ) / 1e18 -- Prices are 1:1 (in-kind) and collateral factor is 0.5, - -- thus supplying 100e18 cBAT gives the user 50e18 + -- thus supplying 100e18 slBAT gives the user 50e18 -- capacity of BAT. User only borrowed 1BAT, but after -- a lot blocks at a 0.0005% interest rate, he'll be -- underwater. Note: with a reserve rate of zero, that @@ -391,28 +391,28 @@ Test "When there's insufficient collateral" -- Thus, we will need to accumulate for twice as many blocks -- to end up where we'd usually be underwater FastForward 200000000 Blocks -- 1e18 * (1 + 200000000 * 0.000005) - AccrueInterest cBAT -- Note: we have to accrue interest + AccrueInterest slBAT -- Note: we have to accrue interest -- since it's not automatic for liquidity - Invariant Remains (CToken cBAT BorrowBalanceStored Geoff) 1001e18 - Invariant Remains (CToken cBAT TotalBorrows) 1001e18 - Comptroller SetCollateralFactor cBAT 0 + Invariant Remains (SLToken slBAT BorrowBalanceStored Geoff) 1001e18 + Invariant Remains (SLToken slBAT TotalBorrows) 1001e18 + Comptroller SetCollateralFactor slBAT 0 -- Check user liquidity and verify < 0 Invariant Remains (Comptroller Liquidity Geoff) -1001e18 -- Okay, so we should be able to liquidate, so let's do that. - Prep Torrey 900e18 BAT cBAT + Prep Torrey 900e18 BAT slBAT AllowFailures - Liquidate Torrey "->" Geoff 900e18 cBAT "Seizing" cBAT + Liquidate Torrey "->" Geoff 900e18 slBAT "Seizing" slBAT Assert Revert "revert LIQUIDATE_SEIZE_TOO_MUCH" Test "when seize is paused" InKindBorrow borrowAmount:1e18 borrowRate:0.000005 - Assert Equal (CToken cBAT BorrowBalance Geoff) 1e18 - Assert Equal (CToken cBAT TotalBorrows) 1e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 1e18 + Assert Equal (SLToken slBAT TotalBorrows) 1e18 Assert Equal (Erc20 BAT TokenBalance Geoff) 1e18 - Assert Equal (Erc20 BAT TokenBalance cBAT) 99e18 + Assert Equal (Erc20 BAT TokenBalance slBAT) 99e18 Assert Equal (Comptroller Liquidity Geoff) 49e18 -- ( ( 1.0 * 100e18 * 0.5 ) - ( 1.0 * 1e18 ) ) / 1e18 -- Prices are 1:1 (in-kind) and collateral factor is 0.5, - -- thus supplying 100e18 cBAT gives the user 50e18 + -- thus supplying 100e18 slBAT gives the user 50e18 -- capacity of BAT. User only borrowed 1BAT, but after -- a lot blocks at a 0.0005% interest rate, he'll be -- underwater. Note: with a reserve rate of zero, that @@ -421,20 +421,20 @@ Test "when seize is paused" -- Thus, we will need to accumulate for twice as many blocks -- to end up where we'd usually be underwater FastForward 20000000 Blocks -- 1e18 * (1 + 20000000 * 0.000005) - AccrueInterest cBAT -- Note: we have to accrue interest + AccrueInterest slBAT -- Note: we have to accrue interest -- since it's not automatic for liquidity - Assert Equal (CToken cBAT BorrowBalanceStored Geoff) 101e18 - Assert Equal (CToken cBAT TotalBorrows) 101e18 + Assert Equal (SLToken slBAT BorrowBalanceStored Geoff) 101e18 + Assert Equal (SLToken slBAT TotalBorrows) 101e18 -- Check user liquidity and verify < 0 Assert Equal (Comptroller Liquidity Geoff) -1e18 -- Okay, so we should be able to liquidate, so let's do that. - Prep Torrey 2e18 BAT cBAT + Prep Torrey 2e18 BAT slBAT Comptroller SetPauseGuardian Coburn From Coburn (Comptroller SetGuardianPaused "Seize" True) AllowFailures - Liquidate Torrey "->" Geoff 2e18 cBAT "Seizing" cBAT + Liquidate Torrey "->" Geoff 2e18 slBAT "Seizing" slBAT Assert Revert "revert seize is paused" -- unpause and check correct values Invariant Success Comptroller SetGuardianPaused "Seize" False - Liquidate Torrey "->" Geoff 2e18 cBAT "Seizing" cBAT + Liquidate Torrey "->" Geoff 2e18 slBAT "Seizing" slBAT diff --git a/spec/scenario/MCDai.scen b/spec/scenario/MCDai.scen index 2a97cb535..df1bbf6ec 100644 --- a/spec/scenario/MCDai.scen +++ b/spec/scenario/MCDai.scen @@ -3,166 +3,166 @@ Macro ForkMCD -- Uses MakerDAO 0.2.16 Release https://changelog.makerdao.com/releases/kovan/0.2.16/index.html - Alias CTokenAdmin "0x9C1856636d78C051deAd6CAB9c5699e4E25549e9" + Alias SLTokenAdmin "0x9C1856636d78C051deAd6CAB9c5699e4E25549e9" Alias DaiHolder "0x9Bffd1579bd6760a186fFf1A720f2a5dB35dE0f4" Alias DaiAddress "0xc27a24e60a89a03bd2f1ffb4ea59076fd8385fe6" Alias DaiJoinAddress "0x3a3cc501d46b84f310067ef7c5df4ae1f05810ea" Alias PotAddress "0x1c11810b1f8551d543f33a48ba88dcb0e8002b0f" Alias VatAddress "0x2d9fad7795f0658f5931b75845d14250aecc81ee" - Web3Fork "https://kovan.infura.io/v3/e1a5d4d2c06a4e81945fca56d0d5d8ea@14760012" (CTokenAdmin DaiHolder) + Web3Fork "https://kovan.infura.io/v3/e1a5d4d2c06a4e81945fca56d0d5d8ea@14760012" (SLTokenAdmin DaiHolder) Erc20 Deploy Existing DAI DaiAddress DAI - Assert Equal (EtherBalance CTokenAdmin) 1.680448935e18 -- Ensure the fork works as expected + Assert Equal (EtherBalance SLTokenAdmin) 1.680448935e18 -- Ensure the fork works as expected Macro ForkMCD101 -- Uses MakerDAO 1.0.1 Release https://changelog.makerdao.com/releases/kovan/1.0.1/index.html - Alias CTokenAdmin "0xA776184Fd6F545DAe5f51361dBcC9018549a9749" + Alias SLTokenAdmin "0xA776184Fd6F545DAe5f51361dBcC9018549a9749" Alias DaiHolder "0x72776bb917751225d24c07d0663b3780b2ada67c" Alias DaiJoinAddress "0x5aa71a3ae1c0bd6ac27a1f28e1415fffb6f15b8c" Alias PotAddress "0xea190dbdc7adf265260ec4da6e9675fd4f5a78bb" Alias VatAddress "0xba987bdb501d131f766fee8180da5d81b34b69d9" Alias JugAddress "0xcbb7718c9f39d05aeede1c472ca8bf804b2f1ead" - Web3Fork "https://kovan.infura.io/v3/e1a5d4d2c06a4e81945fca56d0d5d8ea@15090204" (CTokenAdmin DaiHolder) + Web3Fork "https://kovan.infura.io/v3/e1a5d4d2c06a4e81945fca56d0d5d8ea@15090204" (SLTokenAdmin DaiHolder) -Macro DeployCDAIWithDSR +Macro DeploySLDAIWithDSR ForkMCD NewComptroller InterestRateModel Deploy Fixed StdInterest 0.000005 - CTokenDelegate Deploy CDaiDelegate cDaiDelegate - From CTokenAdmin (CToken Deploy CErc20Delegator cDAI cDAI (Erc20 DAI Address) (Comptroller Address) (InterestRateModel StdInterest Address) 1e9 8 CTokenAdmin (CTokenDelegate cDaiDelegate Address) (EncodeParameters ("address" "address") (DaiJoinAddress PotAddress))) - Comptroller SupportMarket cDAI + SLTokenDelegate Deploy SLDaiDelegate slDaiDelegate + From SLTokenAdmin (SLToken Deploy CErc20Delegator slDAI slDAI (Erc20 DAI Address) (Comptroller Address) (InterestRateModel StdInterest Address) 1e9 8 SLTokenAdmin (SLTokenDelegate slDaiDelegate Address) (EncodeParameters ("address" "address") (DaiJoinAddress PotAddress))) + Comptroller SupportMarket slDAI -Macro DeployCDAI +Macro DeploySLDAI ForkMCD NewComptroller InterestRateModel Deploy Fixed StdInterest 0.000005 - CTokenDelegate Deploy CErc20Delegate cErc20Delegate - From CTokenAdmin (CToken Deploy CErc20Delegator cDAI cDAI (Erc20 DAI Address) (Comptroller Address) (InterestRateModel StdInterest Address) 1e9 8 CTokenAdmin (CTokenDelegate cErc20Delegate Address) "0x0") - Comptroller SupportMarket cDAI + SLTokenDelegate Deploy SLErc20Delegate slErc20Delegate + From SLTokenAdmin (SLToken Deploy CErc20Delegator slDAI slDAI (Erc20 DAI Address) (Comptroller Address) (InterestRateModel StdInterest Address) 1e9 8 SLTokenAdmin (SLTokenDelegate slErc20Delegate Address) "0x0") + Comptroller SupportMarket slDAI Macro UpgradeToDSR - CTokenDelegate Deploy CDaiDelegate cDaiDelegate - From CTokenAdmin (CToken cDAI SetImplementation (CTokenDelegate cDaiDelegate Address) True (EncodeParameters ("address" "address") (DaiJoinAddress PotAddress))) + SLTokenDelegate Deploy SLDaiDelegate slDaiDelegate + From SLTokenAdmin (SLToken slDAI SetImplementation (SLTokenDelegate slDaiDelegate Address) True (EncodeParameters ("address" "address") (DaiJoinAddress PotAddress))) Macro CheckBasicMintRedeem From DaiHolder (Erc20 DAI Transfer Jared 2e18) - From Jared (Erc20 DAI Approve (CToken cDAI Address) 2e18) - Mint Jared 1e18 cDAI - Assert Equal (Erc20 cDAI TokenBalance Jared) (Exactly 1e9) - Expect Changes (Erc20 cDAI TokenBalance Jared) -1e9 - Redeem Jared 1e9 cDAI + From Jared (Erc20 DAI Approve (SLToken slDAI Address) 2e18) + Mint Jared 1e18 slDAI + Assert Equal (Erc20 slDAI TokenBalance Jared) (Exactly 1e9) + Expect Changes (Erc20 slDAI TokenBalance Jared) -1e9 + Redeem Jared 1e9 slDAI Macro CheckBasicMintRedeemWithDSR -- Note: we cannot tightly control time for evm calls in ganache, so we approximate time-based values - -- Approve and mint cDAI from DAI - From DaiHolder (Erc20 DAI Approve (CToken cDAI Address) 1e30) - Mint DaiHolder 1e18 cDAI - Assert Equal (Erc20 cDAI TokenBalance DaiHolder) (Exactly 1e9) + -- Approve and mint slDAI from DAI + From DaiHolder (Erc20 DAI Approve (SLToken slDAI Address) 1e30) + Mint DaiHolder 1e18 slDAI + Assert Equal (Erc20 slDAI TokenBalance DaiHolder) (Exactly 1e9) -- Sanity check the DSR Assert Equal (MCD PotAt PotAddress "dsr") (Exactly 1000000000627937192491029810) -- Check that the funds are in the pot and not the vat - Assert Approx (MCD PotAt PotAddress "pie" (CToken cDAI Address)) 999784970332262855 -- pot is a wad (1e18), check for ~ 1 DAI - Assert (MCD VatAt VatAddress "dai" (CToken cDAI Address)) LessThan 1e27 -- vat is a rad (1e45), check for ~ dust + Assert Approx (MCD PotAt PotAddress "pie" (SLToken slDAI Address)) 999784970332262855 -- pot is a wad (1e18), check for ~ 1 DAI + Assert (MCD VatAt VatAddress "dai" (SLToken slDAI Address)) LessThan 1e27 -- vat is a rad (1e45), check for ~ dust -- Time passes IncreaseTime 100000 -- Check that holder earns the DSR on 1 DAI after redeeming (1 DAI * (dsr ** seconds)) Expect Changes (Erc20 DAI TokenBalance DaiHolder) 1000006279390070400 0.0001 - Redeem DaiHolder 1e9 cDAI + Redeem DaiHolder 1e9 slDAI -- Check that the funds are not in the pot nor the vat -- Note: we always move a little too much into vat on transfer out, so it might be extra dusty - Assert Equal (MCD PotAt PotAddress "pie" (CToken cDAI Address)) 0 -- pot is a wad (1e18), check for ~ dust - Assert (MCD VatAt VatAddress "dai" (CToken cDAI Address)) LessThan 2e27 -- vat is a rad (1e45), check for ~ dust + Assert Equal (MCD PotAt PotAddress "pie" (SLToken slDAI Address)) 0 -- pot is a wad (1e18), check for ~ dust + Assert (MCD VatAt VatAddress "dai" (SLToken slDAI Address)) LessThan 2e27 -- vat is a rad (1e45), check for ~ dust Macro CheckBasicBorrowRepayWithDSR repayAmount=1000015000000000000 -- Note: we cannot tightly control time for evm calls in ganache, so we approximate time-based values - NewCToken BAT cBAT - Support cBAT collateralFactor:0.5 + NewSLToken BAT slBAT + Support slBAT collateralFactor:0.5 -- Add some DAI to borrow - From DaiHolder (Erc20 DAI Approve (CToken cDAI Address) 1e30) - Mint DaiHolder 1e18 cDAI + From DaiHolder (Erc20 DAI Approve (SLToken slDAI Address) 1e30) + Mint DaiHolder 1e18 slDAI -- Get some collateral and borrow - EnterMarkets Geoff cBAT - Prep Geoff Some BAT cBAT - Mint Geoff 100e18 cBAT + EnterMarkets Geoff slBAT + Prep Geoff Some BAT slBAT + Mint Geoff 100e18 slBAT Expect Changes (Erc20 DAI TokenBalance Geoff) (Exactly 1e18) - Borrow Geoff 1e18 cDAI + Borrow Geoff 1e18 slDAI -- Check that the funds are not in the pot nor the vat -- Note: we always move a little too much into vat on transfer out, so it might be extra dusty - Assert (MCD PotAt PotAddress "pie" (CToken cDAI Address)) LessThan 5e10 -- pot is a wad (1e18), check for ~ dust + DSR - Assert (MCD VatAt VatAddress "dai" (CToken cDAI Address)) LessThan 2e27 -- vat is a rad (1e45), check for ~ dust + Assert (MCD PotAt PotAddress "pie" (SLToken slDAI Address)) LessThan 5e10 -- pot is a wad (1e18), check for ~ dust + DSR + Assert (MCD VatAt VatAddress "dai" (SLToken slDAI Address)) LessThan 2e27 -- vat is a rad (1e45), check for ~ dust -- Repay the principal + interest after 3 blocks (i.e. 3 transactions since) From DaiHolder (Erc20 DAI Transfer Geoff 1e18) - From Geoff (Erc20 DAI Approve (CToken cDAI Address) 1e30) - RepayBorrow Geoff repayAmount cDAI - Assert Equal (cToken cDAI BorrowBalance Geoff) 0 + From Geoff (Erc20 DAI Approve (SLToken slDAI Address) 1e30) + RepayBorrow Geoff repayAmount slDAI + Assert Equal (slToken slDAI BorrowBalance Geoff) 0 -- Check that the funds are in the pot and not the vat -- Note: we always move a little too much into vat on transfer out, so it might be extra dusty - Assert Approx (MCD PotAt PotAddress "pie" (CToken cDAI Address)) repayAmount -- pot is a wad (1e18), check for ~ 1 DAI + interest - Assert (MCD VatAt VatAddress "dai" (CToken cDAI Address)) LessThan 2e27 -- vat is a rad (1e45), check for ~ dust + Assert Approx (MCD PotAt PotAddress "pie" (SLToken slDAI Address)) repayAmount -- pot is a wad (1e18), check for ~ 1 DAI + interest + Assert (MCD VatAt VatAddress "dai" (SLToken slDAI Address)) LessThan 2e27 -- vat is a rad (1e45), check for ~ dust -Pending "Basic mint and redeem cDAI2 (directly to swept DSR)" - DeployCDAIWithDSR +Pending "Basic mint and redeem slDAI2 (directly to swept DSR)" + DeploySLDAIWithDSR CheckBasicMintRedeemWithDSR -Pending "Basic borrow and repay cDAI2 (directly to swept DSR)" - DeployCDAIWithDSR +Pending "Basic borrow and repay slDAI2 (directly to swept DSR)" + DeploySLDAIWithDSR CheckBasicBorrowRepayWithDSR -Pending "Basic mint and redeem cDAI2 (upgrade to swept DSR)" - DeployCDAI +Pending "Basic mint and redeem slDAI2 (upgrade to swept DSR)" + DeploySLDAI CheckBasicMintRedeem UpgradeToDSR CheckBasicMintRedeemWithDSR -Pending "Basic borrow and repay cDAI2 (upgrade to swept DSR)" - DeployCDAI +Pending "Basic borrow and repay slDAI2 (upgrade to swept DSR)" + DeploySLDAI CheckBasicMintRedeem UpgradeToDSR CheckBasicBorrowRepayWithDSR repayAmount:1000014999999999999 -- real block numbers can get nasty Pending "Mint, upgrade to DSR and then downgrade to vanilla delegate" - DeployCDAI - From DaiHolder (Erc20 DAI Approve (CToken cDAI Address) 1e18) - Mint DaiHolder 1e18 cDAI - Assert Equal (Erc20 DAI TokenBalance cDAI) 1e18 - Assert Equal (CToken cDAI Cash) 1e18 + DeploySLDAI + From DaiHolder (Erc20 DAI Approve (SLToken slDAI Address) 1e18) + Mint DaiHolder 1e18 slDAI + Assert Equal (Erc20 DAI TokenBalance slDAI) 1e18 + Assert Equal (SLToken slDAI Cash) 1e18 -- Upgrade UpgradeToDSR - Assert Equal (Erc20 DAI TokenBalance cDAI) 0 - Assert Approx (CToken cDAI Cash) 1e18 - Assert Approx (MCD PotAt PotAddress "pie" (CToken cDAI Address)) 1e18 + Assert Equal (Erc20 DAI TokenBalance slDAI) 0 + Assert Approx (SLToken slDAI Cash) 1e18 + Assert Approx (MCD PotAt PotAddress "pie" (SLToken slDAI Address)) 1e18 -- Downgrade - From CTokenAdmin (CToken cDAI SetImplementation (CTokenDelegate cErc20Delegate Address) True "0x0") - Assert Approx (Erc20 DAI TokenBalance cDAI) 1e18 - Assert Approx (CToken cDAI Cash) 1e18 - -Pending "Mint, upgrade to DSR, mint, and then reupgrade to a new cdai delegate" - DeployCDAI - From DaiHolder (Erc20 DAI Approve (CToken cDAI Address) 2e18) - Mint DaiHolder 1e18 cDAI - Assert Equal (Erc20 DAI TokenBalance cDAI) 1e18 - Assert Equal (CToken cDAI Cash) 1e18 + From SLTokenAdmin (SLToken slDAI SetImplementation (SLTokenDelegate slErc20Delegate Address) True "0x0") + Assert Approx (Erc20 DAI TokenBalance slDAI) 1e18 + Assert Approx (SLToken slDAI Cash) 1e18 + +Pending "Mint, upgrade to DSR, mint, and then reupgrade to a new sldai delegate" + DeploySLDAI + From DaiHolder (Erc20 DAI Approve (SLToken slDAI Address) 2e18) + Mint DaiHolder 1e18 slDAI + Assert Equal (Erc20 DAI TokenBalance slDAI) 1e18 + Assert Equal (SLToken slDAI Cash) 1e18 -- Upgrade UpgradeToDSR - Mint DaiHolder 1e18 cDAI - Assert Equal (Erc20 DAI TokenBalance cDAI) 0 - Assert Approx (CToken cDAI Cash) 2e18 - Assert Approx (MCD PotAt PotAddress "pie" (CToken cDAI Address)) 2e18 - -- Reupgrade to a new cDaiDelegate - CTokenDelegate Deploy CDaiDelegate cDaiDelegate2 - From CTokenAdmin (CToken cDAI SetImplementation (CTokenDelegate cDaiDelegate2 Address) True (EncodeParameters ("address" "address") (DaiJoinAddress PotAddress))) - Assert Equal (Erc20 DAI TokenBalance cDAI) 0 - Assert Approx (CToken cDAI Cash) 2e18 - Assert Approx (MCD PotAt PotAddress "pie" (CToken cDAI Address)) 2e18 + Mint DaiHolder 1e18 slDAI + Assert Equal (Erc20 DAI TokenBalance slDAI) 0 + Assert Approx (SLToken slDAI Cash) 2e18 + Assert Approx (MCD PotAt PotAddress "pie" (SLToken slDAI Address)) 2e18 + -- Reupgrade to a new slDaiDelegate + SLTokenDelegate Deploy SLDaiDelegate slDaiDelegate2 + From SLTokenAdmin (SLToken slDAI SetImplementation (SLTokenDelegate slDaiDelegate2 Address) True (EncodeParameters ("address" "address") (DaiJoinAddress PotAddress))) + Assert Equal (Erc20 DAI TokenBalance slDAI) 0 + Assert Approx (SLToken slDAI Cash) 2e18 + Assert Approx (MCD PotAt PotAddress "pie" (SLToken slDAI Address)) 2e18 Pending "Test resigning implementation" ForkMCD101 UseConfigs kovan - Assert Approx (Erc20 DAI TokenBalance cDAI) 0 - Assert Equal (MCD PotAt PotAddress "pie" (CToken cDAI Address)) 137889496810499277888 - From CTokenAdmin (CToken cDAI ResignImplementation) - Assert Approx (Erc20 DAI TokenBalance cDAI) 137889496810499277888 - Assert Approx (MCD PotAt PotAddress "pie" (CToken cDAI Address)) 0 + Assert Approx (Erc20 DAI TokenBalance slDAI) 0 + Assert Equal (MCD PotAt PotAddress "pie" (SLToken slDAI Address)) 137889496810499277888 + From SLTokenAdmin (SLToken slDAI ResignImplementation) + Assert Approx (Erc20 DAI TokenBalance slDAI) 137889496810499277888 + Assert Approx (MCD PotAt PotAddress "pie" (SLToken slDAI Address)) 0 Pending "DAI interest rate model" ForkMCD101 - InterestRateModel Deploy DAIInterestRateModel DSR_Kink_9000bps_Jump_12000bps_AssumedRF_500bps 120e16 90e16 PotAddress JugAddress CTokenAdmin + InterestRateModel Deploy DAIInterestRateModel DSR_Kink_9000bps_Jump_12000bps_AssumedRF_500bps 120e16 90e16 PotAddress JugAddress SLTokenAdmin diff --git a/spec/scenario/Mint.scen b/spec/scenario/Mint.scen index 4d31f0758..32d9edfc8 100644 --- a/spec/scenario/Mint.scen +++ b/spec/scenario/Mint.scen @@ -1,105 +1,105 @@ -- Mint Tests -Test "Mint 1 cZRX" +Test "Mint 1 slZRX" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff Some ZRX cZRX - Mint Geoff 50e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 50e9) - -- Assert Equal (CToken cZRX UnderlyingBalance Geoff) (Exactly 1.0e18) + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff Some ZRX slZRX + Mint Geoff 50e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 50e9) + -- Assert Equal (SLToken slZRX UnderlyingBalance Geoff) (Exactly 1.0e18) Test "Mint with insufficient allowance" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff 50e18 ZRX cZRX allowanceAmount:49e18 + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff 50e18 ZRX slZRX allowanceAmount:49e18 AllowFailures - Mint Geoff 50e18 cZRX + Mint Geoff 50e18 slZRX Assert Revert "revert Insufficient allowance" - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 0e9) + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 0e9) Test "Mint with insufficient balance" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff 49e18 ZRX cZRX allowanceAmount:50e18 + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff 49e18 ZRX slZRX allowanceAmount:50e18 AllowFailures - Mint Geoff 50e18 cZRX + Mint Geoff 50e18 slZRX Assert Revert "revert Insufficient balance" - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 0e9) + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 0e9) Test "Mint two ZRX after minting two ZRX, and then I mint two more" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff Some ZRX cZRX - Mint Geoff 2e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 2e9) - Assert Equal (Erc20 cZRX TotalSupply) (Exactly 2e9) - Mint Geoff 2e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 4e9) - Assert Equal (Erc20 cZRX TotalSupply) (Exactly 4e9) - Mint Geoff 2e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 6e9) - Assert Equal (Erc20 cZRX TotalSupply) (Exactly 6e9) + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff Some ZRX slZRX + Mint Geoff 2e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 2e9) + Assert Equal (Erc20 slZRX TotalSupply) (Exactly 2e9) + Mint Geoff 2e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 4e9) + Assert Equal (Erc20 slZRX TotalSupply) (Exactly 4e9) + Mint Geoff 2e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 6e9) + Assert Equal (Erc20 slZRX TotalSupply) (Exactly 6e9) Test "Two users Mint" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff Some ZRX cZRX - Prep Torrey Some ZRX cZRX - Mint Geoff 2e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 2e9) - Assert Equal (Erc20 cZRX TotalSupply) (Exactly 2e9) - Mint Torrey 2e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 2e9) - Assert Equal (Erc20 cZRX TokenBalance Torrey) (Exactly 2e9) - Assert Equal (Erc20 cZRX TotalSupply) (Exactly 4e9) + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff Some ZRX slZRX + Prep Torrey Some ZRX slZRX + Mint Geoff 2e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 2e9) + Assert Equal (Erc20 slZRX TotalSupply) (Exactly 2e9) + Mint Torrey 2e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 2e9) + Assert Equal (Erc20 slZRX TokenBalance Torrey) (Exactly 2e9) + Assert Equal (Erc20 slZRX TotalSupply) (Exactly 4e9) Test "Mint accrues no interest without borrows" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff Some ZRX cZRX - Prep Torrey Some ZRX cZRX - Mint Geoff 2e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 2e9) - Assert Equal (Erc20 cZRX TotalSupply) (Exactly 2e9) + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff Some ZRX slZRX + Prep Torrey Some ZRX slZRX + Mint Geoff 2e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 2e9) + Assert Equal (Erc20 slZRX TotalSupply) (Exactly 2e9) FastForward 1000 Blocks - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 2e9) - Assert Equal (Erc20 cZRX TotalSupply) (Exactly 2e9) + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 2e9) + Assert Equal (Erc20 slZRX TotalSupply) (Exactly 2e9) Test "Mint transfer in fails" NewComptroller - ListedCToken EVL cEVL tokenType:Evil - Prep Geoff Some EVL cEVL - Prep Torrey Some EVL cEVL - Invariant Static (Erc20 cEVL TokenBalance Geoff) - Invariant Static (Erc20 cEVL TotalSupply) + ListedSLToken EVL slEVL tokenType:Evil + Prep Geoff Some EVL slEVL + Prep Torrey Some EVL slEVL + Invariant Static (Erc20 slEVL TokenBalance Geoff) + Invariant Static (Erc20 slEVL TotalSupply) Invariant Static (Erc20 EVL TotalSupply) AllowFailures - Mint Geoff 2e18 cEVL + Mint Geoff 2e18 slEVL Assert Revert "revert TOKEN_TRANSFER_IN_FAILED" Test "Denied by comptroller because unlisted" NewComptroller - NewCToken ZRX cZRX - Prep Geoff Some ZRX cZRX - Prep Torrey Some ZRX cZRX - Invariant Static (Erc20 cZRX TokenBalance Geoff) - Invariant Static (Erc20 cZRX TotalSupply) + NewSLToken ZRX slZRX + Prep Geoff Some ZRX slZRX + Prep Torrey Some ZRX slZRX + Invariant Static (Erc20 slZRX TokenBalance Geoff) + Invariant Static (Erc20 slZRX TotalSupply) Invariant Static (Erc20 ZRX TotalSupply) AllowFailures - Mint Geoff 2e18 cZRX + Mint Geoff 2e18 slZRX Assert Failure COMPTROLLER_REJECTION MINT_COMPTROLLER_REJECTION MARKET_NOT_LISTED Test "mint reverts if mint is paused" NewComptroller - ListedCToken ZRX cZRX - Prep Geoff Some ZRX cZRX - Prep Torrey Some ZRX cZRX - Invariant Static (Erc20 cZRX TokenBalance Geoff) - Invariant Static (Erc20 cZRX TotalSupply) + ListedSLToken ZRX slZRX + Prep Geoff Some ZRX slZRX + Prep Torrey Some ZRX slZRX + Invariant Static (Erc20 slZRX TokenBalance Geoff) + Invariant Static (Erc20 slZRX TotalSupply) Invariant Static (Erc20 ZRX TotalSupply) Comptroller SetPauseGuardian Coburn - From Coburn (Comptroller SetGuardianMarketPaused cZRX "Mint" True) + From Coburn (Comptroller SetGuardianMarketPaused slZRX "Mint" True) AllowFailures - Mint Geoff 2e18 cZRX + Mint Geoff 2e18 slZRX Assert Revert "revert mint is paused" - Comptroller SetGuardianMarketPaused cZRX "Mint" False + Comptroller SetGuardianMarketPaused slZRX "Mint" False diff --git a/spec/scenario/MintEth.scen b/spec/scenario/MintEth.scen index cc1cd9f75..0d3448362 100644 --- a/spec/scenario/MintEth.scen +++ b/spec/scenario/MintEth.scen @@ -1,66 +1,66 @@ -- Mint Tests -GasTest "Send Mint 1 cETH" +GasTest "Send Mint 1 slETH" NewComptroller - ListedEtherTokenMinted cETH initialExchangeRate:0.005e9 + ListedEtherTokenMinted slETH initialExchangeRate:0.005e9 Expect Changes (EtherBalance Geoff) -0.005e18 - Expect Changes (CToken cETH UnderlyingBalance Geoff) +0.005e18 - SendMintEth Geoff 0.005e18 cETH - Assert Equal (Erc20 cETH TokenBalance Geoff) 10e8 + Expect Changes (SLToken slETH UnderlyingBalance Geoff) +0.005e18 + SendMintEth Geoff 0.005e18 slETH + Assert Equal (Erc20 slETH TokenBalance Geoff) 10e8 Assert LastGas LessThan 1.2e5 -GasTest "Call Mint 1 cETH" +GasTest "Call Mint 1 slETH" NewComptroller - ListedEtherTokenMinted cETH initialExchangeRate:0.005e9 + ListedEtherTokenMinted slETH initialExchangeRate:0.005e9 Expect Changes (EtherBalance Geoff) -0.005e18 - Expect Changes (CToken cETH UnderlyingBalance Geoff) +0.005e18 - CallMintEth Geoff 0.005e18 cETH - Assert Equal (Erc20 cETH TokenBalance Geoff) 10e8 + Expect Changes (SLToken slETH UnderlyingBalance Geoff) +0.005e18 + CallMintEth Geoff 0.005e18 slETH + Assert Equal (Erc20 slETH TokenBalance Geoff) 10e8 Assert LastGas LessThan 1.2e5 Test "Mint with insufficient eth balance" NewComptroller - ListedEtherTokenMinted cETH initialExchangeRate:0.005e9 + ListedEtherTokenMinted slETH initialExchangeRate:0.005e9 AllowFailures - Invariant Remains (CToken cETH UnderlyingBalance Geoff) 0e18 - Invariant Remains (Erc20 cETH TokenBalance Geoff) 0e8 + Invariant Remains (SLToken slETH UnderlyingBalance Geoff) 0e18 + Invariant Remains (Erc20 slETH TokenBalance Geoff) 0e8 Invariant Static (EtherBalance Geoff) - CallMintEth Geoff 1e30 cETH + CallMintEth Geoff 1e30 slETH Assert Error "sender doesn't have enough funds to send tx. The upfront cost is" Test "Mint two Eth after minting two Eth, and then I mint two more" NewComptroller - ListedEtherToken cETH initialExchangeRate:0.005e9 + ListedEtherToken slETH initialExchangeRate:0.005e9 Expect Changes (EtherBalance Geoff) -0.002e18 - CallMintEth Geoff 0.002e18 cETH - Assert Equal (Erc20 cETH TokenBalance Geoff) 4e8 - Assert Equal (Erc20 cETH TotalSupply) 4e8 + CallMintEth Geoff 0.002e18 slETH + Assert Equal (Erc20 slETH TokenBalance Geoff) 4e8 + Assert Equal (Erc20 slETH TotalSupply) 4e8 Expect Changes (EtherBalance Geoff) -0.002e18 - SendMintEth Geoff 0.002e18 cETH - Assert Equal (Erc20 cETH TokenBalance Geoff) 8e8 - Assert Equal (Erc20 cETH TotalSupply) 8e8 + SendMintEth Geoff 0.002e18 slETH + Assert Equal (Erc20 slETH TokenBalance Geoff) 8e8 + Assert Equal (Erc20 slETH TotalSupply) 8e8 Expect Changes (EtherBalance Geoff) -0.002e18 - CallMintEth Geoff 0.002e18 cETH - Assert Equal (Erc20 cETH TokenBalance Geoff) 12e8 - Assert Equal (Erc20 cETH TotalSupply) 12e8 + CallMintEth Geoff 0.002e18 slETH + Assert Equal (Erc20 slETH TokenBalance Geoff) 12e8 + Assert Equal (Erc20 slETH TotalSupply) 12e8 Test "Two users Mint" NewComptroller - ListedEtherToken cETH initialExchangeRate:0.005e9 - CallMintEth Geoff 0.002e18 cETH - Assert Equal (Erc20 cETH TokenBalance Geoff) 4e8 - Assert Equal (Erc20 cETH TotalSupply) 4e8 - CallMintEth Torrey 0.004e18 cETH - Assert Equal (Erc20 cETH TokenBalance Geoff) 4e8 - Assert Equal (Erc20 cETH TokenBalance Torrey) 8e8 - Assert Equal (Erc20 cETH TotalSupply) 12e8 + ListedEtherToken slETH initialExchangeRate:0.005e9 + CallMintEth Geoff 0.002e18 slETH + Assert Equal (Erc20 slETH TokenBalance Geoff) 4e8 + Assert Equal (Erc20 slETH TotalSupply) 4e8 + CallMintEth Torrey 0.004e18 slETH + Assert Equal (Erc20 slETH TokenBalance Geoff) 4e8 + Assert Equal (Erc20 slETH TokenBalance Torrey) 8e8 + Assert Equal (Erc20 slETH TotalSupply) 12e8 Test "Mint accrues no interest without borrows" NewComptroller - ListedEtherToken cETH initialExchangeRate:0.005e9 - CallMintEth Geoff 0.002e18 cETH - Assert Equal (Erc20 cETH TokenBalance Geoff) 4e8 - Assert Equal (Erc20 cETH TotalSupply) 4e8 + ListedEtherToken slETH initialExchangeRate:0.005e9 + CallMintEth Geoff 0.002e18 slETH + Assert Equal (Erc20 slETH TokenBalance Geoff) 4e8 + Assert Equal (Erc20 slETH TotalSupply) 4e8 FastForward 1000 Blocks - Assert Equal (Erc20 cETH TokenBalance Geoff) 4e8 - Assert Equal (Erc20 cETH TotalSupply) 4e8 + Assert Equal (Erc20 slETH TokenBalance Geoff) 4e8 + Assert Equal (Erc20 slETH TotalSupply) 4e8 diff --git a/spec/scenario/MintWBTC.scen b/spec/scenario/MintWBTC.scen index 70fae947e..26c8ed77a 100644 --- a/spec/scenario/MintWBTC.scen +++ b/spec/scenario/MintWBTC.scen @@ -1,93 +1,93 @@ -- Mint Tests -Test "Mint 1 cWBTC" +Test "Mint 1 slWBTC" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.2 tokenType:WBTC - Prep Geoff Some WBTC cWBTC - Mint Geoff 10e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) (Exactly 50e8) - Assert Equal (CToken cWBTC UnderlyingBalance Geoff) (Exactly 10e8) + ListedSLToken WBTC slWBTC initialExchangeRate:0.2 tokenType:WBTC + Prep Geoff Some WBTC slWBTC + Mint Geoff 10e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) (Exactly 50e8) + Assert Equal (SLToken slWBTC UnderlyingBalance Geoff) (Exactly 10e8) Test "Mint WBTC with insufficient allowance" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.2 tokenType:WBTC - Prep Geoff 5e8 WBTC cWBTC allowanceAmount:4.9e8 + ListedSLToken WBTC slWBTC initialExchangeRate:0.2 tokenType:WBTC + Prep Geoff 5e8 WBTC slWBTC allowanceAmount:4.9e8 AllowFailures - Mint Geoff 5e8 cWBTC + Mint Geoff 5e8 slWBTC --wbtc does not revert with reason in transfer from Assert Revert "revert" - Assert Equal (Erc20 cWBTC TokenBalance Geoff) (Exactly 0e8) + Assert Equal (Erc20 slWBTC TokenBalance Geoff) (Exactly 0e8) Test "Mint WBTC with insufficient balance" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.2 tokenType:WBTC - Prep Geoff 4.9e8 WBTC cWBTC allowanceAmount:5e8 + ListedSLToken WBTC slWBTC initialExchangeRate:0.2 tokenType:WBTC + Prep Geoff 4.9e8 WBTC slWBTC allowanceAmount:5e8 AllowFailures - Mint Geoff 5e8 cWBTC + Mint Geoff 5e8 slWBTC --wbtc does not revert with reason in transfer from Assert Revert "revert" - Assert Equal (Erc20 cWBTC TokenBalance Geoff) (Exactly 0e8) + Assert Equal (Erc20 slWBTC TokenBalance Geoff) (Exactly 0e8) Test "Mint two WBTC after minting two WBTC, and then I mint two more" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.2 tokenType:WBTC - Prep Geoff Some WBTC cWBTC - Mint Geoff 2e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) (Exactly 10e8) - Assert Equal (Erc20 cWBTC TotalSupply) (Exactly 10e8) - Mint Geoff 2e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) (Exactly 20e8) - Assert Equal (Erc20 cWBTC TotalSupply) (Exactly 20e8) - Mint Geoff 2e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) (Exactly 30e8) - Assert Equal (Erc20 cWBTC TotalSupply) (Exactly 30e8) + ListedSLToken WBTC slWBTC initialExchangeRate:0.2 tokenType:WBTC + Prep Geoff Some WBTC slWBTC + Mint Geoff 2e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) (Exactly 10e8) + Assert Equal (Erc20 slWBTC TotalSupply) (Exactly 10e8) + Mint Geoff 2e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) (Exactly 20e8) + Assert Equal (Erc20 slWBTC TotalSupply) (Exactly 20e8) + Mint Geoff 2e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) (Exactly 30e8) + Assert Equal (Erc20 slWBTC TotalSupply) (Exactly 30e8) Test "Two users Mint WBTC" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.2 tokenType:WBTC - Prep Geoff Some WBTC cWBTC - Prep Torrey Some WBTC cWBTC - Mint Geoff 2e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) (Exactly 10e8) - Assert Equal (Erc20 cWBTC TotalSupply) (Exactly 10e8) - Mint Torrey 2e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) (Exactly 10e8) - Assert Equal (Erc20 cWBTC TokenBalance Torrey) (Exactly 10e8) - Assert Equal (Erc20 cWBTC TotalSupply) (Exactly 20e8) + ListedSLToken WBTC slWBTC initialExchangeRate:0.2 tokenType:WBTC + Prep Geoff Some WBTC slWBTC + Prep Torrey Some WBTC slWBTC + Mint Geoff 2e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) (Exactly 10e8) + Assert Equal (Erc20 slWBTC TotalSupply) (Exactly 10e8) + Mint Torrey 2e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) (Exactly 10e8) + Assert Equal (Erc20 slWBTC TokenBalance Torrey) (Exactly 10e8) + Assert Equal (Erc20 slWBTC TotalSupply) (Exactly 20e8) Test "Mint WBTC accrues no interest without borrows" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.2 tokenType:WBTC - Prep Geoff Some WBTC cWBTC - Prep Torrey Some WBTC cWBTC - Mint Geoff 2e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) (Exactly 10e8) - Assert Equal (Erc20 cWBTC TotalSupply) (Exactly 10e8) + ListedSLToken WBTC slWBTC initialExchangeRate:0.2 tokenType:WBTC + Prep Geoff Some WBTC slWBTC + Prep Torrey Some WBTC slWBTC + Mint Geoff 2e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) (Exactly 10e8) + Assert Equal (Erc20 slWBTC TotalSupply) (Exactly 10e8) FastForward 1000 Blocks - Assert Equal (Erc20 cWBTC TokenBalance Geoff) (Exactly 10e8) - Assert Equal (Erc20 cWBTC TotalSupply) (Exactly 10e8) + Assert Equal (Erc20 slWBTC TokenBalance Geoff) (Exactly 10e8) + Assert Equal (Erc20 slWBTC TotalSupply) (Exactly 10e8) Test "Mint WBTC transfer in fails due to paused" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.2 tokenType:WBTC - Prep Geoff Some WBTC cWBTC - Prep Torrey Some WBTC cWBTC - Invariant Static (Erc20 cWBTC TokenBalance Geoff) - Invariant Static (Erc20 cWBTC TotalSupply) + ListedSLToken WBTC slWBTC initialExchangeRate:0.2 tokenType:WBTC + Prep Geoff Some WBTC slWBTC + Prep Torrey Some WBTC slWBTC + Invariant Static (Erc20 slWBTC TokenBalance Geoff) + Invariant Static (Erc20 slWBTC TotalSupply) Invariant Static (Erc20 WBTC TotalSupply) Erc20 WBTC Pause AllowFailures - Mint Geoff 2e8 cWBTC + Mint Geoff 2e8 slWBTC Assert Revert Test "Denied by comptroller because WBTC unlisted" NewComptroller - NewCToken WBTC cWBTC tokenType:WBTC - Prep Geoff Some WBTC cWBTC - Prep Torrey Some WBTC cWBTC - Invariant Static (Erc20 cWBTC TokenBalance Geoff) - Invariant Static (Erc20 cWBTC TotalSupply) + NewSLToken WBTC slWBTC tokenType:WBTC + Prep Geoff Some WBTC slWBTC + Prep Torrey Some WBTC slWBTC + Invariant Static (Erc20 slWBTC TokenBalance Geoff) + Invariant Static (Erc20 slWBTC TotalSupply) Invariant Static (Erc20 WBTC TotalSupply) AllowFailures - Mint Geoff 2e8 cWBTC + Mint Geoff 2e8 slWBTC Assert Failure COMPTROLLER_REJECTION MINT_COMPTROLLER_REJECTION MARKET_NOT_LISTED diff --git a/spec/scenario/PriceOracleProxy.scen b/spec/scenario/PriceOracleProxy.scen index 600d0536a..3bd7cafdf 100644 --- a/spec/scenario/PriceOracleProxy.scen +++ b/spec/scenario/PriceOracleProxy.scen @@ -18,36 +18,36 @@ Macro SetupPriceOracleProxy ComptrollerImpl Deploy Scenario ScenComptroller Unitroller SetPendingImpl ScenComptroller ComptrollerImpl ScenComptroller Become - NewEtherToken cETH - NewCToken USDC cUSDC - NewCToken SAI cSAI - NewCToken DAI cDAI - NewCToken USDT cUSDT - Comptroller SupportMarket cETH - Comptroller SupportMarket cUSDC - Comptroller SupportMarket cSAI - Comptroller SupportMarket cDAI - Comptroller SupportMarket cUSDT - PriceOracleProxy Deploy Admin (PriceOracle Address) (Address cETH) (Address cUSDC) (Address cSAI) (Address cDAI) (Address cUSDT) + NewEtherToken slETH + NewSLToken USDC slUSDC + NewSLToken SAI slSAI + NewSLToken DAI slDAI + NewSLToken USDT slUSDT + Comptroller SupportMarket slETH + Comptroller SupportMarket slUSDC + Comptroller SupportMarket slSAI + Comptroller SupportMarket slDAI + Comptroller SupportMarket slUSDT + PriceOracleProxy Deploy Admin (PriceOracle Address) (Address slETH) (Address slUSDC) (Address slSAI) (Address slDAI) (Address slUSDT) Comptroller SetPriceOracle (PriceOracleProxy Address) Test "uses address(2) for dai and address(1) for usdc" SetupPriceOracleProxy PriceOracle SetDirectPrice (Address 0x0000000000000000000000000000000000000001) 5740564708.572881 PriceOracle SetDirectPrice (Address 0x0000000000000000000000000000000000000002) 0.005842307360923634 - Assert Equal (PriceOracleProxy Price cUSDC) 5740564708572881000000000000 - Assert Equal (PriceOracleProxy Price cDAI) 5842307360923634 + Assert Equal (PriceOracleProxy Price slUSDC) 5740564708572881000000000000 + Assert Equal (PriceOracleProxy Price slDAI) 5842307360923634 Test "sai price is dai price until set" SetupPriceOracleProxy PriceOracle SetDirectPrice (Address 0x0000000000000000000000000000000000000002) 0.005842307360923634 - Assert Equal (PriceOracleProxy Price cSAI) 5842307360923634 + Assert Equal (PriceOracleProxy Price slSAI) 5842307360923634 PriceOracleProxy SetSaiPrice 0.006842307360923634 - Assert Equal (PriceOracleProxy Price cSAI) 6842307360923634 + Assert Equal (PriceOracleProxy Price slSAI) 6842307360923634 Test "gets tether and usdc prices" SetupPriceOracleProxy PriceOracle SetDirectPrice (Address 0x0000000000000000000000000000000000000001) 5740564708.572881 -- scaled to 1e30 bc both tokens have 6 decimals - Assert Equal (PriceOracleProxy Price cUSDT) 5740564708572881000000000000 - Assert Equal (PriceOracleProxy Price cUSDC) 5740564708572881000000000000 + Assert Equal (PriceOracleProxy Price slUSDT) 5740564708572881000000000000 + Assert Equal (PriceOracleProxy Price slUSDC) 5740564708572881000000000000 diff --git a/spec/scenario/ReEntry.scen b/spec/scenario/ReEntry.scen index 9a6e0c15c..24c4b9432 100644 --- a/spec/scenario/ReEntry.scen +++ b/spec/scenario/ReEntry.scen @@ -3,10 +3,10 @@ Test "ReEntry Mint @no-cov" NewComptroller Erc20 Deploy ReEntrant PHREAK PHREAK "transferFrom" "mint(uint256)" "0" InterestRateModel Deploy Fixed Std 0.000001 - CToken Deploy Scenario cPHREAK cPHREAK (Erc20 PHREAK Address) (Comptroller Address) (InterestRateModel Std Address) 1e9 8 Admin - Comptroller SupportMarket cPHREAK - Prep Geoff Some PHREAK cPHREAK + SLToken Deploy Scenario slPHREAK slPHREAK (Erc20 PHREAK Address) (Comptroller Address) (InterestRateModel Std Address) 1e9 8 Admin + Comptroller SupportMarket slPHREAK + Prep Geoff Some PHREAK slPHREAK AllowFailures - Mint Geoff 50e18 cPHREAK + Mint Geoff 50e18 slPHREAK Assert Revert "revert re-entered" - Assert Equal (Erc20 cPHREAK TokenBalance Geoff) Zero + Assert Equal (Erc20 slPHREAK TokenBalance Geoff) Zero diff --git a/spec/scenario/Redeem.scen b/spec/scenario/Redeem.scen index df6d6d061..91ac0d4b8 100644 --- a/spec/scenario/Redeem.scen +++ b/spec/scenario/Redeem.scen @@ -2,226 +2,226 @@ Test "Mint then Redeem All" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff 70e18 ZRX cZRX - Mint Geoff 50e18 cZRX + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff 70e18 ZRX slZRX + Mint Geoff 50e18 slZRX -- Check current affairs - Assert Equal (Erc20 cZRX TokenBalance Geoff) 500e8 + Assert Equal (Erc20 slZRX TokenBalance Geoff) 500e8 Assert Equal (Erc20 ZRX TokenBalance Geoff) 20e18 -- Any other good invariants? - Invariant Static (CToken cZRX ExchangeRateStored) + Invariant Static (SLToken slZRX ExchangeRateStored) -- Now redeem after some time FastForward 2 Blocks - Redeem Geoff 500e8 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) Zero + Redeem Geoff 500e8 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) Zero Assert Equal (Erc20 ZRX TokenBalance Geoff) 70e18 Test "Mint, Enter and then Redeem All" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff 70e18 ZRX cZRX - Mint Geoff 50e18 cZRX + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff 70e18 ZRX slZRX + Mint Geoff 50e18 slZRX -- Check current affairs - Assert Equal (Erc20 cZRX TokenBalance Geoff) 500e8 + Assert Equal (Erc20 slZRX TokenBalance Geoff) 500e8 Assert Equal (Erc20 ZRX TokenBalance Geoff) 20e18 -- Any other good invariants? - Invariant Static (CToken cZRX ExchangeRateStored) + Invariant Static (SLToken slZRX ExchangeRateStored) -- Now redeem after some time FastForward 2 Blocks - EnterMarkets Geoff cZRX - Redeem Geoff 500e8 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) Zero + EnterMarkets Geoff slZRX + Redeem Geoff 500e8 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) Zero Assert Equal (Erc20 ZRX TokenBalance Geoff) 70e18 Test "Mint then Redeem Part" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff 70e18 ZRX cZRX - Mint Geoff 50e18 cZRX + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff 70e18 ZRX slZRX + Mint Geoff 50e18 slZRX -- Check current affairs - Assert Equal (Erc20 cZRX TokenBalance Geoff) 500e8 + Assert Equal (Erc20 slZRX TokenBalance Geoff) 500e8 Assert Equal (Erc20 ZRX TokenBalance Geoff) 20e18 -- Any other good invariants? - Invariant Static (CToken cZRX ExchangeRateStored) + Invariant Static (SLToken slZRX ExchangeRateStored) -- Now redeem after some time FastForward 2 Blocks - Redeem Geoff 250e8 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) 250e8 + Redeem Geoff 250e8 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) 250e8 Assert Equal (Erc20 ZRX TokenBalance Geoff) 45e18 Test "Mint then Redeem Too Much" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff 70e18 ZRX cZRX - Mint Geoff 50e18 cZRX + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff 70e18 ZRX slZRX + Mint Geoff 50e18 slZRX -- Check and hold static - Invariant Static (CToken cZRX ExchangeRateStored) - Invariant Remains (Erc20 cZRX TokenBalance Geoff) 500e8 + Invariant Static (SLToken slZRX ExchangeRateStored) + Invariant Remains (Erc20 slZRX TokenBalance Geoff) 500e8 Invariant Remains (Erc20 ZRX TokenBalance Geoff) 20e18 -- Now redeem after some time FastForward 2 Blocks AllowFailures - Redeem Geoff 501e8 cZRX + Redeem Geoff 501e8 slZRX Assert Failure MATH_ERROR REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED "3" Test "Mint then Redeem Zero" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff 70e18 ZRX cZRX - Mint Geoff 50e18 cZRX + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff 70e18 ZRX slZRX + Mint Geoff 50e18 slZRX -- Check current affairs - Assert Equal (Erc20 cZRX TokenBalance Geoff) 500e8 + Assert Equal (Erc20 slZRX TokenBalance Geoff) 500e8 Assert Equal (Erc20 ZRX TokenBalance Geoff) 20e18 -- Any other good invariants? - Invariant Static (CToken cZRX ExchangeRateStored) + Invariant Static (SLToken slZRX ExchangeRateStored) -- Now redeem after some time FastForward 2 Blocks - Redeem Geoff 0e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) 500e8 + Redeem Geoff 0e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) 500e8 Assert Equal (Erc20 ZRX TokenBalance Geoff) 20e18 Test "Mint then redeem with interest - no reserves" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Invariant Remains (CToken cZRX Reserves) Zero - Prep Geoff 50e18 ZRX cZRX - Mint Geoff 50e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) 500e8 - Assert Equal (CToken cZRX UnderlyingBalance Geoff) 50e18 - Assert Equal (CToken cZRX ExchangeRate) 1e9 + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Invariant Remains (SLToken slZRX Reserves) Zero + Prep Geoff 50e18 ZRX slZRX + Mint Geoff 50e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) 500e8 + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) 50e18 + Assert Equal (SLToken slZRX ExchangeRate) 1e9 -- Get some brah to borrow then repay - BorrowAndRepayWithInterest ZRX cZRX 10e18 5e18 interestRate:0.000001 blocks:500000 + BorrowAndRepayWithInterest ZRX slZRX 10e18 5e18 interestRate:0.000001 blocks:500000 -- We've accrued .001% interest for 500000 blocks, or 50% of the principal, -- thus, we should have accrued 5e18 of interest for the protocol -- This is due pro-rata to all suppliers, but we just have one, so -- let's check that account is given correct new balance. - Assert Equal (Erc20 cZRX TokenBalance Geoff) 500e8 - Assert Equal (CToken cZRX UnderlyingBalance Geoff) 55e18 - Assert Equal (CToken cZRX ExchangeRate) 1.1e9 + Assert Equal (Erc20 slZRX TokenBalance Geoff) 500e8 + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) 55e18 + Assert Equal (SLToken slZRX ExchangeRate) 1.1e9 -- Now redeem all with interest - Redeem Geoff 500e8 cZRX + Redeem Geoff 500e8 slZRX Assert Equal (Erc20 ZRX TokenBalance Geoff) 55e18 - Assert Equal (Erc20 ZRX TokenBalance cZRX) 0e18 - Assert Equal (Erc20 cZRX TokenBalance Geoff) 0e8 - Assert Equal (CToken cZRX UnderlyingBalance Geoff) 0e18 - Assert Equal (CToken cZRX ExchangeRate) 1e9 + Assert Equal (Erc20 ZRX TokenBalance slZRX) 0e18 + Assert Equal (Erc20 slZRX TokenBalance Geoff) 0e8 + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) 0e18 + Assert Equal (SLToken slZRX ExchangeRate) 1e9 Test "Mint then redeem part with interest - no reserves" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Invariant Remains (CToken cZRX Reserves) Zero - Prep Geoff 50e18 ZRX cZRX - Mint Geoff 50e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) 500e8 - Assert Equal (CToken cZRX UnderlyingBalance Geoff) 50e18 - Assert Equal (CToken cZRX ExchangeRate) 1e9 + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Invariant Remains (SLToken slZRX Reserves) Zero + Prep Geoff 50e18 ZRX slZRX + Mint Geoff 50e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) 500e8 + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) 50e18 + Assert Equal (SLToken slZRX ExchangeRate) 1e9 -- Get some brah to borrow then repay - BorrowAndRepayWithInterest ZRX cZRX 10e18 5e18 interestRate:0.000001 blocks:500000 + BorrowAndRepayWithInterest ZRX slZRX 10e18 5e18 interestRate:0.000001 blocks:500000 -- We've accrued .001% interest for 500000 blocks, or 50% of the principal, -- thus, we should have accrued 5e18 of interest for the protocol -- This is due pro-rata to all suppliers, but we just have one, so -- let's check that account is given correct new balance. - Assert Equal (Erc20 cZRX TokenBalance Geoff) 500e8 - Assert Equal (CToken cZRX UnderlyingBalance Geoff) 55e18 - Assert Equal (CToken cZRX ExchangeRate) 1.1e9 + Assert Equal (Erc20 slZRX TokenBalance Geoff) 500e8 + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) 55e18 + Assert Equal (SLToken slZRX ExchangeRate) 1.1e9 -- Now redeem all with interest - Redeem Geoff 499e8 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) 1e8 - Assert Equal (CToken cZRX UnderlyingBalance Geoff) 0.11e18 - Assert Equal (CToken cZRX ExchangeRate) 1.1e9 + Redeem Geoff 499e8 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) 1e8 + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) 0.11e18 + Assert Equal (SLToken slZRX ExchangeRate) 1.1e9 Test "Mint then redeem with reserves and interest" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff 50e18 ZRX cZRX - Mint Geoff 50e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) 500e8 - Assert Equal (CToken cZRX UnderlyingBalance Geoff) 50e18 - Assert Equal (CToken cZRX ExchangeRate) 1e9 + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff 50e18 ZRX slZRX + Mint Geoff 50e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) 500e8 + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) 50e18 + Assert Equal (SLToken slZRX ExchangeRate) 1e9 -- Get some brah to borrow then repay - BorrowAndRepayWithInterest ZRX cZRX 10e18 5e18 interestRate:0.000001 blocks:500000 reserveRate:0.2 + BorrowAndRepayWithInterest ZRX slZRX 10e18 5e18 interestRate:0.000001 blocks:500000 reserveRate:0.2 -- We've accrued .001% interest for 500000 blocks, or 50% of the principal, -- thus, we should have accrued 5e18 of interest for the protocol -- The reserves should get 20% of this, or 1e18, and the rest -- is due pro-rata to all holders. We just have one, so -- let's check that account is given correct new balance. - Assert Equal (Erc20 cZRX TokenBalance Geoff) 500e8 - Assert Equal (CToken cZRX Reserves) 1e18 - Assert Equal (CToken cZRX UnderlyingBalance Geoff) 54e18 + Assert Equal (Erc20 slZRX TokenBalance Geoff) 500e8 + Assert Equal (SLToken slZRX Reserves) 1e18 + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) 54e18 -- 55e18 + 0e18 - 1e18 / 500 - Assert Equal (CToken cZRX ExchangeRate) 1.08e9 + Assert Equal (SLToken slZRX ExchangeRate) 1.08e9 -- Now redeem all with interest - Redeem Geoff 500e8 cZRX + Redeem Geoff 500e8 slZRX Assert Equal (Erc20 ZRX TokenBalance Geoff) 54e18 - Assert Equal (Erc20 ZRX TokenBalance cZRX) 1e18 - Assert Equal (Erc20 cZRX TokenBalance Geoff) 0e8 - Assert Equal (CToken cZRX Reserves) 1e18 - Assert Equal (CToken cZRX UnderlyingBalance Geoff) 0e18 - Assert Equal (CToken cZRX ExchangeRate) 1e9 + Assert Equal (Erc20 ZRX TokenBalance slZRX) 1e18 + Assert Equal (Erc20 slZRX TokenBalance Geoff) 0e8 + Assert Equal (SLToken slZRX Reserves) 1e18 + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) 0e18 + Assert Equal (SLToken slZRX ExchangeRate) 1e9 Test "Two users Mint, one redeems" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff Some ZRX cZRX - Prep Torrey Some ZRX cZRX - Mint Geoff 2e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) 20e8 - Assert Equal (Erc20 cZRX TotalSupply) 20e8 - Mint Torrey 2e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) 20e8 - Assert Equal (Erc20 cZRX TokenBalance Torrey) 20e8 - Assert Equal (Erc20 cZRX TotalSupply) 40e8 - Redeem Torrey 10e8 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) 20e8 - Assert Equal (Erc20 cZRX TokenBalance Torrey) 10e8 - Assert Equal (Erc20 cZRX TotalSupply) 30e8 + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff Some ZRX slZRX + Prep Torrey Some ZRX slZRX + Mint Geoff 2e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) 20e8 + Assert Equal (Erc20 slZRX TotalSupply) 20e8 + Mint Torrey 2e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) 20e8 + Assert Equal (Erc20 slZRX TokenBalance Torrey) 20e8 + Assert Equal (Erc20 slZRX TotalSupply) 40e8 + Redeem Torrey 10e8 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) 20e8 + Assert Equal (Erc20 slZRX TokenBalance Torrey) 10e8 + Assert Equal (Erc20 slZRX TotalSupply) 30e8 Test "Redeem transfer out fails" NewComptroller - ListedCToken EVL cEVL initialExchangeRate:1e9 tokenType:Evil + ListedSLToken EVL slEVL initialExchangeRate:1e9 tokenType:Evil Erc20 EVL SetFail False - Prep Geoff 70e18 EVL cEVL - Mint Geoff 50e18 cEVL + Prep Geoff 70e18 EVL slEVL + Mint Geoff 50e18 slEVL -- Check current affairs - Invariant Remains (Erc20 cEVL TokenBalance Geoff) 500e8 + Invariant Remains (Erc20 slEVL TokenBalance Geoff) 500e8 Invariant Remains (Erc20 EVL TokenBalance Geoff) 20e18 - Invariant Static (CToken cEVL ExchangeRateStored) + Invariant Static (SLToken slEVL ExchangeRateStored) -- Now redeem after some time FastForward 2 Blocks Erc20 EVL SetFail True AllowFailures - Redeem Geoff 500e8 cEVL + Redeem Geoff 500e8 slEVL Assert Revert "revert TOKEN_TRANSFER_OUT_FAILED" Test "Mint, Enter, then Redeem Too Much (collateral factor: 0)" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff 70e18 ZRX cZRX - Mint Geoff 50e18 cZRX + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff 70e18 ZRX slZRX + Mint Geoff 50e18 slZRX -- Check and hold static - Invariant Static (CToken cZRX ExchangeRateStored) - Invariant Remains (Erc20 cZRX TokenBalance Geoff) 500e8 + Invariant Static (SLToken slZRX ExchangeRateStored) + Invariant Remains (Erc20 slZRX TokenBalance Geoff) 500e8 Invariant Remains (Erc20 ZRX TokenBalance Geoff) 20e18 -- Now redeem after some time FastForward 2 Blocks - EnterMarkets Geoff cZRX + EnterMarkets Geoff slZRX AllowFailures - Redeem Geoff 501e8 cZRX + Redeem Geoff 501e8 slZRX Assert Failure MATH_ERROR REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED "3" Test "Mint, Enter, then Redeem Too Much (collateral factor: 0.1)" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Comptroller SetCollateralFactor cZRX 0.1 - Prep Geoff 70e18 ZRX cZRX - Mint Geoff 50e18 cZRX + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Comptroller SetCollateralFactor slZRX 0.1 + Prep Geoff 70e18 ZRX slZRX + Mint Geoff 50e18 slZRX -- Check and hold static - Invariant Static (CToken cZRX ExchangeRateStored) - Invariant Remains (Erc20 cZRX TokenBalance Geoff) 500e8 + Invariant Static (SLToken slZRX ExchangeRateStored) + Invariant Remains (Erc20 slZRX TokenBalance Geoff) 500e8 Invariant Remains (Erc20 ZRX TokenBalance Geoff) 20e18 -- Now redeem after some time FastForward 2 Blocks - EnterMarkets Geoff cZRX + EnterMarkets Geoff slZRX AllowFailures - Redeem Geoff 501e8 cZRX + Redeem Geoff 501e8 slZRX Assert Failure COMPTROLLER_REJECTION REDEEM_COMPTROLLER_REJECTION INSUFFICIENT_LIQUIDITY diff --git a/spec/scenario/RedeemEth.scen b/spec/scenario/RedeemEth.scen index 3985fb686..943f2774c 100644 --- a/spec/scenario/RedeemEth.scen +++ b/spec/scenario/RedeemEth.scen @@ -2,155 +2,155 @@ Test "Mint then Redeem All" NewComptroller - ListedEtherToken cETH initialExchangeRate:0.005e9 - CallMintEth Geoff 0.005e18 cETH + ListedEtherToken slETH initialExchangeRate:0.005e9 + CallMintEth Geoff 0.005e18 slETH -- Check current affairs - Assert Equal (Erc20 cETH TokenBalance Geoff) 10e8 - Assert Equal (CToken cETH UnderlyingBalance Geoff) 0.005e18 - Invariant Static (CToken cETH ExchangeRateStored) + Assert Equal (Erc20 slETH TokenBalance Geoff) 10e8 + Assert Equal (SLToken slETH UnderlyingBalance Geoff) 0.005e18 + Invariant Static (SLToken slETH ExchangeRateStored) -- Now redeem after some time FastForward 2 Blocks Expect Changes (EtherBalance Geoff) +0.005e18 - RedeemEth Geoff 10e8 cETH - Assert Equal (Erc20 cETH TokenBalance Geoff) Zero - Assert Equal (CToken cETH UnderlyingBalance Geoff) Zero + RedeemEth Geoff 10e8 slETH + Assert Equal (Erc20 slETH TokenBalance Geoff) Zero + Assert Equal (SLToken slETH UnderlyingBalance Geoff) Zero Test "Mint then Redeem Part" NewComptroller - ListedEtherToken cETH initialExchangeRate:0.005e9 - CallMintEth Geoff 0.005e18 cETH + ListedEtherToken slETH initialExchangeRate:0.005e9 + CallMintEth Geoff 0.005e18 slETH -- Check current affairs - Assert Equal (Erc20 cETH TokenBalance Geoff) 10e8 - Assert Equal (CToken cETH UnderlyingBalance Geoff) 0.005e18 - Invariant Static (CToken cETH ExchangeRateStored) + Assert Equal (Erc20 slETH TokenBalance Geoff) 10e8 + Assert Equal (SLToken slETH UnderlyingBalance Geoff) 0.005e18 + Invariant Static (SLToken slETH ExchangeRateStored) -- Now redeem after some time FastForward 2 Blocks Expect Changes (EtherBalance Geoff) +0.001e18 - RedeemEth Geoff 2e8 cETH - Assert Equal (Erc20 cETH TokenBalance Geoff) 8e8 - Assert Equal (CToken cETH UnderlyingBalance Geoff) 0.004e18 + RedeemEth Geoff 2e8 slETH + Assert Equal (Erc20 slETH TokenBalance Geoff) 8e8 + Assert Equal (SLToken slETH UnderlyingBalance Geoff) 0.004e18 Test "Mint then Redeem Too Much" NewComptroller - ListedEtherToken cETH initialExchangeRate:0.005e9 - CallMintEth Geoff 0.005e18 cETH + ListedEtherToken slETH initialExchangeRate:0.005e9 + CallMintEth Geoff 0.005e18 slETH AllowFailures -- Check and hold static - Invariant Static (CToken cETH ExchangeRateStored) - Invariant Remains (Erc20 cETH TokenBalance Geoff) 10e8 + Invariant Static (SLToken slETH ExchangeRateStored) + Invariant Remains (Erc20 slETH TokenBalance Geoff) 10e8 Invariant Static (EtherBalance Geoff) -- Now redeem after some time FastForward 2 Blocks - RedeemEth Geoff 11e8 cETH + RedeemEth Geoff 11e8 slETH -- TODO: This should really be REDEEM_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED, but based on -- the order of subtractions, total supply comes before account supply. Assert Failure MATH_ERROR REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED "3" -- TODO: This error is wrong Test "Mint then Redeem Zero" NewComptroller - ListedEtherToken cETH initialExchangeRate:0.005e9 - CallMintEth Geoff 0.005e18 cETH + ListedEtherToken slETH initialExchangeRate:0.005e9 + CallMintEth Geoff 0.005e18 slETH -- Check and hold static - Invariant Static (CToken cETH ExchangeRateStored) - Invariant Remains (Erc20 cETH TokenBalance Geoff) 10e8 + Invariant Static (SLToken slETH ExchangeRateStored) + Invariant Remains (Erc20 slETH TokenBalance Geoff) 10e8 Invariant Static (EtherBalance Geoff) -- Now redeem after some time FastForward 2 Blocks - RedeemEth Geoff 0e9 cETH + RedeemEth Geoff 0e9 slETH Pending "Mint then redeem with interest - no reserves" Invariant Success NewComptroller - ListedCToken ZRX cETH initialExchangeRate:1e9 - Invariant Remains (CToken cETH Reserves) Zero - Prep Geoff 50e18 ZRX cETH - Mint Geoff 50e18 cETH - Assert Equal (Erc20 cETH TokenBalance Geoff) 500e8 - Assert Equal (CToken cETH UnderlyingBalance Geoff) 50e18 - Assert Equal (CToken cETH ExchangeRate) 1e9 + ListedSLToken ZRX slETH initialExchangeRate:1e9 + Invariant Remains (SLToken slETH Reserves) Zero + Prep Geoff 50e18 ZRX slETH + Mint Geoff 50e18 slETH + Assert Equal (Erc20 slETH TokenBalance Geoff) 500e8 + Assert Equal (SLToken slETH UnderlyingBalance Geoff) 50e18 + Assert Equal (SLToken slETH ExchangeRate) 1e9 -- Get some brah to borrow then repay - BorrowAndRepayWithInterest ZRX cETH 10e18 5e18 interestRate:0.0001 blocks:5000 + BorrowAndRepayWithInterest ZRX slETH 10e18 5e18 interestRate:0.0001 blocks:5000 -- We've accrued 10% interest for 5 blocks, or 50% of the amount, -- thus, we should have accrued 5e18 of interest for the protocol -- This is due pro-rata to all holders, but we just have one, so -- let's check that account is given correct new balance. - Assert Equal (Erc20 cETH TokenBalance Geoff) 500e8 - Assert Equal (CToken cETH UnderlyingBalance Geoff) 55e18 - Assert Equal (CToken cETH ExchangeRate) 1.1e9 + Assert Equal (Erc20 slETH TokenBalance Geoff) 500e8 + Assert Equal (SLToken slETH UnderlyingBalance Geoff) 55e18 + Assert Equal (SLToken slETH ExchangeRate) 1.1e9 -- Now redeem all with interest - Redeem Geoff 500e8 cETH + Redeem Geoff 500e8 slETH Assert Equal (Erc20 ZRX TokenBalance Geoff) 55e18 - Assert Equal (Erc20 ZRX TokenBalance cETH) 0e18 - Assert Equal (Erc20 cETH TokenBalance Geoff) 0e8 - Assert Equal (CToken cETH UnderlyingBalance Geoff) 0e18 - Assert Equal (CToken cETH ExchangeRate) 1e9 + Assert Equal (Erc20 ZRX TokenBalance slETH) 0e18 + Assert Equal (Erc20 slETH TokenBalance Geoff) 0e8 + Assert Equal (SLToken slETH UnderlyingBalance Geoff) 0e18 + Assert Equal (SLToken slETH ExchangeRate) 1e9 Pending "Mint then redeem part with interest - no reserves" Invariant Success NewComptroller - ListedCToken ZRX cETH initialExchangeRate:1e9 - Invariant Remains (CToken cETH Reserves) Zero - Prep Geoff 50e18 ZRX cETH - Mint Geoff 50e18 cETH - Assert Equal (Erc20 cETH TokenBalance Geoff) 500e8 - Assert Equal (CToken cETH UnderlyingBalance Geoff) 50e18 - Assert Equal (CToken cETH ExchangeRate) 1e9 + ListedSLToken ZRX slETH initialExchangeRate:1e9 + Invariant Remains (SLToken slETH Reserves) Zero + Prep Geoff 50e18 ZRX slETH + Mint Geoff 50e18 slETH + Assert Equal (Erc20 slETH TokenBalance Geoff) 500e8 + Assert Equal (SLToken slETH UnderlyingBalance Geoff) 50e18 + Assert Equal (SLToken slETH ExchangeRate) 1e9 -- Get some brah to borrow then repay - BorrowAndRepayWithInterest ZRX cETH 10e18 5e18 interestRate:0.0001 blocks:5000 + BorrowAndRepayWithInterest ZRX slETH 10e18 5e18 interestRate:0.0001 blocks:5000 -- We've accrued 10% interest for 5 blocks, or 50% of the amount, -- thus, we should have accrued 5e18 of interest for the protocol -- This is due pro-rata to all holders, but we just have one, so -- let's check that account is given correct new balance. - Assert Equal (Erc20 cETH TokenBalance Geoff) 500e8 - Assert Equal (CToken cETH UnderlyingBalance Geoff) 55e18 - Assert Equal (CToken cETH ExchangeRate) 1.1e9 + Assert Equal (Erc20 slETH TokenBalance Geoff) 500e8 + Assert Equal (SLToken slETH UnderlyingBalance Geoff) 55e18 + Assert Equal (SLToken slETH ExchangeRate) 1.1e9 -- Now redeem all with interest - Redeem Geoff 499e8 cETH - Assert Equal (Erc20 cETH TokenBalance Geoff) 1e8 - Assert Equal (CToken cETH UnderlyingBalance Geoff) 0.11e18 - Assert Equal (CToken cETH ExchangeRate) 1.1e9 + Redeem Geoff 499e8 slETH + Assert Equal (Erc20 slETH TokenBalance Geoff) 1e8 + Assert Equal (SLToken slETH UnderlyingBalance Geoff) 0.11e18 + Assert Equal (SLToken slETH ExchangeRate) 1.1e9 Pending "Mint then redeem with reserves and interest" Invariant Success NewComptroller - ListedCToken ZRX cETH initialExchangeRate:1e9 - Prep Geoff 50e18 ZRX cETH - Mint Geoff 50e18 cETH - Assert Equal (Erc20 cETH TokenBalance Geoff) 500e8 - Assert Equal (CToken cETH UnderlyingBalance Geoff) 50e18 - Assert Equal (CToken cETH ExchangeRate) 1e9 + ListedSLToken ZRX slETH initialExchangeRate:1e9 + Prep Geoff 50e18 ZRX slETH + Mint Geoff 50e18 slETH + Assert Equal (Erc20 slETH TokenBalance Geoff) 500e8 + Assert Equal (SLToken slETH UnderlyingBalance Geoff) 50e18 + Assert Equal (SLToken slETH ExchangeRate) 1e9 -- Get some brah to borrow then repay - BorrowAndRepayWithInterest ZRX cETH 10e18 5e18 interestRate:0.0001 blocks:5000 reserveRate:0.2 + BorrowAndRepayWithInterest ZRX slETH 10e18 5e18 interestRate:0.0001 blocks:5000 reserveRate:0.2 -- We've accrued 10% interest for 5 blocks, or 50% of the amount, -- thus, we should have accrued 5e18 of interest for the protocol -- The reserves should get 20% of this, or 1e18, and the rest -- is due pro-rata to all holders. We just have one, so -- let's check that account is given correct new balance. - Assert Equal (Erc20 cETH TokenBalance Geoff) 500e8 - Assert Equal (CToken cETH Reserves) 1e18 - Assert Equal (CToken cETH UnderlyingBalance Geoff) 54e18 + Assert Equal (Erc20 slETH TokenBalance Geoff) 500e8 + Assert Equal (SLToken slETH Reserves) 1e18 + Assert Equal (SLToken slETH UnderlyingBalance Geoff) 54e18 -- 55e18 + 0e18 - 1e18 / 500 - Assert Equal (CToken cETH ExchangeRate) 1.08e9 + Assert Equal (SLToken slETH ExchangeRate) 1.08e9 -- Now redeem all with interest - Redeem Geoff 500e8 cETH + Redeem Geoff 500e8 slETH Assert Equal (Erc20 ZRX TokenBalance Geoff) 54e18 - Assert Equal (Erc20 ZRX TokenBalance cETH) 1e18 - Assert Equal (Erc20 cETH TokenBalance Geoff) 0e8 - Assert Equal (CToken cETH Reserves) 1e18 - Assert Equal (CToken cETH UnderlyingBalance Geoff) 0e18 - Assert Equal (CToken cETH ExchangeRate) 1e9 + Assert Equal (Erc20 ZRX TokenBalance slETH) 1e18 + Assert Equal (Erc20 slETH TokenBalance Geoff) 0e8 + Assert Equal (SLToken slETH Reserves) 1e18 + Assert Equal (SLToken slETH UnderlyingBalance Geoff) 0e18 + Assert Equal (SLToken slETH ExchangeRate) 1e9 Test "Two users Mint, one redeems" NewComptroller - ListedEtherToken cETH initialExchangeRate:0.005e9 - CallMintEth Geoff 0.002e18 cETH - Assert Equal (Erc20 cETH TokenBalance Geoff) 4e8 - Assert Equal (Erc20 cETH TotalSupply) 4e8 - CallMintEth Torrey 0.004e18 cETH - Assert Equal (Erc20 cETH TokenBalance Geoff) 4e8 - Assert Equal (Erc20 cETH TokenBalance Torrey) 8e8 - Assert Equal (Erc20 cETH TotalSupply) 12e8 - RedeemEth Torrey 3e8 cETH - Assert Equal (Erc20 cETH TokenBalance Geoff) 4e8 - Assert Equal (Erc20 cETH TokenBalance Torrey) 5e8 - Assert Equal (Erc20 cETH TotalSupply) 9e8 + ListedEtherToken slETH initialExchangeRate:0.005e9 + CallMintEth Geoff 0.002e18 slETH + Assert Equal (Erc20 slETH TokenBalance Geoff) 4e8 + Assert Equal (Erc20 slETH TotalSupply) 4e8 + CallMintEth Torrey 0.004e18 slETH + Assert Equal (Erc20 slETH TokenBalance Geoff) 4e8 + Assert Equal (Erc20 slETH TokenBalance Torrey) 8e8 + Assert Equal (Erc20 slETH TotalSupply) 12e8 + RedeemEth Torrey 3e8 slETH + Assert Equal (Erc20 slETH TokenBalance Geoff) 4e8 + Assert Equal (Erc20 slETH TokenBalance Torrey) 5e8 + Assert Equal (Erc20 slETH TotalSupply) 9e8 diff --git a/spec/scenario/RedeemUnderlying.scen b/spec/scenario/RedeemUnderlying.scen index afea3436e..77beca80d 100644 --- a/spec/scenario/RedeemUnderlying.scen +++ b/spec/scenario/RedeemUnderlying.scen @@ -2,181 +2,181 @@ Test "Mint then Redeem All" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff 70e18 ZRX cZRX - Mint Geoff 50e18 cZRX + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff 70e18 ZRX slZRX + Mint Geoff 50e18 slZRX -- Check current affairs - Assert Equal (Erc20 cZRX TokenBalance Geoff) 500e8 + Assert Equal (Erc20 slZRX TokenBalance Geoff) 500e8 Assert Equal (Erc20 ZRX TokenBalance Geoff) 20e18 -- Any other good invariants? - Invariant Static (CToken cZRX ExchangeRateStored) + Invariant Static (SLToken slZRX ExchangeRateStored) -- Now redeem after some time FastForward 2 Blocks - RedeemUnderlying Geoff 50e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) Zero + RedeemUnderlying Geoff 50e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) Zero Assert Equal (Erc20 ZRX TokenBalance Geoff) 70e18 Test "Mint then Redeem Part" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff 70e18 ZRX cZRX - Mint Geoff 50e18 cZRX + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff 70e18 ZRX slZRX + Mint Geoff 50e18 slZRX -- Check current affairs - Assert Equal (Erc20 cZRX TokenBalance Geoff) 500e8 + Assert Equal (Erc20 slZRX TokenBalance Geoff) 500e8 Assert Equal (Erc20 ZRX TokenBalance Geoff) 20e18 -- Any other good invariants? - Invariant Static (CToken cZRX ExchangeRateStored) + Invariant Static (SLToken slZRX ExchangeRateStored) -- Now redeem after some time FastForward 2 Blocks - RedeemUnderlying Geoff 25e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) 250e8 + RedeemUnderlying Geoff 25e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) 250e8 Assert Equal (Erc20 ZRX TokenBalance Geoff) 45e18 Test "Mint then Redeem Too Much" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff 70e18 ZRX cZRX - Mint Geoff 50e18 cZRX + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff 70e18 ZRX slZRX + Mint Geoff 50e18 slZRX -- Check and hold static - Invariant Static (CToken cZRX ExchangeRateStored) - Invariant Remains (Erc20 cZRX TokenBalance Geoff) 500e8 + Invariant Static (SLToken slZRX ExchangeRateStored) + Invariant Remains (Erc20 slZRX TokenBalance Geoff) 500e8 Invariant Remains (Erc20 ZRX TokenBalance Geoff) 20e18 -- Now redeem after some time FastForward 2 Blocks AllowFailures - RedeemUnderlying Geoff 50.1e18 cZRX + RedeemUnderlying Geoff 50.1e18 slZRX Assert Failure MATH_ERROR REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED "3" Test "Mint then Redeem Zero" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff 70e18 ZRX cZRX - Mint Geoff 50e18 cZRX + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff 70e18 ZRX slZRX + Mint Geoff 50e18 slZRX -- Check current affairs - Assert Equal (Erc20 cZRX TokenBalance Geoff) 500e8 + Assert Equal (Erc20 slZRX TokenBalance Geoff) 500e8 Assert Equal (Erc20 ZRX TokenBalance Geoff) 20e18 -- Any other good invariants? - Invariant Static (CToken cZRX ExchangeRateStored) + Invariant Static (SLToken slZRX ExchangeRateStored) -- Now redeem after some time FastForward 2 Blocks - RedeemUnderlying Geoff 0e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) 500e8 + RedeemUnderlying Geoff 0e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) 500e8 Assert Equal (Erc20 ZRX TokenBalance Geoff) 20e18 Test "Mint then redeem with interest - no reserves" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Invariant Remains (CToken cZRX Reserves) Zero - Prep Geoff 50e18 ZRX cZRX - Mint Geoff 50e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) 500e8 - Assert Equal (CToken cZRX UnderlyingBalance Geoff) 50e18 - Assert Equal (CToken cZRX ExchangeRate) 1e9 + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Invariant Remains (SLToken slZRX Reserves) Zero + Prep Geoff 50e18 ZRX slZRX + Mint Geoff 50e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) 500e8 + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) 50e18 + Assert Equal (SLToken slZRX ExchangeRate) 1e9 -- Get some brah to borrow then repay - BorrowAndRepayWithInterest ZRX cZRX 10e18 5e18 interestRate:0.000001 blocks:500000 + BorrowAndRepayWithInterest ZRX slZRX 10e18 5e18 interestRate:0.000001 blocks:500000 -- We've accrued .001% interest for 500000 blocks, or 50% of the principal, -- thus, we should have accrued 5e18 of interest for the protocol -- This is due pro-rata to all suppliers, but we just have one, so -- let's check that account is given correct new balance. - Assert Equal (Erc20 cZRX TokenBalance Geoff) 500e8 - Assert Equal (CToken cZRX UnderlyingBalance Geoff) 55e18 - Assert Equal (CToken cZRX ExchangeRate) 1.1e9 + Assert Equal (Erc20 slZRX TokenBalance Geoff) 500e8 + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) 55e18 + Assert Equal (SLToken slZRX ExchangeRate) 1.1e9 -- Now redeem all with interest -- Exchange rate is now 55e18 ÷ 50e9 = 1.1e9 -- 500e9 * 1.1e9 = 55e18 - RedeemUnderlying Geoff 55e18 cZRX + RedeemUnderlying Geoff 55e18 slZRX Assert Equal (Erc20 ZRX TokenBalance Geoff) 55e18 - Assert Equal (Erc20 ZRX TokenBalance cZRX) 0e18 - Assert Equal (Erc20 cZRX TokenBalance Geoff) 0e8 - Assert Equal (CToken cZRX UnderlyingBalance Geoff) 0e18 - Assert Equal (CToken cZRX ExchangeRate) 1e9 + Assert Equal (Erc20 ZRX TokenBalance slZRX) 0e18 + Assert Equal (Erc20 slZRX TokenBalance Geoff) 0e8 + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) 0e18 + Assert Equal (SLToken slZRX ExchangeRate) 1e9 Test "Mint then redeem part with interest - no reserves" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Invariant Remains (CToken cZRX Reserves) Zero - Prep Geoff 50e18 ZRX cZRX - Mint Geoff 50e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) 500e8 - Assert Equal (CToken cZRX UnderlyingBalance Geoff) 50e18 - Assert Equal (CToken cZRX ExchangeRate) 1e9 + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Invariant Remains (SLToken slZRX Reserves) Zero + Prep Geoff 50e18 ZRX slZRX + Mint Geoff 50e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) 500e8 + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) 50e18 + Assert Equal (SLToken slZRX ExchangeRate) 1e9 -- Get some brah to borrow then repay - BorrowAndRepayWithInterest ZRX cZRX 10e18 5e18 interestRate:0.000001 blocks:500000 + BorrowAndRepayWithInterest ZRX slZRX 10e18 5e18 interestRate:0.000001 blocks:500000 -- We've accrued .001% interest for 500000 blocks, or 50% of the principal, -- thus, we should have accrued 5e18 of interest for the protocol -- This is due pro-rata to all suppliers, but we just have one, so -- let's check that account is given correct new balance. - Assert Equal (Erc20 cZRX TokenBalance Geoff) 500e8 - Assert Equal (CToken cZRX UnderlyingBalance Geoff) 55e18 - Assert Equal (CToken cZRX ExchangeRate) 1.1e9 + Assert Equal (Erc20 slZRX TokenBalance Geoff) 500e8 + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) 55e18 + Assert Equal (SLToken slZRX ExchangeRate) 1.1e9 -- Now redeem all with interest -- Exchange rate is now 55e18 ÷ 50e9 = 1.1e9 -- 499e9 * 1.1e9 = 54.89e18 - RedeemUnderlying Geoff 54.89e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) 1e8 - Assert Equal (CToken cZRX UnderlyingBalance Geoff) 0.11e18 - Assert Equal (CToken cZRX ExchangeRate) 1.1e9 + RedeemUnderlying Geoff 54.89e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) 1e8 + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) 0.11e18 + Assert Equal (SLToken slZRX ExchangeRate) 1.1e9 Test "Mint then redeem with reserves and interest" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff 50e18 ZRX cZRX - Mint Geoff 50e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) 500e8 - Assert Equal (CToken cZRX UnderlyingBalance Geoff) 50e18 - Assert Equal (CToken cZRX ExchangeRate) 1e9 + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff 50e18 ZRX slZRX + Mint Geoff 50e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) 500e8 + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) 50e18 + Assert Equal (SLToken slZRX ExchangeRate) 1e9 -- Get some brah to borrow then repay - BorrowAndRepayWithInterest ZRX cZRX 10e18 5e18 interestRate:0.000001 blocks:500000 reserveRate:0.2 + BorrowAndRepayWithInterest ZRX slZRX 10e18 5e18 interestRate:0.000001 blocks:500000 reserveRate:0.2 -- We've accrued .001% interest for 500000 blocks, or 50% of the principal, -- thus, we should have accrued 5e18 of interest for the protocol -- The reserves should get 20% of this, or 1e18, and the rest -- is due pro-rata to all suppliers. We just have one, so -- let's check that account is given correct new balance. - Assert Equal (Erc20 cZRX TokenBalance Geoff) 500e8 - Assert Equal (CToken cZRX Reserves) 1e18 - Assert Equal (CToken cZRX UnderlyingBalance Geoff) 54e18 + Assert Equal (Erc20 slZRX TokenBalance Geoff) 500e8 + Assert Equal (SLToken slZRX Reserves) 1e18 + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) 54e18 -- 55e18 + 0e18 - 1e18 / 500 - Assert Equal (CToken cZRX ExchangeRate) 1.08e9 + Assert Equal (SLToken slZRX ExchangeRate) 1.08e9 -- Now redeem all with interest -- Exchange rate is 1.08e9 -- 500e8 * 1.08e9 = 54e18 - RedeemUnderlying Geoff 54e18 cZRX + RedeemUnderlying Geoff 54e18 slZRX Assert Equal (Erc20 ZRX TokenBalance Geoff) 54e18 - Assert Equal (Erc20 ZRX TokenBalance cZRX) 1e18 - Assert Equal (Erc20 cZRX TokenBalance Geoff) 0e8 - Assert Equal (CToken cZRX Reserves) 1e18 - Assert Equal (CToken cZRX UnderlyingBalance Geoff) 0e18 - Assert Equal (CToken cZRX ExchangeRate) 1e9 + Assert Equal (Erc20 ZRX TokenBalance slZRX) 1e18 + Assert Equal (Erc20 slZRX TokenBalance Geoff) 0e8 + Assert Equal (SLToken slZRX Reserves) 1e18 + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) 0e18 + Assert Equal (SLToken slZRX ExchangeRate) 1e9 Test "Two users Mint, one redeems" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff Some ZRX cZRX - Prep Torrey Some ZRX cZRX - Mint Geoff 2e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) 20e8 - Assert Equal (Erc20 cZRX TotalSupply) 20e8 - Mint Torrey 2e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) 20e8 - Assert Equal (Erc20 cZRX TokenBalance Torrey) 20e8 - Assert Equal (Erc20 cZRX TotalSupply) 40e8 - RedeemUnderlying Torrey 1e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) 20e8 - Assert Equal (Erc20 cZRX TokenBalance Torrey) 10e8 - Assert Equal (Erc20 cZRX TotalSupply) 30e8 + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff Some ZRX slZRX + Prep Torrey Some ZRX slZRX + Mint Geoff 2e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) 20e8 + Assert Equal (Erc20 slZRX TotalSupply) 20e8 + Mint Torrey 2e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) 20e8 + Assert Equal (Erc20 slZRX TokenBalance Torrey) 20e8 + Assert Equal (Erc20 slZRX TotalSupply) 40e8 + RedeemUnderlying Torrey 1e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) 20e8 + Assert Equal (Erc20 slZRX TokenBalance Torrey) 10e8 + Assert Equal (Erc20 slZRX TotalSupply) 30e8 Test "Mint then Redeem 1 wei of underlying" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff 70e18 ZRX cZRX - Mint Geoff 50e18 cZRX + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff 70e18 ZRX slZRX + Mint Geoff 50e18 slZRX AllowFailures -- Check current affairs - Invariant Remains (Erc20 cZRX TokenBalance Geoff) 500e8 + Invariant Remains (Erc20 slZRX TokenBalance Geoff) 500e8 Invariant Remains (Erc20 ZRX TokenBalance Geoff) 20e18 -- Any other good invariants? - Invariant Static (CToken cZRX ExchangeRateStored) + Invariant Static (SLToken slZRX ExchangeRateStored) -- Now redeem after some time FastForward 2 Blocks - RedeemUnderlying Geoff 1 cZRX + RedeemUnderlying Geoff 1 slZRX Assert Revert "revert redeemTokens zero" diff --git a/spec/scenario/RedeemUnderlyingEth.scen b/spec/scenario/RedeemUnderlyingEth.scen index c03ab5a8b..6f7a4e042 100644 --- a/spec/scenario/RedeemUnderlyingEth.scen +++ b/spec/scenario/RedeemUnderlyingEth.scen @@ -2,169 +2,169 @@ Test "Mint then Redeem All" NewComptroller - ListedEtherToken cETH initialExchangeRate:0.005e9 - CallMintEth Geoff 0.005e18 cETH + ListedEtherToken slETH initialExchangeRate:0.005e9 + CallMintEth Geoff 0.005e18 slETH -- Check current affairs - Assert Equal (Erc20 cETH TokenBalance Geoff) 10e8 - Assert Equal (CToken cETH UnderlyingBalance Geoff) 0.005e18 - Invariant Static (CToken cETH ExchangeRateStored) + Assert Equal (Erc20 slETH TokenBalance Geoff) 10e8 + Assert Equal (SLToken slETH UnderlyingBalance Geoff) 0.005e18 + Invariant Static (SLToken slETH ExchangeRateStored) -- Now redeem after some time FastForward 2 Blocks Expect Changes (EtherBalance Geoff) +0.005e18 - RedeemUnderlyingEth Geoff 0.005e18 cETH - Assert Equal (Erc20 cETH TokenBalance Geoff) Zero - Assert Equal (CToken cETH UnderlyingBalance Geoff) Zero + RedeemUnderlyingEth Geoff 0.005e18 slETH + Assert Equal (Erc20 slETH TokenBalance Geoff) Zero + Assert Equal (SLToken slETH UnderlyingBalance Geoff) Zero Test "Mint then Redeem Part" NewComptroller - ListedEtherToken cETH initialExchangeRate:0.005e9 - CallMintEth Geoff 0.005e18 cETH + ListedEtherToken slETH initialExchangeRate:0.005e9 + CallMintEth Geoff 0.005e18 slETH -- Check current affairs - Assert Equal (Erc20 cETH TokenBalance Geoff) 10e8 - Assert Equal (CToken cETH UnderlyingBalance Geoff) 0.005e18 - Invariant Static (CToken cETH ExchangeRateStored) + Assert Equal (Erc20 slETH TokenBalance Geoff) 10e8 + Assert Equal (SLToken slETH UnderlyingBalance Geoff) 0.005e18 + Invariant Static (SLToken slETH ExchangeRateStored) -- Now redeem after some time FastForward 2 Blocks Expect Changes (EtherBalance Geoff) +0.001e18 - RedeemUnderlyingEth Geoff 0.001e18 cETH - Assert Equal (Erc20 cETH TokenBalance Geoff) 8e8 - Assert Equal (CToken cETH UnderlyingBalance Geoff) 0.004e18 + RedeemUnderlyingEth Geoff 0.001e18 slETH + Assert Equal (Erc20 slETH TokenBalance Geoff) 8e8 + Assert Equal (SLToken slETH UnderlyingBalance Geoff) 0.004e18 Test "Mint then Redeem Too Much" NewComptroller - ListedEtherToken cETH initialExchangeRate:0.005e9 - CallMintEth Geoff 0.005e18 cETH + ListedEtherToken slETH initialExchangeRate:0.005e9 + CallMintEth Geoff 0.005e18 slETH AllowFailures -- Check and hold static - Invariant Static (CToken cETH ExchangeRateStored) - Invariant Remains (Erc20 cETH TokenBalance Geoff) 10e8 + Invariant Static (SLToken slETH ExchangeRateStored) + Invariant Remains (Erc20 slETH TokenBalance Geoff) 10e8 Invariant Static (EtherBalance Geoff) -- Now redeem after some time FastForward 2 Blocks - RedeemUnderlyingEth Geoff 0.0055e18 cETH + RedeemUnderlyingEth Geoff 0.0055e18 slETH -- TODO: This should really be REDEEM_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED, but based on -- the order of subtractions, total supply comes before account supply. Assert Failure MATH_ERROR REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED "3" -- TODO: This error is wrong Test "Mint then Redeem Zero" NewComptroller - ListedEtherToken cETH initialExchangeRate:0.005e9 - CallMintEth Geoff 0.005e18 cETH + ListedEtherToken slETH initialExchangeRate:0.005e9 + CallMintEth Geoff 0.005e18 slETH -- Check and hold static - Invariant Static (CToken cETH ExchangeRateStored) - Invariant Remains (Erc20 cETH TokenBalance Geoff) 10e8 + Invariant Static (SLToken slETH ExchangeRateStored) + Invariant Remains (Erc20 slETH TokenBalance Geoff) 10e8 Invariant Static (EtherBalance Geoff) -- Now redeem after some time FastForward 2 Blocks - RedeemUnderlyingEth Geoff 0e18 cETH + RedeemUnderlyingEth Geoff 0e18 slETH Test "Mint then redeem with interest - no reserves" Invariant Success NewComptroller - ListedEtherToken cETH initialExchangeRate:1e9 - Invariant Remains (CToken cETH Reserves) Zero - CallMintEth Geoff 50e18 cETH - Assert Equal (Erc20 cETH TokenBalance Geoff) 500e8 - Assert Equal (CToken cETH UnderlyingBalance Geoff) 50e18 - Assert Equal (CToken cETH ExchangeRate) 1e9 + ListedEtherToken slETH initialExchangeRate:1e9 + Invariant Remains (SLToken slETH Reserves) Zero + CallMintEth Geoff 50e18 slETH + Assert Equal (Erc20 slETH TokenBalance Geoff) 500e8 + Assert Equal (SLToken slETH UnderlyingBalance Geoff) 50e18 + Assert Equal (SLToken slETH ExchangeRate) 1e9 -- Get some brah to borrow then repay - BorrowAndRepayEthWithInterest cETH 10e18 5e18 interestRate:0.000001 blocks:500000 + BorrowAndRepayEthWithInterest slETH 10e18 5e18 interestRate:0.000001 blocks:500000 -- We've accrued 10% interest for 5 blocks, or 50% of the amount, -- thus, we should have accrued 5e18 of interest for the protocol -- This is due pro-rata to all holders, but we just have one, so -- let's check that account is given correct new balance. - Assert Equal (Erc20 cETH TokenBalance Geoff) 500e8 - Assert Equal (CToken cETH UnderlyingBalance Geoff) 55e18 - Assert Equal (CToken cETH ExchangeRate) 1.1e9 + Assert Equal (Erc20 slETH TokenBalance Geoff) 500e8 + Assert Equal (SLToken slETH UnderlyingBalance Geoff) 55e18 + Assert Equal (SLToken slETH ExchangeRate) 1.1e9 -- Now redeem all with interest Expect Changes (EtherBalance Geoff) 55e18 - RedeemUnderlyingEth Geoff 55e18 cETH - Assert Equal (EtherBalance cETH) 0e18 - Assert Equal (Erc20 cETH TokenBalance Geoff) 0e8 - Assert Equal (CToken cETH UnderlyingBalance Geoff) 0e18 - Assert Equal (CToken cETH ExchangeRate) 1e9 + RedeemUnderlyingEth Geoff 55e18 slETH + Assert Equal (EtherBalance slETH) 0e18 + Assert Equal (Erc20 slETH TokenBalance Geoff) 0e8 + Assert Equal (SLToken slETH UnderlyingBalance Geoff) 0e18 + Assert Equal (SLToken slETH ExchangeRate) 1e9 Pending "Mint then redeem part with interest - no reserves" Invariant Success NewComptroller - ListedCToken ZRX cETH initialExchangeRate:1e9 - Invariant Remains (CToken cETH Reserves) Zero - Prep Geoff 50e18 ZRX cETH - Mint Geoff 50e18 cETH - Assert Equal (Erc20 cETH TokenBalance Geoff) 500e8 - Assert Equal (CToken cETH UnderlyingBalance Geoff) 50e18 - Assert Equal (CToken cETH ExchangeRate) 1e9 + ListedSLToken ZRX slETH initialExchangeRate:1e9 + Invariant Remains (SLToken slETH Reserves) Zero + Prep Geoff 50e18 ZRX slETH + Mint Geoff 50e18 slETH + Assert Equal (Erc20 slETH TokenBalance Geoff) 500e8 + Assert Equal (SLToken slETH UnderlyingBalance Geoff) 50e18 + Assert Equal (SLToken slETH ExchangeRate) 1e9 -- Get some brah to borrow then repay - BorrowAndRepayWithInterest ZRX cETH 10e18 5e18 interestRate:0.000001 blocks:500000 + BorrowAndRepayWithInterest ZRX slETH 10e18 5e18 interestRate:0.000001 blocks:500000 -- We've accrued 10% interest for 5 blocks, or 50% of the amount, -- thus, we should have accrued 5e18 of interest for the protocol -- This is due pro-rata to all holders, but we just have one, so -- let's check that account is given correct new balance. - Assert Equal (Erc20 cETH TokenBalance Geoff) 500e8 - Assert Equal (CToken cETH UnderlyingBalance Geoff) 55e18 - Assert Equal (CToken cETH ExchangeRate) 1.1e9 + Assert Equal (Erc20 slETH TokenBalance Geoff) 500e8 + Assert Equal (SLToken slETH UnderlyingBalance Geoff) 55e18 + Assert Equal (SLToken slETH ExchangeRate) 1.1e9 -- Now redeem all with interest - Redeem Geoff 499e8 cETH - Assert Equal (Erc20 cETH TokenBalance Geoff) 1e8 - Assert Equal (CToken cETH UnderlyingBalance Geoff) 0.11e18 - Assert Equal (CToken cETH ExchangeRate) 1.1e9 + Redeem Geoff 499e8 slETH + Assert Equal (Erc20 slETH TokenBalance Geoff) 1e8 + Assert Equal (SLToken slETH UnderlyingBalance Geoff) 0.11e18 + Assert Equal (SLToken slETH ExchangeRate) 1.1e9 Pending "Mint then redeem with reserves and interest" Invariant Success NewComptroller - ListedCToken ZRX cETH initialExchangeRate:1e9 - Prep Geoff 50e18 ZRX cETH - Mint Geoff 50e18 cETH - Assert Equal (Erc20 cETH TokenBalance Geoff) 500e8 - Assert Equal (CToken cETH UnderlyingBalance Geoff) 50e18 - Assert Equal (CToken cETH ExchangeRate) 1e9 + ListedSLToken ZRX slETH initialExchangeRate:1e9 + Prep Geoff 50e18 ZRX slETH + Mint Geoff 50e18 slETH + Assert Equal (Erc20 slETH TokenBalance Geoff) 500e8 + Assert Equal (SLToken slETH UnderlyingBalance Geoff) 50e18 + Assert Equal (SLToken slETH ExchangeRate) 1e9 -- Get some brah to borrow then repay - BorrowAndRepayWithInterest ZRX cETH 10e18 5e18 interestRate:0.000001 blocks:500000 reserveRate:0.2 + BorrowAndRepayWithInterest ZRX slETH 10e18 5e18 interestRate:0.000001 blocks:500000 reserveRate:0.2 -- We've accrued 10% interest for 5 blocks, or 50% of the amount, -- thus, we should have accrued 5e18 of interest for the protocol -- The reserves should get 20% of this, or 1e18, and the rest -- is due pro-rata to all holders. We just have one, so -- let's check that account is given correct new balance. - Assert Equal (Erc20 cETH TokenBalance Geoff) 500e8 - Assert Equal (CToken cETH Reserves) 1e18 - Assert Equal (CToken cETH UnderlyingBalance Geoff) 54e18 + Assert Equal (Erc20 slETH TokenBalance Geoff) 500e8 + Assert Equal (SLToken slETH Reserves) 1e18 + Assert Equal (SLToken slETH UnderlyingBalance Geoff) 54e18 -- 55e18 + 0e18 - 1e18 / 500 - Assert Equal (CToken cETH ExchangeRate) 1.08e9 + Assert Equal (SLToken slETH ExchangeRate) 1.08e9 -- Now redeem all with interest - Redeem Geoff 500e8 cETH + Redeem Geoff 500e8 slETH Assert Equal (Erc20 ZRX TokenBalance Geoff) 54e18 - Assert Equal (Erc20 ZRX TokenBalance cETH) 1e18 - Assert Equal (Erc20 cETH TokenBalance Geoff) 0e8 - Assert Equal (CToken cETH Reserves) 1e18 - Assert Equal (CToken cETH UnderlyingBalance Geoff) 0e18 - Assert Equal (CToken cETH ExchangeRate) 1e9 + Assert Equal (Erc20 ZRX TokenBalance slETH) 1e18 + Assert Equal (Erc20 slETH TokenBalance Geoff) 0e8 + Assert Equal (SLToken slETH Reserves) 1e18 + Assert Equal (SLToken slETH UnderlyingBalance Geoff) 0e18 + Assert Equal (SLToken slETH ExchangeRate) 1e9 Test "Two users Mint, one redeems" NewComptroller - ListedEtherToken cETH initialExchangeRate:0.005e9 - CallMintEth Geoff 0.002e18 cETH - Assert Equal (Erc20 cETH TokenBalance Geoff) 4e8 - Assert Equal (Erc20 cETH TotalSupply) 4e8 - CallMintEth Torrey 0.004e18 cETH - Assert Equal (Erc20 cETH TokenBalance Geoff) 4e8 - Assert Equal (Erc20 cETH TokenBalance Torrey) 8e8 - Assert Equal (Erc20 cETH TotalSupply) 12e8 - RedeemUnderlyingEth Torrey 0.0015e18 cETH - Assert Equal (Erc20 cETH TokenBalance Geoff) 4e8 - Assert Equal (Erc20 cETH TokenBalance Torrey) 5e8 - Assert Equal (Erc20 cETH TotalSupply) 9e8 + ListedEtherToken slETH initialExchangeRate:0.005e9 + CallMintEth Geoff 0.002e18 slETH + Assert Equal (Erc20 slETH TokenBalance Geoff) 4e8 + Assert Equal (Erc20 slETH TotalSupply) 4e8 + CallMintEth Torrey 0.004e18 slETH + Assert Equal (Erc20 slETH TokenBalance Geoff) 4e8 + Assert Equal (Erc20 slETH TokenBalance Torrey) 8e8 + Assert Equal (Erc20 slETH TotalSupply) 12e8 + RedeemUnderlyingEth Torrey 0.0015e18 slETH + Assert Equal (Erc20 slETH TokenBalance Geoff) 4e8 + Assert Equal (Erc20 slETH TokenBalance Torrey) 5e8 + Assert Equal (Erc20 slETH TotalSupply) 9e8 Test "Mint then redeem 1 wei" NewComptroller - ListedEtherToken cETH initialExchangeRate:0.005e9 - CallMintEth Geoff 0.005e18 cETH + ListedEtherToken slETH initialExchangeRate:0.005e9 + CallMintEth Geoff 0.005e18 slETH AllowFailures -- Check current affairs - Assert Equal (Erc20 cETH TokenBalance Geoff) 10e8 - Assert Equal (CToken cETH UnderlyingBalance Geoff) 0.005e18 - Invariant Static (CToken cETH ExchangeRateStored) + Assert Equal (Erc20 slETH TokenBalance Geoff) 10e8 + Assert Equal (SLToken slETH UnderlyingBalance Geoff) 0.005e18 + Invariant Static (SLToken slETH ExchangeRateStored) Invariant Static (EtherBalance Geoff) -- Now redeem after some time FastForward 2 Blocks - RedeemUnderlyingEth Geoff 1 cETH + RedeemUnderlyingEth Geoff 1 slETH Assert Revert "revert redeemTokens zero" diff --git a/spec/scenario/RedeemUnderlyingWBTC.scen b/spec/scenario/RedeemUnderlyingWBTC.scen index d3c058a5e..47b59cadf 100644 --- a/spec/scenario/RedeemUnderlyingWBTC.scen +++ b/spec/scenario/RedeemUnderlyingWBTC.scen @@ -2,182 +2,182 @@ Test "Mint then Redeem All" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.1 tokenType:WBTC - Prep Geoff 70e8 WBTC cWBTC - Mint Geoff 50e8 cWBTC + ListedSLToken WBTC slWBTC initialExchangeRate:0.1 tokenType:WBTC + Prep Geoff 70e8 WBTC slWBTC + Mint Geoff 50e8 slWBTC -- Check current affairs - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 500e8 + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 500e8 Assert Equal (Erc20 WBTC TokenBalance Geoff) 20e8 -- Any other good invariants? - Invariant Static (CToken cWBTC ExchangeRateStored) + Invariant Static (SLToken slWBTC ExchangeRateStored) -- Now redeem after some time FastForward 2 Blocks - RedeemUnderlying Geoff 50e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) Zero + RedeemUnderlying Geoff 50e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) Zero Assert Equal (Erc20 WBTC TokenBalance Geoff) 70e8 Test "Mint then Redeem Part" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.1 tokenType:WBTC - Prep Geoff 70e8 WBTC cWBTC - Mint Geoff 50e8 cWBTC + ListedSLToken WBTC slWBTC initialExchangeRate:0.1 tokenType:WBTC + Prep Geoff 70e8 WBTC slWBTC + Mint Geoff 50e8 slWBTC -- Check current affairs - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 500e8 + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 500e8 Assert Equal (Erc20 WBTC TokenBalance Geoff) 20e8 -- Any other good invariants? - Invariant Static (CToken cWBTC ExchangeRateStored) + Invariant Static (SLToken slWBTC ExchangeRateStored) -- Now redeem after some time FastForward 2 Blocks - RedeemUnderlying Geoff 25e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 250e8 + RedeemUnderlying Geoff 25e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 250e8 Assert Equal (Erc20 WBTC TokenBalance Geoff) 45e8 Test "Mint then Redeem Too Much" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.1 tokenType:WBTC - Prep Geoff 70e8 WBTC cWBTC - Mint Geoff 50e8 cWBTC + ListedSLToken WBTC slWBTC initialExchangeRate:0.1 tokenType:WBTC + Prep Geoff 70e8 WBTC slWBTC + Mint Geoff 50e8 slWBTC -- Check and hold static - Invariant Static (CToken cWBTC ExchangeRateStored) - Invariant Remains (Erc20 cWBTC TokenBalance Geoff) 500e8 + Invariant Static (SLToken slWBTC ExchangeRateStored) + Invariant Remains (Erc20 slWBTC TokenBalance Geoff) 500e8 Invariant Remains (Erc20 WBTC TokenBalance Geoff) 20e8 -- Now redeem after some time FastForward 2 Blocks AllowFailures - RedeemUnderlying Geoff 50.1e8 cWBTC + RedeemUnderlying Geoff 50.1e8 slWBTC Assert Failure MATH_ERROR REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED "3" Test "Mint then Redeem Zero" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.1 tokenType:WBTC - Prep Geoff 70e8 WBTC cWBTC - Mint Geoff 50e8 cWBTC + ListedSLToken WBTC slWBTC initialExchangeRate:0.1 tokenType:WBTC + Prep Geoff 70e8 WBTC slWBTC + Mint Geoff 50e8 slWBTC -- Check current affairs - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 500e8 + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 500e8 Assert Equal (Erc20 WBTC TokenBalance Geoff) 20e8 -- Any other good invariants? - Invariant Static (CToken cWBTC ExchangeRateStored) + Invariant Static (SLToken slWBTC ExchangeRateStored) -- Now redeem after some time FastForward 2 Blocks - RedeemUnderlying Geoff 0e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 500e8 + RedeemUnderlying Geoff 0e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 500e8 Assert Equal (Erc20 WBTC TokenBalance Geoff) 20e8 Test "Mint then redeem with interest - no reserves" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.1 tokenType:WBTC - Invariant Remains (CToken cWBTC Reserves) Zero - Prep Geoff 50e8 WBTC cWBTC - Mint Geoff 50e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 500e8 - Assert Equal (CToken cWBTC UnderlyingBalance Geoff) 50e8 - Assert Equal (CToken cWBTC ExchangeRate) 0.1 + ListedSLToken WBTC slWBTC initialExchangeRate:0.1 tokenType:WBTC + Invariant Remains (SLToken slWBTC Reserves) Zero + Prep Geoff 50e8 WBTC slWBTC + Mint Geoff 50e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 500e8 + Assert Equal (SLToken slWBTC UnderlyingBalance Geoff) 50e8 + Assert Equal (SLToken slWBTC ExchangeRate) 0.1 -- Get some brah to borrow then repay - BorrowAndRepayWithInterest WBTC cWBTC 10e8 5e8 interestRate:0.000001 blocks:500000 + BorrowAndRepayWithInterest WBTC slWBTC 10e8 5e8 interestRate:0.000001 blocks:500000 -- We've accrued .001% interest for 500000 blocks, or 50% of the principal, -- thus, we should have accrued 5e8 of interest for the protocol -- This is due pro-rata to all suppliers, but we just have one, so -- let's check that account is given correct new balance. - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 500e8 - Assert Equal (CToken cWBTC UnderlyingBalance Geoff) 55e8 - Assert Equal (CToken cWBTC ExchangeRate) 0.11 + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 500e8 + Assert Equal (SLToken slWBTC UnderlyingBalance Geoff) 55e8 + Assert Equal (SLToken slWBTC ExchangeRate) 0.11 -- Now redeem all with interest -- Exchange rate is now 55e8 ÷ 50e-1 = 1.1e-1 -- 500e-1 * 1.1e-1 = 55e8 - RedeemUnderlying Geoff 55e8 cWBTC + RedeemUnderlying Geoff 55e8 slWBTC Assert Equal (Erc20 WBTC TokenBalance Geoff) 55e8 - Assert Equal (Erc20 WBTC TokenBalance cWBTC) 0e8 - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 0e8 - Assert Equal (CToken cWBTC UnderlyingBalance Geoff) 0e8 - Assert Equal (CToken cWBTC ExchangeRate) 0.1 + Assert Equal (Erc20 WBTC TokenBalance slWBTC) 0e8 + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 0e8 + Assert Equal (SLToken slWBTC UnderlyingBalance Geoff) 0e8 + Assert Equal (SLToken slWBTC ExchangeRate) 0.1 Test "Mint then redeem part with interest - no reserves" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.1 tokenType:WBTC - Invariant Remains (CToken cWBTC Reserves) Zero - Prep Geoff 50e8 WBTC cWBTC - Mint Geoff 50e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 500e8 - Assert Equal (CToken cWBTC UnderlyingBalance Geoff) 50e8 - Assert Equal (CToken cWBTC ExchangeRate) 0.1 + ListedSLToken WBTC slWBTC initialExchangeRate:0.1 tokenType:WBTC + Invariant Remains (SLToken slWBTC Reserves) Zero + Prep Geoff 50e8 WBTC slWBTC + Mint Geoff 50e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 500e8 + Assert Equal (SLToken slWBTC UnderlyingBalance Geoff) 50e8 + Assert Equal (SLToken slWBTC ExchangeRate) 0.1 -- Get some brah to borrow then repay - BorrowAndRepayWithInterest WBTC cWBTC 10e8 5e8 interestRate:0.000001 blocks:500000 + BorrowAndRepayWithInterest WBTC slWBTC 10e8 5e8 interestRate:0.000001 blocks:500000 -- We've accrued .001% interest for 500000 blocks, or 50% of the principal, -- thus, we should have accrued 5e8 of interest for the protocol -- This is due pro-rata to all suppliers, but we just have one, so -- let's check that account is given correct new balance. - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 500e8 - Assert Equal (CToken cWBTC UnderlyingBalance Geoff) 55e8 - Assert Equal (CToken cWBTC ExchangeRate) 0.11 + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 500e8 + Assert Equal (SLToken slWBTC UnderlyingBalance Geoff) 55e8 + Assert Equal (SLToken slWBTC ExchangeRate) 0.11 -- Now redeem all with interest -- Exchange rate is now 55e8 ÷ 50e-1 = 1.1e-1 -- 499e-1 * 1.1e-1 = 54.89e8 - RedeemUnderlying Geoff 54.89e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 1e8 - Assert Equal (CToken cWBTC UnderlyingBalance Geoff) 0.11e8 - Assert Equal (CToken cWBTC ExchangeRate) 0.11 + RedeemUnderlying Geoff 54.89e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 1e8 + Assert Equal (SLToken slWBTC UnderlyingBalance Geoff) 0.11e8 + Assert Equal (SLToken slWBTC ExchangeRate) 0.11 Test "Mint then redeem with reserves and interest" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.1 tokenType:WBTC - Prep Geoff 50e8 WBTC cWBTC - Mint Geoff 50e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 500e8 - Assert Equal (CToken cWBTC UnderlyingBalance Geoff) 50e8 - Assert Equal (CToken cWBTC ExchangeRate) 0.1 + ListedSLToken WBTC slWBTC initialExchangeRate:0.1 tokenType:WBTC + Prep Geoff 50e8 WBTC slWBTC + Mint Geoff 50e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 500e8 + Assert Equal (SLToken slWBTC UnderlyingBalance Geoff) 50e8 + Assert Equal (SLToken slWBTC ExchangeRate) 0.1 -- Get some brah to borrow then repay - BorrowAndRepayWithInterest WBTC cWBTC 10e8 5e8 interestRate:0.000001 blocks:500000 reserveRate:0.2 + BorrowAndRepayWithInterest WBTC slWBTC 10e8 5e8 interestRate:0.000001 blocks:500000 reserveRate:0.2 -- We've accrued .001% interest for 500000 blocks, or 50% of the principal, -- thus, we should have accrued 5e8 of interest for the protocol -- The reserves should get 20% of this, or 1e8, and the rest -- is due pro-rata to all suppliers. We just have one, so -- let's check that account is given correct new balance. - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 500e8 - Assert Equal (CToken cWBTC Reserves) 1e8 - Assert Equal (CToken cWBTC UnderlyingBalance Geoff) 54e8 + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 500e8 + Assert Equal (SLToken slWBTC Reserves) 1e8 + Assert Equal (SLToken slWBTC UnderlyingBalance Geoff) 54e8 -- 55e8 + 0e8 - 1e8 / 500 - Assert Equal (CToken cWBTC ExchangeRate) 0.108 + Assert Equal (SLToken slWBTC ExchangeRate) 0.108 -- Now redeem all with interest -- Exchange rate is 1.08e-1 -- 500e8 * 1.08e-1 = 54e8 - RedeemUnderlying Geoff 54e8 cWBTC + RedeemUnderlying Geoff 54e8 slWBTC Assert Equal (Erc20 WBTC TokenBalance Geoff) 54e8 - Assert Equal (Erc20 WBTC TokenBalance cWBTC) 1e8 - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 0e8 - Assert Equal (CToken cWBTC Reserves) 1e8 - Assert Equal (CToken cWBTC UnderlyingBalance Geoff) 0e8 - Assert Equal (CToken cWBTC ExchangeRate) 0.1 + Assert Equal (Erc20 WBTC TokenBalance slWBTC) 1e8 + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 0e8 + Assert Equal (SLToken slWBTC Reserves) 1e8 + Assert Equal (SLToken slWBTC UnderlyingBalance Geoff) 0e8 + Assert Equal (SLToken slWBTC ExchangeRate) 0.1 Test "Two users Mint, one redeems" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.1 tokenType:WBTC - Prep Geoff Some WBTC cWBTC - Prep Torrey Some WBTC cWBTC - Mint Geoff 2e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 20e8 - Assert Equal (Erc20 cWBTC TotalSupply) 20e8 - Mint Torrey 2e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 20e8 - Assert Equal (Erc20 cWBTC TokenBalance Torrey) 20e8 - Assert Equal (Erc20 cWBTC TotalSupply) 40e8 - RedeemUnderlying Torrey 1e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 20e8 - Assert Equal (Erc20 cWBTC TokenBalance Torrey) 10e8 - Assert Equal (Erc20 cWBTC TotalSupply) 30e8 + ListedSLToken WBTC slWBTC initialExchangeRate:0.1 tokenType:WBTC + Prep Geoff Some WBTC slWBTC + Prep Torrey Some WBTC slWBTC + Mint Geoff 2e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 20e8 + Assert Equal (Erc20 slWBTC TotalSupply) 20e8 + Mint Torrey 2e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 20e8 + Assert Equal (Erc20 slWBTC TokenBalance Torrey) 20e8 + Assert Equal (Erc20 slWBTC TotalSupply) 40e8 + RedeemUnderlying Torrey 1e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 20e8 + Assert Equal (Erc20 slWBTC TokenBalance Torrey) 10e8 + Assert Equal (Erc20 slWBTC TotalSupply) 30e8 Test "Mint then Redeem 1 wei of underlying is allowed for 1:1 assets" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.1 tokenType:WBTC - Prep Geoff 70e8 WBTC cWBTC - Mint Geoff 50e8 cWBTC + ListedSLToken WBTC slWBTC initialExchangeRate:0.1 tokenType:WBTC + Prep Geoff 70e8 WBTC slWBTC + Mint Geoff 50e8 slWBTC -- Check current affairs - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 500e8 + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 500e8 Assert Equal (Erc20 WBTC TokenBalance Geoff) 20e8 -- Any other good invariants? - Invariant Static (CToken cWBTC ExchangeRateStored) + Invariant Static (SLToken slWBTC ExchangeRateStored) -- Now redeem after some time FastForward 2 Blocks - RedeemUnderlying Geoff 1 cWBTC + RedeemUnderlying Geoff 1 slWBTC -- After affairs - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 49999999990 + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 49999999990 Assert Equal (Erc20 WBTC TokenBalance Geoff) 2000000001 diff --git a/spec/scenario/RedeemWBTC.scen b/spec/scenario/RedeemWBTC.scen index b95ea0da2..79085a675 100644 --- a/spec/scenario/RedeemWBTC.scen +++ b/spec/scenario/RedeemWBTC.scen @@ -2,225 +2,225 @@ Test "Mint WBTC then Redeem All" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.1 tokenType:WBTC - Prep Geoff 70e8 WBTC cWBTC - Mint Geoff 50e8 cWBTC + ListedSLToken WBTC slWBTC initialExchangeRate:0.1 tokenType:WBTC + Prep Geoff 70e8 WBTC slWBTC + Mint Geoff 50e8 slWBTC -- Check current affairs - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 500e8 + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 500e8 Assert Equal (Erc20 WBTC TokenBalance Geoff) 20e8 -- Any other good invariants? - Invariant Static (CToken cWBTC ExchangeRateStored) + Invariant Static (SLToken slWBTC ExchangeRateStored) -- Now redeem after some time FastForward 2 Blocks - Redeem Geoff 500e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) Zero + Redeem Geoff 500e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) Zero Assert Equal (Erc20 WBTC TokenBalance Geoff) 70e8 Test "Mint WBTC, Enter and then Redeem All" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.1 tokenType:WBTC - Prep Geoff 70e8 WBTC cWBTC - Mint Geoff 50e8 cWBTC + ListedSLToken WBTC slWBTC initialExchangeRate:0.1 tokenType:WBTC + Prep Geoff 70e8 WBTC slWBTC + Mint Geoff 50e8 slWBTC -- Check current affairs - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 500e8 + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 500e8 Assert Equal (Erc20 WBTC TokenBalance Geoff) 20e8 -- Any other good invariants? - Invariant Static (CToken cWBTC ExchangeRateStored) + Invariant Static (SLToken slWBTC ExchangeRateStored) -- Now redeem after some time FastForward 2 Blocks - EnterMarkets Geoff cWBTC - Redeem Geoff 500e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) Zero + EnterMarkets Geoff slWBTC + Redeem Geoff 500e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) Zero Assert Equal (Erc20 WBTC TokenBalance Geoff) 70e8 Test "Mint WBTC then Redeem Part" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.1 tokenType:WBTC - Prep Geoff 70e8 WBTC cWBTC - Mint Geoff 50e8 cWBTC + ListedSLToken WBTC slWBTC initialExchangeRate:0.1 tokenType:WBTC + Prep Geoff 70e8 WBTC slWBTC + Mint Geoff 50e8 slWBTC -- Check current affairs - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 500e8 + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 500e8 Assert Equal (Erc20 WBTC TokenBalance Geoff) 20e8 -- Any other good invariants? - Invariant Static (CToken cWBTC ExchangeRateStored) + Invariant Static (SLToken slWBTC ExchangeRateStored) -- Now redeem after some time FastForward 2 Blocks - Redeem Geoff 250e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 250e8 + Redeem Geoff 250e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 250e8 Assert Equal (Erc20 WBTC TokenBalance Geoff) 45e8 Test "Mint WBTC then Redeem Too Much" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.1 tokenType:WBTC - Prep Geoff 70e8 WBTC cWBTC - Mint Geoff 50e8 cWBTC + ListedSLToken WBTC slWBTC initialExchangeRate:0.1 tokenType:WBTC + Prep Geoff 70e8 WBTC slWBTC + Mint Geoff 50e8 slWBTC -- Check and hold static - Invariant Static (CToken cWBTC ExchangeRateStored) - Invariant Remains (Erc20 cWBTC TokenBalance Geoff) 500e8 + Invariant Static (SLToken slWBTC ExchangeRateStored) + Invariant Remains (Erc20 slWBTC TokenBalance Geoff) 500e8 Invariant Remains (Erc20 WBTC TokenBalance Geoff) 20e8 -- Now redeem after some time FastForward 2 Blocks AllowFailures - Redeem Geoff 501e8 cWBTC + Redeem Geoff 501e8 slWBTC Assert Failure MATH_ERROR REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED "3" Test "Mint WBTC then Redeem Zero" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.1 tokenType:WBTC - Prep Geoff 70e8 WBTC cWBTC - Mint Geoff 50e8 cWBTC + ListedSLToken WBTC slWBTC initialExchangeRate:0.1 tokenType:WBTC + Prep Geoff 70e8 WBTC slWBTC + Mint Geoff 50e8 slWBTC -- Check current affairs - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 500e8 + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 500e8 Assert Equal (Erc20 WBTC TokenBalance Geoff) 20e8 -- Any other good invariants? - Invariant Static (CToken cWBTC ExchangeRateStored) + Invariant Static (SLToken slWBTC ExchangeRateStored) -- Now redeem after some time FastForward 2 Blocks - Redeem Geoff 0e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 500e8 + Redeem Geoff 0e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 500e8 Assert Equal (Erc20 WBTC TokenBalance Geoff) 20e8 Test "Mint WBTC then redeem with interest - no reserves" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.1 tokenType:WBTC - Invariant Remains (CToken cWBTC Reserves) Zero - Prep Geoff 50e8 WBTC cWBTC - Mint Geoff 50e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 500e8 - Assert Equal (CToken cWBTC UnderlyingBalance Geoff) 50e8 - Assert Equal (CToken cWBTC ExchangeRate) 0.1 + ListedSLToken WBTC slWBTC initialExchangeRate:0.1 tokenType:WBTC + Invariant Remains (SLToken slWBTC Reserves) Zero + Prep Geoff 50e8 WBTC slWBTC + Mint Geoff 50e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 500e8 + Assert Equal (SLToken slWBTC UnderlyingBalance Geoff) 50e8 + Assert Equal (SLToken slWBTC ExchangeRate) 0.1 -- Get some brah to borrow then repay - BorrowAndRepayWithInterest WBTC cWBTC 10e8 5e8 interestRate:0.000001 blocks:500000 + BorrowAndRepayWithInterest WBTC slWBTC 10e8 5e8 interestRate:0.000001 blocks:500000 -- We've accrued .001% interest for 500000 blocks, or 50% of the principal, -- thus, we should have accrued 5e8 of interest for the protocol -- This is due pro-rata to all suppliers, but we just have one, so -- let's check that account is given correct new balance. - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 500e8 - Assert Equal (CToken cWBTC UnderlyingBalance Geoff) 55e8 - Assert Equal (CToken cWBTC ExchangeRate) 0.11 + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 500e8 + Assert Equal (SLToken slWBTC UnderlyingBalance Geoff) 55e8 + Assert Equal (SLToken slWBTC ExchangeRate) 0.11 -- Now redeem all with interest - Redeem Geoff 500e8 cWBTC + Redeem Geoff 500e8 slWBTC Assert Equal (Erc20 WBTC TokenBalance Geoff) 55e8 - Assert Equal (Erc20 WBTC TokenBalance cWBTC) 0e8 - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 0e8 - Assert Equal (CToken cWBTC UnderlyingBalance Geoff) 0e8 - Assert Equal (CToken cWBTC ExchangeRate) 0.1 + Assert Equal (Erc20 WBTC TokenBalance slWBTC) 0e8 + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 0e8 + Assert Equal (SLToken slWBTC UnderlyingBalance Geoff) 0e8 + Assert Equal (SLToken slWBTC ExchangeRate) 0.1 Test "Mint WBTC then redeem part with interest - no reserves" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.1 tokenType:WBTC - Invariant Remains (CToken cWBTC Reserves) Zero - Prep Geoff 50e8 WBTC cWBTC - Mint Geoff 50e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 500e8 - Assert Equal (CToken cWBTC UnderlyingBalance Geoff) 50e8 - Assert Equal (CToken cWBTC ExchangeRate) 0.1 + ListedSLToken WBTC slWBTC initialExchangeRate:0.1 tokenType:WBTC + Invariant Remains (SLToken slWBTC Reserves) Zero + Prep Geoff 50e8 WBTC slWBTC + Mint Geoff 50e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 500e8 + Assert Equal (SLToken slWBTC UnderlyingBalance Geoff) 50e8 + Assert Equal (SLToken slWBTC ExchangeRate) 0.1 -- Get some brah to borrow then repay - BorrowAndRepayWithInterest WBTC cWBTC 10e8 5e8 interestRate:0.000001 blocks:500000 + BorrowAndRepayWithInterest WBTC slWBTC 10e8 5e8 interestRate:0.000001 blocks:500000 -- We've accrued .001% interest for 500000 blocks, or 50% of the principal, -- thus, we should have accrued 5e8 of interest for the protocol -- This is due pro-rata to all suppliers, but we just have one, so -- let's check that account is given correct new balance. - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 500e8 - Assert Equal (CToken cWBTC UnderlyingBalance Geoff) 55e8 - Assert Equal (CToken cWBTC ExchangeRate) 0.11 + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 500e8 + Assert Equal (SLToken slWBTC UnderlyingBalance Geoff) 55e8 + Assert Equal (SLToken slWBTC ExchangeRate) 0.11 -- Now redeem all with interest - Redeem Geoff 499e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 1e8 - Assert Equal (CToken cWBTC UnderlyingBalance Geoff) 0.11e8 - Assert Equal (CToken cWBTC ExchangeRate) 0.11 + Redeem Geoff 499e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 1e8 + Assert Equal (SLToken slWBTC UnderlyingBalance Geoff) 0.11e8 + Assert Equal (SLToken slWBTC ExchangeRate) 0.11 Test "Mint WBTC then redeem with reserves and interest" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.1 tokenType:WBTC - Prep Geoff 50e8 WBTC cWBTC - Mint Geoff 50e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 500e8 - Assert Equal (CToken cWBTC UnderlyingBalance Geoff) 50e8 - Assert Equal (CToken cWBTC ExchangeRate) 0.1 + ListedSLToken WBTC slWBTC initialExchangeRate:0.1 tokenType:WBTC + Prep Geoff 50e8 WBTC slWBTC + Mint Geoff 50e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 500e8 + Assert Equal (SLToken slWBTC UnderlyingBalance Geoff) 50e8 + Assert Equal (SLToken slWBTC ExchangeRate) 0.1 -- Get some brah to borrow then repay - BorrowAndRepayWithInterest WBTC cWBTC 10e8 5e8 interestRate:0.000001 blocks:500000 reserveRate:0.2 + BorrowAndRepayWithInterest WBTC slWBTC 10e8 5e8 interestRate:0.000001 blocks:500000 reserveRate:0.2 -- We've accrued .001% interest for 500000 blocks, or 50% of the principal, -- thus, we should have accrued 5e8 of interest for the protocol -- The reserves should get 20% of this, or 1e8, and the rest -- is due pro-rata to all suppliers. We just have one, so -- let's check that account is given correct new balance. - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 500e8 - Assert Equal (CToken cWBTC Reserves) 1e8 - Assert Equal (CToken cWBTC UnderlyingBalance Geoff) 54e8 + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 500e8 + Assert Equal (SLToken slWBTC Reserves) 1e8 + Assert Equal (SLToken slWBTC UnderlyingBalance Geoff) 54e8 -- 55e8 + 0e8 - 1e8 / 500 - Assert Equal (CToken cWBTC ExchangeRate) 0.108 + Assert Equal (SLToken slWBTC ExchangeRate) 0.108 -- Now redeem all with interest - Redeem Geoff 500e8 cWBTC + Redeem Geoff 500e8 slWBTC Assert Equal (Erc20 WBTC TokenBalance Geoff) 54e8 - Assert Equal (Erc20 WBTC TokenBalance cWBTC) 1e8 - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 0e8 - Assert Equal (CToken cWBTC Reserves) 1e8 - Assert Equal (CToken cWBTC UnderlyingBalance Geoff) 0e8 - Assert Equal (CToken cWBTC ExchangeRate) 0.1 + Assert Equal (Erc20 WBTC TokenBalance slWBTC) 1e8 + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 0e8 + Assert Equal (SLToken slWBTC Reserves) 1e8 + Assert Equal (SLToken slWBTC UnderlyingBalance Geoff) 0e8 + Assert Equal (SLToken slWBTC ExchangeRate) 0.1 Test "Two users Mint WBTC, one redeems" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.1 tokenType:WBTC - Prep Geoff Some WBTC cWBTC - Prep Torrey Some WBTC cWBTC - Mint Geoff 2e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 20e8 - Assert Equal (Erc20 cWBTC TotalSupply) 20e8 - Mint Torrey 2e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 20e8 - Assert Equal (Erc20 cWBTC TokenBalance Torrey) 20e8 - Assert Equal (Erc20 cWBTC TotalSupply) 40e8 - Redeem Torrey 10e8 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) 20e8 - Assert Equal (Erc20 cWBTC TokenBalance Torrey) 10e8 - Assert Equal (Erc20 cWBTC TotalSupply) 30e8 + ListedSLToken WBTC slWBTC initialExchangeRate:0.1 tokenType:WBTC + Prep Geoff Some WBTC slWBTC + Prep Torrey Some WBTC slWBTC + Mint Geoff 2e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 20e8 + Assert Equal (Erc20 slWBTC TotalSupply) 20e8 + Mint Torrey 2e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 20e8 + Assert Equal (Erc20 slWBTC TokenBalance Torrey) 20e8 + Assert Equal (Erc20 slWBTC TotalSupply) 40e8 + Redeem Torrey 10e8 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) 20e8 + Assert Equal (Erc20 slWBTC TokenBalance Torrey) 10e8 + Assert Equal (Erc20 slWBTC TotalSupply) 30e8 Test "Redeem WBTC transfer out fails" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.1 tokenType:WBTC - Prep Geoff 70e8 WBTC cWBTC - Mint Geoff 50e8 cWBTC + ListedSLToken WBTC slWBTC initialExchangeRate:0.1 tokenType:WBTC + Prep Geoff 70e8 WBTC slWBTC + Mint Geoff 50e8 slWBTC -- Check current affairs - Invariant Remains (Erc20 cWBTC TokenBalance Geoff) 500e8 + Invariant Remains (Erc20 slWBTC TokenBalance Geoff) 500e8 Invariant Remains (Erc20 WBTC TokenBalance Geoff) 20e8 - Invariant Static (CToken cWBTC ExchangeRateStored) + Invariant Static (SLToken slWBTC ExchangeRateStored) -- Now redeem after some time FastForward 2 Blocks Erc20 WBTC Pause AllowFailures - Redeem Geoff 500e8 cWBTC + Redeem Geoff 500e8 slWBTC Assert Revert Test "Mint WBTC, Enter, then Redeem Too Much (collateral factor: 0)" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.1 tokenType:WBTC - Prep Geoff 70e8 WBTC cWBTC - Mint Geoff 50e8 cWBTC + ListedSLToken WBTC slWBTC initialExchangeRate:0.1 tokenType:WBTC + Prep Geoff 70e8 WBTC slWBTC + Mint Geoff 50e8 slWBTC -- Check and hold static - Invariant Static (CToken cWBTC ExchangeRateStored) - Invariant Remains (Erc20 cWBTC TokenBalance Geoff) 500e8 + Invariant Static (SLToken slWBTC ExchangeRateStored) + Invariant Remains (Erc20 slWBTC TokenBalance Geoff) 500e8 Invariant Remains (Erc20 WBTC TokenBalance Geoff) 20e8 -- Now redeem after some time FastForward 2 Blocks - EnterMarkets Geoff cWBTC + EnterMarkets Geoff slWBTC AllowFailures - Redeem Geoff 501e8 cWBTC + Redeem Geoff 501e8 slWBTC Assert Failure MATH_ERROR REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED "3" Test "Mint WBTC, Enter, then Redeem Too Much (collateral factor: 0.1)" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.1 tokenType:WBTC - Comptroller SetCollateralFactor cWBTC 0.1 - Prep Geoff 70e8 WBTC cWBTC - Mint Geoff 50e8 cWBTC + ListedSLToken WBTC slWBTC initialExchangeRate:0.1 tokenType:WBTC + Comptroller SetCollateralFactor slWBTC 0.1 + Prep Geoff 70e8 WBTC slWBTC + Mint Geoff 50e8 slWBTC -- Check and hold static - Invariant Static (CToken cWBTC ExchangeRateStored) - Invariant Remains (Erc20 cWBTC TokenBalance Geoff) 500e8 + Invariant Static (SLToken slWBTC ExchangeRateStored) + Invariant Remains (Erc20 slWBTC TokenBalance Geoff) 500e8 Invariant Remains (Erc20 WBTC TokenBalance Geoff) 20e8 -- Now redeem after some time FastForward 2 Blocks - EnterMarkets Geoff cWBTC + EnterMarkets Geoff slWBTC AllowFailures - Redeem Geoff 501e8 cWBTC + Redeem Geoff 501e8 slWBTC Assert Failure COMPTROLLER_REJECTION REDEEM_COMPTROLLER_REJECTION INSUFFICIENT_LIQUIDITY diff --git a/spec/scenario/ReduceReserves.scen b/spec/scenario/ReduceReserves.scen index 1d290e2db..d4c625367 100644 --- a/spec/scenario/ReduceReserves.scen +++ b/spec/scenario/ReduceReserves.scen @@ -1,136 +1,136 @@ Test "Reduce all reserves and verify effects" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff 50e18 ZRX cZRX - Mint Geoff 50e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 500e8) -- 50e18 / 1e9 - Assert Equal (CToken cZRX UnderlyingBalance Geoff) (Exactly 50e18) - Assert Equal (CToken cZRX ExchangeRate) (Exactly 1e9) + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff 50e18 ZRX slZRX + Mint Geoff 50e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 500e8) -- 50e18 / 1e9 + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) (Exactly 50e18) + Assert Equal (SLToken slZRX ExchangeRate) (Exactly 1e9) -- Get some brah to borrow then repay - BorrowAndRepayWithInterest ZRX cZRX 10e18 5e18 interestRate:0.000001 blocks:500000 reserveRate:0.2 + BorrowAndRepayWithInterest ZRX slZRX 10e18 5e18 interestRate:0.000001 blocks:500000 reserveRate:0.2 -- We've accrued .0001% interest for 500000 blocks, or 50% of the principal (10e18), -- thus, we should have accrued 5e18 of interest for the protocol -- The reserves should get 20% of this, or 1e18, and the rest -- is due pro-rata to all suppliers. We just have one, so -- let's check that account is given correct new balance. - Assert Equal (Erc20 ZRX TokenBalance cZRX) (Exactly 55e18) + Assert Equal (Erc20 ZRX TokenBalance slZRX) (Exactly 55e18) Assert Equal (Erc20 ZRX TokenBalance Root) (Exactly 0e18) - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 500e8) - Assert Equal (CToken cZRX Reserves) (Exactly 1e18) - Assert Equal (CToken cZRX UnderlyingBalance Geoff) (Exactly 54e18) + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 500e8) + Assert Equal (SLToken slZRX Reserves) (Exactly 1e18) + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) (Exactly 54e18) -- (55.0e18+0.0e18-1.0e18)/500.0e8 - Assert Equal (CToken cZRX ExchangeRate) (Exactly 1.08e9) + Assert Equal (SLToken slZRX ExchangeRate) (Exactly 1.08e9) -- Now, let's pull out all of our reserves (1e18) - ReduceReserves 1e18 cZRX - Assert Equal (Erc20 ZRX TokenBalance cZRX) (Exactly 54e18) + ReduceReserves 1e18 slZRX + Assert Equal (Erc20 ZRX TokenBalance slZRX) (Exactly 54e18) Assert Equal (Erc20 ZRX TokenBalance Root) (Exactly 1e18) - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 500e8) - Assert Equal (CToken cZRX Reserves) (Exactly 0e18) - Assert Equal (CToken cZRX UnderlyingBalance Geoff) (Exactly 54e18) + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 500e8) + Assert Equal (SLToken slZRX Reserves) (Exactly 0e18) + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) (Exactly 54e18) -- (54.0e18+0.0e18-0.0e18)/500.0e8 - Assert Equal (CToken cZRX ExchangeRate) (Exactly 1.08e9) + Assert Equal (SLToken slZRX ExchangeRate) (Exactly 1.08e9) Test "Reduce partial reserves and verify effects" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff 50e18 ZRX cZRX - Mint Geoff 50e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 500e8) - Assert Equal (CToken cZRX UnderlyingBalance Geoff) (Exactly 50e18) - Assert Equal (CToken cZRX ExchangeRate) (Exactly 1e9) + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff 50e18 ZRX slZRX + Mint Geoff 50e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 500e8) + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) (Exactly 50e18) + Assert Equal (SLToken slZRX ExchangeRate) (Exactly 1e9) -- Get some brah to borrow then repay - BorrowAndRepayWithInterest ZRX cZRX 10e18 5e18 interestRate:0.000001 blocks:500000 reserveRate:0.2 + BorrowAndRepayWithInterest ZRX slZRX 10e18 5e18 interestRate:0.000001 blocks:500000 reserveRate:0.2 -- We've accrued .0001% interest for 500000 blocks, or 50% of the principal (10e18), -- thus, we should have accrued 5e18 of interest for the protocol -- The reserves should get 20% of this, or 1e18, and the rest -- is due pro-rata to all suppliers. We just have one, so -- let's check that account is given correct new balance. - Assert Equal (Erc20 ZRX TokenBalance cZRX) (Exactly 55e18) + Assert Equal (Erc20 ZRX TokenBalance slZRX) (Exactly 55e18) Assert Equal (Erc20 ZRX TokenBalance Root) (Exactly 0e18) - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 500e8) - Assert Equal (CToken cZRX Reserves) (Exactly 1e18) - Assert Equal (CToken cZRX UnderlyingBalance Geoff) (Exactly 54e18) + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 500e8) + Assert Equal (SLToken slZRX Reserves) (Exactly 1e18) + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) (Exactly 54e18) -- (55.0e18+0.0e18-1.0e18)/500.0e8 - Assert Equal (CToken cZRX ExchangeRate) (Exactly 1.08e9) + Assert Equal (SLToken slZRX ExchangeRate) (Exactly 1.08e9) -- Now, let's pull out all of our reserves (1e18) - ReduceReserves 0.5e18 cZRX - Assert Equal (Erc20 ZRX TokenBalance cZRX) (Exactly 54.5e18) + ReduceReserves 0.5e18 slZRX + Assert Equal (Erc20 ZRX TokenBalance slZRX) (Exactly 54.5e18) Assert Equal (Erc20 ZRX TokenBalance Root) (Exactly 0.5e18) - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 500e8) - Assert Equal (CToken cZRX Reserves) (Exactly 0.5e18) - Assert Equal (CToken cZRX UnderlyingBalance Geoff) (Exactly 54e18) + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 500e8) + Assert Equal (SLToken slZRX Reserves) (Exactly 0.5e18) + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) (Exactly 54e18) -- (54.5e18+0.5e18-0.0e18)/500.0e8 - Assert Equal (CToken cZRX ExchangeRate) (Exactly 1.08e9) + Assert Equal (SLToken slZRX ExchangeRate) (Exactly 1.08e9) Test "Redeem all and then reduce all reserves" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff 50e18 ZRX cZRX - Mint Geoff 50e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 500e8) - Assert Equal (CToken cZRX UnderlyingBalance Geoff) (Exactly 50e18) - Assert Equal (CToken cZRX ExchangeRate) (Exactly 1e9) + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff 50e18 ZRX slZRX + Mint Geoff 50e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 500e8) + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) (Exactly 50e18) + Assert Equal (SLToken slZRX ExchangeRate) (Exactly 1e9) -- Get some brah to borrow then repay - BorrowAndRepayWithInterest ZRX cZRX 10e18 5e18 interestRate:0.000001 blocks:500000 reserveRate:0.2 + BorrowAndRepayWithInterest ZRX slZRX 10e18 5e18 interestRate:0.000001 blocks:500000 reserveRate:0.2 -- We've accrued .0001% interest for 500000 blocks, or 50% of the principal (10e18), -- thus, we should have accrued 5e18 of interest for the protocol -- The reserves should get 20% of this, or 1e18, and the rest -- is due pro-rata to all suppliers. We just have one, so -- let's check that account is given correct new balance. - Assert Equal (Erc20 ZRX TokenBalance cZRX) (Exactly 55e18) + Assert Equal (Erc20 ZRX TokenBalance slZRX) (Exactly 55e18) Assert Equal (Erc20 ZRX TokenBalance Root) (Exactly 0e18) - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 500e8) - Assert Equal (CToken cZRX Reserves) (Exactly 1e18) - Assert Equal (CToken cZRX UnderlyingBalance Geoff) (Exactly 54e18) + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 500e8) + Assert Equal (SLToken slZRX Reserves) (Exactly 1e18) + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) (Exactly 54e18) -- (55.0e18+0.0e18-1.0e18)/500.0e8 - Assert Equal (CToken cZRX ExchangeRate) (Exactly 1.08e9) + Assert Equal (SLToken slZRX ExchangeRate) (Exactly 1.08e9) -- Now let's redeem all - Redeem Geoff 500e8 cZRX + Redeem Geoff 500e8 slZRX -- Check our values Assert Equal (Erc20 ZRX TokenBalance Geoff) (Exactly 54e18) - Assert Equal (Erc20 ZRX TokenBalance cZRX) (Exactly 1e18) + Assert Equal (Erc20 ZRX TokenBalance slZRX) (Exactly 1e18) Assert Equal (Erc20 ZRX TokenBalance Root) (Exactly 0e18) - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 0e8) - Assert Equal (CToken cZRX Reserves) (Exactly 1e18) - Assert Equal (CToken cZRX UnderlyingBalance Geoff) (Exactly 0e18) + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 0e8) + Assert Equal (SLToken slZRX Reserves) (Exactly 1e18) + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) (Exactly 0e18) -- 0 tokens implies initial exchange rate - Assert Equal (CToken cZRX ExchangeRate) (Exactly 1e9) + Assert Equal (SLToken slZRX ExchangeRate) (Exactly 1e9) -- Then now, let's pull out all of our reserves (1e18) - ReduceReserves 1e18 cZRX + ReduceReserves 1e18 slZRX Assert Equal (Erc20 ZRX TokenBalance Geoff) (Exactly 54e18) - Assert Equal (Erc20 ZRX TokenBalance cZRX) (Exactly 0e18) + Assert Equal (Erc20 ZRX TokenBalance slZRX) (Exactly 0e18) Assert Equal (Erc20 ZRX TokenBalance Root) (Exactly 1e18) - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 0e8) - Assert Equal (CToken cZRX Reserves) (Exactly 0e18) - Assert Equal (CToken cZRX UnderlyingBalance Geoff) (Exactly 0e18) + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 0e8) + Assert Equal (SLToken slZRX Reserves) (Exactly 0e18) + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) (Exactly 0e18) -- 0 tokens implies initial exchange rate - Assert Equal (CToken cZRX ExchangeRate) (Exactly 1e9) + Assert Equal (SLToken slZRX ExchangeRate) (Exactly 1e9) Test "Reduce reserves WBTC when paused" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:1e9 tokenType:WBTC - Prep Geoff 50e18 WBTC cWBTC - Mint Geoff 50e18 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) (Exactly 500e8) - Assert Equal (CToken cWBTC UnderlyingBalance Geoff) (Exactly 50e18) - Assert Equal (CToken cWBTC ExchangeRate) (Exactly 1e9) + ListedSLToken WBTC slWBTC initialExchangeRate:1e9 tokenType:WBTC + Prep Geoff 50e18 WBTC slWBTC + Mint Geoff 50e18 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) (Exactly 500e8) + Assert Equal (SLToken slWBTC UnderlyingBalance Geoff) (Exactly 50e18) + Assert Equal (SLToken slWBTC ExchangeRate) (Exactly 1e9) -- Get some brah to borrow then repay - BorrowAndRepayWithInterest WBTC cWBTC 10e18 5e18 interestRate:0.000001 blocks:500000 reserveRate:0.2 + BorrowAndRepayWithInterest WBTC slWBTC 10e18 5e18 interestRate:0.000001 blocks:500000 reserveRate:0.2 -- We've accrued .0001% interest for 500000 blocks, or 50% of the principal (10e18), -- thus, we should have accrued 5e18 of interest for the protocol -- The reserves should get 20% of this, or 1e18, and the rest -- is due pro-rata to all suppliers. We just have one, so -- let's check that account is given correct new balance. - Invariant Remains (Erc20 WBTC TokenBalance cWBTC) (Exactly 55e18) + Invariant Remains (Erc20 WBTC TokenBalance slWBTC) (Exactly 55e18) Invariant Remains (Erc20 WBTC TokenBalance Root) (Exactly 0e18) - Invariant Remains (Erc20 cWBTC TokenBalance Geoff) (Exactly 500e8) - Invariant Remains (CToken cWBTC Reserves) (Exactly 1e18) - Invariant Remains (CToken cWBTC UnderlyingBalance Geoff) (Exactly 54e18) + Invariant Remains (Erc20 slWBTC TokenBalance Geoff) (Exactly 500e8) + Invariant Remains (SLToken slWBTC Reserves) (Exactly 1e18) + Invariant Remains (SLToken slWBTC UnderlyingBalance Geoff) (Exactly 54e18) -- (55.0e18+0.0e18-1.0e18)/500.0e8 - Invariant Remains (CToken cWBTC ExchangeRate) (Exactly 1.08e9) + Invariant Remains (SLToken slWBTC ExchangeRate) (Exactly 1.08e9) -- Now, let's pull out all of our reserves (1e18) Erc20 WBTC Pause AllowFailures - ReduceReserves 1e18 cWBTC + ReduceReserves 1e18 slWBTC Assert Revert diff --git a/spec/scenario/RepayBorrow.scen b/spec/scenario/RepayBorrow.scen index ffdadf878..de82fb9d5 100644 --- a/spec/scenario/RepayBorrow.scen +++ b/spec/scenario/RepayBorrow.scen @@ -2,172 +2,172 @@ Macro NewBorrow borrowAmount borrowRate NewComptroller price:1.0 -- TODO: This should really be a price for a specific asset - NewCToken ZRX cZRX - NewCToken BAT cBAT borrowRate -- note: cannot use macros with named args right now - Give cBAT 10e18 BAT -- Faucet some bat to borrow - Support cZRX collateralFactor:0.5 - Support cBAT collateralFactor:0.5 - Prep Geoff Some ZRX cZRX - Mint Geoff 100e18 cZRX - EnterMarkets Geoff cZRX cBAT - Borrow Geoff borrowAmount cBAT + NewSLToken ZRX slZRX + NewSLToken BAT slBAT borrowRate -- note: cannot use macros with named args right now + Give slBAT 10e18 BAT -- Faucet some bat to borrow + Support slZRX collateralFactor:0.5 + Support slBAT collateralFactor:0.5 + Prep Geoff Some ZRX slZRX + Mint Geoff 100e18 slZRX + EnterMarkets Geoff slZRX slBAT + Borrow Geoff borrowAmount slBAT Test "Borrow, hold a few blocks, and repay part" NewBorrow borrowAmount:1e18 borrowRate:0.000005 - Assert Equal (CToken cBAT BorrowBalance Geoff) 1e18 - Assert Equal (CToken cBAT TotalBorrowsCurrent) 1e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 1e18 + Assert Equal (SLToken slBAT TotalBorrowsCurrent) 1e18 Assert Equal (Erc20 BAT TokenBalance Geoff) 1e18 - Assert Equal (Erc20 BAT TokenBalance cBAT) 9e18 + Assert Equal (Erc20 BAT TokenBalance slBAT) 9e18 -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- 1e18 * (1 + 300000 * 0.000005) - Assert Equal (CToken cBAT BorrowBalance Geoff) 2.5e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 2.5e18 -- Now let's repay one full token - From Geoff (Erc20 BAT Approve cBAT 1.0e18) - RepayBorrow Geoff 1.0e18 cBAT - Assert Equal (CToken cBAT BorrowBalance Geoff) 1.5e18 + From Geoff (Erc20 BAT Approve slBAT 1.0e18) + RepayBorrow Geoff 1.0e18 slBAT + Assert Equal (SLToken slBAT BorrowBalance Geoff) 1.5e18 -- Let's check the overall numbers Assert Equal (Erc20 BAT TokenBalance Geoff) Zero - Assert Equal (Erc20 BAT TokenBalance cBAT) 10e18 - Assert Equal (CToken cBAT TotalBorrowsCurrent) 1.5e18 + Assert Equal (Erc20 BAT TokenBalance slBAT) 10e18 + Assert Equal (SLToken slBAT TotalBorrowsCurrent) 1.5e18 FastForward 200000 Blocks -- 1.5e18 * (1 + 200000 * 0.000005) - Assert Equal (CToken cBAT BorrowBalance Geoff) 3e18 - Assert Equal (CToken cBAT TotalBorrowsCurrent) 3e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 3e18 + Assert Equal (SLToken slBAT TotalBorrowsCurrent) 3e18 Test "Borrow, hold a few blocks, and repay full" NewBorrow borrowAmount:1e18 borrowRate:0.000005 - Assert Equal (CToken cBAT BorrowBalance Geoff) 1e18 - Assert Equal (CToken cBAT TotalBorrowsCurrent) 1e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 1e18 + Assert Equal (SLToken slBAT TotalBorrowsCurrent) 1e18 Assert Equal (Erc20 BAT TokenBalance Geoff) 1e18 - Assert Equal (Erc20 BAT TokenBalance cBAT) 9e18 + Assert Equal (Erc20 BAT TokenBalance slBAT) 9e18 -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- 1e18 * (1 + 300000 * 0.000005) - Assert Equal (CToken cBAT BorrowBalance Geoff) 2.5e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 2.5e18 -- Now let's repay fully Give Geoff 1.5e18 BAT -- Geoff had the 1.0e18 borrowed BAT - From Geoff (Erc20 BAT Approve cBAT 2.5e18) - RepayBorrow Geoff 2.5e18 cBAT - Assert Equal (CToken cBAT BorrowBalance Geoff) 0e18 + From Geoff (Erc20 BAT Approve slBAT 2.5e18) + RepayBorrow Geoff 2.5e18 slBAT + Assert Equal (SLToken slBAT BorrowBalance Geoff) 0e18 -- Let's check the overall numbers Assert Equal (Erc20 BAT TokenBalance Geoff) 0e18 - Assert Equal (Erc20 BAT TokenBalance cBAT) 11.5e18 - Assert Equal (CToken cBAT TotalBorrowsCurrent) 0e18 + Assert Equal (Erc20 BAT TokenBalance slBAT) 11.5e18 + Assert Equal (SLToken slBAT TotalBorrowsCurrent) 0e18 FastForward 200000 Blocks -- 0e18 * (1 + 200000 * 0.000005) - Assert Equal (CToken cBAT BorrowBalance Geoff) 0e18 - Assert Equal (CToken cBAT TotalBorrowsCurrent) 0e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 0e18 + Assert Equal (SLToken slBAT TotalBorrowsCurrent) 0e18 Test "Borrow, hold a few blocks, and repay too much" NewBorrow borrowAmount:1e18 borrowRate:0.000005 - Assert Equal (CToken cBAT BorrowBalance Geoff) 1e18 - Assert Equal (CToken cBAT TotalBorrowsCurrent) 1e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 1e18 + Assert Equal (SLToken slBAT TotalBorrowsCurrent) 1e18 -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- 0.001e18 * (1 + 300000 * 0.000005) - Assert Equal (CToken cBAT BorrowBalance Geoff) 2.5e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 2.5e18 -- Now let's repay fully AllowFailures - Prep Geoff 10e18 BAT cBAT + Prep Geoff 10e18 BAT slBAT Expect Changes (Erc20 BAT TokenBalance Geoff) Zero - Expect Changes (Erc20 BAT TokenBalance cBAT) Zero - RepayBorrow Geoff 10e18 cBAT + Expect Changes (Erc20 BAT TokenBalance slBAT) Zero + RepayBorrow Geoff 10e18 slBAT Assert Revert "revert REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED" -- Let's check the overall numbers - Assert Equal (CToken cBAT BorrowBalance Geoff) 2.5e18 - Assert Equal (CToken cBAT TotalBorrowsCurrent) 2.5e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 2.5e18 + Assert Equal (SLToken slBAT TotalBorrowsCurrent) 2.5e18 Test "Borrow, and get a negative total cash situation" Invariant Success NewBorrow borrowAmount:1e18 borrowRate:0.000005 - Assert Equal (CToken cBAT BorrowBalance Geoff) 1e18 - Assert Equal (CToken cBAT TotalBorrowsCurrent) 1e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 1e18 + Assert Equal (SLToken slBAT TotalBorrowsCurrent) 1e18 Assert Equal (Erc20 BAT TokenBalance Geoff) 1e18 - Assert Equal (Erc20 BAT TokenBalance cBAT) 9e18 + Assert Equal (Erc20 BAT TokenBalance slBAT) 9e18 -- Let's zoom way forward into the future FastForward 9800000 Blocks -- 1e18 * (1 + 9800000 * 0.000005) - Assert Equal (CToken cBAT BorrowBalance Geoff) 50e18 - Assert Equal (CToken cBAT TotalBorrowsCurrent) 50e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 50e18 + Assert Equal (SLToken slBAT TotalBorrowsCurrent) 50e18 -- Now let's repay one full token - From Geoff (Erc20 BAT Approve cBAT 1.0e18) - RepayBorrow Geoff 1.0e18 cBAT - Assert Equal (CToken cBAT BorrowBalance Geoff) 49e18 - Assert Equal (CToken cBAT TotalBorrowsCurrent) 49e18 + From Geoff (Erc20 BAT Approve slBAT 1.0e18) + RepayBorrow Geoff 1.0e18 slBAT + Assert Equal (SLToken slBAT BorrowBalance Geoff) 49e18 + Assert Equal (SLToken slBAT TotalBorrowsCurrent) 49e18 Assert Equal (Erc20 BAT TokenBalance Geoff) 0e18 - Assert Equal (Erc20 BAT TokenBalance cBAT) 10e18 + Assert Equal (Erc20 BAT TokenBalance slBAT) 10e18 Test "Borrow, hold a few blocks, and repay behalf part" Invariant Success NewBorrow borrowAmount:1e18 borrowRate:0.000005 - Assert Equal (CToken cBAT BorrowBalance Geoff) 1e18 - Assert Equal (CToken cBAT TotalBorrowsCurrent) 1e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 1e18 + Assert Equal (SLToken slBAT TotalBorrowsCurrent) 1e18 Assert Equal (Erc20 BAT TokenBalance Geoff) 1e18 - Assert Equal (Erc20 BAT TokenBalance cBAT) 9e18 + Assert Equal (Erc20 BAT TokenBalance slBAT) 9e18 -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- 1e18 * (1 + 300000 * 0.000005) - Assert Equal (CToken cBAT BorrowBalance Geoff) 2.5e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 2.5e18 -- Now let's repay one full token from another user - Prep Torrey 1.0e18 BAT cBAT - RepayBorrowBehalf Torrey Geoff 1.0e18 cBAT - Assert Equal (CToken cBAT BorrowBalance Torrey) Zero - Assert Equal (CToken cBAT BorrowBalance Geoff) 1.5e18 + Prep Torrey 1.0e18 BAT slBAT + RepayBorrowBehalf Torrey Geoff 1.0e18 slBAT + Assert Equal (SLToken slBAT BorrowBalance Torrey) Zero + Assert Equal (SLToken slBAT BorrowBalance Geoff) 1.5e18 -- Let's check the overall numbers Assert Equal (Erc20 BAT TokenBalance Torrey) 0e18 Assert Equal (Erc20 BAT TokenBalance Geoff) 1e18 - Assert Equal (Erc20 BAT TokenBalance cBAT) 10e18 - Assert Equal (CToken cBAT TotalBorrowsCurrent) 1.5e18 + Assert Equal (Erc20 BAT TokenBalance slBAT) 10e18 + Assert Equal (SLToken slBAT TotalBorrowsCurrent) 1.5e18 FastForward 200000 Blocks -- 1.5e18 * (1 + 200000 * 0.000005) - Assert Equal (CToken cBAT BorrowBalance Torrey) Zero - Assert Equal (CToken cBAT BorrowBalance Geoff) 3e18 - Assert Equal (CToken cBAT TotalBorrowsCurrent) 3e18 + Assert Equal (SLToken slBAT BorrowBalance Torrey) Zero + Assert Equal (SLToken slBAT BorrowBalance Geoff) 3e18 + Assert Equal (SLToken slBAT TotalBorrowsCurrent) 3e18 Test "Prohibit repay by comptroller rejection due to mock unlist" NewBorrow borrowAmount:1e18 borrowRate:0.000005 - Assert Equal (CToken cBAT BorrowBalance Geoff) 1e18 - Assert Equal (CToken cBAT TotalBorrowsCurrent) 1e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 1e18 + Assert Equal (SLToken slBAT TotalBorrowsCurrent) 1e18 -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- 1e18 * (1 + 300000 * 0.000005) - Assert Equal (CToken cBAT BorrowBalance Geoff) 2.5e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 2.5e18 -- Now let's repay fully AllowFailures - Prep Geoff 10e18 BAT cBAT + Prep Geoff 10e18 BAT slBAT Expect Changes (Erc20 BAT TokenBalance Geoff) Zero - Expect Changes (Erc20 BAT TokenBalance cBAT) Zero - Comptroller UnList cZRX -- Mock unlist ZRX - RepayBorrow Geoff 2.5e18 cZRX + Expect Changes (Erc20 BAT TokenBalance slBAT) Zero + Comptroller UnList slZRX -- Mock unlist ZRX + RepayBorrow Geoff 2.5e18 slZRX Assert Failure COMPTROLLER_REJECTION REPAY_BORROW_COMPTROLLER_REJECTION MARKET_NOT_LISTED -- Let's check the overall numbers - Assert Equal (CToken cBAT BorrowBalance Geoff) 2.5e18 - Assert Equal (CToken cBAT TotalBorrowsCurrent) 2.5e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 2.5e18 + Assert Equal (SLToken slBAT TotalBorrowsCurrent) 2.5e18 Test "Repay fails with insufficient allowance" NewBorrow borrowAmount:1e18 borrowRate:0.000005 - Assert Equal (CToken cBAT BorrowBalance Geoff) 1e18 - Assert Equal (CToken cBAT TotalBorrowsCurrent) 1e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 1e18 + Assert Equal (SLToken slBAT TotalBorrowsCurrent) 1e18 -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- 1e18 * (1 + 300000 * 0.000005) - Assert Equal (CToken cBAT BorrowBalance Geoff) 2.5e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 2.5e18 -- Now let's repay fully AllowFailures - Prep Geoff 100e18 BAT cBAT allowanceAmount:1.5e18 + Prep Geoff 100e18 BAT slBAT allowanceAmount:1.5e18 Expect Changes (Erc20 BAT TokenBalance Geoff) Zero - Expect Changes (Erc20 BAT TokenBalance cBAT) Zero - RepayBorrow Geoff 2.5e18 cBAT + Expect Changes (Erc20 BAT TokenBalance slBAT) Zero + RepayBorrow Geoff 2.5e18 slBAT Assert Revert "revert Insufficient allowance" -- Let's check the overall numbers - Assert Equal (CToken cBAT BorrowBalance Geoff) 2.5e18 - Assert Equal (CToken cBAT TotalBorrowsCurrent) 2.5e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 2.5e18 + Assert Equal (SLToken slBAT TotalBorrowsCurrent) 2.5e18 Test "Repay fails with insufficient balance" NewBorrow borrowAmount:1e18 borrowRate:0.000005 - Assert Equal (CToken cBAT BorrowBalance Geoff) 1e18 - Assert Equal (CToken cBAT TotalBorrowsCurrent) 1e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 1e18 + Assert Equal (SLToken slBAT TotalBorrowsCurrent) 1e18 -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- 1e18 * (1 + 300000 * 0.000005) - Assert Equal (CToken cBAT BorrowBalance Geoff) 2.5e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 2.5e18 -- Now let's repay fully AllowFailures - Prep Geoff 0e18 BAT cBAT allowanceAmount:2.5e18 + Prep Geoff 0e18 BAT slBAT allowanceAmount:2.5e18 Expect Changes (Erc20 BAT TokenBalance Geoff) Zero - Expect Changes (Erc20 BAT TokenBalance cBAT) Zero - RepayBorrow Geoff 2.5e18 cBAT + Expect Changes (Erc20 BAT TokenBalance slBAT) Zero + RepayBorrow Geoff 2.5e18 slBAT Assert Revert "revert Insufficient balance" -- Let's check the overall numbers - Assert Equal (CToken cBAT BorrowBalance Geoff) 2.5e18 - Assert Equal (CToken cBAT TotalBorrowsCurrent) 2.5e18 + Assert Equal (SLToken slBAT BorrowBalance Geoff) 2.5e18 + Assert Equal (SLToken slBAT TotalBorrowsCurrent) 2.5e18 diff --git a/spec/scenario/RepayBorrowEth.scen b/spec/scenario/RepayBorrowEth.scen index 64f053337..4001a150d 100644 --- a/spec/scenario/RepayBorrowEth.scen +++ b/spec/scenario/RepayBorrowEth.scen @@ -2,205 +2,205 @@ Macro SetupBorrow borrowRate NewComptroller price:1.0 -- TODO: This should really be a price for a specific asset - ListedCToken ZRX cZRX borrowRate - ListedEtherToken cETH borrowRate 0.005e9 - SetCollateralFactor cZRX collateralFactor:0.5 - SetCollateralFactor cETH collateralFactor:0.5 - Donate cETH 0.003e18 - Prep Geoff Some ZRX cZRX - Mint Geoff 100e18 cZRX - EnterMarkets Geoff cZRX cETH + ListedSLToken ZRX slZRX borrowRate + ListedEtherToken slETH borrowRate 0.005e9 + SetCollateralFactor slZRX collateralFactor:0.5 + SetCollateralFactor slETH collateralFactor:0.5 + Donate slETH 0.003e18 + Prep Geoff Some ZRX slZRX + Mint Geoff 100e18 slZRX + EnterMarkets Geoff slZRX slETH Macro NewBorrowEth borrowAmount borrowRate SetupBorrow borrowRate - Borrow Geoff borrowAmount cETH + Borrow Geoff borrowAmount slETH Test "Borrow, hold a few blocks, and repay part" NewBorrowEth borrowAmount:0.001e18 borrowRate:0.000005 - Assert Equal (CToken cETH BorrowBalance Geoff) 0.001e18 - Assert Equal (CToken cETH TotalBorrowsCurrent) 0.001e18 + Assert Equal (SLToken slETH BorrowBalance Geoff) 0.001e18 + Assert Equal (SLToken slETH TotalBorrowsCurrent) 0.001e18 -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- 0.001e18 * (1 + 300000 * 0.000005) - Assert Equal (CToken cETH BorrowBalance Geoff) 0.0025e18 + Assert Equal (SLToken slETH BorrowBalance Geoff) 0.0025e18 -- Now let's repay one full token Expect Changes (EtherBalance Geoff) -0.001e18 - Expect Changes (EtherBalance cETH) +0.001e18 - RepayBorrowEth Geoff 0.001e18 cETH + Expect Changes (EtherBalance slETH) +0.001e18 + RepayBorrowEth Geoff 0.001e18 slETH ---- Let's check the overall numbers - Assert Equal (CToken cETH BorrowBalance Geoff) 0.0015e18 - Assert Equal (CToken cETH TotalBorrowsCurrent) 0.0015e18 + Assert Equal (SLToken slETH BorrowBalance Geoff) 0.0015e18 + Assert Equal (SLToken slETH TotalBorrowsCurrent) 0.0015e18 FastForward 200000 Blocks -- 0.0015e18 * (1 + 2000 * 0.000005) - Assert Equal (CToken cETH BorrowBalance Geoff) 0.003e18 - Assert Equal (CToken cETH TotalBorrowsCurrent) 0.003e18 + Assert Equal (SLToken slETH BorrowBalance Geoff) 0.003e18 + Assert Equal (SLToken slETH TotalBorrowsCurrent) 0.003e18 Test "Borrow, hold a few blocks, and repay part via maximillion" NewBorrowEth borrowAmount:0.001e18 borrowRate:0.000005 - Maximillion Deploy cETH - Assert Equal (CToken cETH BorrowBalance Geoff) 0.001e18 - Assert Equal (CToken cETH TotalBorrowsCurrent) 0.001e18 + Maximillion Deploy slETH + Assert Equal (SLToken slETH BorrowBalance Geoff) 0.001e18 + Assert Equal (SLToken slETH TotalBorrowsCurrent) 0.001e18 -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- 0.001e18 * (1 + 300000 * 0.000005) - Assert Equal (CToken cETH BorrowBalance Geoff) 0.0025e18 + Assert Equal (SLToken slETH BorrowBalance Geoff) 0.0025e18 -- Now let's repay one full token Expect Changes (EtherBalance Geoff) -0.001e18 - Expect Changes (EtherBalance cETH) +0.001e18 - RepayBorrowEthMax Geoff 0.001e18 cETH + Expect Changes (EtherBalance slETH) +0.001e18 + RepayBorrowEthMax Geoff 0.001e18 slETH ---- Let's check the overall numbers - Assert Equal (CToken cETH BorrowBalance Geoff) 0.0015e18 - Assert Equal (CToken cETH TotalBorrowsCurrent) 0.0015e18 + Assert Equal (SLToken slETH BorrowBalance Geoff) 0.0015e18 + Assert Equal (SLToken slETH TotalBorrowsCurrent) 0.0015e18 FastForward 200000 Blocks -- 0.0015e18 * (1 + 200000 * 0.000005) - Assert Equal (CToken cETH BorrowBalance Geoff) 0.003e18 - Assert Equal (CToken cETH TotalBorrowsCurrent) 0.003e18 + Assert Equal (SLToken slETH BorrowBalance Geoff) 0.003e18 + Assert Equal (SLToken slETH TotalBorrowsCurrent) 0.003e18 Test "Don't borrow and then do repay" SetupBorrow borrowRate:0.000005 - Assert Equal (CToken cETH BorrowBalance Geoff) Zero - Assert Equal (CToken cETH TotalBorrowsCurrent) Zero + Assert Equal (SLToken slETH BorrowBalance Geoff) Zero + Assert Equal (SLToken slETH TotalBorrowsCurrent) Zero -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- 0 * (1 + 300000 * 0.000005) - Assert Equal (CToken cETH BorrowBalance Geoff) Zero + Assert Equal (SLToken slETH BorrowBalance Geoff) Zero -- Now let's repay one full token Expect Changes (EtherBalance Geoff) Zero - Expect Changes (EtherBalance cETH) Zero - RepayBorrowEth Geoff 0 cETH + Expect Changes (EtherBalance slETH) Zero + RepayBorrowEth Geoff 0 slETH ---- Let's check the overall numbers - Assert Equal (CToken cETH BorrowBalance Geoff) Zero - Assert Equal (CToken cETH TotalBorrowsCurrent) Zero + Assert Equal (SLToken slETH BorrowBalance Geoff) Zero + Assert Equal (SLToken slETH TotalBorrowsCurrent) Zero Test "Don't borrow and repay part via maximillion" SetupBorrow borrowRate:0.000005 - Maximillion Deploy cETH - Assert Equal (CToken cETH BorrowBalance Geoff) Zero - Assert Equal (CToken cETH TotalBorrowsCurrent) Zero + Maximillion Deploy slETH + Assert Equal (SLToken slETH BorrowBalance Geoff) Zero + Assert Equal (SLToken slETH TotalBorrowsCurrent) Zero -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- 0 * (1 + 300000 * 0.000005) - Assert Equal (CToken cETH BorrowBalance Geoff) Zero + Assert Equal (SLToken slETH BorrowBalance Geoff) Zero -- Now let's repay one full token Expect Changes (EtherBalance Geoff) Zero - Expect Changes (EtherBalance cETH) Zero - RepayBorrowEthMax Geoff 0.001e18 cETH + Expect Changes (EtherBalance slETH) Zero + RepayBorrowEthMax Geoff 0.001e18 slETH ---- Let's check the overall numbers - Assert Equal (CToken cETH BorrowBalance Geoff) Zero - Assert Equal (CToken cETH TotalBorrowsCurrent) Zero + Assert Equal (SLToken slETH BorrowBalance Geoff) Zero + Assert Equal (SLToken slETH TotalBorrowsCurrent) Zero Test "Borrow, hold a few blocks, and repay full" NewBorrowEth borrowAmount:0.001e18 borrowRate:0.000005 - Assert Equal (CToken cETH BorrowBalance Geoff) 0.001e18 - Assert Equal (CToken cETH TotalBorrowsCurrent) 0.001e18 + Assert Equal (SLToken slETH BorrowBalance Geoff) 0.001e18 + Assert Equal (SLToken slETH TotalBorrowsCurrent) 0.001e18 -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- 0.001e18 * (1 + 300000 * 0.000005) - Assert Equal (CToken cETH BorrowBalance Geoff) 0.0025e18 + Assert Equal (SLToken slETH BorrowBalance Geoff) 0.0025e18 -- Now let's repay fully Expect Changes (EtherBalance Geoff) -0.0025e18 - Expect Changes (EtherBalance cETH) +0.0025e18 - RepayBorrowEth Geoff 0.0025e18 cETH + Expect Changes (EtherBalance slETH) +0.0025e18 + RepayBorrowEth Geoff 0.0025e18 slETH -- Let's check the overall numbers - Assert Equal (CToken cETH BorrowBalance Geoff) Zero - Assert Equal (CToken cETH TotalBorrowsCurrent) Zero + Assert Equal (SLToken slETH BorrowBalance Geoff) Zero + Assert Equal (SLToken slETH TotalBorrowsCurrent) Zero FastForward 200000 Blocks -- 0e18 * (1 + 200000 * 0.000005) - Assert Equal (CToken cETH BorrowBalance Geoff) Zero - Assert Equal (CToken cETH TotalBorrowsCurrent) Zero + Assert Equal (SLToken slETH BorrowBalance Geoff) Zero + Assert Equal (SLToken slETH TotalBorrowsCurrent) Zero Test "Borrow, hold a few blocks, and repay full via maximillion" NewBorrowEth borrowAmount:0.001e18 borrowRate:0.000005 - Maximillion Deploy cETH - Assert Equal (CToken cETH BorrowBalance Geoff) 0.001e18 - Assert Equal (CToken cETH TotalBorrowsCurrent) 0.001e18 + Maximillion Deploy slETH + Assert Equal (SLToken slETH BorrowBalance Geoff) 0.001e18 + Assert Equal (SLToken slETH TotalBorrowsCurrent) 0.001e18 -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- 0.001e18 * (1 + 300000 * 0.000005) - Assert Equal (CToken cETH BorrowBalance Geoff) 0.0025e18 + Assert Equal (SLToken slETH BorrowBalance Geoff) 0.0025e18 -- Now let's repay fully Expect Changes (EtherBalance Geoff) -0.0025e18 - Expect Changes (EtherBalance cETH) +0.0025e18 - RepayBorrowEthMax Geoff 0.0025e18 cETH + Expect Changes (EtherBalance slETH) +0.0025e18 + RepayBorrowEthMax Geoff 0.0025e18 slETH -- Let's check the overall numbers - Assert Equal (CToken cETH BorrowBalance Geoff) Zero - Assert Equal (CToken cETH TotalBorrowsCurrent) Zero + Assert Equal (SLToken slETH BorrowBalance Geoff) Zero + Assert Equal (SLToken slETH TotalBorrowsCurrent) Zero FastForward 200000 Blocks -- 0e18 * (1 + 200000 * 0.000005) - Assert Equal (CToken cETH BorrowBalance Geoff) Zero - Assert Equal (CToken cETH TotalBorrowsCurrent) Zero + Assert Equal (SLToken slETH BorrowBalance Geoff) Zero + Assert Equal (SLToken slETH TotalBorrowsCurrent) Zero Test "Borrow, hold a few blocks, and repay too much" NewBorrowEth borrowAmount:0.001e18 borrowRate:0.000005 - Assert Equal (CToken cETH BorrowBalance Geoff) 0.001e18 - Assert Equal (CToken cETH TotalBorrowsCurrent) 0.001e18 + Assert Equal (SLToken slETH BorrowBalance Geoff) 0.001e18 + Assert Equal (SLToken slETH TotalBorrowsCurrent) 0.001e18 -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- 0.001e18 * (1 + 300000 * 0.000005) - Assert Equal (CToken cETH BorrowBalance Geoff) 0.0025e18 + Assert Equal (SLToken slETH BorrowBalance Geoff) 0.0025e18 -- Now let's repay fully Expect Changes (EtherBalance Geoff) Zero - Expect Changes (EtherBalance cETH) Zero + Expect Changes (EtherBalance slETH) Zero -- TODO: This currently drains the sent-eth AllowFailures - RepayBorrowEth Geoff 1.0e18 cETH + RepayBorrowEth Geoff 1.0e18 slETH Assert Revert "revert REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED" -- Let's check the overall numbers - Assert Equal (CToken cETH BorrowBalance Geoff) 0.0025e18 - Assert Equal (CToken cETH TotalBorrowsCurrent) 0.0025e18 + Assert Equal (SLToken slETH BorrowBalance Geoff) 0.0025e18 + Assert Equal (SLToken slETH TotalBorrowsCurrent) 0.0025e18 Test "Borrow, hold a few blocks, and repay too much via maximillion" NewBorrowEth borrowAmount:0.001e18 borrowRate:0.000005 - Maximillion Deploy cETH - Assert Equal (CToken cETH BorrowBalance Geoff) 0.001e18 - Assert Equal (CToken cETH TotalBorrowsCurrent) 0.001e18 + Maximillion Deploy slETH + Assert Equal (SLToken slETH BorrowBalance Geoff) 0.001e18 + Assert Equal (SLToken slETH TotalBorrowsCurrent) 0.001e18 -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- 0.001e18 * (1 + 300000 * 0.000005) - Assert Equal (CToken cETH BorrowBalance Geoff) 0.0025e18 + Assert Equal (SLToken slETH BorrowBalance Geoff) 0.0025e18 -- Now let's repay fully Expect Changes (EtherBalance Geoff) -0.0025e18 - Expect Changes (EtherBalance cETH) +0.0025e18 - RepayBorrowEthMax Geoff 1.0e18 cETH + Expect Changes (EtherBalance slETH) +0.0025e18 + RepayBorrowEthMax Geoff 1.0e18 slETH -- Let's check the overall numbers - Assert Equal (CToken cETH BorrowBalance Geoff) Zero - Assert Equal (CToken cETH TotalBorrowsCurrent) Zero + Assert Equal (SLToken slETH BorrowBalance Geoff) Zero + Assert Equal (SLToken slETH TotalBorrowsCurrent) Zero FastForward 200000 Blocks -- 0e18 * (1 + 200000 * 0.000005) - Assert Equal (CToken cETH BorrowBalance Geoff) Zero - Assert Equal (CToken cETH TotalBorrowsCurrent) Zero + Assert Equal (SLToken slETH BorrowBalance Geoff) Zero + Assert Equal (SLToken slETH TotalBorrowsCurrent) Zero Test "Borrow, and get a negative total cash situation" NewBorrowEth borrowAmount:0.001e18 borrowRate:0.000005 - Assert Equal (CToken cETH BorrowBalance Geoff) 0.001e18 - Assert Equal (CToken cETH TotalBorrowsCurrent) 0.001e18 + Assert Equal (SLToken slETH BorrowBalance Geoff) 0.001e18 + Assert Equal (SLToken slETH TotalBorrowsCurrent) 0.001e18 -- Let's zoom way forward into the future FastForward 9800000 Blocks -- 0.001e18 * (1 + 9800000 * 0.000005) - Assert Equal (CToken cETH BorrowBalance Geoff) 0.05e18 - Assert Equal (CToken cETH TotalBorrowsCurrent) 0.05e18 + Assert Equal (SLToken slETH BorrowBalance Geoff) 0.05e18 + Assert Equal (SLToken slETH TotalBorrowsCurrent) 0.05e18 -- Now let's repay one bit - RepayBorrowEth Geoff 0.001e18 cETH - Assert Equal (CToken cETH BorrowBalance Geoff) 0.049e18 - Assert Equal (CToken cETH TotalBorrowsCurrent) 0.049e18 + RepayBorrowEth Geoff 0.001e18 slETH + Assert Equal (SLToken slETH BorrowBalance Geoff) 0.049e18 + Assert Equal (SLToken slETH TotalBorrowsCurrent) 0.049e18 Test "Borrow, hold a few blocks, and repay behalf part" NewBorrowEth borrowAmount:0.001e18 borrowRate:0.000005 - Assert Equal (CToken cETH BorrowBalance Geoff) 0.001e18 - Assert Equal (CToken cETH TotalBorrowsCurrent) 0.001e18 + Assert Equal (SLToken slETH BorrowBalance Geoff) 0.001e18 + Assert Equal (SLToken slETH TotalBorrowsCurrent) 0.001e18 -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- 0.001e18 * (1 + 300000 * 0.000005) - Assert Equal (CToken cETH BorrowBalance Geoff) 0.0025e18 + Assert Equal (SLToken slETH BorrowBalance Geoff) 0.0025e18 -- Now let's repay one full token from another user - RepayBorrowEthBehalf Torrey Geoff 0.001e18 cETH - Assert Equal (CToken cETH BorrowBalance Torrey) Zero - Assert Equal (CToken cETH BorrowBalance Geoff) 0.0015e18 - Assert Equal (CToken cETH TotalBorrowsCurrent) 0.0015e18 + RepayBorrowEthBehalf Torrey Geoff 0.001e18 slETH + Assert Equal (SLToken slETH BorrowBalance Torrey) Zero + Assert Equal (SLToken slETH BorrowBalance Geoff) 0.0015e18 + Assert Equal (SLToken slETH TotalBorrowsCurrent) 0.0015e18 FastForward 200000 Blocks -- 0.0015e18 * (1 + 200000 * 0.000005) - Assert Equal (CToken cETH BorrowBalance Torrey) Zero - Assert Equal (CToken cETH BorrowBalance Geoff) 0.003e18 - Assert Equal (CToken cETH TotalBorrowsCurrent) 0.003e18 + Assert Equal (SLToken slETH BorrowBalance Torrey) Zero + Assert Equal (SLToken slETH BorrowBalance Geoff) 0.003e18 + Assert Equal (SLToken slETH TotalBorrowsCurrent) 0.003e18 Test "Prohibit repay by comptroller hook" NewBorrowEth borrowAmount:0.001e18 borrowRate:0.000005 - Assert Equal (CToken cETH BorrowBalance Geoff) 0.001e18 - Assert Equal (CToken cETH TotalBorrowsCurrent) 0.001e18 + Assert Equal (SLToken slETH BorrowBalance Geoff) 0.001e18 + Assert Equal (SLToken slETH TotalBorrowsCurrent) 0.001e18 -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- 0.001e18 * (1 + 300000 * 0.000005) - Assert Equal (CToken cETH BorrowBalance Geoff) 0.0025e18 + Assert Equal (SLToken slETH BorrowBalance Geoff) 0.0025e18 -- Now let's repay one full token Expect Changes (EtherBalance Geoff) Zero - Expect Changes (EtherBalance cETH) Zero - Comptroller UnList cETH -- Mock unlist cETH + Expect Changes (EtherBalance slETH) Zero + Comptroller UnList slETH -- Mock unlist slETH AllowFailures - RepayBorrowEth Geoff 0.001e18 cETH + RepayBorrowEth Geoff 0.001e18 slETH Assert RevertFailure COMPTROLLER_REJECTION "revert repayBorrow failed" ---- Let's check the overall numbers - Assert Equal (CToken cETH BorrowBalance Geoff) 0.0025e18 - Assert Equal (CToken cETH TotalBorrowsCurrent) 0.0025e18 + Assert Equal (SLToken slETH BorrowBalance Geoff) 0.0025e18 + Assert Equal (SLToken slETH TotalBorrowsCurrent) 0.0025e18 diff --git a/spec/scenario/RepayBorrowWBTC.scen b/spec/scenario/RepayBorrowWBTC.scen index b28648098..0af06de00 100644 --- a/spec/scenario/RepayBorrowWBTC.scen +++ b/spec/scenario/RepayBorrowWBTC.scen @@ -2,190 +2,190 @@ Macro NewBorrow borrowAmount borrowRate NewComptroller price:1.0 -- TODO: This should really be a price for a specific asset - NewCToken ZRX cZRX - NewCToken WBTC cWBTC borrowRate 0.1 8 WBTC -- note: cannot use macros with named args right now - Give cWBTC 10e8 WBTC -- Faucet some WBTC to borrow - Support cZRX collateralFactor:0.5 - Support cWBTC collateralFactor:0.5 - Prep Geoff Some ZRX cZRX - Mint Geoff 100e18 cZRX - EnterMarkets Geoff cZRX cWBTC - Borrow Geoff borrowAmount cWBTC + NewSLToken ZRX slZRX + NewSLToken WBTC slWBTC borrowRate 0.1 8 WBTC -- note: cannot use macros with named args right now + Give slWBTC 10e8 WBTC -- Faucet some WBTC to borrow + Support slZRX collateralFactor:0.5 + Support slWBTC collateralFactor:0.5 + Prep Geoff Some ZRX slZRX + Mint Geoff 100e18 slZRX + EnterMarkets Geoff slZRX slWBTC + Borrow Geoff borrowAmount slWBTC Test "Borrow WBTC, hold a few blocks, and repay part" NewBorrow borrowAmount:1e8 borrowRate:0.000005 - Assert Equal (CToken cWBTC BorrowBalance Geoff) 1e8 - Assert Equal (CToken cWBTC TotalBorrowsCurrent) 1e8 + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 1e8 + Assert Equal (SLToken slWBTC TotalBorrowsCurrent) 1e8 Assert Equal (Erc20 WBTC TokenBalance Geoff) 1e8 - Assert Equal (Erc20 WBTC TokenBalance cWBTC) 9e8 + Assert Equal (Erc20 WBTC TokenBalance slWBTC) 9e8 -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- 1e18 * (1 + 300000 * 0.000005) - Assert Equal (CToken cWBTC BorrowBalance Geoff) 2.5e8 + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 2.5e8 -- Now let's repay one full token - From Geoff (Erc20 WBTC Approve cWBTC 1.0e8) - RepayBorrow Geoff 1e8 cWBTC - Assert Equal (CToken cWBTC BorrowBalance Geoff) 1.5e8 + From Geoff (Erc20 WBTC Approve slWBTC 1.0e8) + RepayBorrow Geoff 1e8 slWBTC + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 1.5e8 -- Let's check the overall numbers Assert Equal (Erc20 WBTC TokenBalance Geoff) Zero - Assert Equal (Erc20 WBTC TokenBalance cWBTC) 10e8 - Assert Equal (CToken cWBTC TotalBorrowsCurrent) 1.5e8 + Assert Equal (Erc20 WBTC TokenBalance slWBTC) 10e8 + Assert Equal (SLToken slWBTC TotalBorrowsCurrent) 1.5e8 FastForward 200000 Blocks -- 1.5e8 * (1 + 200000 * 0.000005) - Assert Equal (CToken cWBTC BorrowBalance Geoff) 3e8 - Assert Equal (CToken cWBTC TotalBorrowsCurrent) 3e8 + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 3e8 + Assert Equal (SLToken slWBTC TotalBorrowsCurrent) 3e8 Test "Borrow, hold a few blocks, and repay full" NewBorrow borrowAmount:1e8 borrowRate:0.000005 - Assert Equal (CToken cWBTC BorrowBalance Geoff) 1e8 - Assert Equal (CToken cWBTC TotalBorrowsCurrent) 1e8 + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 1e8 + Assert Equal (SLToken slWBTC TotalBorrowsCurrent) 1e8 Assert Equal (Erc20 WBTC TokenBalance Geoff) 1e8 - Assert Equal (Erc20 WBTC TokenBalance cWBTC) 9e8 + Assert Equal (Erc20 WBTC TokenBalance slWBTC) 9e8 -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- 1e8 * (1 + 300000 * 0.000005) - Assert Equal (CToken cWBTC BorrowBalance Geoff) 2.5e8 + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 2.5e8 -- Now let's repay fully Give Geoff 1.5e8 WBTC -- Geoff had the 1.0e8 borrowed WBTC - From Geoff (Erc20 WBTC Approve cWBTC 2.5e8) - RepayBorrow Geoff 2.5e8 cWBTC - Assert Equal (CToken cWBTC BorrowBalance Geoff) 0e8 + From Geoff (Erc20 WBTC Approve slWBTC 2.5e8) + RepayBorrow Geoff 2.5e8 slWBTC + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 0e8 -- Let's check the overall numbers Assert Equal (Erc20 WBTC TokenBalance Geoff) 0e8 - Assert Equal (Erc20 WBTC TokenBalance cWBTC) 11.5e8 - Assert Equal (CToken cWBTC TotalBorrowsCurrent) 0e8 + Assert Equal (Erc20 WBTC TokenBalance slWBTC) 11.5e8 + Assert Equal (SLToken slWBTC TotalBorrowsCurrent) 0e8 FastForward 200000 Blocks -- 0e8 * (1 + 200000 * 0.000005) - Assert Equal (CToken cWBTC BorrowBalance Geoff) 0e8 - Assert Equal (CToken cWBTC TotalBorrowsCurrent) 0e8 + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 0e8 + Assert Equal (SLToken slWBTC TotalBorrowsCurrent) 0e8 Test "Borrow, hold a few blocks, and repay too much" NewBorrow borrowAmount:1e8 borrowRate:0.000005 - Assert Equal (CToken cWBTC BorrowBalance Geoff) 1e8 - Assert Equal (CToken cWBTC TotalBorrowsCurrent) 1e8 + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 1e8 + Assert Equal (SLToken slWBTC TotalBorrowsCurrent) 1e8 -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- 1e8 * (1 + 300000 * 0.000005) - Assert Equal (CToken cWBTC BorrowBalance Geoff) 2.5e8 + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 2.5e8 -- Now let's repay fully AllowFailures - Prep Geoff 10e8 WBTC cWBTC + Prep Geoff 10e8 WBTC slWBTC Expect Changes (Erc20 WBTC TokenBalance Geoff) Zero - Expect Changes (Erc20 WBTC TokenBalance cWBTC) Zero - RepayBorrow Geoff 10e8 cWBTC + Expect Changes (Erc20 WBTC TokenBalance slWBTC) Zero + RepayBorrow Geoff 10e8 slWBTC Assert Revert "revert REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED" -- Let's check the overall numbers - Assert Equal (CToken cWBTC BorrowBalance Geoff) 2.5e8 - Assert Equal (CToken cWBTC TotalBorrowsCurrent) 2.5e8 + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 2.5e8 + Assert Equal (SLToken slWBTC TotalBorrowsCurrent) 2.5e8 Test "Borrow, and get a negative total cash situation" Invariant Success NewBorrow borrowAmount:1e8 borrowRate:0.000005 - Assert Equal (CToken cWBTC BorrowBalance Geoff) 1e8 - Assert Equal (CToken cWBTC TotalBorrowsCurrent) 1e8 + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 1e8 + Assert Equal (SLToken slWBTC TotalBorrowsCurrent) 1e8 Assert Equal (Erc20 WBTC TokenBalance Geoff) 1e8 - Assert Equal (Erc20 WBTC TokenBalance cWBTC) 9e8 + Assert Equal (Erc20 WBTC TokenBalance slWBTC) 9e8 -- Let's zoom way forward into the future FastForward 9800000 Blocks -- 1e8 * (1 + 9800000 * 0.000005) - Assert Equal (CToken cWBTC BorrowBalance Geoff) 50e8 - Assert Equal (CToken cWBTC TotalBorrowsCurrent) 50e8 + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 50e8 + Assert Equal (SLToken slWBTC TotalBorrowsCurrent) 50e8 -- Now let's repay one full token - From Geoff (Erc20 WBTC Approve cWBTC 1.0e8) - RepayBorrow Geoff 1.0e8 cWBTC - Assert Equal (CToken cWBTC BorrowBalance Geoff) 49e8 - Assert Equal (CToken cWBTC TotalBorrowsCurrent) 49e8 + From Geoff (Erc20 WBTC Approve slWBTC 1.0e8) + RepayBorrow Geoff 1.0e8 slWBTC + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 49e8 + Assert Equal (SLToken slWBTC TotalBorrowsCurrent) 49e8 Assert Equal (Erc20 WBTC TokenBalance Geoff) 0e8 - Assert Equal (Erc20 WBTC TokenBalance cWBTC) 10e8 + Assert Equal (Erc20 WBTC TokenBalance slWBTC) 10e8 Test "Borrow, hold a few blocks, and repay behalf part" Invariant Success NewBorrow borrowAmount:1e8 borrowRate:0.000005 - Assert Equal (CToken cWBTC BorrowBalance Geoff) 1e8 - Assert Equal (CToken cWBTC TotalBorrowsCurrent) 1e8 + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 1e8 + Assert Equal (SLToken slWBTC TotalBorrowsCurrent) 1e8 Assert Equal (Erc20 WBTC TokenBalance Geoff) 1e8 - Assert Equal (Erc20 WBTC TokenBalance cWBTC) 9e8 + Assert Equal (Erc20 WBTC TokenBalance slWBTC) 9e8 -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- 1e8 * (1 + 300000 * 0.000005) - Assert Equal (CToken cWBTC BorrowBalance Geoff) 2.5e8 + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 2.5e8 -- Now let's repay one full token from another user - Prep Torrey 1.0e8 WBTC cWBTC - RepayBorrowBehalf Torrey Geoff 1.0e8 cWBTC - Assert Equal (CToken cWBTC BorrowBalance Torrey) Zero - Assert Equal (CToken cWBTC BorrowBalance Geoff) 1.5e8 + Prep Torrey 1.0e8 WBTC slWBTC + RepayBorrowBehalf Torrey Geoff 1.0e8 slWBTC + Assert Equal (SLToken slWBTC BorrowBalance Torrey) Zero + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 1.5e8 -- Let's check the overall numbers Assert Equal (Erc20 WBTC TokenBalance Torrey) 0e8 Assert Equal (Erc20 WBTC TokenBalance Geoff) 1e8 - Assert Equal (Erc20 WBTC TokenBalance cWBTC) 10e8 - Assert Equal (CToken cWBTC TotalBorrowsCurrent) 1.5e8 + Assert Equal (Erc20 WBTC TokenBalance slWBTC) 10e8 + Assert Equal (SLToken slWBTC TotalBorrowsCurrent) 1.5e8 FastForward 200000 Blocks -- 1.5e8 * (1 + 200000 * 0.000005) - Assert Equal (CToken cWBTC BorrowBalance Torrey) Zero - Assert Equal (CToken cWBTC BorrowBalance Geoff) 3e8 - Assert Equal (CToken cWBTC TotalBorrowsCurrent) 3e8 + Assert Equal (SLToken slWBTC BorrowBalance Torrey) Zero + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 3e8 + Assert Equal (SLToken slWBTC TotalBorrowsCurrent) 3e8 Test "Prohibit repay by comptroller rejection due to mock unlist" NewBorrow borrowAmount:1e8 borrowRate:0.000005 - Assert Equal (CToken cWBTC BorrowBalance Geoff) 1e8 - Assert Equal (CToken cWBTC TotalBorrowsCurrent) 1e8 + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 1e8 + Assert Equal (SLToken slWBTC TotalBorrowsCurrent) 1e8 -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- 0.001e8 * (1 + 300000 * 0.000005) - Assert Equal (CToken cWBTC BorrowBalance Geoff) 2.5e8 + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 2.5e8 -- Now let's repay fully AllowFailures - Prep Geoff 10e8 WBTC cWBTC + Prep Geoff 10e8 WBTC slWBTC Expect Changes (Erc20 WBTC TokenBalance Geoff) Zero - Expect Changes (Erc20 WBTC TokenBalance cWBTC) Zero - Comptroller UnList cZRX -- Mock unlist ZRX - RepayBorrow Geoff 2.5e8 cZRX + Expect Changes (Erc20 WBTC TokenBalance slWBTC) Zero + Comptroller UnList slZRX -- Mock unlist ZRX + RepayBorrow Geoff 2.5e8 slZRX Assert Failure COMPTROLLER_REJECTION REPAY_BORROW_COMPTROLLER_REJECTION MARKET_NOT_LISTED -- Let's check the overall numbers - Assert Equal (CToken cWBTC BorrowBalance Geoff) 2.5e8 - Assert Equal (CToken cWBTC TotalBorrowsCurrent) 2.5e8 + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 2.5e8 + Assert Equal (SLToken slWBTC TotalBorrowsCurrent) 2.5e8 Test "Borrow WBTC, can't repay when paused" NewBorrow borrowAmount:1e8 borrowRate:0.000005 - Assert Equal (CToken cWBTC BorrowBalance Geoff) 1e8 - Assert Equal (CToken cWBTC TotalBorrowsCurrent) 1e8 + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 1e8 + Assert Equal (SLToken slWBTC TotalBorrowsCurrent) 1e8 Assert Equal (Erc20 WBTC TokenBalance Geoff) 1e8 - Assert Equal (Erc20 WBTC TokenBalance cWBTC) 9e8 + Assert Equal (Erc20 WBTC TokenBalance slWBTC) 9e8 -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- 1e18 * (1 + 300000 * 0.000005) - Invariant Remains (CToken cWBTC BorrowBalance Geoff) 2.5e8 + Invariant Remains (SLToken slWBTC BorrowBalance Geoff) 2.5e8 -- Now let's repay one full token - From Geoff (Erc20 WBTC Approve cWBTC 1.0e8) + From Geoff (Erc20 WBTC Approve slWBTC 1.0e8) Erc20 WBTC Pause AllowFailures - RepayBorrow Geoff 1e8 cWBTC + RepayBorrow Geoff 1e8 slWBTC Assert Revert Test "Repay fails with insufficient allowance" NewBorrow borrowAmount:1e8 borrowRate:0.000005 - Assert Equal (CToken cWBTC BorrowBalance Geoff) 1e8 - Assert Equal (CToken cWBTC TotalBorrowsCurrent) 1e8 + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 1e8 + Assert Equal (SLToken slWBTC TotalBorrowsCurrent) 1e8 -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- 1e8 * (1 + 300000 * 0.000005) - Assert Equal (CToken cWBTC BorrowBalance Geoff) 2.5e8 + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 2.5e8 -- Now let's repay fully AllowFailures - Prep Geoff 100e8 WBTC cWBTC allowanceAmount:1.5e8 + Prep Geoff 100e8 WBTC slWBTC allowanceAmount:1.5e8 Expect Changes (Erc20 WBTC TokenBalance Geoff) Zero - Expect Changes (Erc20 WBTC TokenBalance cWBTC) Zero - RepayBorrow Geoff 2.5e8 cWBTC + Expect Changes (Erc20 WBTC TokenBalance slWBTC) Zero + RepayBorrow Geoff 2.5e8 slWBTC --wbtc does not revert with reason in transfer from Assert Revert "revert" -- Let's check the overall numbers - Assert Equal (CToken cWBTC BorrowBalance Geoff) 2.5e8 - Assert Equal (CToken cWBTC TotalBorrowsCurrent) 2.5e8 + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 2.5e8 + Assert Equal (SLToken slWBTC TotalBorrowsCurrent) 2.5e8 Test "Repay fails with insufficient balance" NewBorrow borrowAmount:1e8 borrowRate:0.000005 - Assert Equal (CToken cWBTC BorrowBalance Geoff) 1e8 - Assert Equal (CToken cWBTC TotalBorrowsCurrent) 1e8 + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 1e8 + Assert Equal (SLToken slWBTC TotalBorrowsCurrent) 1e8 -- Now let's add some blocks and see what happs FastForward 300000 Blocks -- 1e8 * (1 + 300000 * 0.000005) - Assert Equal (CToken cWBTC BorrowBalance Geoff) 2.5e8 + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 2.5e8 -- Now let's repay fully AllowFailures - Prep Geoff 0e8 WBTC cWBTC allowanceAmount:2.5e8 + Prep Geoff 0e8 WBTC slWBTC allowanceAmount:2.5e8 Expect Changes (Erc20 WBTC TokenBalance Geoff) Zero - Expect Changes (Erc20 WBTC TokenBalance cWBTC) Zero - RepayBorrow Geoff 2.5e8 cWBTC + Expect Changes (Erc20 WBTC TokenBalance slWBTC) Zero + RepayBorrow Geoff 2.5e8 slWBTC --wbtc does not revert with reason in transfer from Assert Revert "revert" -- Let's check the overall numbers - Assert Equal (CToken cWBTC BorrowBalance Geoff) 2.5e8 - Assert Equal (CToken cWBTC TotalBorrowsCurrent) 2.5e8 + Assert Equal (SLToken slWBTC BorrowBalance Geoff) 2.5e8 + Assert Equal (SLToken slWBTC TotalBorrowsCurrent) 2.5e8 diff --git a/spec/scenario/SLTokenAdmin.scen b/spec/scenario/SLTokenAdmin.scen new file mode 100644 index 000000000..c1bc27fc0 --- /dev/null +++ b/spec/scenario/SLTokenAdmin.scen @@ -0,0 +1,43 @@ + +Test "Set admin" + NewComptroller + NewSLToken ZRX slZRX + Assert Equal (SLToken slZRX Admin) (Address Root) + Assert Equal (SLToken slZRX PendingAdmin) (Address Zero) + From Root (SLToken slZRX SetPendingAdmin Geoff) + Assert Equal (SLToken slZRX Admin) (Address Root) + Assert Equal (SLToken slZRX PendingAdmin) (Address Geoff) + From Geoff (SLToken slZRX AcceptAdmin) + Assert Equal (SLToken slZRX Admin) (Address Geoff) + Assert Equal (SLToken slZRX PendingAdmin) (Address Zero) + +Test "Set admin to contructor argument" + NewComptroller + NewSLToken ZRX slZRX admin:Torrey + Assert Equal (SLToken slZRX Admin) (Address Torrey) + Assert Equal (SLToken slZRX PendingAdmin) (Address Zero) + From Torrey (SLToken slZRX SetPendingAdmin Geoff) + Assert Equal (SLToken slZRX Admin) (Address Torrey) + Assert Equal (SLToken slZRX PendingAdmin) (Address Geoff) + From Geoff (SLToken slZRX AcceptAdmin) + Assert Equal (SLToken slZRX Admin) (Address Geoff) + Assert Equal (SLToken slZRX PendingAdmin) (Address Zero) + + +Test "Fail to set pending admin" + NewComptroller + NewSLToken ZRX slZRX + Invariant Remains (SLToken slZRX Admin) (Address Root) + Invariant Remains (SLToken slZRX PendingAdmin) (Address Zero) + AllowFailures + From Geoff (SLToken slZRX SetPendingAdmin Geoff) + Assert Failure UNAUTHORIZED SET_PENDING_ADMIN_OWNER_CHECK + +Test "Fail to accept admin" + NewComptroller + NewSLToken ZRX slZRX + Invariant Remains (SLToken slZRX Admin) (Address Root) + Invariant Remains (SLToken slZRX PendingAdmin) (Address Zero) + AllowFailures + From Geoff (SLToken slZRX AcceptAdmin) + Assert Failure UNAUTHORIZED ACCEPT_ADMIN_PENDING_ADMIN_CHECK diff --git a/spec/scenario/Seize.scen b/spec/scenario/Seize.scen index 268bd73b5..6d628f9f3 100644 --- a/spec/scenario/Seize.scen +++ b/spec/scenario/Seize.scen @@ -1,50 +1,50 @@ Test "Fail to seize calling directly" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - ListedCToken BAT cBAT initialExchangeRate:1e9 - Prep Geoff Some ZRX cZRX - Mint Geoff 50e18 cZRX - Invariant Remains (Erc20 cZRX TokenBalance Geoff) 50e9 + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + ListedSLToken BAT slBAT initialExchangeRate:1e9 + Prep Geoff Some ZRX slZRX + Mint Geoff 50e18 slZRX + Invariant Remains (Erc20 slZRX TokenBalance Geoff) 50e9 AllowFailures - Seize 1e9 cZRX caller:Geoff liquidator:Geoff borrower:Torrey - -- The caller must be from another cToken market, thus this fails + Seize 1e9 slZRX caller:Geoff liquidator:Geoff borrower:Torrey + -- The caller must be from another slToken market, thus this fails Assert Failure COMPTROLLER_REJECTION LIQUIDATE_SEIZE_COMPTROLLER_REJECTION MARKET_NOT_LISTED -Test "Seize tokens with a paused WBTC cToken-- like normal" +Test "Seize tokens with a paused WBTC slToken-- like normal" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - ListedCToken WBTC cWBTC initialExchangeRate:0.1 tokenType:WBTC - Prep Geoff Some ZRX cZRX - Mint Geoff 50e18 cZRX + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + ListedSLToken WBTC slWBTC initialExchangeRate:0.1 tokenType:WBTC + Prep Geoff Some ZRX slZRX + Mint Geoff 50e18 slZRX Erc20 WBTC Pause - Invariant Remains (Erc20 cZRX TokenBalance Geoff) 50e9 + Invariant Remains (Erc20 slZRX TokenBalance Geoff) 50e9 AllowFailures - Seize 1e9 cWBTC caller:Geoff liquidator:Geoff borrower:Torrey - -- The caller must be from another cToken market, thus this fails + Seize 1e9 slWBTC caller:Geoff liquidator:Geoff borrower:Torrey + -- The caller must be from another slToken market, thus this fails Assert Failure COMPTROLLER_REJECTION LIQUIDATE_SEIZE_COMPTROLLER_REJECTION MARKET_NOT_LISTED -Test "Not able to seize tokens with a malicious unlisted cToken" +Test "Not able to seize tokens with a malicious unlisted slToken" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - NewCTokenImmutable EVL cEVL initialExchangeRate:1e9 cTokenType:CEvil - Prep Geoff Some ZRX cZRX - Mint Geoff 50e18 cZRX - Invariant Remains (Erc20 cZRX TokenBalance Geoff) 50e9 - Invariant Static (Erc20 cZRX TokenBalance Geoff) - Invariant Static (Erc20 cZRX TokenBalance Torrey) + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + NewSLTokenImmutable EVL slEVL initialExchangeRate:1e9 slTokenType:SLEvil + Prep Geoff Some ZRX slZRX + Mint Geoff 50e18 slZRX + Invariant Remains (Erc20 slZRX TokenBalance Geoff) 50e9 + Invariant Static (Erc20 slZRX TokenBalance Geoff) + Invariant Static (Erc20 slZRX TokenBalance Torrey) AllowFailures - EvilSeize cEVL 1e9 cZRX seizer:Geoff seizee:Torrey - -- The caller must be from another cToken market, thus this fails + EvilSeize slEVL 1e9 slZRX seizer:Geoff seizee:Torrey + -- The caller must be from another slToken market, thus this fails Assert Failure COMPTROLLER_REJECTION LIQUIDATE_SEIZE_COMPTROLLER_REJECTION MARKET_NOT_LISTED -Test "Able to seize tokens with a malicious listed cToken" +Test "Able to seize tokens with a malicious listed slToken" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - ListedCTokenImmutable EVL cEVL initialExchangeRate:1e9 cTokenType:CEvil - Prep Geoff Some ZRX cZRX - Mint Geoff 50e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) 50e9 - Expect Changes (Erc20 cZRX TokenBalance Geoff) -1e9 - Expect Changes (Erc20 cZRX TokenBalance Torrey) +1e9 - EvilSeize cEVL 1e9 cZRX seizer:Torrey seizee:Geoff + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + ListedSLTokenImmutable EVL slEVL initialExchangeRate:1e9 slTokenType:SLEvil + Prep Geoff Some ZRX slZRX + Mint Geoff 50e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) 50e9 + Expect Changes (Erc20 slZRX TokenBalance Geoff) -1e9 + Expect Changes (Erc20 slZRX TokenBalance Torrey) +1e9 + EvilSeize slEVL 1e9 slZRX seizer:Torrey seizee:Geoff diff --git a/spec/scenario/SetComptroller.scen b/spec/scenario/SetComptroller.scen index e3a7f89d0..25a03f168 100644 --- a/spec/scenario/SetComptroller.scen +++ b/spec/scenario/SetComptroller.scen @@ -2,25 +2,25 @@ Test "Set Comptroller" NewComptroller - NewCToken ZRX cZRX - Assert Equal (CToken cZRX Comptroller) (Unitroller Address) + NewSLToken ZRX slZRX + Assert Equal (SLToken slZRX Comptroller) (Unitroller Address) ComptrollerImpl Deploy Scenario NewComptroller - From Root (CToken cZRX SetComptroller (ComptrollerImpl NewComptroller Address)) + From Root (SLToken slZRX SetComptroller (ComptrollerImpl NewComptroller Address)) -- TODO: Fix log assertion -- Assert Log "NewComptroller" ("oldComptroller" (Unitroller Address)) ("newComptroller" (ComptrollerImpl NewComptroller Address)) - Assert Equal (CToken cZRX Comptroller) (ComptrollerImpl NewComptroller Address) + Assert Equal (SLToken slZRX Comptroller) (ComptrollerImpl NewComptroller Address) Test "Fail when is not a comptroller" NewComptroller - NewCToken ZRX cZRX - Invariant Remains (CToken cZRX Comptroller) (Unitroller Address) + NewSLToken ZRX slZRX + Invariant Remains (SLToken slZRX Comptroller) (Unitroller Address) AllowFailures - From Root (CToken cZRX SetComptroller (PriceOracle Address)) + From Root (SLToken slZRX SetComptroller (PriceOracle Address)) Assert Revert Test "Fail to set comptroller as not admin" NewComptroller - NewCToken ZRX cZRX + NewSLToken ZRX slZRX AllowFailures - From Geoff (CToken cZRX SetComptroller (PriceOracle Address)) + From Geoff (SLToken slZRX SetComptroller (PriceOracle Address)) Assert Failure UNAUTHORIZED SET_COMPTROLLER_OWNER_CHECK diff --git a/spec/scenario/Tether.scen b/spec/scenario/Tether.scen index 75f7d3cb1..767f90ea3 100644 --- a/spec/scenario/Tether.scen +++ b/spec/scenario/Tether.scen @@ -32,55 +32,55 @@ Pending "TODO: Add Back Tether Tests" -- ForkTether -- NewComptroller price:1.0 -- Erc20 Deploy ExistingTether USDT TetherAddress --- NewCTokenBringERC20 USDT cUSDT +-- NewSLTokenBringERC20 USDT slUSDT -- From TetherAdmin (Erc20 USDT SetFee 10 10) --- Invariant Static (CToken cUSDT ExchangeRate) --- Support cUSDT --- From TetherHolder (Erc20 USDT Approve cUSDT 1e8) --- Mint TetherHolder 1e8 cUSDT --- Assert Equal (ERC20 USDT TokenBalance cUSDT) 0.999e8 +-- Invariant Static (SLToken slUSDT ExchangeRate) +-- Support slUSDT +-- From TetherHolder (Erc20 USDT Approve slUSDT 1e8) +-- Mint TetherHolder 1e8 slUSDT +-- Assert Equal (ERC20 USDT TokenBalance slUSDT) 0.999e8 --- Test "Should be able to redeem a fee CToken, exchange Rate should not change" +-- Test "Should be able to redeem a fee SLToken, exchange Rate should not change" -- ForkTether -- NewComptroller price:1.0 -- Erc20 Deploy ExistingTether USDT TetherAddress --- NewCTokenBringERC20 USDT cUSDT +-- NewSLTokenBringERC20 USDT slUSDT -- From TetherAdmin (Erc20 USDT SetFee 10 10) --- Support cUSDT --- Invariant Static (CToken cUSDT ExchangeRate) --- From TetherHolder (Erc20 USDT Approve cUSDT 1e8) --- Mint TetherHolder 1e8 cUSDT --- Redeem Torrey (Erc20 cUSDT TokenBalance TetherHolder) cUSDT +-- Support slUSDT +-- Invariant Static (SLToken slUSDT ExchangeRate) +-- From TetherHolder (Erc20 USDT Approve slUSDT 1e8) +-- Mint TetherHolder 1e8 slUSDT +-- Redeem Torrey (Erc20 slUSDT TokenBalance TetherHolder) slUSDT -- Test "Repay borrow should work and not change exchange rate" -- ForkTether -- PricedComptroller -- Erc20 Deploy ExistingTether USDT TetherAddress --- NewCTokenBringERC20 USDT cUSDT --- NewCToken ZRX cZRX 0.000005 2e9 8 Standard --- PriceOracle SetPrice cZRX 1.0 --- PriceOracle SetPrice cUSDT 1.0 --- Support cZRX 0.5 --- Support cUSDT 0.5 --- Invariant Static (CToken cUSDT ExchangeRate) +-- NewSLTokenBringERC20 USDT slUSDT +-- NewSLToken ZRX slZRX 0.000005 2e9 8 Standard +-- PriceOracle SetPrice slZRX 1.0 +-- PriceOracle SetPrice slUSDT 1.0 +-- Support slZRX 0.5 +-- Support slUSDT 0.5 +-- Invariant Static (SLToken slUSDT ExchangeRate) -- -- --- From TetherHolder (Erc20 USDT Approve cUSDT 1e8) --- Mint TetherHolder 1e8 cUSDT +-- From TetherHolder (Erc20 USDT Approve slUSDT 1e8) +-- Mint TetherHolder 1e8 slUSDT -- From TetherAdmin (Erc20 USDT SetFee 10 10) -- -- --- Prep Torrey 100e8 ZRX cZRX --- Mint Torrey 100e8 cZRX --- EnterMarkets Torrey cUSDT --- EnterMarkets Torrey cZRX --- Borrow Torrey 1e8 cUSDT -- we only received 0.999e8 tether bc of fee +-- Prep Torrey 100e8 ZRX slZRX +-- Mint Torrey 100e8 slZRX +-- EnterMarkets Torrey slUSDT +-- EnterMarkets Torrey slZRX +-- Borrow Torrey 1e8 slUSDT -- we only received 0.999e8 tether bc of fee -- Assert Equal (ERC20 USDT TokenBalance Torrey) 0.999e8 -- FastForward 199600 Blocks -- 1e8 * 199800 * 0.000005 = 0.998e8 interest accrued --- Assert Equal (CToken cUSDT TotalBorrowsCurrent) 1.998e8 +-- Assert Equal (SLToken slUSDT TotalBorrowsCurrent) 1.998e8 -- From TetherHolder (Erc20 USDT Transfer Torrey 2e8) --- From Torrey (Erc20 USDT Approve cUSDT 2e8) --- RepayBorrow Torrey 2e8 cUSDT -- repay more than we owe to account for fee --- Assert Equal (CToken cUSDT BorrowBalance Torrey) 0 --- Assert Equal (CToken cUSDT TotalBorrowsCurrent) 0 +-- From Torrey (Erc20 USDT Approve slUSDT 2e8) +-- RepayBorrow Torrey 2e8 slUSDT -- repay more than we owe to account for fee +-- Assert Equal (SLToken slUSDT BorrowBalance Torrey) 0 +-- Assert Equal (SLToken slUSDT TotalBorrowsCurrent) 0 -- --Assert Equal (ERC20 USDT TokenBalance Torrey) 0 -- Test "Should be able to liquidate Tether token borrow" @@ -88,30 +88,30 @@ Pending "TODO: Add Back Tether Tests" -- PricedComptroller -- Comptroller LiquidationIncentive 1.1 -- Erc20 Deploy ExistingTether USDT TetherAddress-- FYI tether is 6 decimals --- NewCTokenBringERC20 USDT cUSDT --- NewCToken ZRX cZRX 0.000005 2e9 8 Standard --- PriceOracle SetPrice cZRX 1.0 --- PriceOracle SetPrice cUSDT 1e12 --- Support cZRX 0.5 --- Support cUSDT 0.5 --- Invariant Static (CToken cUSDT ExchangeRate) --- -- Give some Tether to cUSDT --- From TetherHolder (Erc20 USDT Approve cUSDT 2e8) --- Mint TetherHolder 2e8 cUSDT +-- NewSLTokenBringERC20 USDT slUSDT +-- NewSLToken ZRX slZRX 0.000005 2e9 8 Standard +-- PriceOracle SetPrice slZRX 1.0 +-- PriceOracle SetPrice slUSDT 1e12 +-- Support slZRX 0.5 +-- Support slUSDT 0.5 +-- Invariant Static (SLToken slUSDT ExchangeRate) +-- -- Give some Tether to slUSDT +-- From TetherHolder (Erc20 USDT Approve slUSDT 2e8) +-- Mint TetherHolder 2e8 slUSDT -- From TetherAdmin (Erc20 USDT SetFee 10 10) -- -- Prep our Tether borrower --- Prep Torrey 2e18 ZRX cZRX --- Mint Torrey 2e18 cZRX --- EnterMarkets Torrey cUSDT --- EnterMarkets Torrey cZRX --- Borrow Torrey 1e6 cUSDT -- fyi we only received 0.999e8 tether bc of fee +-- Prep Torrey 2e18 ZRX slZRX +-- Mint Torrey 2e18 slZRX +-- EnterMarkets Torrey slUSDT +-- EnterMarkets Torrey slZRX +-- Borrow Torrey 1e6 slUSDT -- fyi we only received 0.999e8 tether bc of fee -- Assert Equal (ERC20 USDT TokenBalance Torrey) 0.999e6 -- FastForward 199600 Blocks -- 1e6 * 199800 * 0.000005 = 0.998e6 interest accrued --- Assert Equal (CToken cUSDT TotalBorrowsCurrent) 1.998e6 +-- Assert Equal (SLToken slUSDT TotalBorrowsCurrent) 1.998e6 -- -- ok.. ready the liquidator -- From TetherHolder (Erc20 USDT Transfer Coburn 2e6) -- should give 1.001001001 --- From Coburn (Erc20 USDT Approve cUSDT 2e6) --- Liquidate Coburn "->" Torrey 0.1e6 cUSDT "Seizing" cZRX +-- From Coburn (Erc20 USDT Approve slUSDT 2e6) +-- Liquidate Coburn "->" Torrey 0.1e6 slUSDT "Seizing" slZRX -- -- 5.4945e7 = (1e18 / 1e6) * 0.1e6 (amt liquidated) * 1.1 (liq discount) * .999 (fee) / 2e9 (exchange rate) --- Assert Equal (Erc20 cZRX TokenBalance Coburn) 5.4945e7 --- Assert Equal (CToken cUSDT BorrowBalance Torrey) 1.8981e6 -- 1.998 - (.1 * .999) was liquidated +-- Assert Equal (Erc20 slZRX TokenBalance Coburn) 5.4945e7 +-- Assert Equal (SLToken slUSDT BorrowBalance Torrey) 1.8981e6 -- 1.998 - (.1 * .999) was liquidated diff --git a/spec/scenario/Timelock.scen b/spec/scenario/Timelock.scen index bf2e039ca..d01b3a307 100644 --- a/spec/scenario/Timelock.scen +++ b/spec/scenario/Timelock.scen @@ -51,27 +51,27 @@ Test "Queuing and execute a transaction for setPendingAdmin" Assert Equal (Timelock Admin) (User Jared Address) Assert Equal (Timelock PendingAdmin) (Address Zero) -Test "Accept cToken admin from Timelock" +Test "Accept slToken admin from Timelock" FreezeTime 90 -- Admin:Geoff Delay:1 week Timelock Deploy Geoff 604800 Assert Equal (Timelock Admin) (User Geoff Address) NewComptroller - NewCToken ZRX cZRX - Assert Equal (CToken cZRX Admin) (Address Root) - Assert Equal (CToken cZRX PendingAdmin) (Address Zero) - From Root (CToken cZRX SetPendingAdmin (Timelock Address)) - Assert Equal (CToken cZRX PendingAdmin) (Timelock Address) + NewSLToken ZRX slZRX + Assert Equal (SLToken slZRX Admin) (Address Root) + Assert Equal (SLToken slZRX PendingAdmin) (Address Zero) + From Root (SLToken slZRX SetPendingAdmin (Timelock Address)) + Assert Equal (SLToken slZRX PendingAdmin) (Timelock Address) -- eta = 1 week (604800) + blockTimestamp (~100) = 604900 - Assert False (Timelock QueuedTransaction (Timelock TxHash (CToken cZRX Address) 0 604900 "_acceptAdmin()" "")) - From Geoff (Timelock QueueTransaction (CToken cZRX Address) 0 604900 "_acceptAdmin()" "") - Assert True (Timelock QueuedTransaction (Timelock TxHash (CToken cZRX Address) 0 604900 "_acceptAdmin()" "")) + Assert False (Timelock QueuedTransaction (Timelock TxHash (SLToken slZRX Address) 0 604900 "_acceptAdmin()" "")) + From Geoff (Timelock QueueTransaction (SLToken slZRX Address) 0 604900 "_acceptAdmin()" "") + Assert True (Timelock QueuedTransaction (Timelock TxHash (SLToken slZRX Address) 0 604900 "_acceptAdmin()" "")) -- Now execute after delay time FreezeTime 604900 - From Geoff (Timelock ExecuteTransaction (CToken cZRX Address) 0 604900 "_acceptAdmin()" "") - Assert False (Timelock QueuedTransaction (Timelock TxHash (CToken cZRX Address) 0 604900 "_acceptAdmin()" "")) - Assert Equal (CToken cZRX Admin) (Timelock Address) - Assert Equal (CToken cZRX PendingAdmin) (Address Zero) + From Geoff (Timelock ExecuteTransaction (SLToken slZRX Address) 0 604900 "_acceptAdmin()" "") + Assert False (Timelock QueuedTransaction (Timelock TxHash (SLToken slZRX Address) 0 604900 "_acceptAdmin()" "")) + Assert Equal (SLToken slZRX Admin) (Timelock Address) + Assert Equal (SLToken slZRX PendingAdmin) (Address Zero) Test "Accept unitroller admin from Timelock" -- Admin:Geoff Delay:1 week @@ -97,44 +97,44 @@ Test "Accept unitroller admin from Timelock" Test "Reduce reserves for CErc20 from Timelock and send reserves to external address" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff 50e18 ZRX cZRX - Mint Geoff 50e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 500e8) - Assert Equal (CToken cZRX UnderlyingBalance Geoff) (Exactly 50e18) - Assert Equal (CToken cZRX ExchangeRate) (Exactly 1e9) - BorrowAndRepayWithInterest ZRX cZRX 10e18 5e18 interestRate:0.000001 blocks:500000 reserveRate:0.2 + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff 50e18 ZRX slZRX + Mint Geoff 50e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 500e8) + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) (Exactly 50e18) + Assert Equal (SLToken slZRX ExchangeRate) (Exactly 1e9) + BorrowAndRepayWithInterest ZRX slZRX 10e18 5e18 interestRate:0.000001 blocks:500000 reserveRate:0.2 -- We've accrued 10% interest for 5 blocks, or 50% of the amount, -- thus, we should have accrued 5e18 of interest for the protocol -- The reserves should get 20% of this, or 1e18, and the rest -- is due pro-rata to all holders. We just have one, so -- let's check that account is given correct new balance. Timelock Deploy Jared 604800 - Assert Equal (Erc20 ZRX TokenBalance cZRX) (Exactly 55e18) + Assert Equal (Erc20 ZRX TokenBalance slZRX) (Exactly 55e18) Assert Equal (Erc20 ZRX TokenBalance (Timelock Address)) (Exactly 0e18) - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 500e8) - Assert Equal (CToken cZRX Reserves) (Exactly 1e18) - Assert Equal (CToken cZRX UnderlyingBalance Geoff) (Exactly 54e18) + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 500e8) + Assert Equal (SLToken slZRX Reserves) (Exactly 1e18) + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) (Exactly 54e18) -- (55.0e18+0.0e18-1.0e18)/500.0e8 - Assert Equal (CToken cZRX ExchangeRate) (Exactly 1.08e9) + Assert Equal (SLToken slZRX ExchangeRate) (Exactly 1.08e9) -- Set Timelock as admin - From Root (CToken cZRX SetPendingAdmin (Timelock Address)) + From Root (SLToken slZRX SetPendingAdmin (Timelock Address)) -- Queue Transactions FreezeTime 90 - From Jared (Timelock QueueTransaction (CToken cZRX Address) 0 604900 "_acceptAdmin()" "") - From Jared (Timelock QueueTransaction (CToken cZRX Address) 0 604900 "_reduceReserves(uint256)" "1000000000000000000") + From Jared (Timelock QueueTransaction (SLToken slZRX Address) 0 604900 "_acceptAdmin()" "") + From Jared (Timelock QueueTransaction (SLToken slZRX Address) 0 604900 "_reduceReserves(uint256)" "1000000000000000000") From Jared (Timelock QueueTransaction (Erc20 ZRX Address) 0 604900 "transfer(address,uint256)" "0x0000000000000000000000000000000000000001" "1000000000000000000") FreezeTime 604900 - From Jared (Timelock ExecuteTransaction (CToken cZRX Address) 0 604900 "_acceptAdmin()" "") + From Jared (Timelock ExecuteTransaction (SLToken slZRX Address) 0 604900 "_acceptAdmin()" "") -- Now, let's pull out all of our reserves (1e18) - From Jared (Timelock ExecuteTransaction (CToken cZRX Address) 0 604900 "_reduceReserves(uint256)" "1000000000000000000") - Assert Equal (Erc20 ZRX TokenBalance cZRX) (Exactly 54e18) + From Jared (Timelock ExecuteTransaction (SLToken slZRX Address) 0 604900 "_reduceReserves(uint256)" "1000000000000000000") + Assert Equal (Erc20 ZRX TokenBalance slZRX) (Exactly 54e18) Assert Equal (Erc20 ZRX TokenBalance (Timelock Address)) (Exactly 1e18) - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 500e8) - Assert Equal (CToken cZRX Reserves) (Exactly 0e18) - Assert Equal (CToken cZRX UnderlyingBalance Geoff) (Exactly 54e18) + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 500e8) + Assert Equal (SLToken slZRX Reserves) (Exactly 0e18) + Assert Equal (SLToken slZRX UnderlyingBalance Geoff) (Exactly 54e18) -- (54.0e18+0.0e18-0.0e18)/500.0e8 - Assert Equal (CToken cZRX ExchangeRate) (Exactly 1.08e9) + Assert Equal (SLToken slZRX ExchangeRate) (Exactly 1.08e9) Assert Equal (Erc20 ZRX TokenBalance "0x0000000000000000000000000000000000000001") (Exactly 0e18) From Jared (Timelock ExecuteTransaction (Erc20 ZRX Address) 0 604900 "transfer(address,uint256)" "0x0000000000000000000000000000000000000001" "1000000000000000000") Assert Equal (Erc20 ZRX TokenBalance (Timelock Address)) (Exactly 0e18) @@ -142,12 +142,12 @@ Test "Reduce reserves for CErc20 from Timelock and send reserves to external add Test "Reduce reserves for CEther from Timelock and send reserves to external address" NewComptroller - ListedEtherToken cETH initialExchangeRate:1e9 - CallMintEth Geoff 50e18 cETH - Assert Equal (Erc20 cETH TokenBalance Geoff) (Exactly 500e8) - Assert Equal (CToken cETH UnderlyingBalance Geoff) (Exactly 50e18) - Assert Equal (CToken cETH ExchangeRate) (Exactly 1e9) - BorrowAndRepayEthWithInterest cETH 10e18 5e18 interestRate:0.000001 blocks:500000 reserveRate:0.2 + ListedEtherToken slETH initialExchangeRate:1e9 + CallMintEth Geoff 50e18 slETH + Assert Equal (Erc20 slETH TokenBalance Geoff) (Exactly 500e8) + Assert Equal (SLToken slETH UnderlyingBalance Geoff) (Exactly 50e18) + Assert Equal (SLToken slETH ExchangeRate) (Exactly 1e9) + BorrowAndRepayEthWithInterest slETH 10e18 5e18 interestRate:0.000001 blocks:500000 reserveRate:0.2 -- We've accrued 10% interest for 5 blocks, or 50% of the amount, -- thus, we should have accrued 5e18 of interest for the protocol -- The reserves should get 20% of this, or 1e18, and the rest @@ -155,30 +155,30 @@ Test "Reduce reserves for CEther from Timelock and send reserves to external add -- let's check that account is given correct new balance. FreezeTime 90 Timelock Deploy Jared 604800 - Assert Equal (EtherBalance cETH) (Exactly 55e18) + Assert Equal (EtherBalance slETH) (Exactly 55e18) Assert Equal (EtherBalance (Timelock Address)) (Exactly 0e18) - Assert Equal (Erc20 cETH TokenBalance Geoff) (Exactly 500e8) - Assert Equal (CToken cETH Reserves) (Exactly 1e18) - Assert Equal (CToken cETH UnderlyingBalance Geoff) (Exactly 54e18) + Assert Equal (Erc20 slETH TokenBalance Geoff) (Exactly 500e8) + Assert Equal (SLToken slETH Reserves) (Exactly 1e18) + Assert Equal (SLToken slETH UnderlyingBalance Geoff) (Exactly 54e18) -- (55.0e18+0.0e18-1.0e18)/500.0e8 - Assert Equal (CToken cETH ExchangeRate) (Exactly 1.08e9) + Assert Equal (SLToken slETH ExchangeRate) (Exactly 1.08e9) -- Set Timelock as admin - From Root (CToken cETH SetPendingAdmin (Timelock Address)) + From Root (SLToken slETH SetPendingAdmin (Timelock Address)) -- Queue Transactions - From Jared (Timelock QueueTransaction (CToken cETH Address) 0 604900 "_acceptAdmin()" "") - From Jared (Timelock QueueTransaction (CToken cETH Address) 0 604900 "_reduceReserves(uint256)" "1000000000000000000") + From Jared (Timelock QueueTransaction (SLToken slETH Address) 0 604900 "_acceptAdmin()" "") + From Jared (Timelock QueueTransaction (SLToken slETH Address) 0 604900 "_reduceReserves(uint256)" "1000000000000000000") From Jared (Timelock QueueTransaction Jared 1000000000000000000 604900 "" "") FreezeTime 604900 - From Jared (Timelock ExecuteTransaction (CToken cETH Address) 0 604900 "_acceptAdmin()" "") + From Jared (Timelock ExecuteTransaction (SLToken slETH Address) 0 604900 "_acceptAdmin()" "") -- Now, let's pull out all of our reserves (1e18) - From Jared (Timelock ExecuteTransaction (CToken cETH Address) 0 604900 "_reduceReserves(uint256)" "1000000000000000000") + From Jared (Timelock ExecuteTransaction (SLToken slETH Address) 0 604900 "_reduceReserves(uint256)" "1000000000000000000") Assert Equal (EtherBalance (Timelock Address)) 1e18 - Assert Equal (EtherBalance cETH) (Exactly 54e18) - Assert Equal (Erc20 cETH TokenBalance Geoff) (Exactly 500e8) - Assert Equal (CToken cETH Reserves) (Exactly 0e18) - Assert Equal (CToken cETH UnderlyingBalance Geoff) (Exactly 54e18) + Assert Equal (EtherBalance slETH) (Exactly 54e18) + Assert Equal (Erc20 slETH TokenBalance Geoff) (Exactly 500e8) + Assert Equal (SLToken slETH Reserves) (Exactly 0e18) + Assert Equal (SLToken slETH UnderlyingBalance Geoff) (Exactly 54e18) -- (54.0e18+0.0e18-0.0e18)/500.0e8 - Assert Equal (CToken cETH ExchangeRate) (Exactly 1.08e9) + Assert Equal (SLToken slETH ExchangeRate) (Exactly 1.08e9) Expect Changes (EtherBalance Jared) 1e18 Trx GasPrice 0 (From Jared (Timelock ExecuteTransaction Jared 1000000000000000000 604900 "" "")) Assert Equal (EtherBalance (Timelock Address)) (Exactly 0e18) diff --git a/spec/scenario/TokenTransfer.scen b/spec/scenario/TokenTransfer.scen index e480747ce..070692a54 100644 --- a/spec/scenario/TokenTransfer.scen +++ b/spec/scenario/TokenTransfer.scen @@ -1,108 +1,108 @@ -Test "Simple cToken Transfer" +Test "Simple slToken Transfer" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff Some ZRX cZRX - Mint Geoff 50e18 cZRX + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff Some ZRX slZRX + Mint Geoff 50e18 slZRX -- Just to be sure, check initial balances - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 50e9) - Assert Equal (Erc20 cZRX TokenBalance Torrey) Zero + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 50e9) + Assert Equal (Erc20 slZRX TokenBalance Torrey) Zero -- Just transfer - Transfer Geoff Torrey 10e9 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 40e9) - Assert Equal (Erc20 cZRX TokenBalance Torrey) (Exactly 10e9) + Transfer Geoff Torrey 10e9 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 40e9) + Assert Equal (Erc20 slZRX TokenBalance Torrey) (Exactly 10e9) -Test "Simple cToken Transfer When Underlying Paused" +Test "Simple slToken Transfer When Underlying Paused" NewComptroller - ListedCToken WBTC cWBTC initialExchangeRate:0.1 tokenType:WBTC - Prep Geoff Some WBTC cWBTC - Mint Geoff 50e8 cWBTC + ListedSLToken WBTC slWBTC initialExchangeRate:0.1 tokenType:WBTC + Prep Geoff Some WBTC slWBTC + Mint Geoff 50e8 slWBTC -- Just to be sure, check initial balances - Assert Equal (Erc20 cWBTC TokenBalance Geoff) (Exactly 50e9) - Assert Equal (Erc20 cWBTC TokenBalance Torrey) Zero + Assert Equal (Erc20 slWBTC TokenBalance Geoff) (Exactly 50e9) + Assert Equal (Erc20 slWBTC TokenBalance Torrey) Zero -- Just transfer Erc20 WBTC Pause - Transfer Geoff Torrey 10e9 cWBTC - Assert Equal (Erc20 cWBTC TokenBalance Geoff) (Exactly 40e9) - Assert Equal (Erc20 cWBTC TokenBalance Torrey) (Exactly 10e9) + Transfer Geoff Torrey 10e9 slWBTC + Assert Equal (Erc20 slWBTC TokenBalance Geoff) (Exactly 40e9) + Assert Equal (Erc20 slWBTC TokenBalance Torrey) (Exactly 10e9) -Test "Simple cToken Transfer 1:1 Rate" +Test "Simple slToken Transfer 1:1 Rate" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e0 - Prep Geoff Some ZRX cZRX - Mint Geoff 50e18 cZRX + ListedSLToken ZRX slZRX initialExchangeRate:1e0 + Prep Geoff Some ZRX slZRX + Mint Geoff 50e18 slZRX -- Just to be sure, check initial balances - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 50e18) - Assert Equal (Erc20 cZRX TokenBalance Torrey) Zero + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 50e18) + Assert Equal (Erc20 slZRX TokenBalance Torrey) Zero -- Just transfer - Transfer Geoff Torrey 10e18 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 40e18) - Assert Equal (Erc20 cZRX TokenBalance Torrey) (Exactly 10e18) + Transfer Geoff Torrey 10e18 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 40e18) + Assert Equal (Erc20 slZRX TokenBalance Torrey) (Exactly 10e18) -Test "Simple cToken Transfer Not Allowed by Comptroller" +Test "Simple slToken Transfer Not Allowed by Comptroller" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e0 - Comptroller SetCollateralFactor cZRX 0.1 - EnterMarkets Geoff cZRX - Prep Geoff Some ZRX cZRX - Mint Geoff 50e18 cZRX + ListedSLToken ZRX slZRX initialExchangeRate:1e0 + Comptroller SetCollateralFactor slZRX 0.1 + EnterMarkets Geoff slZRX + Prep Geoff Some ZRX slZRX + Mint Geoff 50e18 slZRX -- Just to be sure, check initial balances - Invariant Remains (Erc20 cZRX TokenBalance Geoff) (Exactly 50e18) - Invariant Remains (Erc20 cZRX TokenBalance Torrey) Zero + Invariant Remains (Erc20 slZRX TokenBalance Geoff) (Exactly 50e18) + Invariant Remains (Erc20 slZRX TokenBalance Torrey) Zero -- Just transfer AllowFailures - Transfer Geoff Torrey 60e18 cZRX + Transfer Geoff Torrey 60e18 slZRX Assert Failure COMPTROLLER_REJECTION TRANSFER_COMPTROLLER_REJECTION INSUFFICIENT_LIQUIDITY -Test "Simple cToken Transfer From" +Test "Simple slToken Transfer From" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff Some ZRX cZRX - Mint Geoff 50e18 cZRX + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff Some ZRX slZRX + Mint Geoff 50e18 slZRX -- Just to be sure, check initial balances - Invariant Remains (Erc20 cZRX TokenBalance Torrey) Zero - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 50e9) - Assert Equal (Erc20 cZRX TokenBalance Coburn) Zero + Invariant Remains (Erc20 slZRX TokenBalance Torrey) Zero + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 50e9) + Assert Equal (Erc20 slZRX TokenBalance Coburn) Zero -- Add approval - From Geoff (Erc20 cZRX Approve Torrey 25e9) - Assert Equal (Erc20 cZRX Allowance Geoff Torrey) (Exactly 25e9) + From Geoff (Erc20 slZRX Approve Torrey 25e9) + Assert Equal (Erc20 slZRX Allowance Geoff Torrey) (Exactly 25e9) -- Perform transfer from - From Torrey (Erc20 cZRX TransferFrom Geoff Coburn 10e9) - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 40e9) - Assert Equal (Erc20 cZRX TokenBalance Coburn) (Exactly 10e9) - Assert Equal (Erc20 cZRX Allowance Geoff Torrey) (Exactly 15e9) + From Torrey (Erc20 slZRX TransferFrom Geoff Coburn 10e9) + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 40e9) + Assert Equal (Erc20 slZRX TokenBalance Coburn) (Exactly 10e9) + Assert Equal (Erc20 slZRX Allowance Geoff Torrey) (Exactly 15e9) -Test "cToken Transfer From Not Allowed" +Test "slToken Transfer From Not Allowed" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff Some ZRX cZRX - Mint Geoff 50e18 cZRX + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff Some ZRX slZRX + Mint Geoff 50e18 slZRX -- - Invariant Remains (Erc20 cZRX TokenBalance Geoff) (Exactly 50e9) - Invariant Remains (Erc20 cZRX TokenBalance Torrey) (Exactly 0e9) + Invariant Remains (Erc20 slZRX TokenBalance Geoff) (Exactly 50e9) + Invariant Remains (Erc20 slZRX TokenBalance Torrey) (Exactly 0e9) AllowFailures - Erc20 cZRX TransferFrom Geoff Torrey 10e9 + Erc20 slZRX TransferFrom Geoff Torrey 10e9 Assert Failure MATH_ERROR TRANSFER_NOT_ALLOWED -Test "cToken Transfer paused" +Test "slToken Transfer paused" NewComptroller - ListedCToken ZRX cZRX initialExchangeRate:1e9 - Prep Geoff Some ZRX cZRX - Mint Geoff 50e18 cZRX + ListedSLToken ZRX slZRX initialExchangeRate:1e9 + Prep Geoff Some ZRX slZRX + Mint Geoff 50e18 slZRX -- Just to be sure, check initial balances - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 50e9) - Assert Equal (Erc20 cZRX TokenBalance Coburn) Zero + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 50e9) + Assert Equal (Erc20 slZRX TokenBalance Coburn) Zero -- Pause and attempt transfer Comptroller SetPauseGuardian Coburn From Coburn (Comptroller SetGuardianPaused "Transfer" True) AllowFailures - Transfer Geoff Torrey 10e9 cZRX + Transfer Geoff Torrey 10e9 slZRX Assert Revert "revert transfer is paused" - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 50e9) - Assert Equal (Erc20 cZRX TokenBalance Coburn) Zero + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 50e9) + Assert Equal (Erc20 slZRX TokenBalance Coburn) Zero -- unPause and complete transfer Invariant Success Comptroller SetGuardianPaused "Transfer" False - Transfer Geoff Coburn 10e9 cZRX - Assert Equal (Erc20 cZRX TokenBalance Geoff) (Exactly 40e9) - Assert Equal (Erc20 cZRX TokenBalance Coburn) (Exactly 10e9) + Transfer Geoff Coburn 10e9 slZRX + Assert Equal (Erc20 slZRX TokenBalance Geoff) (Exactly 40e9) + Assert Equal (Erc20 slZRX TokenBalance Coburn) (Exactly 10e9) diff --git a/spec/scenario/Unitroller.scen b/spec/scenario/Unitroller.scen index cb854e1bf..f48ab1bcc 100644 --- a/spec/scenario/Unitroller.scen +++ b/spec/scenario/Unitroller.scen @@ -9,8 +9,8 @@ Test "Standard Upgrade" Assert Equal (Comptroller CloseFactor) 0.2 Assert Equal (Comptroller MaxAssets) 20 Assert Equal (Comptroller Implementation) (Address ScenComptrollerG1) - ListedCToken ZRX cZRX - ListedCToken DAI cDAI + ListedSLToken ZRX slZRX + ListedSLToken DAI slDAI -- Upgrade to G2 ComptrollerImpl Deploy StandardG2 StandardComptrollerG2 Unitroller SetPendingImpl StandardComptrollerG2 @@ -21,7 +21,7 @@ Test "Standard Upgrade" -- Upgrade to G3 ComptrollerImpl Deploy ScenarioG3 ScenComptrollerG3 Unitroller SetPendingImpl ScenComptrollerG3 - ComptrollerImpl ScenComptrollerG3 BecomeG3 1e18 [cZRX cDAI] + ComptrollerImpl ScenComptrollerG3 BecomeG3 1e18 [slZRX slDAI] Assert Equal (Comptroller CloseFactor) 0.2 Assert Equal (Comptroller MaxAssets) 20 Assert Equal (Comptroller Implementation) (Address ScenComptrollerG3) @@ -36,8 +36,8 @@ Test "Standard Upgrade, then downgrade then upgrade again" Assert Equal (Comptroller CloseFactor) 0.2 Assert Equal (Comptroller MaxAssets) 20 Assert Equal (Comptroller Implementation) (Address ScenComptrollerG1) - ListedCToken ZRX cZRX - ListedCToken DAI cDAI + ListedSLToken ZRX slZRX + ListedSLToken DAI slDAI -- Upgrade to G2 ComptrollerImpl Deploy StandardG2 ComptrollerG2 Unitroller SetPendingImpl ComptrollerG2 @@ -50,7 +50,7 @@ Test "Standard Upgrade, then downgrade then upgrade again" -- Upgrade to G3 ComptrollerImpl Deploy ScenarioG3 ScenComptrollerG3 Unitroller SetPendingImpl ScenComptrollerG3 - ComptrollerImpl ScenComptrollerG3 BecomeG3 1e18 [cZRX cDAI] + ComptrollerImpl ScenComptrollerG3 BecomeG3 1e18 [slZRX slDAI] Assert Equal (Comptroller PauseGuardian) (Address Coburn) Assert Equal (Comptroller CloseFactor) 0.2 Assert Equal (Comptroller MaxAssets) 20 @@ -64,7 +64,7 @@ Test "Standard Upgrade, then downgrade then upgrade again" -- Upgrade to G3 again Unitroller SetPendingImpl ScenComptrollerG3 ComptrollerImpl ScenComptrollerG3 BecomeG3 1e18 [] - Assert Equal (Comptroller GetCompMarkets) [(Address cZRX) (Address cDAI)] + Assert Equal (Comptroller GetSashimiMarkets) [(Address slZRX) (Address slDAI)] Assert Equal (Comptroller PauseGuardian) (Address Coburn) Assert Equal (Comptroller CloseFactor) 0.2 Assert Equal (Comptroller MaxAssets) 20 @@ -152,17 +152,17 @@ Macro CheckV1Storage -- AccountAssets; 8 * Assert Equal (StorageAt Comptroller 8 0 "number") 0 Assert Equal (StorageAtMapping Comptroller 8 (Address Geoff) "number") 2 - Assert Equal (StorageAtMapping Comptroller 8 (Address Geoff) "list(address)") [(Address cZRX) (Address cBAT)] - Assert Equal (Comptroller AssetsIn Geoff) [(Address cZRX) (Address cBAT)] + Assert Equal (StorageAtMapping Comptroller 8 (Address Geoff) "list(address)") [(Address slZRX) (Address slBAT)] + Assert Equal (Comptroller AssetsIn Geoff) [(Address slZRX) (Address slBAT)] -- Markets; 9 * Assert Equal (StorageAt Comptroller 9 0 "number") 0 - Assert Equal (StorageAtNestedMapping Comptroller 9 (Address cZRX) Geoff "marketStruct") [True 0.5 True] - Assert Equal (StorageAtNestedMapping Comptroller 9 (Address cBAT) Geoff "marketStruct") [True 0.4 True] - Assert Equal (StorageAtNestedMapping Comptroller 9 (Address cBAT) Coburn "marketStruct") [True 0.4 False] - Assert Equal (Comptroller CollateralFactor cZRX) 0.5 - Assert Equal (Comptroller CollateralFactor cBAT) 0.4 - Assert Equal (Comptroller CheckMembership Geoff cZRX) True - Assert Equal (Comptroller CheckMembership Geoff cBAT) True + Assert Equal (StorageAtNestedMapping Comptroller 9 (Address slZRX) Geoff "marketStruct") [True 0.5 True] + Assert Equal (StorageAtNestedMapping Comptroller 9 (Address slBAT) Geoff "marketStruct") [True 0.4 True] + Assert Equal (StorageAtNestedMapping Comptroller 9 (Address slBAT) Coburn "marketStruct") [True 0.4 False] + Assert Equal (Comptroller CollateralFactor slZRX) 0.5 + Assert Equal (Comptroller CollateralFactor slBAT) 0.4 + Assert Equal (Comptroller CheckMembership Geoff slZRX) True + Assert Equal (Comptroller CheckMembership Geoff slBAT) True Macro CheckV2Storage -- PauseGuardian; 10 @@ -190,35 +190,35 @@ Macro CheckV2Storage -- Pause by market storage -- -- MintGuardianPaused; 15 - Assert Equal (StorageAtMapping Comptroller 11 (Address cZRX) "bool") False - From Coburn (Comptroller SetGuardianMarketPaused cZRX "Mint" True) - Assert Equal (Comptroller MintGuardianMarketPaused cZRX) True - Assert Equal (StorageAtMapping Comptroller 11 (Address cZRX) "bool") True - Comptroller SetGuardianMarketPaused cZRX "Mint" False + Assert Equal (StorageAtMapping Comptroller 11 (Address slZRX) "bool") False + From Coburn (Comptroller SetGuardianMarketPaused slZRX "Mint" True) + Assert Equal (Comptroller MintGuardianMarketPaused slZRX) True + Assert Equal (StorageAtMapping Comptroller 11 (Address slZRX) "bool") True + Comptroller SetGuardianMarketPaused slZRX "Mint" False -- BorrowGuardianPaused; 16 - Assert Equal (StorageAtMapping Comptroller 12 (Address cZRX) "bool") False - From Coburn (Comptroller SetGuardianMarketPaused cZRX "Borrow" True) - Assert Equal (Comptroller BorrowGuardianMarketPaused cZRX) True - Assert Equal (StorageAtMapping Comptroller 12 (Address cZRX) "bool") True - Comptroller SetGuardianMarketPaused cZRX "Borrow" False + Assert Equal (StorageAtMapping Comptroller 12 (Address slZRX) "bool") False + From Coburn (Comptroller SetGuardianMarketPaused slZRX "Borrow" True) + Assert Equal (Comptroller BorrowGuardianMarketPaused slZRX) True + Assert Equal (StorageAtMapping Comptroller 12 (Address slZRX) "bool") True + Comptroller SetGuardianMarketPaused slZRX "Borrow" False Macro CheckV3Storage -- AllMarkets; 17 Assert Equal (StorageAt Comptroller 13 0 "number") 2 -- TODO: StorageAtArray Comptroller 13? - -- CompRate; 18 + -- SashimiRate; 18 Assert Equal (StorageAt Comptroller 14 0 "number") 1e18 -- CompSpeeds; 19 Assert Equal (StorageAt Comptroller 15 0 "number") 0 - -- CompSupplyState; 20 + -- SashimiSupplyState; 20 Assert Equal (StorageAt Comptroller 16 0 "number") 0 - -- CompBorrowState; 21 + -- SashimiBorrowState; 21 Assert Equal (StorageAt Comptroller 17 0 "number") 0 - -- CompSupplierIndex; 22 + -- SashimiSupplierIndex; 22 Assert Equal (StorageAt Comptroller 18 0 "number") 0 - -- CompBorrowerIndex; 23 + -- SashimiBorrowerIndex; 23 Assert Equal (StorageAt Comptroller 19 0 "number") 0 - -- CompAccrued; 24 + -- SashimiAccrued; 24 Assert Equal (StorageAt Comptroller 20 0 "number") 0 -- Times out coverage, disable for now - ideally set flag to not run in coverage @@ -230,15 +230,15 @@ Pending "Keeps all storage" ComptrollerImpl ComptrollerG1 BecomeG1 (PriceOracle Address) 0.2 20 Comptroller SetPendingAdmin Coburn --- - NewCToken ZRX cZRX delegatorType:CErc20Delegator cTokenType:CErc20Delegate - NewCToken BAT cBAT delegatorType:CErc20Delegator cTokenType:CErc20Delegate - Give cBAT 10e18 BAT -- Faucet some bat to borrow - Support cZRX collateralFactor:0.5 - Support cBAT collateralFactor:0.4 - Prep Geoff Some ZRX cZRX - Mint Geoff 100e18 cZRX - EnterMarkets Geoff cZRX cBAT - Borrow Geoff 1e18 cBAT + NewSLToken ZRX slZRX delegatorType:CErc20Delegator slTokenType:SLErc20Delegate + NewSLToken BAT slBAT delegatorType:CErc20Delegator slTokenType:SLErc20Delegate + Give slBAT 10e18 BAT -- Faucet some bat to borrow + Support slZRX collateralFactor:0.5 + Support slBAT collateralFactor:0.4 + Prep Geoff Some ZRX slZRX + Mint Geoff 100e18 slZRX + EnterMarkets Geoff slZRX slBAT + Borrow Geoff 1e18 slBAT -- CheckUnitrollerStorage (Address ComptrollerG1) CheckV1Storage @@ -256,7 +256,7 @@ Pending "Keeps all storage" -- ComptrollerImpl Deploy StandardG3 ComptrollerG3 Unitroller SetPendingImpl ComptrollerG3 - ComptrollerImpl ComptrollerG3 BecomeG3 1e18 [cZRX cBAT] + ComptrollerImpl ComptrollerG3 BecomeG3 1e18 [slZRX slBAT] -- CheckUnitrollerStorage (Address ComptrollerG3) CheckV1Storage diff --git a/spec/sim/0001-comp-distribution-patch/hypothetical_upgrade.scen b/spec/sim/0001-comp-distribution-patch/hypothetical_upgrade.scen index c65586c0b..feb613122 100755 --- a/spec/sim/0001-comp-distribution-patch/hypothetical_upgrade.scen +++ b/spec/sim/0001-comp-distribution-patch/hypothetical_upgrade.scen @@ -1,10 +1,10 @@ #!/usr/bin/env yarn repl -s PrintTransactionLogs -Alias CompHolder "0x19bc62ff7cd9ffd6bdced9802ff718f09f7259f1" +Alias SashimiHolder "0x19bc62ff7cd9ffd6bdced9802ff718f09f7259f1" Alias USDCWhale "0x92d7796c04ee34d1d16c57fab92fc2bccf434468" -Alias cBATBorrower "0xe5f3dbcc3dcf75a6946822aae7df5160505d3069" -Web3Fork "https://mainnet-eth.compound.finance/@10331520" (CompHolder USDCWhale cBATBorrower) +Alias slBATBorrower "0xe5f3dbcc3dcf75a6946822aae7df5160505d3069" +Web3Fork "https://mainnet-eth.compound.finance/@10331520" (SashimiHolder USDCWhale slBATBorrower) UseConfigs mainnet -- Deploy the flywheel impl @@ -13,13 +13,13 @@ ComptrollerImpl Deploy Standard ComptrollerG4 -- Propose to apply the patch -From CompHolder (Comp Delegate CompHolder) -From CompHolder (Governor GovernorAlpha Propose "COMP Distribution Patch" [(Address Unitroller) (Address ComptrollerG4)] [0 0] ["_setPendingImplementation(address)" "_become(address)"] [[(Address ComptrollerG4)] [(Address Unitroller)]]) +From SashimiHolder (Sashimi Delegate SashimiHolder) +From SashimiHolder (Governor GovernorAlpha Propose "SASHIMI Distribution Patch" [(Address Unitroller) (Address ComptrollerG4)] [0 0] ["_setPendingImplementation(address)" "_become(address)"] [[(Address ComptrollerG4)] [(Address Unitroller)]]) -- Vote for, queue, and execute the proposal MineBlock -From CompHolder (Governor GovernorAlpha Proposal LastProposal Vote For) +From SashimiHolder (Governor GovernorAlpha Proposal LastProposal Vote For) AdvanceBlocks 20000 Governor GovernorAlpha Proposal LastProposal Queue IncreaseTime 604910 @@ -27,56 +27,56 @@ Governor GovernorAlpha Proposal LastProposal Execute -- Sanity check the upgrade -Assert Equal (Comptroller CompRate) 0.25e18 -Assert Equal (Comptroller CheckIsComped cBAT) True -Assert Equal (Comptroller CheckIsComped cDAI) True -Assert Equal (Comptroller CheckIsComped cETH) True -Assert Equal (Comptroller CheckIsComped cREP) True -Assert Equal (Comptroller CheckIsComped cSAI) False -Assert Equal (Comptroller CheckIsComped cUSDC) True -Assert Equal (Comptroller CheckIsComped cUSDT) True -Assert Equal (Comptroller CheckisComped cWBTC) True -Assert Equal (Comptroller CheckIsComped cZRX) True +Assert Equal (Comptroller SashimiRate) 0.25e18 +Assert Equal (Comptroller CheckIsSashimied slBAT) True +Assert Equal (Comptroller CheckIsSashimied slDAI) True +Assert Equal (Comptroller CheckIsSashimied slETH) True +Assert Equal (Comptroller CheckIsSashimied slREP) True +Assert Equal (Comptroller CheckIsSashimied slSAI) False +Assert Equal (Comptroller CheckIsSashimied slUSDC) True +Assert Equal (Comptroller CheckIsSashimied slUSDT) True +Assert Equal (Comptroller CheckisComped slWBTC) True +Assert Equal (Comptroller CheckIsSashimied slZRX) True -- Sanity check the speeds -Assert Equal (Comptroller CompSpeed cBAT) 0.211801939788283286e18 -Assert Equal (Comptroller CompSpeed cDAI) 0.001175763573454607e18 -Assert Equal (Comptroller CompSpeed cETH) 0.000020887685831991e18 -Assert Equal (Comptroller CompSpeed cREP) 0.000007175802675015e18 -Assert Equal (Comptroller CompSpeed cSAI) 0 -Assert Equal (Comptroller CompSpeed cUSDC) 0.000884273506888560e18 -Assert Equal (Comptroller CompSpeed cUSDT) 0.020341204032904166e18 -Assert Equal (Comptroller CompSpeed cWBTC) 0.005869479211613005e18 -Assert Equal (Comptroller CompSpeed cZRX) 0.009899276398349366e18 +Assert Equal (Comptroller SashimiSpeed slBAT) 0.211801939788283286e18 +Assert Equal (Comptroller SashimiSpeed slDAI) 0.001175763573454607e18 +Assert Equal (Comptroller SashimiSpeed slETH) 0.000020887685831991e18 +Assert Equal (Comptroller SashimiSpeed slREP) 0.000007175802675015e18 +Assert Equal (Comptroller SashimiSpeed slSAI) 0 +Assert Equal (Comptroller SashimiSpeed slUSDC) 0.000884273506888560e18 +Assert Equal (Comptroller SashimiSpeed slUSDT) 0.020341204032904166e18 +Assert Equal (Comptroller SashimiSpeed slWBTC) 0.005869479211613005e18 +Assert Equal (Comptroller SashimiSpeed slZRX) 0.009899276398349366e18 -- Check the market borrows -Assert Equal (CToken cBAT TotalBorrows) 816167647101108360363936140 -Assert Equal (CToken cDAI TotalBorrows) 23521775646627969501566436 -Assert Equal (CToken cETH TotalBorrows) 1260824767124865834187 -Assert Equal (CToken cREP TotalBorrows) 5305791273320090270164 -Assert Equal (CToken cSAI TotalBorrows) 87120566019791136455808 -Assert Equal (CToken cUSDC TotalBorrows) 9369602511430 -Assert Equal (CToken cUSDT TotalBorrows) 51344064688134 -Assert Equal (CToken cWBTC TotalBorrows) 134858882039 -Assert Equal (CToken cZRX TotalBorrows) 54734120640511560139309871 +Assert Equal (SLToken slBAT TotalBorrows) 816167647101108360363936140 +Assert Equal (SLToken slDAI TotalBorrows) 23521775646627969501566436 +Assert Equal (SLToken slETH TotalBorrows) 1260824767124865834187 +Assert Equal (SLToken slREP TotalBorrows) 5305791273320090270164 +Assert Equal (SLToken slSAI TotalBorrows) 87120566019791136455808 +Assert Equal (SLToken slUSDC TotalBorrows) 9369602511430 +Assert Equal (SLToken slUSDT TotalBorrows) 51344064688134 +Assert Equal (SLToken slWBTC TotalBorrows) 134858882039 +Assert Equal (SLToken slZRX TotalBorrows) 54734120640511560139309871 -- Check the market prices -Assert Equal (PriceOracleProxy Price cBAT) 1057982500000000 -Assert Equal (PriceOracleProxy Price cDAI) 4296489354886929 -Assert Equal (PriceOracleProxy Price cETH) 1000000000000000000 -Assert Equal (PriceOracleProxy Price cREP) 71436527500000010 -Assert Equal (PriceOracleProxy Price cSAI) 5285551943761727 -Assert Equal (PriceOracleProxy Price cUSDC) 4261783149807061700000000000 -Assert Equal (PriceOracleProxy Price cUSDT) 4261783149807061700000000000 -Assert Equal (PriceOracleProxy Price cWBTC) 397626172108253540000000000000 -Assert Equal (PriceOracleProxy Price cZRX) 1464966666666666 +Assert Equal (PriceOracleProxy Price slBAT) 1057982500000000 +Assert Equal (PriceOracleProxy Price slDAI) 4296489354886929 +Assert Equal (PriceOracleProxy Price slETH) 1000000000000000000 +Assert Equal (PriceOracleProxy Price slREP) 71436527500000010 +Assert Equal (PriceOracleProxy Price slSAI) 5285551943761727 +Assert Equal (PriceOracleProxy Price slUSDC) 4261783149807061700000000000 +Assert Equal (PriceOracleProxy Price slUSDT) 4261783149807061700000000000 +Assert Equal (PriceOracleProxy Price slWBTC) 397626172108253540000000000000 +Assert Equal (PriceOracleProxy Price slZRX) 1464966666666666 -- Refresh speeds -Comptroller RefreshCompSpeeds +Comptroller RefreshSashimiSpeeds -- Check the new speeds match utility metric -- Total Utility = @@ -84,7 +84,7 @@ Comptroller RefreshCompSpeeds -- 23521775646627969501566436 * 4296489354886929 + -- 1260824767124865834187 * 1000000000000000000 + -- 5305791273320090270164 * 71436527500000010 + --- 87120566019791136455808 * 5285551943761727 * 0 (cSAI not comped) + +-- 87120566019791136455808 * 5285551943761727 * 0 (slSAI not comped) + -- 9369602511430 * 4261783149807061700000000000 + -- 51344064688134 * 4261783149807061700000000000 + -- 134858882039 * 397626172108253540000000000000 + @@ -93,84 +93,84 @@ Comptroller RefreshCompSpeeds -- .25e18 * 816167647101108360363936140 * 1057982500000000 / 1358747565585977723277660096116431304676770 -- = 158876289748264717 -Assert Equal (Comptroller CompSpeed cBAT) 158876289748264702 +Assert Equal (Comptroller SashimiSpeed slBAT) 158876289748264702 -- .25e18 * 23521775646627969501566436 * 4296489354886929 / 1358747565585977723277660096116431304676770 -- = 18594524331344760 -Assert Equal (Comptroller CompSpeed cDAI) 18594524331344758 +Assert Equal (Comptroller SashimiSpeed slDAI) 18594524331344758 -- .25e18 * 1260824767124865834187 * 1000000000000000000 / 1358747565585977723277660096116431304676770 -- = 231982893485648 -Assert Equal (Comptroller CompSpeed cETH) 231982893485648 +Assert Equal (Comptroller SashimiSpeed slETH) 231982893485648 -- .25e18 * 5305791273320090270164 * 71436527500000010 / 1358747565585977723277660096116431304676770 -- = 69738359391711 -Assert Equal (Comptroller CompSpeed cREP) 69738359391711 +Assert Equal (Comptroller SashimiSpeed slREP) 69738359391711 -- not comped -Assert Equal (Comptroller CompSpeed cSAI) 0 +Assert Equal (Comptroller SashimiSpeed slSAI) 0 -- .25e18 * 9369602511430 * 4261783149807061700000000000 / 1358747565585977723277660096116431304676770 -- = 7347062676498972 -Assert Equal (Comptroller CompSpeed cUSDC) 7347062676498971 +Assert Equal (Comptroller SashimiSpeed slUSDC) 7347062676498971 -- .25e18 * 51344064688134 * 4261783149807061700000000000 / 1358747565585977723277660096116431304676770 -- = 40260839333339567 -Assert Equal (Comptroller CompSpeed cUSDT) 40260839333339565 +Assert Equal (Comptroller SashimiSpeed slUSDT) 40260839333339565 -- .25e18 * 134858882039 * 397626172108253540000000000000 / 1358747565585977723277660096116431304676770 -- = 9866332495845221 -Assert Equal (Comptroller CompSpeed cWBTC) 9866332495845221 +Assert Equal (Comptroller SashimiSpeed slWBTC) 9866332495845221 -- .25e18 * 54734120640511560139309871 * 1464966666666666 / 1358747565585977723277660096116431304676770 -- = 14753230161829421 -Assert Equal (Comptroller CompSpeed cZRX) 14753230161829420 +Assert Equal (Comptroller SashimiSpeed slZRX) 14753230161829420 -- Now sanity check that we can continue to use the market as usual -- First check the USDC Whale, mint -Assert Equal (Erc20 cUSDC TokenBalance USDCWhale) 0 +Assert Equal (Erc20 slUSDC TokenBalance USDCWhale) 0 -From USDCWhale (Trx GasPrice 0 (Erc20 USDC Approve cUSDC UInt256Max)) -From USDCWhale (Trx GasPrice 0 (CToken cUSDC Mint 10000e6)) +From USDCWhale (Trx GasPrice 0 (Erc20 USDC Approve slUSDC UInt256Max)) +From USDCWhale (Trx GasPrice 0 (SLToken slUSDC Mint 10000e6)) -Assert Equal (Erc20 cUSDC TokenBalance USDCWhale) 47481980579468 -Assert Equal (Erc20 cUSDC TotalSupply) 927050045835492296 +Assert Equal (Erc20 slUSDC TokenBalance USDCWhale) 47481980579468 +Assert Equal (Erc20 slUSDC TotalSupply) 927050045835492296 -- Next check the BAT borrower, borrow a little more -Assert Equal (Erc20 cETH TokenBalance cBATBorrower) 384765976900 -Assert Equal (Erc20 cETH TotalSupply) 4585405574577755 +Assert Equal (Erc20 slETH TokenBalance slBATBorrower) 384765976900 +Assert Equal (Erc20 slETH TotalSupply) 4585405574577755 -Assert Equal (CToken cBAT BorrowBalance cBATBorrower) 37550980777226218529804 -Assert Equal (CToken cBAT TotalBorrows) 816167647101108360363936140 +Assert Equal (SLToken slBAT BorrowBalance slBATBorrower) 37550980777226218529804 +Assert Equal (SLToken slBAT TotalBorrows) 816167647101108360363936140 -Expect Changes (CToken cBAT BorrowBalance cBATBorrower) 6666005042256047300989 -From cBATBorrower (CToken cBAT Borrow 6666000000000000000000) +Expect Changes (SLToken slBAT BorrowBalance slBATBorrower) 6666005042256047300989 +From slBATBorrower (SLToken slBAT Borrow 6666000000000000000000) -Assert Equal (CToken cBAT BorrowBalance cBATBorrower) 44216985819482265830793 -Assert Equal (CToken cBAT TotalBorrows) 818374059192055804747435060 +Assert Equal (SLToken slBAT BorrowBalance slBATBorrower) 44216985819482265830793 +Assert Equal (SLToken slBAT TotalBorrows) 818374059192055804747435060 -- Claim comp to true up their balances -Comptroller ClaimComp USDCWhale -Comptroller ClaimComp cBATBorrower +Comptroller ClaimSashimi USDCWhale +Comptroller ClaimSashimi slBATBorrower -- Now move the clock forward AdvanceBlocks 1000000 --- And check that they receive the right amount of COMP when claimed +-- And check that they receive the right amount of SASHIMI when claimed --- cUSDC: 47481980579468 / 927050045835492296 * 7347062676498971 * 1e6 = 376304482038247230 -Expect Changes (Erc20 Comp TokenBalance USDCWhale) 0.376305610951693392e18 -Comptroller ClaimComp USDCWhale +-- slUSDC: 47481980579468 / 927050045835492296 * 7347062676498971 * 1e6 = 376304482038247230 +Expect Changes (Erc20 Sashimi TokenBalance USDCWhale) 0.376305610951693392e18 +Comptroller ClaimSashimi USDCWhale --- cETH: 384765976900 / 4585405574577755 * 231982893485648 * 1e6 = 19465917067611490 --- cBAT: 44216985819482265830793 / 818374059192055804747435060 * 158876289748264702 * 1e6 = 8584131635094196000 +-- slETH: 384765976900 / 4585405574577755 * 231982893485648 * 1e6 = 19465917067611490 +-- slBAT: 44216985819482265830793 / 818374059192055804747435060 * 158876289748264702 * 1e6 = 8584131635094196000 -- = 0.01946591706761149 + 8.584131635094196000 = 8.603597552161807 -Expect Changes (Erc20 Comp TokenBalance cBATBorrower) 8.603623362954463581e18 -Comptroller ClaimComp cBATBorrower +Expect Changes (Erc20 Sashimi TokenBalance slBATBorrower) 8.603623362954463581e18 +Comptroller ClaimSashimi slBATBorrower -Print "COMP distribution patch OK!" +Print "SASHIMI distribution patch OK!" diff --git a/spec/sim/0001-comp-distribution-patch/hypothetical_upgrade_post_deploy.scen b/spec/sim/0001-comp-distribution-patch/hypothetical_upgrade_post_deploy.scen index 2be610004..8da553efe 100755 --- a/spec/sim/0001-comp-distribution-patch/hypothetical_upgrade_post_deploy.scen +++ b/spec/sim/0001-comp-distribution-patch/hypothetical_upgrade_post_deploy.scen @@ -1,21 +1,21 @@ #!/usr/bin/env yarn repl -s PrintTransactionLogs -Alias CompHolder "0x19bc62ff7cd9ffd6bdced9802ff718f09f7259f1" +Alias SashimiHolder "0x19bc62ff7cd9ffd6bdced9802ff718f09f7259f1" Alias USDCWhale "0x92d7796c04ee34d1d16c57fab92fc2bccf434468" -Alias cBATBorrower "0xe5f3dbcc3dcf75a6946822aae7df5160505d3069" -Web3Fork "https://mainnet-eth.compound.finance/@10348955" (CompHolder USDCWhale cBATBorrower) +Alias slBATBorrower "0xe5f3dbcc3dcf75a6946822aae7df5160505d3069" +Web3Fork "https://mainnet-eth.compound.finance/@10348955" (SashimiHolder USDCWhale slBATBorrower) UseConfigs mainnet -- Propose to apply the patch -From CompHolder (Comp Delegate CompHolder) -From CompHolder (Governor GovernorAlpha Propose "COMP Distribution Patch" [(Address Unitroller) (Address StdComptrollerG4)] [0 0] ["_setPendingImplementation(address)" "_become(address)"] [[(Address StdComptrollerG4)] [(Address Unitroller)]]) +From SashimiHolder (Sashimi Delegate SashimiHolder) +From SashimiHolder (Governor GovernorAlpha Propose "SASHIMI Distribution Patch" [(Address Unitroller) (Address StdComptrollerG4)] [0 0] ["_setPendingImplementation(address)" "_become(address)"] [[(Address StdComptrollerG4)] [(Address Unitroller)]]) -- Vote for, queue, and execute the proposal MineBlock -From CompHolder (Governor GovernorAlpha Proposal LastProposal Vote For) +From SashimiHolder (Governor GovernorAlpha Proposal LastProposal Vote For) AdvanceBlocks 20000 Governor GovernorAlpha Proposal LastProposal Queue IncreaseTime 604910 @@ -23,56 +23,56 @@ Governor GovernorAlpha Proposal LastProposal Execute -- Sanity check the upgrade -Assert Equal (Comptroller CompRate) 0.22e18 -Assert Equal (Comptroller CheckIsComped cBAT) True -Assert Equal (Comptroller CheckIsComped cDAI) True -Assert Equal (Comptroller CheckIsComped cETH) True -Assert Equal (Comptroller CheckIsComped cREP) True -Assert Equal (Comptroller CheckIsComped cSAI) False -Assert Equal (Comptroller CheckIsComped cUSDC) True -Assert Equal (Comptroller CheckIsComped cUSDT) True -Assert Equal (Comptroller CheckisComped cWBTC) True -Assert Equal (Comptroller CheckIsComped cZRX) True +Assert Equal (Comptroller SashimiRate) 0.22e18 +Assert Equal (Comptroller CheckIsSashimied slBAT) True +Assert Equal (Comptroller CheckIsSashimied slDAI) True +Assert Equal (Comptroller CheckIsSashimied slETH) True +Assert Equal (Comptroller CheckIsSashimied slREP) True +Assert Equal (Comptroller CheckIsSashimied slSAI) False +Assert Equal (Comptroller CheckIsSashimied slUSDC) True +Assert Equal (Comptroller CheckIsSashimied slUSDT) True +Assert Equal (Comptroller CheckisComped slWBTC) True +Assert Equal (Comptroller CheckIsSashimied slZRX) True -- Sanity check the speeds -Assert Equal (Comptroller CompSpeed cBAT) 0.203121569295974918e18 -Assert Equal (Comptroller CompSpeed cDAI) 0.001103447907469680e18 -Assert Equal (Comptroller CompSpeed cETH) 0.000017970643503360e18 -Assert Equal (Comptroller CompSpeed cREP) 0.000127756157903774e18 -Assert Equal (Comptroller CompSpeed cSAI) 0 -Assert Equal (Comptroller CompSpeed cUSDC) 0.000940109498639776e18 -Assert Equal (Comptroller CompSpeed cUSDT) 0.008447487333746899e18 -Assert Equal (Comptroller CompSpeed cWBTC) 0.004841175362144006e18 -Assert Equal (Comptroller CompSpeed cZRX) 0.001400483800617582e18 +Assert Equal (Comptroller SashimiSpeed slBAT) 0.203121569295974918e18 +Assert Equal (Comptroller SashimiSpeed slDAI) 0.001103447907469680e18 +Assert Equal (Comptroller SashimiSpeed slETH) 0.000017970643503360e18 +Assert Equal (Comptroller SashimiSpeed slREP) 0.000127756157903774e18 +Assert Equal (Comptroller SashimiSpeed slSAI) 0 +Assert Equal (Comptroller SashimiSpeed slUSDC) 0.000940109498639776e18 +Assert Equal (Comptroller SashimiSpeed slUSDT) 0.008447487333746899e18 +Assert Equal (Comptroller SashimiSpeed slWBTC) 0.004841175362144006e18 +Assert Equal (Comptroller SashimiSpeed slZRX) 0.001400483800617582e18 -- Check the market borrows -Assert Equal (CToken cBAT TotalBorrows) 933675278927019769365181653 -Assert Equal (CToken cDAI TotalBorrows) 28288631632222856320436141 -Assert Equal (CToken cETH TotalBorrows) 1489418340783050403890 -Assert Equal (CToken cREP TotalBorrows) 83744752724324161827907 -Assert Equal (CToken cSAI TotalBorrows) 85694017918878755539524 -Assert Equal (CToken cUSDC TotalBorrows) 13559619925496 -Assert Equal (CToken cUSDT TotalBorrows) 34881672655224 -Assert Equal (CToken cWBTC TotalBorrows) 148448436871 -Assert Equal (CToken cZRX TotalBorrows) 17678865043142504899157201 +Assert Equal (SLToken slBAT TotalBorrows) 933675278927019769365181653 +Assert Equal (SLToken slDAI TotalBorrows) 28288631632222856320436141 +Assert Equal (SLToken slETH TotalBorrows) 1489418340783050403890 +Assert Equal (SLToken slREP TotalBorrows) 83744752724324161827907 +Assert Equal (SLToken slSAI TotalBorrows) 85694017918878755539524 +Assert Equal (SLToken slUSDC TotalBorrows) 13559619925496 +Assert Equal (SLToken slUSDT TotalBorrows) 34881672655224 +Assert Equal (SLToken slWBTC TotalBorrows) 148448436871 +Assert Equal (SLToken slZRX TotalBorrows) 17678865043142504899157201 -- Check the market prices -Assert Equal (PriceOracleProxy Price cBAT) 1241500000000000 -Assert Equal (PriceOracleProxy Price cDAI) 4429377994656539 -Assert Equal (PriceOracleProxy Price cETH) 1000000000000000000 -Assert Equal (PriceOracleProxy Price cREP) 73035785000000000 -Assert Equal (PriceOracleProxy Price cSAI) 5285551943761727 -Assert Equal (PriceOracleProxy Price cUSDC) 4442302859110025000000000000 -Assert Equal (PriceOracleProxy Price cUSDT) 4442302859110025000000000000 -Assert Equal (PriceOracleProxy Price cWBTC) 401937357611677730000000000000 -Assert Equal (PriceOracleProxy Price cZRX) 1506198333333333 +Assert Equal (PriceOracleProxy Price slBAT) 1241500000000000 +Assert Equal (PriceOracleProxy Price slDAI) 4429377994656539 +Assert Equal (PriceOracleProxy Price slETH) 1000000000000000000 +Assert Equal (PriceOracleProxy Price slREP) 73035785000000000 +Assert Equal (PriceOracleProxy Price slSAI) 5285551943761727 +Assert Equal (PriceOracleProxy Price slUSDC) 4442302859110025000000000000 +Assert Equal (PriceOracleProxy Price slUSDT) 4442302859110025000000000000 +Assert Equal (PriceOracleProxy Price slWBTC) 401937357611677730000000000000 +Assert Equal (PriceOracleProxy Price slZRX) 1506198333333333 -- Refresh speeds -Comptroller RefreshCompSpeeds +Comptroller RefreshSashimiSpeeds -- Check the new speeds match utility metric -- Total Utility = @@ -80,7 +80,7 @@ Comptroller RefreshCompSpeeds -- 28288631632222856320436141 * 4429377994656539 + -- 1489418340783050403890 * 1000000000000000000 + -- 83744752724324161827907 * 73035785000000000 + --- 85694017918878755539524 * 5285551943761727 * 0 (cSAI not comped) + +-- 85694017918878755539524 * 5285551943761727 * 0 (slSAI not comped) + -- 13559619925496 * 4442302859110025000000000000 + -- 34881672655224 * 4442302859110025000000000000 + -- 148448436871 * 401937357611677730000000000000 + @@ -89,84 +89,84 @@ Comptroller RefreshCompSpeeds -- .22e18 * 933675278927019769365181653 * 1241500000000000 / 1593550425385280362248038892811635677856932 -- = 160029281076361760 -Assert Equal (Comptroller CompSpeed cBAT) 0.160029281076361778e18 +Assert Equal (Comptroller SashimiSpeed slBAT) 0.160029281076361778e18 -- .22e18 * 28288631632222856320436141 * 4429377994656539 / 1593550425385280362248038892811635677856932 -- = 17298623815115230 -Assert Equal (Comptroller CompSpeed cDAI) 0.017298623815115231e18 +Assert Equal (Comptroller SashimiSpeed slDAI) 0.017298623815115231e18 -- .22e18 * 1489418340783050403890 * 1000000000000000000 / 1593550425385280362248038892811635677856932 -- = 205623888489784 -Assert Equal (Comptroller CompSpeed cETH) 0.000205623888489784e18 +Assert Equal (Comptroller SashimiSpeed slETH) 0.000205623888489784e18 -- .22e18 * 83744752724324161827907 * 73035785000000000 / 1593550425385280362248038892811635677856932 -- = 844403794590991 -Assert Equal (Comptroller CompSpeed cREP) 0.000844403794590990e18 +Assert Equal (Comptroller SashimiSpeed slREP) 0.000844403794590990e18 -- not comped -Assert Equal (Comptroller CompSpeed cSAI) 0 +Assert Equal (Comptroller SashimiSpeed slSAI) 0 -- .22e18 * 13559619925496 * 4442302859110025000000000000 / 1593550425385280362248038892811635677856932 -- = 8315963040053016 -Assert Equal (Comptroller CompSpeed cUSDC) 0.008315963040053015e18 +Assert Equal (Comptroller SashimiSpeed slUSDC) 0.008315963040053015e18 -- .22e18 * 34881672655224 * 4442302859110025000000000000 / 1593550425385280362248038892811635677856932 -- = 21392539183981588 -Assert Equal (Comptroller CompSpeed cUSDT) 0.021392539183981590e18 +Assert Equal (Comptroller SashimiSpeed slUSDT) 0.021392539183981590e18 -- .22e18 * 148448436871 * 401937357611677730000000000000 / 1593550425385280362248038892811635677856932 -- = 8237413596422151 -Assert Equal (Comptroller CompSpeed cWBTC) 0.008237413596422151e18 +Assert Equal (Comptroller SashimiSpeed slWBTC) 0.008237413596422151e18 -- .22e18 * 17678865043142504899157201 * 1506198333333333 / 1593550425385280362248038892811635677856932 -- = 3676151604985456 -Assert Equal (Comptroller CompSpeed cZRX) 0.003676151604985456e18 +Assert Equal (Comptroller SashimiSpeed slZRX) 0.003676151604985456e18 -- Now sanity check that we can continue to use the market as usual -- First check the USDC Whale, mint -Assert Equal (Erc20 cUSDC TokenBalance USDCWhale) 0 +Assert Equal (Erc20 slUSDC TokenBalance USDCWhale) 0 -From USDCWhale (Trx GasPrice 0 (Erc20 USDC Approve cUSDC UInt256Max)) -From USDCWhale (Trx GasPrice 0 (CToken cUSDC Mint 10000e6)) +From USDCWhale (Trx GasPrice 0 (Erc20 USDC Approve slUSDC UInt256Max)) +From USDCWhale (Trx GasPrice 0 (SLToken slUSDC Mint 10000e6)) -Assert Equal (Erc20 cUSDC TokenBalance USDCWhale) 47481175626857 -Assert Equal (Erc20 cUSDC TotalSupply) 1067945787269646173 +Assert Equal (Erc20 slUSDC TokenBalance USDCWhale) 47481175626857 +Assert Equal (Erc20 slUSDC TotalSupply) 1067945787269646173 -- Next check the BAT borrower, borrow a little more -Assert Equal (Erc20 cETH TokenBalance cBATBorrower) 1034370824418 -Assert Equal (Erc20 cETH TotalSupply) 5163948275203265 +Assert Equal (Erc20 slETH TokenBalance slBATBorrower) 1034370824418 +Assert Equal (Erc20 slETH TotalSupply) 5163948275203265 -Assert Equal (CToken cBAT BorrowBalance cBATBorrower) 123004206941461188039104 -Assert Equal (CToken cBAT TotalBorrows) 933675278927019769365181653 +Assert Equal (SLToken slBAT BorrowBalance slBATBorrower) 123004206941461188039104 +Assert Equal (SLToken slBAT TotalBorrows) 933675278927019769365181653 -Expect Changes (CToken cBAT BorrowBalance cBATBorrower) 6666016377088188607420 -From cBATBorrower (CToken cBAT Borrow 6666000000000000000000) +Expect Changes (SLToken slBAT BorrowBalance slBATBorrower) 6666016377088188607420 +From slBATBorrower (SLToken slBAT Borrow 6666000000000000000000) -Assert Equal (CToken cBAT BorrowBalance cBATBorrower) 129670223318549376646524 -Assert Equal (CToken cBAT TotalBorrows) 936176444748237020604963003 +Assert Equal (SLToken slBAT BorrowBalance slBATBorrower) 129670223318549376646524 +Assert Equal (SLToken slBAT TotalBorrows) 936176444748237020604963003 -- Claim comp to true up their balances -Comptroller ClaimComp USDCWhale -Comptroller ClaimComp cBATBorrower +Comptroller ClaimSashimi USDCWhale +Comptroller ClaimSashimi slBATBorrower -- Now move the clock forward AdvanceBlocks 1000000 --- And check that they receive the right amount of COMP when claimed +-- And check that they receive the right amount of SASHIMI when claimed --- cUSDC: 47481175626857 / 1067945787269646173 * 8315963040053015 * 1e6 = 369730098960081900 -Expect Changes (Erc20 Comp TokenBalance USDCWhale) 0.369731208150378785e18 -Comptroller ClaimComp USDCWhale +-- slUSDC: 47481175626857 / 1067945787269646173 * 8315963040053015 * 1e6 = 369730098960081900 +Expect Changes (Erc20 Sashimi TokenBalance USDCWhale) 0.369731208150378785e18 +Comptroller ClaimSashimi USDCWhale --- cETH: 1034370824418 / 5163948275203265 * 205623888489784 * 1e6 = 41187738474944500 --- cBAT: 123004206941461188039104 / 933675278927019769365181653 * 160029281076361778 * 1e6 = 21082570408023708000 +-- slETH: 1034370824418 / 5163948275203265 * 205623888489784 * 1e6 = 41187738474944500 +-- slBAT: 123004206941461188039104 / 933675278927019769365181653 * 160029281076361778 * 1e6 = 21082570408023708000 -- = 0.041187738474944495 + 21.082570408023706 = 21.123758146498652 -Expect Changes (Erc20 Comp TokenBalance cBATBorrower) 22.576722556314661630e18 -Comptroller ClaimComp cBATBorrower +Expect Changes (Erc20 Sashimi TokenBalance slBATBorrower) 22.576722556314661630e18 +Comptroller ClaimSashimi slBATBorrower -Print "COMP distribution patch OK!" +Print "SASHIMI distribution patch OK!" diff --git a/spec/sim/0001-comp-distribution-patch/hypothetical_upgrade_post_propose.scen b/spec/sim/0001-comp-distribution-patch/hypothetical_upgrade_post_propose.scen index fe6d33b18..945aaedab 100755 --- a/spec/sim/0001-comp-distribution-patch/hypothetical_upgrade_post_propose.scen +++ b/spec/sim/0001-comp-distribution-patch/hypothetical_upgrade_post_propose.scen @@ -4,8 +4,8 @@ PrintTransactionLogs Alias CompVoter1 "0xf25f26a42adcb153b1966a4bf5df6d0c9e27197f" Alias CompVoter2 "0xed409c9ff60f3020abf9012bcd45fc294f5608ff" Alias USDCWhale "0x92d7796c04ee34d1d16c57fab92fc2bccf434468" -Alias cBATBorrower "0xe5f3dbcc3dcf75a6946822aae7df5160505d3069" -Web3Fork "https://mainnet-eth.compound.finance/@10351502" (CompVoter1 CompVoter2 USDCWhale cBATBorrower) +Alias slBATBorrower "0xe5f3dbcc3dcf75a6946822aae7df5160505d3069" +Web3Fork "https://mainnet-eth.compound.finance/@10351502" (CompVoter1 CompVoter2 USDCWhale slBATBorrower) UseConfigs mainnet -- Vote for, queue, and execute the proposal @@ -20,56 +20,56 @@ Governor GovernorAlpha Proposal 11 Execute -- Sanity check the upgrade -Assert Equal (Comptroller CompRate) 0.22e18 -Assert Equal (Comptroller CheckIsComped cBAT) True -Assert Equal (Comptroller CheckIsComped cDAI) True -Assert Equal (Comptroller CheckIsComped cETH) True -Assert Equal (Comptroller CheckIsComped cREP) True -Assert Equal (Comptroller CheckIsComped cSAI) False -Assert Equal (Comptroller CheckIsComped cUSDC) True -Assert Equal (Comptroller CheckIsComped cUSDT) True -Assert Equal (Comptroller CheckisComped cWBTC) True -Assert Equal (Comptroller CheckIsComped cZRX) True +Assert Equal (Comptroller SashimiRate) 0.22e18 +Assert Equal (Comptroller CheckIsSashimied slBAT) True +Assert Equal (Comptroller CheckIsSashimied slDAI) True +Assert Equal (Comptroller CheckIsSashimied slETH) True +Assert Equal (Comptroller CheckIsSashimied slREP) True +Assert Equal (Comptroller CheckIsSashimied slSAI) False +Assert Equal (Comptroller CheckIsSashimied slUSDC) True +Assert Equal (Comptroller CheckIsSashimied slUSDT) True +Assert Equal (Comptroller CheckIsSashimied slWBTC) True +Assert Equal (Comptroller CheckIsSashimied slZRX) True -- Sanity check the speeds -Assert Equal (Comptroller CompSpeed cBAT) 0.203121569295974918e18 -Assert Equal (Comptroller CompSpeed cDAI) 0.001103447907469680e18 -Assert Equal (Comptroller CompSpeed cETH) 0.000017970643503360e18 -Assert Equal (Comptroller CompSpeed cREP) 0.000127756157903774e18 -Assert Equal (Comptroller CompSpeed cSAI) 0 -Assert Equal (Comptroller CompSpeed cUSDC) 0.000940109498639776e18 -Assert Equal (Comptroller CompSpeed cUSDT) 0.008447487333746899e18 -Assert Equal (Comptroller CompSpeed cWBTC) 0.004841175362144006e18 -Assert Equal (Comptroller CompSpeed cZRX) 0.001400483800617582e18 +Assert Equal (Comptroller SashimiSpeed slBAT) 0.203121569295974918e18 +Assert Equal (Comptroller SashimiSpeed slDAI) 0.001103447907469680e18 +Assert Equal (Comptroller SashimiSpeed slETH) 0.000017970643503360e18 +Assert Equal (Comptroller SashimiSpeed slREP) 0.000127756157903774e18 +Assert Equal (Comptroller SashimiSpeed slSAI) 0 +Assert Equal (Comptroller SashimiSpeed slUSDC) 0.000940109498639776e18 +Assert Equal (Comptroller SashimiSpeed slUSDT) 0.008447487333746899e18 +Assert Equal (Comptroller SashimiSpeed slWBTC) 0.004841175362144006e18 +Assert Equal (Comptroller SashimiSpeed slZRX) 0.001400483800617582e18 -- Check the market borrows -Assert Equal (CToken cBAT TotalBorrows) 994790805782510516637146235 -Assert Equal (CToken cDAI TotalBorrows) 28733415458831908292748520 -Assert Equal (CToken cETH TotalBorrows) 1423195009215949475714 -Assert Equal (CToken cREP TotalBorrows) 11741036506536325005938 -Assert Equal (CToken cSAI TotalBorrows) 85702639018129680274971 -Assert Equal (CToken cUSDC TotalBorrows) 13194641271913 -Assert Equal (CToken cUSDT TotalBorrows) 33842222695086 -Assert Equal (CToken cWBTC TotalBorrows) 166281366345 -Assert Equal (CToken cZRX TotalBorrows) 14602818278789368467659480 +Assert Equal (SLToken slBAT TotalBorrows) 994790805782510516637146235 +Assert Equal (SLToken slDAI TotalBorrows) 28733415458831908292748520 +Assert Equal (SLToken slETH TotalBorrows) 1423195009215949475714 +Assert Equal (SLToken slREP TotalBorrows) 11741036506536325005938 +Assert Equal (SLToken slSAI TotalBorrows) 85702639018129680274971 +Assert Equal (SLToken slUSDC TotalBorrows) 13194641271913 +Assert Equal (SLToken slUSDT TotalBorrows) 33842222695086 +Assert Equal (SLToken slWBTC TotalBorrows) 166281366345 +Assert Equal (SLToken slZRX TotalBorrows) 14602818278789368467659480 -- Check the market prices -Assert Equal (PriceOracleProxy Price cBAT) 1189627500000000 -Assert Equal (PriceOracleProxy Price cDAI) 4579024512369984 -Assert Equal (PriceOracleProxy Price cETH) 1000000000000000000 -Assert Equal (PriceOracleProxy Price cREP) 71700617500000010 -Assert Equal (PriceOracleProxy Price cSAI) 5285551943761727 -Assert Equal (PriceOracleProxy Price cUSDC) 4554587056912220000000000000 -Assert Equal (PriceOracleProxy Price cUSDT) 4554587056912220000000000000 -Assert Equal (PriceOracleProxy Price cWBTC) 410378476771980800000000000000 -Assert Equal (PriceOracleProxy Price cZRX) 1465310000000000 +Assert Equal (PriceOracleProxy Price slBAT) 1189627500000000 +Assert Equal (PriceOracleProxy Price slDAI) 4579024512369984 +Assert Equal (PriceOracleProxy Price slETH) 1000000000000000000 +Assert Equal (PriceOracleProxy Price slREP) 71700617500000010 +Assert Equal (PriceOracleProxy Price slSAI) 5285551943761727 +Assert Equal (PriceOracleProxy Price slUSDC) 4554587056912220000000000000 +Assert Equal (PriceOracleProxy Price slUSDT) 4554587056912220000000000000 +Assert Equal (PriceOracleProxy Price slWBTC) 410378476771980800000000000000 +Assert Equal (PriceOracleProxy Price slZRX) 1465310000000000 -- Refresh speeds -Comptroller RefreshCompSpeeds +Comptroller RefreshSashimiSpeeds -- Check the new speeds match utility metric -- Total Utility = @@ -77,7 +77,7 @@ Comptroller RefreshCompSpeeds -- 28733415458831908292748520 * 4579024512369984 + -- 1423195009215949475714 * 1000000000000000000 + -- 11741036506536325005938 * 71700617500000010 + --- 85702639018129680274971 * 5285551943761727 * 0 (cSAI not comped) + +-- 85702639018129680274971 * 5285551943761727 * 0 (slSAI not comped) + -- 13194641271913 * 4554587056912220000000000000 + -- 33842222695086 * 4554587056912220000000000000 + -- 166281366345 * 410378476771980800000000000000 + @@ -86,84 +86,84 @@ Comptroller RefreshCompSpeeds -- .22e18 * 994790805782510516637146235 * 1189627500000000 / 1621135988903112202016711619617847258483060 -- = 160600166568066720 -Assert Equal (Comptroller CompSpeed cBAT) 0.160600166568066716e18 +Assert Equal (Comptroller SashimiSpeed slBAT) 0.160600166568066716e18 -- .22e18 * 28733415458831908292748520 * 4579024512369984 / 1621135988903112202016711619617847258483060 -- = 17855148003843600 -Assert Equal (Comptroller CompSpeed cDAI) 0.017855148003843601e18 +Assert Equal (Comptroller SashimiSpeed slDAI) 0.017855148003843601e18 -- .22e18 * 1423195009215949475714 * 1000000000000000000 / 1621135988903112202016711619617847258483060 -- = 193137962620495 -Assert Equal (Comptroller CompSpeed cETH) 0.000193137962620495e18 +Assert Equal (Comptroller SashimiSpeed slETH) 0.000193137962620495e18 -- .22e18 * 11741036506536325005938 * 71700617500000010 / 1621135988903112202016711619617847258483060 -- = 114243780991640 -Assert Equal (Comptroller CompSpeed cREP) 0.000114243780991640e18 +Assert Equal (Comptroller SashimiSpeed slREP) 0.000114243780991640e18 -- not comped -Assert Equal (Comptroller CompSpeed cSAI) 0 +Assert Equal (Comptroller SashimiSpeed slSAI) 0 -- .22e18 * 13194641271913 * 4554587056912220000000000000 / 1621135988903112202016711619617847258483060 -- = 8155485665104318 -Assert Equal (Comptroller CompSpeed cUSDC) 0.008155485665104317e18 +Assert Equal (Comptroller SashimiSpeed slUSDC) 0.008155485665104317e18 -- .22e18 * 33842222695086 * 4554587056912220000000000000 / 1621135988903112202016711619617847258483060 -- = 20917564667146620 -Assert Equal (Comptroller CompSpeed cUSDT) 0.020917564667146617e18 +Assert Equal (Comptroller SashimiSpeed slUSDT) 0.020917564667146617e18 -- .22e18 * 166281366345 * 410378476771980800000000000000 / 1621135988903112202016711619617847258483060 -- = 9260435118787978 -Assert Equal (Comptroller CompSpeed cWBTC) 0.009260435118787978e18 +Assert Equal (Comptroller SashimiSpeed slWBTC) 0.009260435118787978e18 -- .22e18 * 14602818278789368467659480 * 1465310000000000 / 1621135988903112202016711619617847258483060 -- = 2903818233438633 -Assert Equal (Comptroller CompSpeed cZRX) 0.002903818233438633e18 +Assert Equal (Comptroller SashimiSpeed slZRX) 0.002903818233438633e18 -- Now sanity check that we can continue to use the market as usual -- First check the USDC Whale, mint -Assert Equal (Erc20 cUSDC TokenBalance USDCWhale) 0 +Assert Equal (Erc20 slUSDC TokenBalance USDCWhale) 0 -From USDCWhale (Trx GasPrice 0 (Erc20 USDC Approve cUSDC UInt256Max)) -From USDCWhale (Trx GasPrice 0 (CToken cUSDC Mint 10000e6)) +From USDCWhale (Trx GasPrice 0 (Erc20 USDC Approve slUSDC UInt256Max)) +From USDCWhale (Trx GasPrice 0 (SLToken slUSDC Mint 10000e6)) -Assert Equal (Erc20 cUSDC TokenBalance USDCWhale) 47481122314530 -Assert Equal (Erc20 cUSDC TotalSupply) 1080141236963466282 +Assert Equal (Erc20 slUSDC TokenBalance USDCWhale) 47481122314530 +Assert Equal (Erc20 slUSDC TotalSupply) 1080141236963466282 -- Next check the BAT borrower, borrow a little more -Assert Equal (Erc20 cETH TokenBalance cBATBorrower) 1034370824418 -Assert Equal (Erc20 cETH TotalSupply) 5134544277187300 +Assert Equal (Erc20 slETH TokenBalance slBATBorrower) 1034370824418 +Assert Equal (Erc20 slETH TotalSupply) 5134544277187300 -Assert Equal (CToken cBAT BorrowBalance cBATBorrower) 123048404201235973562497 -Assert Equal (CToken cBAT TotalBorrows) 994790805782510516637146235 +Assert Equal (SLToken slBAT BorrowBalance slBATBorrower) 123048404201235973562497 +Assert Equal (SLToken slBAT TotalBorrows) 994790805782510516637146235 -Expect Changes (CToken cBAT BorrowBalance cBATBorrower) 6666016503078751208324 -From cBATBorrower (CToken cBAT Borrow 6666000000000000000000) +Expect Changes (SLToken slBAT BorrowBalance slBATBorrower) 6666016503078751208324 +From slBATBorrower (SLToken slBAT Borrow 6666000000000000000000) -Assert Equal (CToken cBAT BorrowBalance cBATBorrower) 129714420704314724770821 -Assert Equal (CToken cBAT TotalBorrows) 997475461661266096431316572 +Assert Equal (SLToken slBAT BorrowBalance slBATBorrower) 129714420704314724770821 +Assert Equal (SLToken slBAT TotalBorrows) 997475461661266096431316572 -- Claim comp to true up their balances -Comptroller ClaimComp USDCWhale -Comptroller ClaimComp cBATBorrower +Comptroller ClaimSashimi USDCWhale +Comptroller ClaimSashimi slBATBorrower -- Now move the clock forward AdvanceBlocks 1000000 --- And check that they receive the right amount of COMP when claimed +-- And check that they receive the right amount of SASHIMI when claimed --- cUSDC: 47481122314530 / 1080141236963466282 * 8155485665104318 * 1e6 = 358500906314635600 -Expect Changes (Erc20 Comp TokenBalance USDCWhale) 0.358501981817354439e18 -Comptroller ClaimComp USDCWhale +-- slUSDC: 47481122314530 / 1080141236963466282 * 8155485665104318 * 1e6 = 358500906314635600 +Expect Changes (Erc20 Sashimi TokenBalance USDCWhale) 0.358501981817354439e18 +Comptroller ClaimSashimi USDCWhale --- cETH: 1034370824418 / 5134544277187300 * 193137962620495 * 1e6 = 38908277509608240 --- cBAT: 129714420704314724770821 / 997475461661266096431316572 * 160600166568066720 * 1e6 = 20884882257351856000 +-- slETH: 1034370824418 / 5134544277187300 * 193137962620495 * 1e6 = 38908277509608240 +-- slBAT: 129714420704314724770821 / 997475461661266096431316572 * 160600166568066720 * 1e6 = 20884882257351856000 -- = 0.358500906314635600 + 20.884882257351856000 = 21.24338316366649 -Expect Changes (Erc20 Comp TokenBalance cBATBorrower) 21.282364219697601761e18 -Comptroller ClaimComp cBATBorrower +Expect Changes (Erc20 Sashimi TokenBalance slBATBorrower) 21.282364219697601761e18 +Comptroller ClaimSashimi slBATBorrower -Print "COMP distribution patch OK!" +Print "SASHIMI distribution patch OK!" diff --git a/spec/sim/0002-dai-irm-v3/hypothetical_upgrade.scen b/spec/sim/0002-dai-irm-v3/hypothetical_upgrade.scen index df4d45825..8ebe0a4ea 100755 --- a/spec/sim/0002-dai-irm-v3/hypothetical_upgrade.scen +++ b/spec/sim/0002-dai-irm-v3/hypothetical_upgrade.scen @@ -5,34 +5,34 @@ PrintTransactionLogs -- verify at https://changelog.makerdao.com/releases/mainnet/1.0.8/contracts.json Alias PotAddress "0x197E90f9FAD81970bA7976f33CbD77088E5D7cf7" Alias JugAddress "0x19c0976f590D67707E62397C87829d896Dc0f1F1" -Alias CompHolder "0x19bc62ff7cd9ffd6bdced9802ff718f09f7259f1" -Web3Fork "https://mainnet-eth.compound.finance/@10473211" (CompHolder) +Alias SashimiHolder "0x19bc62ff7cd9ffd6bdced9802ff718f09f7259f1" +Web3Fork "https://mainnet-eth.compound.finance/@10473211" (SashimiHolder) UseConfigs mainnet -- Deploy IRM contract InterestRateModel Deploy DAIInterestRateModel UpdateableDaiInterestRateModel (Exp 1.09) (Exp 0.8) PotAddress JugAddress (Address Timelock) -- Propose to apply the patch -From CompHolder (Comp Delegate CompHolder) -From CompHolder (Governor GovernorAlpha Propose "DAI IRM v3" [(Address cDAI)] [0] ["_setInterestRateModel(address)"] [[(InterestRateModel UpdateableDaiInterestRateModel Address)]]) +From SashimiHolder (Sashimi Delegate SashimiHolder) +From SashimiHolder (Governor GovernorAlpha Propose "DAI IRM v3" [(Address slDAI)] [0] ["_setInterestRateModel(address)"] [[(InterestRateModel UpdateableDaiInterestRateModel Address)]]) -- Vote for, queue, and execute the proposal MineBlock -From CompHolder (Governor GovernorAlpha Proposal LastProposal Vote For) +From SashimiHolder (Governor GovernorAlpha Proposal LastProposal Vote For) AdvanceBlocks 20000 Governor GovernorAlpha Proposal LastProposal Queue IncreaseTime 604910 Governor GovernorAlpha Proposal LastProposal Execute -- Check model -Assert Equal (CToken cDAI InterestRateModel) (InterestRateModel UpdateableDaiInterestRateModel Address) +Assert Equal (SLToken slDAI InterestRateModel) (InterestRateModel UpdateableDaiInterestRateModel Address) -- Propose to apply the update -From CompHolder (Governor GovernorAlpha Propose "DAI IRM v3 update" [(Address UpdateableDaiInterestRateModel)] [0] ["updateJumpRateModel(uint256,uint256,uint256,uint256)"] [[0 (Exp 0.4) (Exp 1.1) (Exp 0.7)]]) +From SashimiHolder (Governor GovernorAlpha Propose "DAI IRM v3 update" [(Address UpdateableDaiInterestRateModel)] [0] ["updateJumpRateModel(uint256,uint256,uint256,uint256)"] [[0 (Exp 0.4) (Exp 1.1) (Exp 0.7)]]) -- Vote for, queue, and execute the proposal to update MineBlock -From CompHolder (Governor GovernorAlpha Proposal LastProposal Vote For) +From SashimiHolder (Governor GovernorAlpha Proposal LastProposal Vote For) AdvanceBlocks 20000 Governor GovernorAlpha Proposal LastProposal Queue IncreaseTime 604910 @@ -45,7 +45,7 @@ Governor GovernorAlpha Proposal LastProposal Execute Assert Equal (InterestRateModel UpdateableDaiInterestRateModel BorrowRate 1 10 1) (0.7299999999953279) -- TODO: --- * additional tests that new cDAI interest rate matches expectations +-- * additional tests that new slDAI interest rate matches expectations -- * no one else can propose rate update -- * get a non-zero initial interest rate! diff --git a/spec/sim/0003-borrow-caps-patch/hypothetical_upgrade.scen b/spec/sim/0003-borrow-caps-patch/hypothetical_upgrade.scen index 4d11a281a..300fdfcac 100755 --- a/spec/sim/0003-borrow-caps-patch/hypothetical_upgrade.scen +++ b/spec/sim/0003-borrow-caps-patch/hypothetical_upgrade.scen @@ -1,10 +1,10 @@ #!/usr/bin/env yarn repl -s PrintTransactionLogs -Alias CompHolder "0x19bc62ff7cd9ffd6bdced9802ff718f09f7259f1" +Alias SashimiHolder "0x19bc62ff7cd9ffd6bdced9802ff718f09f7259f1" Alias USDCWhale "0x3dfd23a6c5e8bbcfc9581d2e864a68feb6a076d3" Alias Arr00 "0x2b384212edc04ae8bb41738d05ba20e33277bf33" -Web3Fork "https://mainnet-eth.compound.finance/@10706095" (CompHolder USDCWhale) +Web3Fork "https://mainnet-eth.compound.finance/@10706095" (SashimiHolder USDCWhale) UseConfigs mainnet -- Deploy the flywheel impl @@ -13,13 +13,13 @@ ComptrollerImpl Deploy Standard ComptrollerG5 -- Propose to apply the patch -From CompHolder (Comp Delegate CompHolder) -From CompHolder (Governor GovernorAlpha Propose "Borrow Cap Comptroller Patch" [(Address Unitroller) (Address ComptrollerG5) (Address Unitroller) (Address cSAI) (Address SAI)] [0 0 0 0 0] ["_setPendingImplementation(address)" "_become(address)" "_setBorrowCapGuardian(address)" "_reduceReserves(uint256)" "transfer(address,uint256)"] [[(Address ComptrollerG5)] [(Address Unitroller)] [(Address CompHolder)] [2360000000000000000000] [(Address Arr00) 2360000000000000000000]]) +From SashimiHolder (Sashimi Delegate SashimiHolder) +From SashimiHolder (Governor GovernorAlpha Propose "Borrow Cap Comptroller Patch" [(Address Unitroller) (Address ComptrollerG5) (Address Unitroller) (Address slSAI) (Address SAI)] [0 0 0 0 0] ["_setPendingImplementation(address)" "_become(address)" "_setBorrowCapGuardian(address)" "_reduceReserves(uint256)" "transfer(address,uint256)"] [[(Address ComptrollerG5)] [(Address Unitroller)] [(Address SashimiHolder)] [2360000000000000000000] [(Address Arr00) 2360000000000000000000]]) -- Vote for, queue, and execute the proposal MineBlock -From CompHolder (Governor GovernorAlpha Proposal LastProposal Vote For) +From SashimiHolder (Governor GovernorAlpha Proposal LastProposal Vote For) AdvanceBlocks 20000 Governor GovernorAlpha Proposal LastProposal Queue IncreaseTime 604910 @@ -29,19 +29,19 @@ ComptrollerImpl ComptrollerG5 MergeABI Assert Equal (Address (Unitroller Implementation)) (Address ComptrollerG5) Assert Equal (Erc20 SAI TokenBalance (Address Arr00)) (2360000000000000000000) -From USDCWhale (Trx GasPrice 0 (Erc20 USDC Approve cUSDC UInt256Max)) -From USDCWhale (Trx GasPrice 0 (CToken cUSDC Mint 214000000e6)) -From USDCWhale (Trx GasPrice 0 (CToken cUSDC Borrow 1000000e6)) +From USDCWhale (Trx GasPrice 0 (Erc20 USDC Approve slUSDC UInt256Max)) +From USDCWhale (Trx GasPrice 0 (SLToken slUSDC Mint 214000000e6)) +From USDCWhale (Trx GasPrice 0 (SLToken slUSDC Borrow 1000000e6)) -From CompHolder (Comptroller SetMarketBorrowCaps (cUSDC) (83000000e6)) +From SashimiHolder (Comptroller SetMarketBorrowCaps (slUSDC) (83000000e6)) AllowFailures -From USDCWhale (Trx GasPrice 0 (CToken cUSDC Borrow 1000000e6)) +From USDCWhale (Trx GasPrice 0 (SLToken slUSDC Borrow 1000000e6)) Assert Revert Successfully -From USDCWhale (Trx GasPrice 0 (CToken cUSDC RepayBorrow 1000000e6)) -From USDCWhale (Trx GasPrice 0 (CToken cUSDC Borrow 10e6)) +From USDCWhale (Trx GasPrice 0 (SLToken slUSDC RepayBorrow 1000000e6)) +From USDCWhale (Trx GasPrice 0 (SLToken slUSDC Borrow 10e6)) diff --git a/spec/sim/0003-borrow-caps-patch/hypothetical_upgrade_post_deploy.scen b/spec/sim/0003-borrow-caps-patch/hypothetical_upgrade_post_deploy.scen index 679ec0261..9cd9197f5 100755 --- a/spec/sim/0003-borrow-caps-patch/hypothetical_upgrade_post_deploy.scen +++ b/spec/sim/0003-borrow-caps-patch/hypothetical_upgrade_post_deploy.scen @@ -1,22 +1,22 @@ #!/usr/bin/env yarn repl -s PrintTransactionLogs -Alias CompHolder "0x19bc62ff7cd9ffd6bdced9802ff718f09f7259f1" +Alias SashimiHolder "0x19bc62ff7cd9ffd6bdced9802ff718f09f7259f1" Alias USDCWhale "0x3dfd23a6c5e8bbcfc9581d2e864a68feb6a076d3" Alias Arr00 "0x2b384212edc04ae8bb41738d05ba20e33277bf33" -Web3Fork "https://mainnet-eth.compound.finance/@10809638" (CompHolder USDCWhale) +Web3Fork "https://mainnet-eth.compound.finance/@10809638" (SashimiHolder USDCWhale) UseConfigs mainnet -- Propose to apply the patch -From CompHolder (Comp Delegate CompHolder) -From CompHolder (Governor GovernorAlpha Propose "Borrow Limit Comptroller Patch" [(Address Unitroller) (Address StdComptrollerG5) (Address Unitroller) (Address cSAI) (Address SAI)] [0 0 0 0 0] ["_setPendingImplementation(address)" "_become(address)" "_setBorrowCapGuardian(address)" "_reduceReserves(uint256)" "transfer(address,uint256)"] [[(Address StdComptrollerG5)] [(Address Unitroller)] [(Address CompHolder)] [2360000000000000000000] [(Address Arr00) 2360000000000000000000]]) +From SashimiHolder (Sashimi Delegate SashimiHolder) +From SashimiHolder (Governor GovernorAlpha Propose "Borrow Limit Comptroller Patch" [(Address Unitroller) (Address StdComptrollerG5) (Address Unitroller) (Address slSAI) (Address SAI)] [0 0 0 0 0] ["_setPendingImplementation(address)" "_become(address)" "_setBorrowCapGuardian(address)" "_reduceReserves(uint256)" "transfer(address,uint256)"] [[(Address StdComptrollerG5)] [(Address Unitroller)] [(Address SashimiHolder)] [2360000000000000000000] [(Address Arr00) 2360000000000000000000]]) -- Vote for, queue, and execute the proposal MineBlock -From CompHolder (Governor GovernorAlpha Proposal LastProposal Vote For) +From SashimiHolder (Governor GovernorAlpha Proposal LastProposal Vote For) AdvanceBlocks 20000 Governor GovernorAlpha Proposal LastProposal Queue IncreaseTime 604910 @@ -26,20 +26,20 @@ ComptrollerImpl StdComptrollerG5 MergeABI Assert Equal (Address (Unitroller Implementation)) (Address StdComptrollerG5) Assert Equal (Erc20 SAI TokenBalance (Address Arr00)) (2360000000000000000000) -From USDCWhale (Trx GasPrice 0 (Erc20 USDC Approve cUSDC UInt256Max)) -From USDCWhale (Trx GasPrice 0 (CToken cUSDC Mint 100000000e6)) -From USDCWhale (Trx GasPrice 0 (CToken cUSDC Borrow 1000000e6)) +From USDCWhale (Trx GasPrice 0 (Erc20 USDC Approve slUSDC UInt256Max)) +From USDCWhale (Trx GasPrice 0 (SLToken slUSDC Mint 100000000e6)) +From USDCWhale (Trx GasPrice 0 (SLToken slUSDC Borrow 1000000e6)) -- Market borrows were just under 81M at this block -From CompHolder (Comptroller SetMarketBorrowCaps (cUSDC) (68000000e6)) +From SashimiHolder (Comptroller SetMarketBorrowCaps (slUSDC) (68000000e6)) AllowFailures -From USDCWhale (Trx GasPrice 0 (CToken cUSDC Borrow 1000000e6)) +From USDCWhale (Trx GasPrice 0 (SLToken slUSDC Borrow 1000000e6)) Assert Revert Successfully -From USDCWhale (Trx GasPrice 0 (CToken cUSDC RepayBorrow 1000000e6)) -From USDCWhale (Trx GasPrice 0 (CToken cUSDC Borrow 10e6)) +From USDCWhale (Trx GasPrice 0 (SLToken slUSDC RepayBorrow 1000000e6)) +From USDCWhale (Trx GasPrice 0 (SLToken slUSDC Borrow 10e6)) diff --git a/spec/sim/0003-borrow-caps-patch/hypothetical_upgrade_post_propose.scen b/spec/sim/0003-borrow-caps-patch/hypothetical_upgrade_post_propose.scen index 5d777dfaa..f921b45e0 100755 --- a/spec/sim/0003-borrow-caps-patch/hypothetical_upgrade_post_propose.scen +++ b/spec/sim/0003-borrow-caps-patch/hypothetical_upgrade_post_propose.scen @@ -24,9 +24,9 @@ ComptrollerImpl StdComptrollerG5 MergeABI Assert Equal (Address (Unitroller Implementation)) (Address StdComptrollerG5) Assert Equal (Erc20 SAI TokenBalance (Address Arr00)) (2800000000000000000000) -From USDCWhale (Trx GasPrice 0 (Erc20 USDC Approve cUSDC UInt256Max)) -From USDCWhale (Trx GasPrice 0 (CToken cUSDC Mint 100000000e6)) -From USDCWhale (Trx GasPrice 0 (CToken cUSDC Borrow 1000000e6)) +From USDCWhale (Trx GasPrice 0 (Erc20 USDC Approve slUSDC UInt256Max)) +From USDCWhale (Trx GasPrice 0 (SLToken slUSDC Mint 100000000e6)) +From USDCWhale (Trx GasPrice 0 (SLToken slUSDC Borrow 1000000e6)) Print "Borrow Limit Comptroller Patch OK!" \ No newline at end of file diff --git a/spec/sim/0004-cusdc-irm-update/hypothetical_upgrade.scen b/spec/sim/0004-cusdc-irm-update/hypothetical_upgrade.scen index bc0a53e5d..d954581d9 100755 --- a/spec/sim/0004-cusdc-irm-update/hypothetical_upgrade.scen +++ b/spec/sim/0004-cusdc-irm-update/hypothetical_upgrade.scen @@ -1,8 +1,8 @@ #!/usr/bin/env yarn repl -s PrintTransactionLogs -Alias CompHolder "0x19bc62ff7cd9ffd6bdced9802ff718f09f7259f1" -Web3Fork "https://mainnet-eth.compound.finance/@10796407" (CompHolder) +Alias SashimiHolder "0x19bc62ff7cd9ffd6bdced9802ff718f09f7259f1" +Web3Fork "https://mainnet-eth.compound.finance/@10796407" (SashimiHolder) UseConfigs mainnet -- Deploy new interest rate model @@ -10,21 +10,21 @@ InterestRateModel Deploy LegacyJumpRateModelV2 MyInterestRateModel 0 0.04 1.09 0 -- Propose to apply the patch -From CompHolder (Comp Delegate CompHolder) -From CompHolder (Governor GovernorAlpha Propose "Update cUSDC interest rate model" [(Address cUSDC)] [0] ["_setInterestRateModel(address)"] [[(Address MyInterestRateModel)]]) +From SashimiHolder (Sashimi Delegate SashimiHolder) +From SashimiHolder (Governor GovernorAlpha Propose "Update slUSDC interest rate model" [(Address slUSDC)] [0] ["_setInterestRateModel(address)"] [[(Address MyInterestRateModel)]]) -- Vote for, queue, and execute the proposal MineBlock -From CompHolder (Governor GovernorAlpha Proposal LastProposal Vote For) +From SashimiHolder (Governor GovernorAlpha Proposal LastProposal Vote For) AdvanceBlocks 20000 Governor GovernorAlpha Proposal LastProposal Queue IncreaseTime 604910 Governor GovernorAlpha Proposal LastProposal Execute -Assert Equal (Address (CToken cUSDC InterestRateModel)) (Address MyInterestRateModel) -CToken cUSDC AccrueInterest +Assert Equal (Address (SLToken slUSDC InterestRateModel)) (Address MyInterestRateModel) +SLToken slUSDC AccrueInterest -Print "cUSDC interest rate model upgrade ok" \ No newline at end of file +Print "slUSDC interest rate model upgrade ok" \ No newline at end of file diff --git a/tests/CompilerTest.js b/tests/CompilerTest.js index f22f65909..d89019296 100644 --- a/tests/CompilerTest.js +++ b/tests/CompilerTest.js @@ -6,11 +6,11 @@ const { const { makeComptroller, - makeCToken, + makeSLToken, makePriceOracle, pretendBorrow, borrowSnapshot -} = require('./Utils/Compound'); +} = require('./Utils/SashimiLending'); describe('Const', () => { it("does the right thing and not too expensive", async () => { diff --git a/tests/Comptroller/accountLiquidityTest.js b/tests/Comptroller/accountLiquidityTest.js index 3c423eace..3a4fc62ea 100644 --- a/tests/Comptroller/accountLiquidityTest.js +++ b/tests/Comptroller/accountLiquidityTest.js @@ -1,9 +1,9 @@ const { makeComptroller, - makeCToken, + makeSLToken, enterMarkets, quickMint -} = require('../Utils/Compound'); +} = require('../Utils/SashimiLending'); describe('Comptroller', () => { let root, accounts; @@ -14,38 +14,38 @@ describe('Comptroller', () => { describe('liquidity', () => { it("fails if a price has not been set", async () => { - const cToken = await makeCToken({supportMarket: true}); - await enterMarkets([cToken], accounts[1]); - let result = await call(cToken.comptroller, 'getAccountLiquidity', [accounts[1]]); + const slToken = await makeSLToken({supportMarket: true}); + await enterMarkets([slToken], accounts[1]); + let result = await call(slToken.comptroller, 'getAccountLiquidity', [accounts[1]]); expect(result).toHaveTrollError('PRICE_ERROR'); }); it("allows a borrow up to collateralFactor, but not more", async () => { const collateralFactor = 0.5, underlyingPrice = 1, user = accounts[1], amount = 1e6; - const cToken = await makeCToken({supportMarket: true, collateralFactor, underlyingPrice}); + const slToken = await makeSLToken({supportMarket: true, collateralFactor, underlyingPrice}); let error, liquidity, shortfall; // not in market yet, hypothetical borrow should have no effect - ({1: liquidity, 2: shortfall} = await call(cToken.comptroller, 'getHypotheticalAccountLiquidity', [user, cToken._address, 0, amount])); + ({1: liquidity, 2: shortfall} = await call(slToken.comptroller, 'getHypotheticalAccountLiquidity', [user, slToken._address, 0, amount])); expect(liquidity).toEqualNumber(0); expect(shortfall).toEqualNumber(0); - await enterMarkets([cToken], user); - await quickMint(cToken, user, amount); + await enterMarkets([slToken], user); + await quickMint(slToken, user, amount); // total account liquidity after supplying `amount` - ({1: liquidity, 2: shortfall} = await call(cToken.comptroller, 'getAccountLiquidity', [user])); + ({1: liquidity, 2: shortfall} = await call(slToken.comptroller, 'getAccountLiquidity', [user])); expect(liquidity).toEqualNumber(amount * collateralFactor); expect(shortfall).toEqualNumber(0); // hypothetically borrow `amount`, should shortfall over collateralFactor - ({1: liquidity, 2: shortfall} = await call(cToken.comptroller, 'getHypotheticalAccountLiquidity', [user, cToken._address, 0, amount])); + ({1: liquidity, 2: shortfall} = await call(slToken.comptroller, 'getHypotheticalAccountLiquidity', [user, slToken._address, 0, amount])); expect(liquidity).toEqualNumber(0); expect(shortfall).toEqualNumber(amount * (1 - collateralFactor)); // hypothetically redeem `amount`, should be back to even - ({1: liquidity, 2: shortfall} = await call(cToken.comptroller, 'getHypotheticalAccountLiquidity', [user, cToken._address, amount, 0])); + ({1: liquidity, 2: shortfall} = await call(slToken.comptroller, 'getHypotheticalAccountLiquidity', [user, slToken._address, amount, 0])); expect(liquidity).toEqualNumber(0); expect(shortfall).toEqualNumber(0); }, 20000); @@ -54,34 +54,34 @@ describe('Comptroller', () => { const amount1 = 1e6, amount2 = 1e3, user = accounts[1]; const cf1 = 0.5, cf2 = 0.666, cf3 = 0, up1 = 3, up2 = 2.718, up3 = 1; const c1 = amount1 * cf1 * up1, c2 = amount2 * cf2 * up2, collateral = Math.floor(c1 + c2); - const cToken1 = await makeCToken({supportMarket: true, collateralFactor: cf1, underlyingPrice: up1}); - const cToken2 = await makeCToken({supportMarket: true, comptroller: cToken1.comptroller, collateralFactor: cf2, underlyingPrice: up2}); - const cToken3 = await makeCToken({supportMarket: true, comptroller: cToken1.comptroller, collateralFactor: cf3, underlyingPrice: up3}); + const slToken1 = await makeSLToken({supportMarket: true, collateralFactor: cf1, underlyingPrice: up1}); + const slToken2 = await makeSLToken({supportMarket: true, comptroller: slToken1.comptroller, collateralFactor: cf2, underlyingPrice: up2}); + const slToken3 = await makeSLToken({supportMarket: true, comptroller: slToken1.comptroller, collateralFactor: cf3, underlyingPrice: up3}); - await enterMarkets([cToken1, cToken2, cToken3], user); - await quickMint(cToken1, user, amount1); - await quickMint(cToken2, user, amount2); + await enterMarkets([slToken1, slToken2, slToken3], user); + await quickMint(slToken1, user, amount1); + await quickMint(slToken2, user, amount2); let error, liquidity, shortfall; - ({0: error, 1: liquidity, 2: shortfall} = await call(cToken3.comptroller, 'getAccountLiquidity', [user])); + ({0: error, 1: liquidity, 2: shortfall} = await call(slToken3.comptroller, 'getAccountLiquidity', [user])); expect(error).toEqualNumber(0); expect(liquidity).toEqualNumber(collateral); expect(shortfall).toEqualNumber(0); - ({1: liquidity, 2: shortfall} = await call(cToken3.comptroller, 'getHypotheticalAccountLiquidity', [user, cToken3._address, Math.floor(c2), 0])); + ({1: liquidity, 2: shortfall} = await call(slToken3.comptroller, 'getHypotheticalAccountLiquidity', [user, slToken3._address, Math.floor(c2), 0])); expect(liquidity).toEqualNumber(collateral); expect(shortfall).toEqualNumber(0); - ({1: liquidity, 2: shortfall} = await call(cToken3.comptroller, 'getHypotheticalAccountLiquidity', [user, cToken3._address, 0, Math.floor(c2)])); + ({1: liquidity, 2: shortfall} = await call(slToken3.comptroller, 'getHypotheticalAccountLiquidity', [user, slToken3._address, 0, Math.floor(c2)])); expect(liquidity).toEqualNumber(c1); expect(shortfall).toEqualNumber(0); - ({1: liquidity, 2: shortfall} = await call(cToken3.comptroller, 'getHypotheticalAccountLiquidity', [user, cToken3._address, 0, collateral + c1])); + ({1: liquidity, 2: shortfall} = await call(slToken3.comptroller, 'getHypotheticalAccountLiquidity', [user, slToken3._address, 0, collateral + c1])); expect(liquidity).toEqualNumber(0); expect(shortfall).toEqualNumber(c1); - ({1: liquidity, 2: shortfall} = await call(cToken1.comptroller, 'getHypotheticalAccountLiquidity', [user, cToken1._address, amount1, 0])); + ({1: liquidity, 2: shortfall} = await call(slToken1.comptroller, 'getHypotheticalAccountLiquidity', [user, slToken1._address, amount1, 0])); expect(liquidity).toEqualNumber(Math.floor(c2)); expect(shortfall).toEqualNumber(0); }); @@ -99,8 +99,8 @@ describe('Comptroller', () => { describe("getHypotheticalAccountLiquidity", () => { it("returns 0 if not 'in' any markets", async () => { - const cToken = await makeCToken(); - const {0: error, 1: liquidity, 2: shortfall} = await call(cToken.comptroller, 'getHypotheticalAccountLiquidity', [accounts[0], cToken._address, 0, 0]); + const slToken = await makeSLToken(); + const {0: error, 1: liquidity, 2: shortfall} = await call(slToken.comptroller, 'getHypotheticalAccountLiquidity', [accounts[0], slToken._address, 0, 0]); expect(error).toEqualNumber(0); expect(liquidity).toEqualNumber(0); expect(shortfall).toEqualNumber(0); @@ -108,13 +108,13 @@ describe('Comptroller', () => { it("returns collateral factor times dollar amount of tokens minted in a single market", async () => { const collateralFactor = 0.5, exchangeRate = 1, underlyingPrice = 1; - const cToken = await makeCToken({supportMarket: true, collateralFactor, exchangeRate, underlyingPrice}); + const slToken = await makeSLToken({supportMarket: true, collateralFactor, exchangeRate, underlyingPrice}); const from = accounts[0], balance = 1e7, amount = 1e6; - await enterMarkets([cToken], from); - await send(cToken.underlying, 'harnessSetBalance', [from, balance], {from}); - await send(cToken.underlying, 'approve', [cToken._address, balance], {from}); - await send(cToken, 'mint', [amount], {from}); - const {0: error, 1: liquidity, 2: shortfall} = await call(cToken.comptroller, 'getHypotheticalAccountLiquidity', [from, cToken._address, 0, 0]); + await enterMarkets([slToken], from); + await send(slToken.underlying, 'harnessSetBalance', [from, balance], {from}); + await send(slToken.underlying, 'approve', [slToken._address, balance], {from}); + await send(slToken, 'mint', [amount], {from}); + const {0: error, 1: liquidity, 2: shortfall} = await call(slToken.comptroller, 'getHypotheticalAccountLiquidity', [from, slToken._address, 0, 0]); expect(error).toEqualNumber(0); expect(liquidity).toEqualNumber(amount * collateralFactor * exchangeRate * underlyingPrice); expect(shortfall).toEqualNumber(0); diff --git a/tests/Comptroller/assetsListTest.js b/tests/Comptroller/assetsListTest.js index b58f1ddf9..19b139ebc 100644 --- a/tests/Comptroller/assetsListTest.js +++ b/tests/Comptroller/assetsListTest.js @@ -1,8 +1,8 @@ const {both} = require('../Utils/Ethereum'); const { makeComptroller, - makeCToken -} = require('../Utils/Compound'); + makeSLToken +} = require('../Utils/SashimiLending'); describe('assetListTest', () => { let root, customer, accounts; @@ -14,7 +14,7 @@ describe('assetListTest', () => { comptroller = await makeComptroller({maxAssets: 10}); allTokens = [OMG, ZRX, BAT, REP, DAI, SKT] = await Promise.all( ['OMG', 'ZRX', 'BAT', 'REP', 'DAI', 'sketch'] - .map(async (name) => makeCToken({comptroller, name, symbol: name, supportMarket: name != 'sketch', underlyingPrice: 0.5})) + .map(async (name) => makeSLToken({comptroller, name, symbol: name, supportMarket: name != 'sketch', underlyingPrice: 0.5})) ); }); @@ -72,7 +72,7 @@ describe('assetListTest', () => { const result1 = await enterAndCheckMarkets([OMG], [OMG]); const result2 = await enterAndCheckMarkets([OMG], [OMG]); expect(result1).toHaveLog('MarketEntered', { - cToken: OMG._address, + slToken: OMG._address, account: customer }); expect(result2.events).toEqual({}); @@ -186,7 +186,7 @@ describe('assetListTest', () => { }); describe('entering from borrowAllowed', () => { - it("enters when called by a ctoken", async () => { + it("enters when called by a sltoken", async () => { await send(BAT, 'harnessCallBorrowAllowed', [1], {from: customer}); const assetsIn = await call(comptroller, 'getAssetsIn', [customer]); @@ -196,10 +196,10 @@ describe('assetListTest', () => { await checkMarkets([BAT]); }); - it("reverts when called by not a ctoken", async () => { + it("reverts when called by not a sltoken", async () => { await expect( send(comptroller, 'borrowAllowed', [BAT._address, customer, 1], {from: customer}) - ).rejects.toRevert('revert sender must be cToken'); + ).rejects.toRevert('revert sender must be slToken'); const assetsIn = await call(comptroller, 'getAssetsIn', [customer]); diff --git a/tests/Comptroller/comptrollerTest.js b/tests/Comptroller/comptrollerTest.js index 4792f4a27..350c12709 100644 --- a/tests/Comptroller/comptrollerTest.js +++ b/tests/Comptroller/comptrollerTest.js @@ -6,9 +6,9 @@ const { const { makeComptroller, makePriceOracle, - makeCToken, + makeSLToken, makeToken -} = require('../Utils/Compound'); +} = require('../Utils/SashimiLending'); describe('Comptroller', () => { let root, accounts; @@ -122,20 +122,20 @@ describe('Comptroller', () => { describe('_setCloseFactor', () => { it("fails if not called by admin", async () => { - const cToken = await makeCToken(); + const slToken = await makeSLToken(); expect( - await send(cToken.comptroller, '_setCloseFactor', [1], {from: accounts[0]}) + await send(slToken.comptroller, '_setCloseFactor', [1], {from: accounts[0]}) ).toHaveTrollFailure('UNAUTHORIZED', 'SET_CLOSE_FACTOR_OWNER_CHECK'); }); it("fails if close factor too low", async () => { - const cToken = await makeCToken(); - expect(await send(cToken.comptroller, '_setCloseFactor', [1])).toHaveTrollFailure('INVALID_CLOSE_FACTOR', 'SET_CLOSE_FACTOR_VALIDATION'); + const slToken = await makeSLToken(); + expect(await send(slToken.comptroller, '_setCloseFactor', [1])).toHaveTrollFailure('INVALID_CLOSE_FACTOR', 'SET_CLOSE_FACTOR_VALIDATION'); }); it("fails if close factor too low", async () => { - const cToken = await makeCToken(); - expect(await send(cToken.comptroller, '_setCloseFactor', [etherMantissa(1e18)])).toHaveTrollFailure('INVALID_CLOSE_FACTOR', 'SET_CLOSE_FACTOR_VALIDATION'); + const slToken = await makeSLToken(); + expect(await send(slToken.comptroller, '_setCloseFactor', [etherMantissa(1e18)])).toHaveTrollFailure('INVALID_CLOSE_FACTOR', 'SET_CLOSE_FACTOR_VALIDATION'); }); }); @@ -144,38 +144,38 @@ describe('Comptroller', () => { const one = etherMantissa(1); it("fails if not called by admin", async () => { - const cToken = await makeCToken(); + const slToken = await makeSLToken(); expect( - await send(cToken.comptroller, '_setCollateralFactor', [cToken._address, half], {from: accounts[0]}) + await send(slToken.comptroller, '_setCollateralFactor', [slToken._address, half], {from: accounts[0]}) ).toHaveTrollFailure('UNAUTHORIZED', 'SET_COLLATERAL_FACTOR_OWNER_CHECK'); }); it("fails if asset is not listed", async () => { - const cToken = await makeCToken(); + const slToken = await makeSLToken(); expect( - await send(cToken.comptroller, '_setCollateralFactor', [cToken._address, half]) + await send(slToken.comptroller, '_setCollateralFactor', [slToken._address, half]) ).toHaveTrollFailure('MARKET_NOT_LISTED', 'SET_COLLATERAL_FACTOR_NO_EXISTS'); }); it("fails if factor is too high", async () => { - const cToken = await makeCToken({supportMarket: true}); + const slToken = await makeSLToken({supportMarket: true}); expect( - await send(cToken.comptroller, '_setCollateralFactor', [cToken._address, one]) + await send(slToken.comptroller, '_setCollateralFactor', [slToken._address, one]) ).toHaveTrollFailure('INVALID_COLLATERAL_FACTOR', 'SET_COLLATERAL_FACTOR_VALIDATION'); }); it("fails if factor is set without an underlying price", async () => { - const cToken = await makeCToken({supportMarket: true}); + const slToken = await makeSLToken({supportMarket: true}); expect( - await send(cToken.comptroller, '_setCollateralFactor', [cToken._address, half]) + await send(slToken.comptroller, '_setCollateralFactor', [slToken._address, half]) ).toHaveTrollFailure('PRICE_ERROR', 'SET_COLLATERAL_FACTOR_WITHOUT_PRICE'); }); it("succeeds and sets market", async () => { - const cToken = await makeCToken({supportMarket: true, underlyingPrice: 1}); - const result = await send(cToken.comptroller, '_setCollateralFactor', [cToken._address, half]); + const slToken = await makeSLToken({supportMarket: true, underlyingPrice: 1}); + const result = await send(slToken.comptroller, '_setCollateralFactor', [slToken._address, half]); expect(result).toHaveLog('NewCollateralFactor', { - cToken: cToken._address, + slToken: slToken._address, oldCollateralFactorMantissa: '0', newCollateralFactorMantissa: half.toString() }); @@ -184,59 +184,59 @@ describe('Comptroller', () => { describe('_supportMarket', () => { it("fails if not called by admin", async () => { - const cToken = await makeCToken(root); + const slToken = await makeSLToken(root); expect( - await send(cToken.comptroller, '_supportMarket', [cToken._address], {from: accounts[0]}) + await send(slToken.comptroller, '_supportMarket', [slToken._address], {from: accounts[0]}) ).toHaveTrollFailure('UNAUTHORIZED', 'SUPPORT_MARKET_OWNER_CHECK'); }); - it("fails if asset is not a CToken", async () => { + it("fails if asset is not a SLToken", async () => { const comptroller = await makeComptroller() const asset = await makeToken(root); await expect(send(comptroller, '_supportMarket', [asset._address])).rejects.toRevert(); }); it("succeeds and sets market", async () => { - const cToken = await makeCToken(); - const result = await send(cToken.comptroller, '_supportMarket', [cToken._address]); - expect(result).toHaveLog('MarketListed', {cToken: cToken._address}); + const slToken = await makeSLToken(); + const result = await send(slToken.comptroller, '_supportMarket', [slToken._address]); + expect(result).toHaveLog('MarketListed', {slToken: slToken._address}); }); it("cannot list a market a second time", async () => { - const cToken = await makeCToken(); - const result1 = await send(cToken.comptroller, '_supportMarket', [cToken._address]); - const result2 = await send(cToken.comptroller, '_supportMarket', [cToken._address]); - expect(result1).toHaveLog('MarketListed', {cToken: cToken._address}); + const slToken = await makeSLToken(); + const result1 = await send(slToken.comptroller, '_supportMarket', [slToken._address]); + const result2 = await send(slToken.comptroller, '_supportMarket', [slToken._address]); + expect(result1).toHaveLog('MarketListed', {slToken: slToken._address}); expect(result2).toHaveTrollFailure('MARKET_ALREADY_LISTED', 'SUPPORT_MARKET_EXISTS'); }); it("can list two different markets", async () => { - const cToken1 = await makeCToken(); - const cToken2 = await makeCToken({comptroller: cToken1.comptroller}); - const result1 = await send(cToken1.comptroller, '_supportMarket', [cToken1._address]); - const result2 = await send(cToken1.comptroller, '_supportMarket', [cToken2._address]); - expect(result1).toHaveLog('MarketListed', {cToken: cToken1._address}); - expect(result2).toHaveLog('MarketListed', {cToken: cToken2._address}); + const slToken1 = await makeSLToken(); + const slToken2 = await makeSLToken({comptroller: slToken1.comptroller}); + const result1 = await send(slToken1.comptroller, '_supportMarket', [slToken1._address]); + const result2 = await send(slToken1.comptroller, '_supportMarket', [slToken2._address]); + expect(result1).toHaveLog('MarketListed', {slToken: slToken1._address}); + expect(result2).toHaveLog('MarketListed', {slToken: slToken2._address}); }); }); describe('redeemVerify', () => { it('should allow you to redeem 0 underlying for 0 tokens', async () => { const comptroller = await makeComptroller(); - const cToken = await makeCToken({comptroller: comptroller}); - await call(comptroller, 'redeemVerify', [cToken._address, accounts[0], 0, 0]); + const slToken = await makeSLToken({comptroller: comptroller}); + await call(comptroller, 'redeemVerify', [slToken._address, accounts[0], 0, 0]); }); it('should allow you to redeem 5 underlyig for 5 tokens', async () => { const comptroller = await makeComptroller(); - const cToken = await makeCToken({comptroller: comptroller}); - await call(comptroller, 'redeemVerify', [cToken._address, accounts[0], 5, 5]); + const slToken = await makeSLToken({comptroller: comptroller}); + await call(comptroller, 'redeemVerify', [slToken._address, accounts[0], 5, 5]); }); it('should not allow you to redeem 5 underlying for 0 tokens', async () => { const comptroller = await makeComptroller(); - const cToken = await makeCToken({comptroller: comptroller}); - await expect(call(comptroller, 'redeemVerify', [cToken._address, accounts[0], 5, 0])).rejects.toRevert("revert redeemTokens zero"); + const slToken = await makeSLToken({comptroller: comptroller}); + await expect(call(comptroller, 'redeemVerify', [slToken._address, accounts[0], 5, 0])).rejects.toRevert("revert redeemTokens zero"); }); }) }); diff --git a/tests/Comptroller/liquidateCalculateAmountSeizeTest.js b/tests/Comptroller/liquidateCalculateAmountSeizeTest.js index 90cb8f1db..b4aa65b14 100644 --- a/tests/Comptroller/liquidateCalculateAmountSeizeTest.js +++ b/tests/Comptroller/liquidateCalculateAmountSeizeTest.js @@ -1,16 +1,16 @@ const {etherUnsigned} = require('../Utils/Ethereum'); const { makeComptroller, - makeCToken, + makeSLToken, setOraclePrice -} = require('../Utils/Compound'); +} = require('../Utils/SashimiLending'); const borrowedPrice = 2e10; const collateralPrice = 1e18; const repayAmount = etherUnsigned(1e18); -async function calculateSeizeTokens(comptroller, cTokenBorrowed, cTokenCollateral, repayAmount) { - return call(comptroller, 'liquidateCalculateSeizeTokens', [cTokenBorrowed._address, cTokenCollateral._address, repayAmount]); +async function calculateSeizeTokens(comptroller, slTokenBorrowed, slTokenCollateral, repayAmount) { + return call(comptroller, 'liquidateCalculateSeizeTokens', [slTokenBorrowed._address, slTokenCollateral._address, repayAmount]); } function rando(min, max) { @@ -19,51 +19,51 @@ function rando(min, max) { describe('Comptroller', () => { let root, accounts; - let comptroller, cTokenBorrowed, cTokenCollateral; + let comptroller, slTokenBorrowed, slTokenCollateral; beforeEach(async () => { [root, ...accounts] = saddle.accounts; comptroller = await makeComptroller(); - cTokenBorrowed = await makeCToken({comptroller: comptroller, underlyingPrice: 0}); - cTokenCollateral = await makeCToken({comptroller: comptroller, underlyingPrice: 0}); + slTokenBorrowed = await makeSLToken({comptroller: comptroller, underlyingPrice: 0}); + slTokenCollateral = await makeSLToken({comptroller: comptroller, underlyingPrice: 0}); }); beforeEach(async () => { - await setOraclePrice(cTokenBorrowed, borrowedPrice); - await setOraclePrice(cTokenCollateral, collateralPrice); - await send(cTokenCollateral, 'harnessExchangeRateDetails', [8e10, 4e10, 0]); + await setOraclePrice(slTokenBorrowed, borrowedPrice); + await setOraclePrice(slTokenCollateral, collateralPrice); + await send(slTokenCollateral, 'harnessExchangeRateDetails', [8e10, 4e10, 0]); }); describe('liquidateCalculateAmountSeize', () => { it("fails if either asset price is 0", async () => { - await setOraclePrice(cTokenBorrowed, 0); + await setOraclePrice(slTokenBorrowed, 0); expect( - await calculateSeizeTokens(comptroller, cTokenBorrowed, cTokenCollateral, repayAmount) + await calculateSeizeTokens(comptroller, slTokenBorrowed, slTokenCollateral, repayAmount) ).toHaveTrollErrorTuple(['PRICE_ERROR', 0]); - await setOraclePrice(cTokenCollateral, 0); + await setOraclePrice(slTokenCollateral, 0); expect( - await calculateSeizeTokens(comptroller, cTokenBorrowed, cTokenCollateral, repayAmount) + await calculateSeizeTokens(comptroller, slTokenBorrowed, slTokenCollateral, repayAmount) ).toHaveTrollErrorTuple(['PRICE_ERROR', 0]); }); it("fails if the repayAmount causes overflow ", async () => { expect( - await calculateSeizeTokens(comptroller, cTokenBorrowed, cTokenCollateral, -1) + await calculateSeizeTokens(comptroller, slTokenBorrowed, slTokenCollateral, -1) ).toHaveTrollErrorTuple(['MATH_ERROR', 0]); }); it("fails if the borrowed asset price causes overflow ", async () => { - await setOraclePrice(cTokenBorrowed, -1); + await setOraclePrice(slTokenBorrowed, -1); expect( - await calculateSeizeTokens(comptroller, cTokenBorrowed, cTokenCollateral, repayAmount) + await calculateSeizeTokens(comptroller, slTokenBorrowed, slTokenCollateral, repayAmount) ).toHaveTrollErrorTuple(['MATH_ERROR', 0]); }); it("reverts if it fails to calculate the exchange rate", async () => { - await send(cTokenCollateral, 'harnessExchangeRateDetails', [1, 0, 10]); // (1 - 10) -> underflow + await send(slTokenCollateral, 'harnessExchangeRateDetails', [1, 0, 10]); // (1 - 10) -> underflow await expect( - send(comptroller, 'liquidateCalculateSeizeTokens', [cTokenBorrowed._address, cTokenCollateral._address, repayAmount]) + send(comptroller, 'liquidateCalculateSeizeTokens', [slTokenBorrowed._address, slTokenCollateral._address, repayAmount]) ).rejects.toRevert("revert exchangeRateStored: exchangeRateStoredInternal failed"); }); @@ -78,16 +78,16 @@ describe('Comptroller', () => { it(`returns the correct value for ${testCase}`, async () => { const [exchangeRate, borrowedPrice, collateralPrice, liquidationIncentive, repayAmount] = testCase.map(etherUnsigned); - await setOraclePrice(cTokenCollateral, collateralPrice); - await setOraclePrice(cTokenBorrowed, borrowedPrice); + await setOraclePrice(slTokenCollateral, collateralPrice); + await setOraclePrice(slTokenBorrowed, borrowedPrice); await send(comptroller, '_setLiquidationIncentive', [liquidationIncentive]); - await send(cTokenCollateral, 'harnessSetExchangeRate', [exchangeRate]); + await send(slTokenCollateral, 'harnessSetExchangeRate', [exchangeRate]); const seizeAmount = repayAmount.mul(liquidationIncentive).mul(borrowedPrice).div(collateralPrice); const seizeTokens = seizeAmount.div(exchangeRate); expect( - await calculateSeizeTokens(comptroller, cTokenBorrowed, cTokenCollateral, repayAmount) + await calculateSeizeTokens(comptroller, slTokenBorrowed, slTokenCollateral, repayAmount) ).toHaveTrollErrorTuple( ['NO_ERROR', Number(seizeTokens)], (x, y) => Math.abs(x - y) < 1e7 diff --git a/tests/Comptroller/pauseGuardianTest.js b/tests/Comptroller/pauseGuardianTest.js index 8e07d618a..493676e1b 100644 --- a/tests/Comptroller/pauseGuardianTest.js +++ b/tests/Comptroller/pauseGuardianTest.js @@ -1,8 +1,8 @@ const { address, both, etherMantissa } = require('../Utils/Ethereum'); -const { makeComptroller, makeCToken } = require('../Utils/Compound'); +const { makeComptroller, makeSLToken } = require('../Utils/SashimiLending'); describe('Comptroller', () => { - let comptroller, cToken; + let comptroller, slToken; let root, accounts; beforeEach(async () => { @@ -56,8 +56,8 @@ describe('Comptroller', () => { describe('setting paused', () => { beforeEach(async () => { - cToken = await makeCToken({supportMarket: true}); - comptroller = cToken.comptroller; + slToken = await makeSLToken({supportMarket: true}); + comptroller = slToken.comptroller; }); let globalMethods = ["Transfer", "Seize"]; @@ -124,39 +124,39 @@ describe('Comptroller', () => { marketMethods.forEach(async (method) => { it(`only pause guardian or admin can pause ${method}`, async () => { - await expect(send(comptroller, `_set${method}Paused`, [cToken._address, true], {from: accounts[2]})).rejects.toRevert("revert only pause guardian and admin can pause"); - await expect(send(comptroller, `_set${method}Paused`, [cToken._address, false], {from: accounts[2]})).rejects.toRevert("revert only pause guardian and admin can pause"); + await expect(send(comptroller, `_set${method}Paused`, [slToken._address, true], {from: accounts[2]})).rejects.toRevert("revert only pause guardian and admin can pause"); + await expect(send(comptroller, `_set${method}Paused`, [slToken._address, false], {from: accounts[2]})).rejects.toRevert("revert only pause guardian and admin can pause"); }); it(`PauseGuardian can pause of ${method}GuardianPaused`, async () => { - result = await send(comptroller, `_set${method}Paused`, [cToken._address, true], {from: pauseGuardian}); - expect(result).toHaveLog(`ActionPaused`, {cToken: cToken._address, action: method, pauseState: true}); + result = await send(comptroller, `_set${method}Paused`, [slToken._address, true], {from: pauseGuardian}); + expect(result).toHaveLog(`ActionPaused`, {slToken: slToken._address, action: method, pauseState: true}); let camelCase = method.charAt(0).toLowerCase() + method.substring(1); - state = await call(comptroller, `${camelCase}GuardianPaused`, [cToken._address]); + state = await call(comptroller, `${camelCase}GuardianPaused`, [slToken._address]); expect(state).toEqual(true); - await expect(send(comptroller, `_set${method}Paused`, [cToken._address, false], {from: pauseGuardian})).rejects.toRevert("revert only admin can unpause"); - result = await send(comptroller, `_set${method}Paused`, [cToken._address, false]); + await expect(send(comptroller, `_set${method}Paused`, [slToken._address, false], {from: pauseGuardian})).rejects.toRevert("revert only admin can unpause"); + result = await send(comptroller, `_set${method}Paused`, [slToken._address, false]); - expect(result).toHaveLog(`ActionPaused`, {cToken: cToken._address, action: method, pauseState: false}); + expect(result).toHaveLog(`ActionPaused`, {slToken: slToken._address, action: method, pauseState: false}); - state = await call(comptroller, `${camelCase}GuardianPaused`, [cToken._address]); + state = await call(comptroller, `${camelCase}GuardianPaused`, [slToken._address]); expect(state).toEqual(false); }); it(`pauses ${method}`, async() => { - await send(comptroller, `_set${method}Paused`, [cToken._address, true], {from: pauseGuardian}); + await send(comptroller, `_set${method}Paused`, [slToken._address, true], {from: pauseGuardian}); switch (method) { case "Mint": expect(await call(comptroller, 'mintAllowed', [address(1), address(2), 1])).toHaveTrollError('MARKET_NOT_LISTED'); - await expect(send(comptroller, 'mintAllowed', [cToken._address, address(2), 1])).rejects.toRevert(`revert ${method.toLowerCase()} is paused`); + await expect(send(comptroller, 'mintAllowed', [slToken._address, address(2), 1])).rejects.toRevert(`revert ${method.toLowerCase()} is paused`); break; case "Borrow": expect(await call(comptroller, 'borrowAllowed', [address(1), address(2), 1])).toHaveTrollError('MARKET_NOT_LISTED'); - await expect(send(comptroller, 'borrowAllowed', [cToken._address, address(2), 1])).rejects.toRevert(`revert ${method.toLowerCase()} is paused`); + await expect(send(comptroller, 'borrowAllowed', [slToken._address, address(2), 1])).rejects.toRevert(`revert ${method.toLowerCase()} is paused`); break; default: diff --git a/tests/Comptroller/proxiedComptrollerV1Test.js b/tests/Comptroller/proxiedComptrollerV1Test.js index b23d86d44..27c21b8df 100644 --- a/tests/Comptroller/proxiedComptrollerV1Test.js +++ b/tests/Comptroller/proxiedComptrollerV1Test.js @@ -1,6 +1,6 @@ const { address, etherMantissa } = require('../Utils/Ethereum'); -const { makeComptroller, makeCToken, makePriceOracle } = require('../Utils/Compound'); +const { makeComptroller, makeSLToken, makePriceOracle } = require('../Utils/SashimiLending'); describe('ComptrollerV1', function() { let root, accounts; @@ -30,11 +30,11 @@ describe('ComptrollerV1', function() { describe('delegating to comptroller v1', () => { const closeFactor = etherMantissa(0.051); const maxAssets = 10; - let unitrollerAsComptroller, cToken; + let unitrollerAsComptroller, slToken; beforeEach(async () => { unitrollerAsComptroller = await initializeBrains(oracle, etherMantissa(0.06), 30); - cToken = await makeCToken({ comptroller: unitrollerAsComptroller }); + slToken = await makeSLToken({ comptroller: unitrollerAsComptroller }); }); describe('becoming brains sets initial state', () => { @@ -95,7 +95,7 @@ describe('ComptrollerV1', function() { it('fails if not called by admin', async () => { expect( - await send(unitrollerAsComptroller, '_setCollateralFactor', [cToken._address, half], { + await send(unitrollerAsComptroller, '_setCollateralFactor', [slToken._address, half], { from: accounts[1] }) ).toHaveTrollFailure('UNAUTHORIZED', 'SET_COLLATERAL_FACTOR_OWNER_CHECK'); @@ -103,31 +103,31 @@ describe('ComptrollerV1', function() { it('fails if asset is not listed', async () => { expect( - await send(unitrollerAsComptroller, '_setCollateralFactor', [cToken._address, half]) + await send(unitrollerAsComptroller, '_setCollateralFactor', [slToken._address, half]) ).toHaveTrollFailure('MARKET_NOT_LISTED', 'SET_COLLATERAL_FACTOR_NO_EXISTS'); }); it('fails if factor is too high', async () => { - const cToken = await makeCToken({ supportMarket: true, comptroller: unitrollerAsComptroller }); + const slToken = await makeSLToken({ supportMarket: true, comptroller: unitrollerAsComptroller }); expect( - await send(unitrollerAsComptroller, '_setCollateralFactor', [cToken._address, one]) + await send(unitrollerAsComptroller, '_setCollateralFactor', [slToken._address, one]) ).toHaveTrollFailure('INVALID_COLLATERAL_FACTOR', 'SET_COLLATERAL_FACTOR_VALIDATION'); }); it('fails if factor is set without an underlying price', async () => { - const cToken = await makeCToken({ supportMarket: true, comptroller: unitrollerAsComptroller }); + const slToken = await makeSLToken({ supportMarket: true, comptroller: unitrollerAsComptroller }); expect( - await send(unitrollerAsComptroller, '_setCollateralFactor', [cToken._address, half]) + await send(unitrollerAsComptroller, '_setCollateralFactor', [slToken._address, half]) ).toHaveTrollFailure('PRICE_ERROR', 'SET_COLLATERAL_FACTOR_WITHOUT_PRICE'); }); it('succeeds and sets market', async () => { - const cToken = await makeCToken({ supportMarket: true, comptroller: unitrollerAsComptroller }); - await send(oracle, 'setUnderlyingPrice', [cToken._address, 1]); + const slToken = await makeSLToken({ supportMarket: true, comptroller: unitrollerAsComptroller }); + await send(oracle, 'setUnderlyingPrice', [slToken._address, 1]); expect( - await send(unitrollerAsComptroller, '_setCollateralFactor', [cToken._address, half]) + await send(unitrollerAsComptroller, '_setCollateralFactor', [slToken._address, half]) ).toHaveLog('NewCollateralFactor', { - cToken: cToken._address, + slToken: slToken._address, oldCollateralFactorMantissa: '0', newCollateralFactorMantissa: half.toString() }); @@ -137,34 +137,34 @@ describe('ComptrollerV1', function() { describe('_supportMarket', () => { it('fails if not called by admin', async () => { expect( - await send(unitrollerAsComptroller, '_supportMarket', [cToken._address], { from: accounts[1] }) + await send(unitrollerAsComptroller, '_supportMarket', [slToken._address], { from: accounts[1] }) ).toHaveTrollFailure('UNAUTHORIZED', 'SUPPORT_MARKET_OWNER_CHECK'); }); - it('fails if asset is not a CToken', async () => { - const notACToken = await makePriceOracle(); - await expect(send(unitrollerAsComptroller, '_supportMarket', [notACToken._address])).rejects.toRevert(); + it('fails if asset is not a SLToken', async () => { + const notASLToken = await makePriceOracle(); + await expect(send(unitrollerAsComptroller, '_supportMarket', [notASLToken._address])).rejects.toRevert(); }); it('succeeds and sets market', async () => { - const result = await send(unitrollerAsComptroller, '_supportMarket', [cToken._address]); - expect(result).toHaveLog('MarketListed', { cToken: cToken._address }); + const result = await send(unitrollerAsComptroller, '_supportMarket', [slToken._address]); + expect(result).toHaveLog('MarketListed', { slToken: slToken._address }); }); it('cannot list a market a second time', async () => { - const result1 = await send(unitrollerAsComptroller, '_supportMarket', [cToken._address]); - const result2 = await send(unitrollerAsComptroller, '_supportMarket', [cToken._address]); - expect(result1).toHaveLog('MarketListed', { cToken: cToken._address }); + const result1 = await send(unitrollerAsComptroller, '_supportMarket', [slToken._address]); + const result2 = await send(unitrollerAsComptroller, '_supportMarket', [slToken._address]); + expect(result1).toHaveLog('MarketListed', { slToken: slToken._address }); expect(result2).toHaveTrollFailure('MARKET_ALREADY_LISTED', 'SUPPORT_MARKET_EXISTS'); }); it('can list two different markets', async () => { - const cToken1 = await makeCToken({ comptroller: unitroller }); - const cToken2 = await makeCToken({ comptroller: unitroller }); - const result1 = await send(unitrollerAsComptroller, '_supportMarket', [cToken1._address]); - const result2 = await send(unitrollerAsComptroller, '_supportMarket', [cToken2._address]); - expect(result1).toHaveLog('MarketListed', { cToken: cToken1._address }); - expect(result2).toHaveLog('MarketListed', { cToken: cToken2._address }); + const slToken1 = await makeSLToken({ comptroller: unitroller }); + const slToken2 = await makeSLToken({ comptroller: unitroller }); + const result1 = await send(unitrollerAsComptroller, '_supportMarket', [slToken1._address]); + const result2 = await send(unitrollerAsComptroller, '_supportMarket', [slToken2._address]); + expect(result1).toHaveLog('MarketListed', { slToken: slToken1._address }); + expect(result2).toHaveLog('MarketListed', { slToken: slToken2._address }); }); }); }); diff --git a/tests/Comptroller/unitrollerTest.js b/tests/Comptroller/unitrollerTest.js index 64b5b903d..645203290 100644 --- a/tests/Comptroller/unitrollerTest.js +++ b/tests/Comptroller/unitrollerTest.js @@ -6,7 +6,7 @@ const { const { makeComptroller, makePriceOracle -} = require('../Utils/Compound'); +} = require('../Utils/SashimiLending'); describe('Unitroller', () => { let root, accounts; diff --git a/tests/Contracts/CompHarness.sol b/tests/Contracts/CompHarness.sol deleted file mode 100644 index 55fa4e3c3..000000000 --- a/tests/Contracts/CompHarness.sol +++ /dev/null @@ -1,30 +0,0 @@ -pragma solidity ^0.5.16; -pragma experimental ABIEncoderV2; - -import "../../contracts/Governance/Comp.sol"; - -contract CompScenario is Comp { - constructor(address account) Comp(account) public {} - - function transferScenario(address[] calldata destinations, uint256 amount) external returns (bool) { - for (uint i = 0; i < destinations.length; i++) { - address dst = destinations[i]; - _transferTokens(msg.sender, dst, uint96(amount)); - } - return true; - } - - function transferFromScenario(address[] calldata froms, uint256 amount) external returns (bool) { - for (uint i = 0; i < froms.length; i++) { - address from = froms[i]; - _transferTokens(from, msg.sender, uint96(amount)); - } - return true; - } - - function generateCheckpoints(uint count, uint offset) external { - for (uint i = 1 + offset; i <= count + offset; i++) { - checkpoints[msg.sender][numCheckpoints[msg.sender]++] = Checkpoint(uint32(i), uint96(i)); - } - } -} diff --git a/tests/Contracts/ComptrollerHarness.sol b/tests/Contracts/ComptrollerHarness.sol index 7e5812c0c..7481a08c4 100644 --- a/tests/Contracts/ComptrollerHarness.sol +++ b/tests/Contracts/ComptrollerHarness.sol @@ -4,19 +4,19 @@ import "../../contracts/Comptroller.sol"; import "../../contracts/PriceOracle.sol"; contract ComptrollerKovan is Comptroller { - function getCompAddress() public view returns (address) { + function getSashimiAddress() public view returns (address) { return 0x61460874a7196d6a22D1eE4922473664b3E95270; } } contract ComptrollerRopsten is Comptroller { - function getCompAddress() public view returns (address) { + function getSashimiAddress() public view returns (address) { return 0x1Fe16De955718CFAb7A44605458AB023838C2793; } } contract ComptrollerHarness is Comptroller { - address compAddress; + address sashimiAddress; uint public blockNumber; constructor() Comptroller() public {} @@ -25,58 +25,58 @@ contract ComptrollerHarness is Comptroller { pauseGuardian = harnessedPauseGuardian; } - function setCompSupplyState(address cToken, uint224 index, uint32 blockNumber_) public { - compSupplyState[cToken].index = index; - compSupplyState[cToken].block = blockNumber_; + function setSashimiSupplyState(address slToken, uint224 index, uint32 blockNumber_) public { + sashimiSupplyState[slToken].index = index; + sashimiSupplyState[slToken].block = blockNumber_; } - function setCompBorrowState(address cToken, uint224 index, uint32 blockNumber_) public { - compBorrowState[cToken].index = index; - compBorrowState[cToken].block = blockNumber_; + function setSashimiBorrowState(address slToken, uint224 index, uint32 blockNumber_) public { + sashimiBorrowState[slToken].index = index; + sashimiBorrowState[slToken].block = blockNumber_; } - function setCompAccrued(address user, uint userAccrued) public { - compAccrued[user] = userAccrued; + function setSashimiAccrued(address user, uint userAccrued) public { + sashimiAccrued[user] = userAccrued; } - function setCompAddress(address compAddress_) public { - compAddress = compAddress_; + function setSashimiAddress(address sashimiAddress_) public { + sashimiAddress = sashimiAddress_; } - function getCompAddress() public view returns (address) { - return compAddress; + function getSashimiAddress() public view returns (address) { + return sashimiAddress; } - function setCompSpeed(address cToken, uint compSpeed) public { - compSpeeds[cToken] = compSpeed; + function setSashimiSpeed(address slToken, uint sashimiSpeed) public { + sashimiSpeeds[slToken] = sashimiSpeed; } - function setCompBorrowerIndex(address cToken, address borrower, uint index) public { - compBorrowerIndex[cToken][borrower] = index; + function setSashimiBorrowerIndex(address slToken, address borrower, uint index) public { + sashimiBorrowerIndex[slToken][borrower] = index; } - function setCompSupplierIndex(address cToken, address supplier, uint index) public { - compSupplierIndex[cToken][supplier] = index; + function setSashimiSupplierIndex(address slToken, address supplier, uint index) public { + sashimiSupplierIndex[slToken][supplier] = index; } - function harnessUpdateCompBorrowIndex(address cToken, uint marketBorrowIndexMantissa) public { - updateCompBorrowIndex(cToken, Exp({mantissa: marketBorrowIndexMantissa})); + function harnessUpdateSashimiBorrowIndex(address slToken, uint marketBorrowIndexMantissa) public { + updateSashimiBorrowIndex(slToken, Exp({mantissa: marketBorrowIndexMantissa})); } - function harnessUpdateCompSupplyIndex(address cToken) public { - updateCompSupplyIndex(cToken); + function harnessUpdateSashimiSupplyIndex(address slToken) public { + updateSashimiSupplyIndex(slToken); } - function harnessDistributeBorrowerComp(address cToken, address borrower, uint marketBorrowIndexMantissa) public { - distributeBorrowerComp(cToken, borrower, Exp({mantissa: marketBorrowIndexMantissa}), false); + function harnessDistributeBorrowerSashimi(address slToken, address borrower, uint marketBorrowIndexMantissa) public { + distributeBorrowerSashimi(slToken, borrower, Exp({mantissa: marketBorrowIndexMantissa}), false); } - function harnessDistributeSupplierComp(address cToken, address supplier) public { - distributeSupplierComp(cToken, supplier, false); + function harnessDistributeSupplierSashimi(address slToken, address supplier) public { + distributeSupplierSashimi(slToken, supplier, false); } - function harnessTransferComp(address user, uint userAccrued, uint threshold) public returns (uint) { - return transferComp(user, userAccrued, threshold); + function harnessTransferSashimi(address user, uint userAccrued, uint threshold) public returns (uint) { + return transferSashimi(user, userAccrued, threshold); } function harnessFastForward(uint blocks) public returns (uint) { @@ -92,23 +92,23 @@ contract ComptrollerHarness is Comptroller { return blockNumber; } - function getCompMarkets() public view returns (address[] memory) { + function getSashimiMarkets() public view returns (address[] memory) { uint m = allMarkets.length; uint n = 0; for (uint i = 0; i < m; i++) { - if (markets[address(allMarkets[i])].isComped) { + if (markets[address(allMarkets[i])].isSashimied) { n++; } } - address[] memory compMarkets = new address[](n); + address[] memory sashimiMarkets = new address[](n); uint k = 0; for (uint i = 0; i < m; i++) { - if (markets[address(allMarkets[i])].isComped) { - compMarkets[k++] = address(allMarkets[i]); + if (markets[address(allMarkets[i])].isSashimied) { + sashimiMarkets[k++] = address(allMarkets[i]); } } - return compMarkets; + return sashimiMarkets; } } @@ -149,69 +149,69 @@ contract BoolComptroller is ComptrollerInterface { /*** Assets You Are In ***/ - function enterMarkets(address[] calldata _cTokens) external returns (uint[] memory) { - _cTokens; + function enterMarkets(address[] calldata _slTokens) external returns (uint[] memory) { + _slTokens; uint[] memory ret; return ret; } - function exitMarket(address _cToken) external returns (uint) { - _cToken; + function exitMarket(address _slToken) external returns (uint) { + _slToken; return noError; } /*** Policy Hooks ***/ - function mintAllowed(address _cToken, address _minter, uint _mintAmount) public returns (uint) { - _cToken; + function mintAllowed(address _slToken, address _minter, uint _mintAmount) public returns (uint) { + _slToken; _minter; _mintAmount; return allowMint ? noError : opaqueError; } - function mintVerify(address _cToken, address _minter, uint _mintAmount, uint _mintTokens) external { - _cToken; + function mintVerify(address _slToken, address _minter, uint _mintAmount, uint _mintTokens) external { + _slToken; _minter; _mintAmount; _mintTokens; require(verifyMint, "mintVerify rejected mint"); } - function redeemAllowed(address _cToken, address _redeemer, uint _redeemTokens) public returns (uint) { - _cToken; + function redeemAllowed(address _slToken, address _redeemer, uint _redeemTokens) public returns (uint) { + _slToken; _redeemer; _redeemTokens; return allowRedeem ? noError : opaqueError; } - function redeemVerify(address _cToken, address _redeemer, uint _redeemAmount, uint _redeemTokens) external { - _cToken; + function redeemVerify(address _slToken, address _redeemer, uint _redeemAmount, uint _redeemTokens) external { + _slToken; _redeemer; _redeemAmount; _redeemTokens; require(verifyRedeem, "redeemVerify rejected redeem"); } - function borrowAllowed(address _cToken, address _borrower, uint _borrowAmount) public returns (uint) { - _cToken; + function borrowAllowed(address _slToken, address _borrower, uint _borrowAmount) public returns (uint) { + _slToken; _borrower; _borrowAmount; return allowBorrow ? noError : opaqueError; } - function borrowVerify(address _cToken, address _borrower, uint _borrowAmount) external { - _cToken; + function borrowVerify(address _slToken, address _borrower, uint _borrowAmount) external { + _slToken; _borrower; _borrowAmount; require(verifyBorrow, "borrowVerify rejected borrow"); } function repayBorrowAllowed( - address _cToken, + address _slToken, address _payer, address _borrower, uint _repayAmount) public returns (uint) { - _cToken; + _slToken; _payer; _borrower; _repayAmount; @@ -219,12 +219,12 @@ contract BoolComptroller is ComptrollerInterface { } function repayBorrowVerify( - address _cToken, + address _slToken, address _payer, address _borrower, uint _repayAmount, uint _borrowerIndex) external { - _cToken; + _slToken; _payer; _borrower; _repayAmount; @@ -233,13 +233,13 @@ contract BoolComptroller is ComptrollerInterface { } function liquidateBorrowAllowed( - address _cTokenBorrowed, - address _cTokenCollateral, + address _slTokenBorrowed, + address _slTokenCollateral, address _liquidator, address _borrower, uint _repayAmount) public returns (uint) { - _cTokenBorrowed; - _cTokenCollateral; + _slTokenBorrowed; + _slTokenCollateral; _liquidator; _borrower; _repayAmount; @@ -247,14 +247,14 @@ contract BoolComptroller is ComptrollerInterface { } function liquidateBorrowVerify( - address _cTokenBorrowed, - address _cTokenCollateral, + address _slTokenBorrowed, + address _slTokenCollateral, address _liquidator, address _borrower, uint _repayAmount, uint _seizeTokens) external { - _cTokenBorrowed; - _cTokenCollateral; + _slTokenBorrowed; + _slTokenCollateral; _liquidator; _borrower; _repayAmount; @@ -263,13 +263,13 @@ contract BoolComptroller is ComptrollerInterface { } function seizeAllowed( - address _cTokenCollateral, - address _cTokenBorrowed, + address _slTokenCollateral, + address _slTokenBorrowed, address _borrower, address _liquidator, uint _seizeTokens) public returns (uint) { - _cTokenCollateral; - _cTokenBorrowed; + _slTokenCollateral; + _slTokenBorrowed; _liquidator; _borrower; _seizeTokens; @@ -277,13 +277,13 @@ contract BoolComptroller is ComptrollerInterface { } function seizeVerify( - address _cTokenCollateral, - address _cTokenBorrowed, + address _slTokenCollateral, + address _slTokenBorrowed, address _liquidator, address _borrower, uint _seizeTokens) external { - _cTokenCollateral; - _cTokenBorrowed; + _slTokenCollateral; + _slTokenBorrowed; _liquidator; _borrower; _seizeTokens; @@ -291,11 +291,11 @@ contract BoolComptroller is ComptrollerInterface { } function transferAllowed( - address _cToken, + address _slToken, address _src, address _dst, uint _transferTokens) public returns (uint) { - _cToken; + _slToken; _src; _dst; _transferTokens; @@ -303,11 +303,11 @@ contract BoolComptroller is ComptrollerInterface { } function transferVerify( - address _cToken, + address _slToken, address _src, address _dst, uint _transferTokens) external { - _cToken; + _slToken; _src; _dst; _transferTokens; @@ -317,11 +317,11 @@ contract BoolComptroller is ComptrollerInterface { /*** Special Liquidation Calculation ***/ function liquidateCalculateSeizeTokens( - address _cTokenBorrowed, - address _cTokenCollateral, + address _slTokenBorrowed, + address _slTokenCollateral, uint _repayAmount) public view returns (uint, uint) { - _cTokenBorrowed; - _cTokenCollateral; + _slTokenBorrowed; + _slTokenCollateral; _repayAmount; return failCalculateSeizeTokens ? (opaqueError, 0) : (noError, calculatedSeizeTokens); } diff --git a/tests/Contracts/ComptrollerScenario.sol b/tests/Contracts/ComptrollerScenario.sol index 4c6b189ed..ec60fe687 100644 --- a/tests/Contracts/ComptrollerScenario.sol +++ b/tests/Contracts/ComptrollerScenario.sol @@ -16,11 +16,11 @@ contract ComptrollerScenario is Comptroller { blockNumber = number; } - function membershipLength(CToken cToken) public view returns (uint) { - return accountAssets[address(cToken)].length; + function membershipLength(SLToken slToken) public view returns (uint) { + return accountAssets[address(slToken)].length; } - function unlist(CToken cToken) public { - markets[address(cToken)].isListed = false; + function unlist(SLToken slToken) public { + markets[address(slToken)].isListed = false; } } diff --git a/tests/Contracts/ComptrollerScenarioG1.sol b/tests/Contracts/ComptrollerScenarioG1.sol index 9850f3f1b..000c6da90 100644 --- a/tests/Contracts/ComptrollerScenarioG1.sol +++ b/tests/Contracts/ComptrollerScenarioG1.sol @@ -11,8 +11,8 @@ contract ComptrollerScenarioG1 is ComptrollerG1 { constructor() ComptrollerG1() public {} - function membershipLength(CToken cToken) public view returns (uint) { - return accountAssets[address(cToken)].length; + function membershipLength(SLToken slToken) public view returns (uint) { + return accountAssets[address(slToken)].length; } function fastForward(uint blocks) public returns (uint) { @@ -36,15 +36,15 @@ contract ComptrollerScenarioG1 is ComptrollerG1 { function getHypotheticalAccountLiquidity( address account, - address cTokenModify, + address slTokenModify, uint redeemTokens, uint borrowAmount) public view returns (uint, uint, uint) { (Error err, uint liquidity, uint shortfall) = - super.getHypotheticalAccountLiquidityInternal(account, CToken(cTokenModify), redeemTokens, borrowAmount); + super.getHypotheticalAccountLiquidityInternal(account, SLToken(slTokenModify), redeemTokens, borrowAmount); return (uint(err), liquidity, shortfall); } - function unlist(CToken cToken) public { - markets[address(cToken)].isListed = false; + function unlist(SLToken slToken) public { + markets[address(slToken)].isListed = false; } } diff --git a/tests/Contracts/ComptrollerScenarioG3.sol b/tests/Contracts/ComptrollerScenarioG3.sol index 6b4d17ebf..36e2fd2b5 100644 --- a/tests/Contracts/ComptrollerScenarioG3.sol +++ b/tests/Contracts/ComptrollerScenarioG3.sol @@ -4,20 +4,20 @@ import "../../contracts/ComptrollerG3.sol"; contract ComptrollerScenarioG3 is ComptrollerG3 { uint public blockNumber; - address public compAddress; + address public sashimiAddress; constructor() ComptrollerG3() public {} - function setCompAddress(address compAddress_) public { - compAddress = compAddress_; + function setSashimiAddress(address sashimiAddress_) public { + sashimiAddress = sashimiAddress_; } - function getCompAddress() public view returns (address) { - return compAddress; + function getSashimiAddress() public view returns (address) { + return sashimiAddress; } - function membershipLength(CToken cToken) public view returns (uint) { - return accountAssets[address(cToken)].length; + function membershipLength(SLToken slToken) public view returns (uint) { + return accountAssets[address(slToken)].length; } function fastForward(uint blocks) public returns (uint) { @@ -34,26 +34,26 @@ contract ComptrollerScenarioG3 is ComptrollerG3 { return blockNumber; } - function getCompMarkets() public view returns (address[] memory) { + function getSashimiMarkets() public view returns (address[] memory) { uint m = allMarkets.length; uint n = 0; for (uint i = 0; i < m; i++) { - if (markets[address(allMarkets[i])].isComped) { + if (markets[address(allMarkets[i])].isSashimied) { n++; } } - address[] memory compMarkets = new address[](n); + address[] memory sashimiMarkets = new address[](n); uint k = 0; for (uint i = 0; i < m; i++) { - if (markets[address(allMarkets[i])].isComped) { - compMarkets[k++] = address(allMarkets[i]); + if (markets[address(allMarkets[i])].isSashimied) { + sashimiMarkets[k++] = address(allMarkets[i]); } } - return compMarkets; + return sashimiMarkets; } - function unlist(CToken cToken) public { - markets[address(cToken)].isListed = false; + function unlist(SLToken slToken) public { + markets[address(slToken)].isListed = false; } } diff --git a/tests/Contracts/ComptrollerScenarioG4.sol b/tests/Contracts/ComptrollerScenarioG4.sol index 59419bd90..32f2047bf 100644 --- a/tests/Contracts/ComptrollerScenarioG4.sol +++ b/tests/Contracts/ComptrollerScenarioG4.sol @@ -16,11 +16,11 @@ contract ComptrollerScenarioG4 is ComptrollerG4 { blockNumber = number; } - function membershipLength(CToken cToken) public view returns (uint) { - return accountAssets[address(cToken)].length; + function membershipLength(SLToken slToken) public view returns (uint) { + return accountAssets[address(slToken)].length; } - function unlist(CToken cToken) public { - markets[address(cToken)].isListed = false; + function unlist(SLToken slToken) public { + markets[address(slToken)].isListed = false; } } diff --git a/tests/Contracts/FixedPriceOracle.sol b/tests/Contracts/FixedPriceOracle.sol index 1306d5095..ba0604f5b 100644 --- a/tests/Contracts/FixedPriceOracle.sol +++ b/tests/Contracts/FixedPriceOracle.sol @@ -9,8 +9,8 @@ contract FixedPriceOracle is PriceOracle { price = _price; } - function getUnderlyingPrice(CToken cToken) public view returns (uint) { - cToken; + function getUnderlyingPrice(SLToken slToken) public view returns (uint) { + slToken; return price; } diff --git a/tests/Contracts/GovernorAlphaHarness.sol b/tests/Contracts/GovernorAlphaHarness.sol deleted file mode 100644 index fc0179220..000000000 --- a/tests/Contracts/GovernorAlphaHarness.sol +++ /dev/null @@ -1,10 +0,0 @@ -pragma solidity ^0.5.16; -pragma experimental ABIEncoderV2; - -import "../../contracts/Governance/GovernorAlpha.sol"; - -contract GovernorAlphaHarness is GovernorAlpha { - constructor(address timelock_, address comp_, address guardian_) GovernorAlpha(timelock_, comp_, guardian_) public {} - - function votingPeriod() public pure returns (uint) { return 240; } -} diff --git a/tests/Contracts/PriceOracleProxy.sol b/tests/Contracts/PriceOracleProxy.sol index 666d84887..443c01014 100644 --- a/tests/Contracts/PriceOracleProxy.sol +++ b/tests/Contracts/PriceOracleProxy.sol @@ -1,7 +1,7 @@ pragma solidity ^0.5.16; -import "../../contracts/CErc20.sol"; -import "../../contracts/CToken.sol"; +import "../../contracts/SLErc20.sol"; +import "../../contracts/SLToken.sol"; import "../../contracts/PriceOracle.sol"; interface V1PriceOracleInterface { @@ -18,20 +18,20 @@ contract PriceOracleProxy is PriceOracle { /// @notice Address of the guardian, which may set the SAI price once address public guardian; - /// @notice Address of the cEther contract, which has a constant price - address public cEthAddress; + /// @notice Address of the slEther contract, which has a constant price + address public slEthAddress; - /// @notice Address of the cUSDC contract, which we hand pick a key for - address public cUsdcAddress; + /// @notice Address of the slUSDC contract, which we hand pick a key for + address public slUsdcAddress; - /// @notice Address of the cUSDT contract, which uses the cUSDC price - address public cUsdtAddress; + /// @notice Address of the slUSDT contract, which uses the slUSDC price + address public slUsdtAddress; - /// @notice Address of the cSAI contract, which may have its price set - address public cSaiAddress; + /// @notice Address of the slSAI contract, which may have its price set + address public slSaiAddress; - /// @notice Address of the cDAI contract, which we hand pick a key for - address public cDaiAddress; + /// @notice Address of the slDAI contract, which we hand pick a key for + address public slDaiAddress; /// @notice Handpicked key for USDC address public constant usdcOracleKey = address(1); @@ -45,57 +45,57 @@ contract PriceOracleProxy is PriceOracle { /** * @param guardian_ The address of the guardian, which may set the SAI price once * @param v1PriceOracle_ The address of the v1 price oracle, which will continue to operate and hold prices for collateral assets - * @param cEthAddress_ The address of cETH, which will return a constant 1e18, since all prices relative to ether - * @param cUsdcAddress_ The address of cUSDC, which will be read from a special oracle key - * @param cSaiAddress_ The address of cSAI, which may be read directly from storage - * @param cDaiAddress_ The address of cDAI, which will be read from a special oracle key - * @param cUsdtAddress_ The address of cUSDT, which uses the cUSDC price + * @param slEthAddress_ The address of slETH, which will return a constant 1e18, since all prices relative to ether + * @param slUsdcAddress_ The address of cUSDC, which will be read from a special oracle key + * @param slSaiAddress_ The address of cSAI, which may be read directly from storage + * @param slDaiAddress_ The address of cDAI, which will be read from a special oracle key + * @param slUsdtAddress_ The address of cUSDT, which uses the cUSDC price */ constructor(address guardian_, address v1PriceOracle_, - address cEthAddress_, - address cUsdcAddress_, - address cSaiAddress_, - address cDaiAddress_, - address cUsdtAddress_) public { + address slEthAddress_, + address slUsdcAddress_, + address slSaiAddress_, + address slDaiAddress_, + address slUsdtAddress_) public { guardian = guardian_; v1PriceOracle = V1PriceOracleInterface(v1PriceOracle_); - cEthAddress = cEthAddress_; - cUsdcAddress = cUsdcAddress_; - cSaiAddress = cSaiAddress_; - cDaiAddress = cDaiAddress_; - cUsdtAddress = cUsdtAddress_; + slEthAddress = slEthAddress_; + slUsdcAddress = slUsdcAddress_; + slSaiAddress = slSaiAddress_; + slDaiAddress = slDaiAddress_; + slUsdtAddress = slUsdtAddress_; } /** - * @notice Get the underlying price of a listed cToken asset - * @param cToken The cToken to get the underlying price of + * @notice Get the underlying price of a listed slToken asset + * @param slToken The slToken to get the underlying price of * @return The underlying asset price mantissa (scaled by 1e18) */ - function getUnderlyingPrice(CToken cToken) public view returns (uint) { - address cTokenAddress = address(cToken); + function getUnderlyingPrice(SLToken slToken) public view returns (uint) { + address slTokenAddress = address(slToken); - if (cTokenAddress == cEthAddress) { + if (slTokenAddress == slEthAddress) { // ether always worth 1 return 1e18; } - if (cTokenAddress == cUsdcAddress || cTokenAddress == cUsdtAddress) { + if (slTokenAddress == slUsdcAddress || slTokenAddress == slUsdtAddress) { return v1PriceOracle.assetPrices(usdcOracleKey); } - if (cTokenAddress == cDaiAddress) { + if (slTokenAddress == slDaiAddress) { return v1PriceOracle.assetPrices(daiOracleKey); } - if (cTokenAddress == cSaiAddress) { + if (slTokenAddress == slSaiAddress) { // use the frozen SAI price if set, otherwise use the DAI price return saiPrice > 0 ? saiPrice : v1PriceOracle.assetPrices(daiOracleKey); } // otherwise just read from v1 oracle - address underlying = CErc20(cTokenAddress).underlying(); + address underlying = SLErc20(slTokenAddress).underlying(); return v1PriceOracle.assetPrices(underlying); } diff --git a/tests/Contracts/RefreshSpeedsProxy.sol b/tests/Contracts/RefreshSpeedsProxy.sol index 6b6438545..104704e24 100644 --- a/tests/Contracts/RefreshSpeedsProxy.sol +++ b/tests/Contracts/RefreshSpeedsProxy.sol @@ -1,11 +1,11 @@ pragma solidity ^0.5.16; interface IComptroller { - function refreshCompSpeeds() external; + function refreshSashimiSpeeds() external; } contract RefreshSpeedsProxy { constructor(address comptroller) public { - IComptroller(comptroller).refreshCompSpeeds(); + IComptroller(comptroller).refreshSashimiSpeeds(); } } diff --git a/tests/Contracts/CErc20Harness.sol b/tests/Contracts/SLErc20Harness.sol similarity index 90% rename from tests/Contracts/CErc20Harness.sol rename to tests/Contracts/SLErc20Harness.sol index 116582a5d..8b0b1ada7 100644 --- a/tests/Contracts/CErc20Harness.sol +++ b/tests/Contracts/SLErc20Harness.sol @@ -1,12 +1,12 @@ pragma solidity ^0.5.16; -import "../../contracts/CErc20Immutable.sol"; -import "../../contracts/CErc20Delegator.sol"; -import "../../contracts/CErc20Delegate.sol"; -import "../../contracts/CDaiDelegate.sol"; +import "../../contracts/SLErc20Immutable.sol"; +import "../../contracts/SLErc20Delegator.sol"; +import "../../contracts/SLErc20Delegate.sol"; +import "../../contracts/SLDaiDelegate.sol"; import "./ComptrollerScenario.sol"; -contract CErc20Harness is CErc20Immutable { +contract SLErc20Harness is SLErc20Immutable { uint blockNumber = 100000; uint harnessExchangeRate; bool harnessExchangeRateStored; @@ -21,7 +21,7 @@ contract CErc20Harness is CErc20Immutable { string memory symbol_, uint8 decimals_, address payable admin_) - CErc20Immutable( + SLErc20Immutable( underlying_, comptroller_, interestRateModel_, @@ -99,8 +99,8 @@ contract CErc20Harness is CErc20Immutable { return err; } - function harnessRedeemFresh(address payable account, uint cTokenAmount, uint underlyingAmount) public returns (uint) { - return super.redeemFresh(account, cTokenAmount, underlyingAmount); + function harnessRedeemFresh(address payable account, uint slTokenAmount, uint underlyingAmount) public returns (uint) { + return super.redeemFresh(account, slTokenAmount, underlyingAmount); } function harnessAccountBorrows(address account) public view returns (uint principal, uint interestIndex) { @@ -125,8 +125,8 @@ contract CErc20Harness is CErc20Immutable { return err; } - function harnessLiquidateBorrowFresh(address liquidator, address borrower, uint repayAmount, CToken cTokenCollateral) public returns (uint) { - (uint err,) = liquidateBorrowFresh(liquidator, borrower, repayAmount, cTokenCollateral); + function harnessLiquidateBorrowFresh(address liquidator, address borrower, uint repayAmount, SLToken slTokenCollateral) public returns (uint) { + (uint err,) = liquidateBorrowFresh(liquidator, borrower, repayAmount, slTokenCollateral); return err; } @@ -151,7 +151,7 @@ contract CErc20Harness is CErc20Immutable { } } -contract CErc20Scenario is CErc20Immutable { +contract SLErc20Scenario is SLErc20Immutable { constructor(address underlying_, ComptrollerInterface comptroller_, InterestRateModel interestRateModel_, @@ -160,7 +160,7 @@ contract CErc20Scenario is CErc20Immutable { string memory symbol_, uint8 decimals_, address payable admin_) - CErc20Immutable( + SLErc20Immutable( underlying_, comptroller_, interestRateModel_, @@ -184,7 +184,7 @@ contract CErc20Scenario is CErc20Immutable { } } -contract CEvil is CErc20Scenario { +contract SLEvil is SLErc20Scenario { constructor(address underlying_, ComptrollerInterface comptroller_, InterestRateModel interestRateModel_, @@ -193,7 +193,7 @@ contract CEvil is CErc20Scenario { string memory symbol_, uint8 decimals_, address payable admin_) - CErc20Scenario( + SLErc20Scenario( underlying_, comptroller_, interestRateModel_, @@ -203,12 +203,12 @@ contract CEvil is CErc20Scenario { decimals_, admin_) public {} - function evilSeize(CToken treasure, address liquidator, address borrower, uint seizeTokens) public returns (uint) { + function evilSeize(SLToken treasure, address liquidator, address borrower, uint seizeTokens) public returns (uint) { return treasure.seize(liquidator, borrower, seizeTokens); } } -contract CErc20DelegatorScenario is CErc20Delegator { +contract SLErc20DelegatorScenario is SLErc20Delegator { constructor(address underlying_, ComptrollerInterface comptroller_, InterestRateModel interestRateModel_, @@ -219,7 +219,7 @@ contract CErc20DelegatorScenario is CErc20Delegator { address payable admin_, address implementation_, bytes memory becomeImplementationData) - CErc20Delegator( + SLErc20Delegator( underlying_, comptroller_, interestRateModel_, @@ -240,7 +240,7 @@ contract CErc20DelegatorScenario is CErc20Delegator { } } -contract CErc20DelegateHarness is CErc20Delegate { +contract SLErc20DelegateHarness is SLErc20Delegate { event Log(string x, address y); event Log(string x, uint y); @@ -322,8 +322,8 @@ contract CErc20DelegateHarness is CErc20Delegate { return err; } - function harnessRedeemFresh(address payable account, uint cTokenAmount, uint underlyingAmount) public returns (uint) { - return super.redeemFresh(account, cTokenAmount, underlyingAmount); + function harnessRedeemFresh(address payable account, uint slTokenAmount, uint underlyingAmount) public returns (uint) { + return super.redeemFresh(account, slTokenAmount, underlyingAmount); } function harnessAccountBorrows(address account) public view returns (uint principal, uint interestIndex) { @@ -348,8 +348,8 @@ contract CErc20DelegateHarness is CErc20Delegate { return err; } - function harnessLiquidateBorrowFresh(address liquidator, address borrower, uint repayAmount, CToken cTokenCollateral) public returns (uint) { - (uint err,) = liquidateBorrowFresh(liquidator, borrower, repayAmount, cTokenCollateral); + function harnessLiquidateBorrowFresh(address liquidator, address borrower, uint repayAmount, SLToken slTokenCollateral) public returns (uint) { + (uint err,) = liquidateBorrowFresh(liquidator, borrower, repayAmount, slTokenCollateral); return err; } @@ -374,7 +374,7 @@ contract CErc20DelegateHarness is CErc20Delegate { } } -contract CErc20DelegateScenario is CErc20Delegate { +contract SLErc20DelegateScenario is SLErc20Delegate { constructor() public {} function setTotalBorrows(uint totalBorrows_) public { @@ -391,7 +391,7 @@ contract CErc20DelegateScenario is CErc20Delegate { } } -contract CErc20DelegateScenarioExtra is CErc20DelegateScenario { +contract SLErc20DelegateScenarioExtra is SLErc20DelegateScenario { function iHaveSpoken() public pure returns (string memory) { return "i have spoken"; } @@ -405,7 +405,7 @@ contract CErc20DelegateScenarioExtra is CErc20DelegateScenario { } } -contract CDaiDelegateHarness is CDaiDelegate { +contract SLDaiDelegateHarness is SLDaiDelegate { uint blockNumber = 100000; uint harnessExchangeRate; bool harnessExchangeRateStored; @@ -440,7 +440,7 @@ contract CDaiDelegateHarness is CDaiDelegate { } } -contract CDaiDelegateScenario is CDaiDelegate { +contract SLDaiDelegateScenario is SLDaiDelegate { function setTotalBorrows(uint totalBorrows_) public { totalBorrows = totalBorrows_; } @@ -455,7 +455,7 @@ contract CDaiDelegateScenario is CDaiDelegate { } } -contract CDaiDelegateMakerHarness is PotLike, VatLike, GemLike, DaiJoinLike { +contract SLDaiDelegateMakerHarness is PotLike, VatLike, GemLike, DaiJoinLike { /* Pot */ // exchangeRate diff --git a/tests/Contracts/CEtherHarness.sol b/tests/Contracts/SLEtherHarness.sol similarity index 92% rename from tests/Contracts/CEtherHarness.sol rename to tests/Contracts/SLEtherHarness.sol index 4d494cf0a..c142421e4 100644 --- a/tests/Contracts/CEtherHarness.sol +++ b/tests/Contracts/SLEtherHarness.sol @@ -1,9 +1,9 @@ pragma solidity ^0.5.16; -import "../../contracts/CEther.sol"; +import "../../contracts/SLEther.sol"; import "./ComptrollerScenario.sol"; -contract CEtherHarness is CEther { +contract SLEtherHarness is SLEther { uint harnessExchangeRate; uint public blockNumber = 100000; @@ -16,7 +16,7 @@ contract CEtherHarness is CEther { string memory symbol_, uint8 decimals_, address payable admin_) - CEther( + SLEther( comptroller_, interestRateModel_, initialExchangeRateMantissa, @@ -88,8 +88,8 @@ contract CEtherHarness is CEther { return err; } - function harnessRedeemFresh(address payable account, uint cTokenAmount, uint underlyingAmount) public returns (uint) { - return super.redeemFresh(account, cTokenAmount, underlyingAmount); + function harnessRedeemFresh(address payable account, uint slTokenAmount, uint underlyingAmount) public returns (uint) { + return super.redeemFresh(account, slTokenAmount, underlyingAmount); } function harnessAccountBorrows(address account) public view returns (uint principal, uint interestIndex) { @@ -114,8 +114,8 @@ contract CEtherHarness is CEther { return err; } - function harnessLiquidateBorrowFresh(address liquidator, address borrower, uint repayAmount, CToken cTokenCollateral) public returns (uint) { - (uint err,) = liquidateBorrowFresh(liquidator, borrower, repayAmount, cTokenCollateral); + function harnessLiquidateBorrowFresh(address liquidator, address borrower, uint repayAmount, SLToken slTokenCollateral) public returns (uint) { + (uint err,) = liquidateBorrowFresh(liquidator, borrower, repayAmount, slTokenCollateral); return err; } @@ -156,7 +156,7 @@ contract CEtherHarness is CEther { } } -contract CEtherScenario is CEther { +contract SLEtherScenario is SLEther { uint reserveFactor; constructor(string memory name_, @@ -166,7 +166,7 @@ contract CEtherScenario is CEther { ComptrollerInterface comptroller_, InterestRateModel interestRateModel_, uint initialExchangeRateMantissa) - CEther(comptroller_, + SLEther(comptroller_, interestRateModel_, initialExchangeRateMantissa, name_, diff --git a/tests/Contracts/SashimiToken.sol b/tests/Contracts/SashimiToken.sol new file mode 100644 index 000000000..f0b4be413 --- /dev/null +++ b/tests/Contracts/SashimiToken.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.5.17; + +import "./ERC20.sol"; + +contract SashimiToken is StandardToken(10000000000000000000000000, "SashimiToken", 18, "SASHIMI") { +} \ No newline at end of file diff --git a/tests/Contracts/WBTC.sol b/tests/Contracts/WBTC.sol index 9162c0823..d5e62f246 100644 --- a/tests/Contracts/WBTC.sol +++ b/tests/Contracts/WBTC.sol @@ -70,13 +70,13 @@ library SafeMath { } } -// File: openzeppelin-solidity/contracts/token/ERC20/BasicToken.sol +// File: openzeppelin-solidity/contracts/token/ERC20/BasislToken.sol /** * @title Basic token * @dev Basic version of StandardToken, with no allowances. */ -contract BasicToken is ERC20Basic { +contract BasislToken is ERC20Basic { using SafeMath for uint256; mapping(address => uint256) internal balances; @@ -146,7 +146,7 @@ contract ERC20 is ERC20Basic { * https://github.com/ethereum/EIPs/issues/20 * Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol */ -contract StandardToken is ERC20, BasicToken { +contract StandardToken is ERC20, BasislToken { mapping (address => mapping (address => uint256)) internal allowed; @@ -405,7 +405,7 @@ contract MintableToken is StandardToken, Ownable { * @title Burnable Token * @dev Token that can be irreversibly burned (destroyed). */ -contract BurnableToken is BasicToken { +contract BurnableToken is BasislToken { event Burn(address indexed burner, uint256 value); @@ -646,7 +646,7 @@ contract OwnableContract is CanReclaimToken, Claimable { } /* solhint-disable-li // File: contracts/token/WBTC.sol -contract WBTCToken is StandardToken, DetailedERC20("Wrapped BTC", "WBTC", 8), +contract WBTSLToken is StandardToken, DetailedERC20("Wrapped BTC", "WBTC", 8), MintableToken, BurnableToken, PausableToken, OwnableContract { function burn(uint value) public onlyOwner { diff --git a/tests/Flywheel/FlywheelTest.js b/tests/Flywheel/FlywheelTest.js index 33e16094b..92b1f0002 100644 --- a/tests/Flywheel/FlywheelTest.js +++ b/tests/Flywheel/FlywheelTest.js @@ -1,11 +1,11 @@ const { makeComptroller, - makeCToken, + makeSLToken, balanceOf, fastForward, pretendBorrow, quickMint -} = require('../Utils/Compound'); +} = require('../Utils/SashimiLending'); const { etherExp, etherDouble, @@ -13,48 +13,48 @@ const { etherMantissa } = require('../Utils/Ethereum'); -const compRate = etherUnsigned(1e18); +const sashimiRate = etherUnsigned(1e18); -async function compAccrued(comptroller, user) { - return etherUnsigned(await call(comptroller, 'compAccrued', [user])); +async function sashimiAccrued(comptroller, user) { + return etherUnsigned(await call(comptroller, 'sashimiAccrued', [user])); } -async function compBalance(comptroller, user) { - return etherUnsigned(await call(comptroller.comp, 'balanceOf', [user])) +async function sashimiBalance(comptroller, user) { + return etherUnsigned(await call(comptroller.sashimi, 'balanceOf', [user])) } -async function totalCompAccrued(comptroller, user) { - return (await compAccrued(comptroller, user)).add(await compBalance(comptroller, user)); +async function totalSashimiAccrued(comptroller, user) { + return (await sashimiAccrued(comptroller, user)).add(await sashimiBalance(comptroller, user)); } describe('Flywheel upgrade', () => { describe('becomes the comptroller', () => { - it('adds the comp markets', async () => { + it('adds the sashimi markets', async () => { let root = saddle.accounts[0]; let unitroller = await makeComptroller({kind: 'unitroller-g2'}); - let compMarkets = await Promise.all([1, 2, 3].map(async _ => { - return makeCToken({comptroller: unitroller, supportMarket: true}); + let sashimiMarkets = await Promise.all([1, 2, 3].map(async _ => { + return makeSLToken({comptroller: unitroller, supportMarket: true}); })); - compMarkets = compMarkets.map(c => c._address); - unitroller = await makeComptroller({kind: 'unitroller-g3', unitroller, compMarkets}); - expect(await call(unitroller, 'getCompMarkets')).toEqual(compMarkets); + sashimiMarkets = sashimiMarkets.map(c => c._address); + unitroller = await makeComptroller({kind: 'unitroller-g3', unitroller, sashimiMarkets}); + expect(await call(unitroller, 'getSashimiMarkets')).toEqual(sashimiMarkets); }); it('adds the other markets', async () => { let root = saddle.accounts[0]; let unitroller = await makeComptroller({kind: 'unitroller-g2'}); let allMarkets = await Promise.all([1, 2, 3].map(async _ => { - return makeCToken({comptroller: unitroller, supportMarket: true}); + return makeSLToken({comptroller: unitroller, supportMarket: true}); })); allMarkets = allMarkets.map(c => c._address); unitroller = await makeComptroller({ kind: 'unitroller-g3', unitroller, - compMarkets: allMarkets.slice(0, 1), + sashimiMarkets: allMarkets.slice(0, 1), otherMarkets: allMarkets.slice(1) }); expect(await call(unitroller, 'getAllMarkets')).toEqual(allMarkets); - expect(await call(unitroller, 'getCompMarkets')).toEqual(allMarkets.slice(0, 1)); + expect(await call(unitroller, 'getSashimiMarkets')).toEqual(allMarkets.slice(0, 1)); }); it('_supportMarket() adds to all markets, and only once', async () => { @@ -62,7 +62,7 @@ describe('Flywheel upgrade', () => { let unitroller = await makeComptroller({kind: 'unitroller-g3'}); let allMarkets = []; for (let _ of Array(10)) { - allMarkets.push(await makeCToken({comptroller: unitroller, supportMarket: true})); + allMarkets.push(await makeSLToken({comptroller: unitroller, supportMarket: true})); } expect(await call(unitroller, 'getAllMarkets')).toEqual(allMarkets.map(c => c._address)); expect( @@ -78,33 +78,33 @@ describe('Flywheel upgrade', () => { describe('Flywheel', () => { let root, a1, a2, a3, accounts; - let comptroller, cLOW, cREP, cZRX, cEVIL; + let comptroller, slLOW, slREP, slZRX, cEVIL; beforeEach(async () => { let interestRateModelOpts = {borrowRate: 0.000001}; [root, a1, a2, a3, ...accounts] = saddle.accounts; comptroller = await makeComptroller(); - cLOW = await makeCToken({comptroller, supportMarket: true, underlyingPrice: 1, interestRateModelOpts}); - cREP = await makeCToken({comptroller, supportMarket: true, underlyingPrice: 2, interestRateModelOpts}); - cZRX = await makeCToken({comptroller, supportMarket: true, underlyingPrice: 3, interestRateModelOpts}); - cEVIL = await makeCToken({comptroller, supportMarket: false, underlyingPrice: 3, interestRateModelOpts}); - await send(comptroller, '_addCompMarkets', [[cLOW, cREP, cZRX].map(c => c._address)]); + slLOW = await makeSLToken({comptroller, supportMarket: true, underlyingPrice: 1, interestRateModelOpts}); + slREP = await makeSLToken({comptroller, supportMarket: true, underlyingPrice: 2, interestRateModelOpts}); + slZRX = await makeSLToken({comptroller, supportMarket: true, underlyingPrice: 3, interestRateModelOpts}); + cEVIL = await makeSLToken({comptroller, supportMarket: false, underlyingPrice: 3, interestRateModelOpts}); + await send(comptroller, '_addSashimiMarkets', [[slLOW, slREP, slZRX].map(c => c._address)]); }); - describe('getCompMarkets()', () => { - it('should return the comp markets', async () => { - expect(await call(comptroller, 'getCompMarkets')).toEqual( - [cLOW, cREP, cZRX].map((c) => c._address) + describe('getSashimiMarkets()', () => { + it('should return the sashimi markets', async () => { + expect(await call(comptroller, 'getSashimiMarkets')).toEqual( + [slLOW, slREP, slZRX].map((c) => c._address) ); }); }); - describe('updateCompBorrowIndex()', () => { - it('should calculate comp borrower index correctly', async () => { - const mkt = cREP; + describe('updateSashimiBorrowIndex()', () => { + it('should calculate sashimi borrower index correctly', async () => { + const mkt = slREP; await send(comptroller, 'setBlockNumber', [100]); await send(mkt, 'harnessSetTotalBorrows', [etherUnsigned(11e18)]); - await send(comptroller, 'setCompSpeed', [mkt._address, etherExp(0.5)]); - await send(comptroller, 'harnessUpdateCompBorrowIndex', [ + await send(comptroller, 'setSashimiSpeed', [mkt._address, etherExp(0.5)]); + await send(comptroller, 'harnessUpdateSashimiBorrowIndex', [ mkt._address, etherExp(1.1), ]); @@ -113,146 +113,146 @@ describe('Flywheel', () => { borrowAmt = totalBorrows * 1e18 / borrowIdx = 11e18 * 1e18 / 1.1e18 = 10e18 - compAccrued = deltaBlocks * borrowSpeed + sashimiAccrued = deltaBlocks * borrowSpeed = 100 * 0.5e18 = 50e18 - newIndex += 1e36 + compAccrued * 1e36 / borrowAmt + newIndex += 1e36 + sashimiAccrued * 1e36 / borrowAmt = 1e36 + 50e18 * 1e36 / 10e18 = 6e36 */ - const {index, block} = await call(comptroller, 'compBorrowState', [mkt._address]); + const {index, block} = await call(comptroller, 'sashimiBorrowState', [mkt._address]); expect(index).toEqualNumber(6e36); expect(block).toEqualNumber(100); }); - it('should not revert or update compBorrowState index if cToken not in COMP markets', async () => { - const mkt = await makeCToken({ + it('should not revert or update sashimiBorrowState index if slToken not in SASHIMI markets', async () => { + const mkt = await makeSLToken({ comptroller: comptroller, supportMarket: true, - addCompMarket: false, + addSashimiMarket: false, }); await send(comptroller, 'setBlockNumber', [100]); - await send(comptroller, 'harnessUpdateCompBorrowIndex', [ + await send(comptroller, 'harnessUpdateSashimiBorrowIndex', [ mkt._address, etherExp(1.1), ]); - const {index, block} = await call(comptroller, 'compBorrowState', [mkt._address]); + const {index, block} = await call(comptroller, 'sashimiBorrowState', [mkt._address]); expect(index).toEqualNumber(0); expect(block).toEqualNumber(100); - const speed = await call(comptroller, 'compSpeeds', [mkt._address]); + const speed = await call(comptroller, 'sashimiSpeeds', [mkt._address]); expect(speed).toEqualNumber(0); }); it('should not update index if no blocks passed since last accrual', async () => { - const mkt = cREP; - await send(comptroller, 'setCompSpeed', [mkt._address, etherExp(0.5)]); - await send(comptroller, 'harnessUpdateCompBorrowIndex', [ + const mkt = slREP; + await send(comptroller, 'setSashimiSpeed', [mkt._address, etherExp(0.5)]); + await send(comptroller, 'harnessUpdateSashimiBorrowIndex', [ mkt._address, etherExp(1.1), ]); - const {index, block} = await call(comptroller, 'compBorrowState', [mkt._address]); + const {index, block} = await call(comptroller, 'sashimiBorrowState', [mkt._address]); expect(index).toEqualNumber(1e36); expect(block).toEqualNumber(0); }); - it('should not update index if comp speed is 0', async () => { - const mkt = cREP; - await send(comptroller, 'setCompSpeed', [mkt._address, etherExp(0)]); + it('should not update index if sashimi speed is 0', async () => { + const mkt = slREP; + await send(comptroller, 'setSashimiSpeed', [mkt._address, etherExp(0)]); await send(comptroller, 'setBlockNumber', [100]); - await send(comptroller, 'harnessUpdateCompBorrowIndex', [ + await send(comptroller, 'harnessUpdateSashimiBorrowIndex', [ mkt._address, etherExp(1.1), ]); - const {index, block} = await call(comptroller, 'compBorrowState', [mkt._address]); + const {index, block} = await call(comptroller, 'sashimiBorrowState', [mkt._address]); expect(index).toEqualNumber(1e36); expect(block).toEqualNumber(100); }); }); - describe('updateCompSupplyIndex()', () => { - it('should calculate comp supplier index correctly', async () => { - const mkt = cREP; + describe('updateSashimiSupplyIndex()', () => { + it('should calculate sashimi supplier index correctly', async () => { + const mkt = slREP; await send(comptroller, 'setBlockNumber', [100]); await send(mkt, 'harnessSetTotalSupply', [etherUnsigned(10e18)]); - await send(comptroller, 'setCompSpeed', [mkt._address, etherExp(0.5)]); - await send(comptroller, 'harnessUpdateCompSupplyIndex', [mkt._address]); + await send(comptroller, 'setSashimiSpeed', [mkt._address, etherExp(0.5)]); + await send(comptroller, 'harnessUpdateSashimiSupplyIndex', [mkt._address]); /* suppyTokens = 10e18 - compAccrued = deltaBlocks * supplySpeed + sashimiAccrued = deltaBlocks * supplySpeed = 100 * 0.5e18 = 50e18 - newIndex += compAccrued * 1e36 / supplyTokens + newIndex += sashimiAccrued * 1e36 / supplyTokens = 1e36 + 50e18 * 1e36 / 10e18 = 6e36 */ - const {index, block} = await call(comptroller, 'compSupplyState', [mkt._address]); + const {index, block} = await call(comptroller, 'sashimiSupplyState', [mkt._address]); expect(index).toEqualNumber(6e36); expect(block).toEqualNumber(100); }); - it('should not update index on non-COMP markets', async () => { - const mkt = await makeCToken({ + it('should not update index on non-SASHIMI markets', async () => { + const mkt = await makeSLToken({ comptroller: comptroller, supportMarket: true, - addCompMarket: false + addSashimiMarket: false }); await send(comptroller, 'setBlockNumber', [100]); - await send(comptroller, 'harnessUpdateCompSupplyIndex', [ + await send(comptroller, 'harnessUpdateSashimiSupplyIndex', [ mkt._address ]); - const {index, block} = await call(comptroller, 'compSupplyState', [mkt._address]); + const {index, block} = await call(comptroller, 'sashimiSupplyState', [mkt._address]); expect(index).toEqualNumber(0); expect(block).toEqualNumber(100); - const speed = await call(comptroller, 'compSpeeds', [mkt._address]); + const speed = await call(comptroller, 'sashimiSpeeds', [mkt._address]); expect(speed).toEqualNumber(0); - // ctoken could have no comp speed or comp supplier state if not in comp markets + // sltoken could have no sashimi speed or sashimi supplier state if not in sashimi markets // this logic could also possibly be implemented in the allowed hook }); it('should not update index if no blocks passed since last accrual', async () => { - const mkt = cREP; + const mkt = slREP; await send(comptroller, 'setBlockNumber', [0]); await send(mkt, 'harnessSetTotalSupply', [etherUnsigned(10e18)]); - await send(comptroller, 'setCompSpeed', [mkt._address, etherExp(0.5)]); - await send(comptroller, 'harnessUpdateCompSupplyIndex', [mkt._address]); + await send(comptroller, 'setSashimiSpeed', [mkt._address, etherExp(0.5)]); + await send(comptroller, 'harnessUpdateSashimiSupplyIndex', [mkt._address]); - const {index, block} = await call(comptroller, 'compSupplyState', [mkt._address]); + const {index, block} = await call(comptroller, 'sashimiSupplyState', [mkt._address]); expect(index).toEqualNumber(1e36); expect(block).toEqualNumber(0); }); it('should not matter if the index is updated multiple times', async () => { - const compRemaining = compRate.mul(100) - await send(comptroller.comp, 'transfer', [comptroller._address, compRemaining], {from: root}); - await pretendBorrow(cLOW, a1, 1, 1, 100); - await send(comptroller, 'refreshCompSpeeds'); + const sashimiRemaining = sashimiRate.mul(100) + await send(comptroller.sashimi, 'transfer', [comptroller._address, sashimiRemaining], {from: root}); + await pretendBorrow(slLOW, a1, 1, 1, 100); + await send(comptroller, 'refreshSashimiSpeeds'); - await quickMint(cLOW, a2, etherUnsigned(10e18)); - await quickMint(cLOW, a3, etherUnsigned(15e18)); + await quickMint(slLOW, a2, etherUnsigned(10e18)); + await quickMint(slLOW, a3, etherUnsigned(15e18)); - const a2Accrued0 = await totalCompAccrued(comptroller, a2); - const a3Accrued0 = await totalCompAccrued(comptroller, a3); - const a2Balance0 = await balanceOf(cLOW, a2); - const a3Balance0 = await balanceOf(cLOW, a3); + const a2Accrued0 = await totalSashimiAccrued(comptroller, a2); + const a3Accrued0 = await totalSashimiAccrued(comptroller, a3); + const a2Balance0 = await balanceOf(slLOW, a2); + const a3Balance0 = await balanceOf(slLOW, a3); await fastForward(comptroller, 20); - const txT1 = await send(cLOW, 'transfer', [a2, a3Balance0.sub(a2Balance0)], {from: a3}); + const txT1 = await send(slLOW, 'transfer', [a2, a3Balance0.sub(a2Balance0)], {from: a3}); - const a2Accrued1 = await totalCompAccrued(comptroller, a2); - const a3Accrued1 = await totalCompAccrued(comptroller, a3); - const a2Balance1 = await balanceOf(cLOW, a2); - const a3Balance1 = await balanceOf(cLOW, a3); + const a2Accrued1 = await totalSashimiAccrued(comptroller, a2); + const a3Accrued1 = await totalSashimiAccrued(comptroller, a3); + const a2Balance1 = await balanceOf(slLOW, a2); + const a3Balance1 = await balanceOf(slLOW, a3); await fastForward(comptroller, 10); - await send(comptroller, 'harnessUpdateCompSupplyIndex', [cLOW._address]); + await send(comptroller, 'harnessUpdateSashimiSupplyIndex', [slLOW._address]); await fastForward(comptroller, 10); - const txT2 = await send(cLOW, 'transfer', [a3, a2Balance1.sub(a3Balance1)], {from: a2}); + const txT2 = await send(slLOW, 'transfer', [a3, a2Balance1.sub(a3Balance1)], {from: a2}); - const a2Accrued2 = await totalCompAccrued(comptroller, a2); - const a3Accrued2 = await totalCompAccrued(comptroller, a3); + const a2Accrued2 = await totalSashimiAccrued(comptroller, a2); + const a3Accrued2 = await totalSashimiAccrued(comptroller, a3); expect(a2Accrued0).toEqualNumber(0); expect(a3Accrued0).toEqualNumber(0); @@ -268,28 +268,28 @@ describe('Flywheel', () => { }); }); - describe('distributeBorrowerComp()', () => { + describe('distributeBorrowerSashimi()', () => { - it('should update borrow index checkpoint but not compAccrued for first time user', async () => { - const mkt = cREP; - await send(comptroller, "setCompBorrowState", [mkt._address, etherDouble(6), 10]); - await send(comptroller, "setCompBorrowerIndex", [mkt._address, root, etherUnsigned(0)]); + it('should update borrow index checkpoint but not sashimiAccrued for first time user', async () => { + const mkt = slREP; + await send(comptroller, "setSashimiBorrowState", [mkt._address, etherDouble(6), 10]); + await send(comptroller, "setSashimiBorrowerIndex", [mkt._address, root, etherUnsigned(0)]); - await send(comptroller, "harnessDistributeBorrowerComp", [mkt._address, root, etherExp(1.1)]); - expect(await call(comptroller, "compAccrued", [root])).toEqualNumber(0); - expect(await call(comptroller, "compBorrowerIndex", [ mkt._address, root])).toEqualNumber(6e36); + await send(comptroller, "harnessDistributeBorrowerSashimi", [mkt._address, root, etherExp(1.1)]); + expect(await call(comptroller, "sashimiAccrued", [root])).toEqualNumber(0); + expect(await call(comptroller, "sashimiBorrowerIndex", [ mkt._address, root])).toEqualNumber(6e36); }); - it('should transfer comp and update borrow index checkpoint correctly for repeat time user', async () => { - const mkt = cREP; - await send(comptroller.comp, 'transfer', [comptroller._address, etherUnsigned(50e18)], {from: root}); + it('should transfer sashimi and update borrow index checkpoint correctly for repeat time user', async () => { + const mkt = slREP; + await send(comptroller.sashimi, 'transfer', [comptroller._address, etherUnsigned(50e18)], {from: root}); await send(mkt, "harnessSetAccountBorrows", [a1, etherUnsigned(5.5e18), etherExp(1)]); - await send(comptroller, "setCompBorrowState", [mkt._address, etherDouble(6), 10]); - await send(comptroller, "setCompBorrowerIndex", [mkt._address, a1, etherDouble(1)]); + await send(comptroller, "setSashimiBorrowState", [mkt._address, etherDouble(6), 10]); + await send(comptroller, "setSashimiBorrowerIndex", [mkt._address, a1, etherDouble(1)]); /* - * 100 delta blocks, 10e18 origin total borrows, 0.5e18 borrowSpeed => 6e18 compBorrowIndex - * this tests that an acct with half the total borrows over that time gets 25e18 COMP + * 100 delta blocks, 10e18 origin total borrows, 0.5e18 borrowSpeed => 6e18 sashimiBorrowIndex + * this tests that an acct with half the total borrows over that time gets 25e18 SASHIMI borrowerAmount = borrowBalance * 1e18 / borrow idx = 5.5e18 * 1e18 / 1.1e18 = 5e18 deltaIndex = marketStoredIndex - userStoredIndex @@ -297,23 +297,23 @@ describe('Flywheel', () => { borrowerAccrued= borrowerAmount * deltaIndex / 1e36 = 5e18 * 5e36 / 1e36 = 25e18 */ - const tx = await send(comptroller, "harnessDistributeBorrowerComp", [mkt._address, a1, etherUnsigned(1.1e18)]); - expect(await compAccrued(comptroller, a1)).toEqualNumber(0); - expect(await compBalance(comptroller, a1)).toEqualNumber(25e18); - expect(tx).toHaveLog('DistributedBorrowerComp', { - cToken: mkt._address, + const tx = await send(comptroller, "harnessDistributeBorrowerSashimi", [mkt._address, a1, etherUnsigned(1.1e18)]); + expect(await sashimiAccrued(comptroller, a1)).toEqualNumber(0); + expect(await sashimiBalance(comptroller, a1)).toEqualNumber(25e18); + expect(tx).toHaveLog('DistributedBorrowerSashimi', { + slToken: mkt._address, borrower: a1, - compDelta: etherUnsigned(25e18).toString(), - compBorrowIndex: etherDouble(6).toString() + sashimiDelta: etherUnsigned(25e18).toString(), + sashimiBorrowIndex: etherDouble(6).toString() }); }); - it('should not transfer if below comp claim threshold', async () => { - const mkt = cREP; - await send(comptroller.comp, 'transfer', [comptroller._address, etherUnsigned(50e18)], {from: root}); + it('should not transfer if below sashimi claim threshold', async () => { + const mkt = slREP; + await send(comptroller.sashimi, 'transfer', [comptroller._address, etherUnsigned(50e18)], {from: root}); await send(mkt, "harnessSetAccountBorrows", [a1, etherUnsigned(5.5e17), etherExp(1)]); - await send(comptroller, "setCompBorrowState", [mkt._address, etherDouble(1.0019), 10]); - await send(comptroller, "setCompBorrowerIndex", [mkt._address, a1, etherDouble(1)]); + await send(comptroller, "setSashimiBorrowState", [mkt._address, etherDouble(1.0019), 10]); + await send(comptroller, "setSashimiBorrowerIndex", [mkt._address, a1, etherDouble(1)]); /* borrowerAmount = borrowBalance * 1e18 / borrow idx = 5.5e17 * 1e18 / 1.1e18 = 5e17 @@ -321,37 +321,37 @@ describe('Flywheel', () => { = 1.0019e36 - 1e36 = 0.0019e36 borrowerAccrued= borrowerAmount * deltaIndex / 1e36 = 5e17 * 0.0019e36 / 1e36 = 0.00095e18 - 0.00095e18 < compClaimThreshold of 0.001e18 + 0.00095e18 < sashimiClaimThreshold of 0.001e18 */ - await send(comptroller, "harnessDistributeBorrowerComp", [mkt._address, a1, etherExp(1.1)]); - expect(await compAccrued(comptroller, a1)).toEqualNumber(0.00095e18); - expect(await compBalance(comptroller, a1)).toEqualNumber(0); + await send(comptroller, "harnessDistributeBorrowerSashimi", [mkt._address, a1, etherExp(1.1)]); + expect(await sashimiAccrued(comptroller, a1)).toEqualNumber(0.00095e18); + expect(await sashimiBalance(comptroller, a1)).toEqualNumber(0); }); - it('should not revert or distribute when called with non-COMP market', async () => { - const mkt = await makeCToken({ + it('should not revert or distribute when called with non-SASHIMI market', async () => { + const mkt = await makeSLToken({ comptroller: comptroller, supportMarket: true, - addCompMarket: false, + addSashimiMarket: false, }); - await send(comptroller, "harnessDistributeBorrowerComp", [mkt._address, a1, etherExp(1.1)]); - expect(await compAccrued(comptroller, a1)).toEqualNumber(0); - expect(await compBalance(comptroller, a1)).toEqualNumber(0); - expect(await call(comptroller, 'compBorrowerIndex', [mkt._address, a1])).toEqualNumber(0); + await send(comptroller, "harnessDistributeBorrowerSashimi", [mkt._address, a1, etherExp(1.1)]); + expect(await sashimiAccrued(comptroller, a1)).toEqualNumber(0); + expect(await sashimiBalance(comptroller, a1)).toEqualNumber(0); + expect(await call(comptroller, 'sashimiBorrowerIndex', [mkt._address, a1])).toEqualNumber(0); }); }); - describe('distributeSupplierComp()', () => { - it('should transfer comp and update supply index correctly for first time user', async () => { - const mkt = cREP; - await send(comptroller.comp, 'transfer', [comptroller._address, etherUnsigned(50e18)], {from: root}); + describe('distributeSupplierSashimi()', () => { + it('should transfer sashimi and update supply index correctly for first time user', async () => { + const mkt = slREP; + await send(comptroller.sashimi, 'transfer', [comptroller._address, etherUnsigned(50e18)], {from: root}); await send(mkt, "harnessSetBalance", [a1, etherUnsigned(5e18)]); - await send(comptroller, "setCompSupplyState", [mkt._address, etherDouble(6), 10]); + await send(comptroller, "setSashimiSupplyState", [mkt._address, etherDouble(6), 10]); /* - * 100 delta blocks, 10e18 total supply, 0.5e18 supplySpeed => 6e18 compSupplyIndex - * confirming an acct with half the total supply over that time gets 25e18 COMP: + * 100 delta blocks, 10e18 total supply, 0.5e18 supplySpeed => 6e18 sashimiSupplyIndex + * confirming an acct with half the total supply over that time gets 25e18 SASHIMI: supplierAmount = 5e18 deltaIndex = marketStoredIndex - userStoredIndex = 6e36 - 1e36 = 5e36 @@ -359,24 +359,24 @@ describe('Flywheel', () => { = 5e18 * 5e36 / 1e36 = 25e18 */ - const tx = await send(comptroller, "harnessDistributeSupplierComp", [mkt._address, a1]); - expect(await compAccrued(comptroller, a1)).toEqualNumber(0); - expect(await compBalance(comptroller, a1)).toEqualNumber(25e18); - expect(tx).toHaveLog('DistributedSupplierComp', { - cToken: mkt._address, + const tx = await send(comptroller, "harnessDistributeSupplierSashimi", [mkt._address, a1]); + expect(await sashimiAccrued(comptroller, a1)).toEqualNumber(0); + expect(await sashimiBalance(comptroller, a1)).toEqualNumber(25e18); + expect(tx).toHaveLog('DistributedSupplierSashimi', { + slToken: mkt._address, supplier: a1, - compDelta: etherUnsigned(25e18).toString(), - compSupplyIndex: etherDouble(6).toString() + sashimiDelta: etherUnsigned(25e18).toString(), + sashimiSupplyIndex: etherDouble(6).toString() }); }); - it('should update comp accrued and supply index for repeat user', async () => { - const mkt = cREP; - await send(comptroller.comp, 'transfer', [comptroller._address, etherUnsigned(50e18)], {from: root}); + it('should update sashimi accrued and supply index for repeat user', async () => { + const mkt = slREP; + await send(comptroller.sashimi, 'transfer', [comptroller._address, etherUnsigned(50e18)], {from: root}); await send(mkt, "harnessSetBalance", [a1, etherUnsigned(5e18)]); - await send(comptroller, "setCompSupplyState", [mkt._address, etherDouble(6), 10]); - await send(comptroller, "setCompSupplierIndex", [mkt._address, a1, etherDouble(2)]) + await send(comptroller, "setSashimiSupplyState", [mkt._address, etherDouble(6), 10]); + await send(comptroller, "setSashimiSupplierIndex", [mkt._address, a1, etherDouble(2)]) /* supplierAmount = 5e18 deltaIndex = marketStoredIndex - userStoredIndex @@ -385,17 +385,17 @@ describe('Flywheel', () => { = 5e18 * 4e36 / 1e36 = 20e18 */ - await send(comptroller, "harnessDistributeSupplierComp", [mkt._address, a1]); - expect(await compAccrued(comptroller, a1)).toEqualNumber(0); - expect(await compBalance(comptroller, a1)).toEqualNumber(20e18); + await send(comptroller, "harnessDistributeSupplierSashimi", [mkt._address, a1]); + expect(await sashimiAccrued(comptroller, a1)).toEqualNumber(0); + expect(await sashimiBalance(comptroller, a1)).toEqualNumber(20e18); }); - it('should not transfer when compAccrued below threshold', async () => { - const mkt = cREP; - await send(comptroller.comp, 'transfer', [comptroller._address, etherUnsigned(50e18)], {from: root}); + it('should not transfer when sashimiAccrued below threshold', async () => { + const mkt = slREP; + await send(comptroller.sashimi, 'transfer', [comptroller._address, etherUnsigned(50e18)], {from: root}); await send(mkt, "harnessSetBalance", [a1, etherUnsigned(5e17)]); - await send(comptroller, "setCompSupplyState", [mkt._address, etherDouble(1.0019), 10]); + await send(comptroller, "setSashimiSupplyState", [mkt._address, etherDouble(1.0019), 10]); /* supplierAmount = 5e17 deltaIndex = marketStoredIndex - userStoredIndex @@ -404,371 +404,371 @@ describe('Flywheel', () => { = 5e17 * 0.0019e36 / 1e36 = 0.00095e18 */ - await send(comptroller, "harnessDistributeSupplierComp", [mkt._address, a1]); - expect(await compAccrued(comptroller, a1)).toEqualNumber(0.00095e18); - expect(await compBalance(comptroller, a1)).toEqualNumber(0); + await send(comptroller, "harnessDistributeSupplierSashimi", [mkt._address, a1]); + expect(await sashimiAccrued(comptroller, a1)).toEqualNumber(0.00095e18); + expect(await sashimiBalance(comptroller, a1)).toEqualNumber(0); }); - it('should not revert or distribute when called with non-COMP market', async () => { - const mkt = await makeCToken({ + it('should not revert or distribute when called with non-SASHIMI market', async () => { + const mkt = await makeSLToken({ comptroller: comptroller, supportMarket: true, - addCompMarket: false, + addSashimiMarket: false, }); - await send(comptroller, "harnessDistributeSupplierComp", [mkt._address, a1]); - expect(await compAccrued(comptroller, a1)).toEqualNumber(0); - expect(await compBalance(comptroller, a1)).toEqualNumber(0); - expect(await call(comptroller, 'compBorrowerIndex', [mkt._address, a1])).toEqualNumber(0); + await send(comptroller, "harnessDistributeSupplierSashimi", [mkt._address, a1]); + expect(await sashimiAccrued(comptroller, a1)).toEqualNumber(0); + expect(await sashimiBalance(comptroller, a1)).toEqualNumber(0); + expect(await call(comptroller, 'sashimiBorrowerIndex', [mkt._address, a1])).toEqualNumber(0); }); }); - describe('transferComp', () => { - it('should transfer comp accrued when amount is above threshold', async () => { - const compRemaining = 1000, a1AccruedPre = 100, threshold = 1; - const compBalancePre = await compBalance(comptroller, a1); - const tx0 = await send(comptroller.comp, 'transfer', [comptroller._address, compRemaining], {from: root}); - const tx1 = await send(comptroller, 'setCompAccrued', [a1, a1AccruedPre]); - const tx2 = await send(comptroller, 'harnessTransferComp', [a1, a1AccruedPre, threshold]); - const a1AccruedPost = await compAccrued(comptroller, a1); - const compBalancePost = await compBalance(comptroller, a1); - expect(compBalancePre).toEqualNumber(0); - expect(compBalancePost).toEqualNumber(a1AccruedPre); - }); - - it('should not transfer when comp accrued is below threshold', async () => { - const compRemaining = 1000, a1AccruedPre = 100, threshold = 101; - const compBalancePre = await call(comptroller.comp, 'balanceOf', [a1]); - const tx0 = await send(comptroller.comp, 'transfer', [comptroller._address, compRemaining], {from: root}); - const tx1 = await send(comptroller, 'setCompAccrued', [a1, a1AccruedPre]); - const tx2 = await send(comptroller, 'harnessTransferComp', [a1, a1AccruedPre, threshold]); - const a1AccruedPost = await compAccrued(comptroller, a1); - const compBalancePost = await compBalance(comptroller, a1); - expect(compBalancePre).toEqualNumber(0); - expect(compBalancePost).toEqualNumber(0); - }); - - it('should not transfer comp if comp accrued is greater than comp remaining', async () => { - const compRemaining = 99, a1AccruedPre = 100, threshold = 1; - const compBalancePre = await compBalance(comptroller, a1); - const tx0 = await send(comptroller.comp, 'transfer', [comptroller._address, compRemaining], {from: root}); - const tx1 = await send(comptroller, 'setCompAccrued', [a1, a1AccruedPre]); - const tx2 = await send(comptroller, 'harnessTransferComp', [a1, a1AccruedPre, threshold]); - const a1AccruedPost = await compAccrued(comptroller, a1); - const compBalancePost = await compBalance(comptroller, a1); - expect(compBalancePre).toEqualNumber(0); - expect(compBalancePost).toEqualNumber(0); + describe('transferSashimi', () => { + it('should transfer sashimi accrued when amount is above threshold', async () => { + const sashimiRemaining = 1000, a1AccruedPre = 100, threshold = 1; + const sashimiBalancePre = await sashimiBalance(comptroller, a1); + const tx0 = await send(comptroller.sashimi, 'transfer', [comptroller._address, sashimiRemaining], {from: root}); + const tx1 = await send(comptroller, 'setSashimiAccrued', [a1, a1AccruedPre]); + const tx2 = await send(comptroller, 'harnessTransferSashimi', [a1, a1AccruedPre, threshold]); + const a1AccruedPost = await sashimiAccrued(comptroller, a1); + const sashimiBalancePost = await sashimiBalance(comptroller, a1); + expect(sashimiBalancePre).toEqualNumber(0); + expect(sashimiBalancePost).toEqualNumber(a1AccruedPre); + }); + + it('should not transfer when sashimi accrued is below threshold', async () => { + const sashimiRemaining = 1000, a1AccruedPre = 100, threshold = 101; + const sashimiBalancePre = await call(comptroller.sashimi, 'balanceOf', [a1]); + const tx0 = await send(comptroller.sashimi, 'transfer', [comptroller._address, sashimiRemaining], {from: root}); + const tx1 = await send(comptroller, 'setSashimiAccrued', [a1, a1AccruedPre]); + const tx2 = await send(comptroller, 'harnessTransferSashimi', [a1, a1AccruedPre, threshold]); + const a1AccruedPost = await sashimiAccrued(comptroller, a1); + const sashimiBalancePost = await sashimiBalance(comptroller, a1); + expect(sashimiBalancePre).toEqualNumber(0); + expect(sashimiBalancePost).toEqualNumber(0); + }); + + it('should not transfer sashimi if sashimi accrued is greater than sashimi remaining', async () => { + const sashimiRemaining = 99, a1AccruedPre = 100, threshold = 1; + const sashimiBalancePre = await sashimiBalance(comptroller, a1); + const tx0 = await send(comptroller.sashimi, 'transfer', [comptroller._address, sashimiRemaining], {from: root}); + const tx1 = await send(comptroller, 'setSashimiAccrued', [a1, a1AccruedPre]); + const tx2 = await send(comptroller, 'harnessTransferSashimi', [a1, a1AccruedPre, threshold]); + const a1AccruedPost = await sashimiAccrued(comptroller, a1); + const sashimiBalancePost = await sashimiBalance(comptroller, a1); + expect(sashimiBalancePre).toEqualNumber(0); + expect(sashimiBalancePost).toEqualNumber(0); }); }); - describe('claimComp', () => { - it('should accrue comp and then transfer comp accrued', async () => { - const compRemaining = compRate.mul(100), mintAmount = etherUnsigned(12e18), deltaBlocks = 10; - await send(comptroller.comp, 'transfer', [comptroller._address, compRemaining], {from: root}); - await pretendBorrow(cLOW, a1, 1, 1, 100); - await send(comptroller, 'refreshCompSpeeds'); - const speed = await call(comptroller, 'compSpeeds', [cLOW._address]); - const a2AccruedPre = await compAccrued(comptroller, a2); - const compBalancePre = await compBalance(comptroller, a2); - await quickMint(cLOW, a2, mintAmount); + describe('claimSashimi', () => { + it('should accrue sashimi and then transfer sashimi accrued', async () => { + const sashimiRemaining = sashimiRate.mul(100), mintAmount = etherUnsigned(12e18), deltaBlocks = 10; + await send(comptroller.sashimi, 'transfer', [comptroller._address, sashimiRemaining], {from: root}); + await pretendBorrow(slLOW, a1, 1, 1, 100); + await send(comptroller, 'refreshSashimiSpeeds'); + const speed = await call(comptroller, 'sashimiSpeeds', [slLOW._address]); + const a2AccruedPre = await sashimiAccrued(comptroller, a2); + const sashimiBalancePre = await sashimiBalance(comptroller, a2); + await quickMint(slLOW, a2, mintAmount); await fastForward(comptroller, deltaBlocks); - const tx = await send(comptroller, 'claimComp', [a2]); - const a2AccruedPost = await compAccrued(comptroller, a2); - const compBalancePost = await compBalance(comptroller, a2); + const tx = await send(comptroller, 'claimSashimi', [a2]); + const a2AccruedPost = await sashimiAccrued(comptroller, a2); + const sashimiBalancePost = await sashimiBalance(comptroller, a2); expect(tx.gasUsed).toBeLessThan(330000); - expect(speed).toEqualNumber(compRate); + expect(speed).toEqualNumber(sashimiRate); expect(a2AccruedPre).toEqualNumber(0); expect(a2AccruedPost).toEqualNumber(0); - expect(compBalancePre).toEqualNumber(0); - expect(compBalancePost).toEqualNumber(compRate.mul(deltaBlocks).sub(1)); // index is 8333... - }); - - it('should accrue comp and then transfer comp accrued in a single market', async () => { - const compRemaining = compRate.mul(100), mintAmount = etherUnsigned(12e18), deltaBlocks = 10; - await send(comptroller.comp, 'transfer', [comptroller._address, compRemaining], {from: root}); - await pretendBorrow(cLOW, a1, 1, 1, 100); - await send(comptroller, 'refreshCompSpeeds'); - const speed = await call(comptroller, 'compSpeeds', [cLOW._address]); - const a2AccruedPre = await compAccrued(comptroller, a2); - const compBalancePre = await compBalance(comptroller, a2); - await quickMint(cLOW, a2, mintAmount); + expect(sashimiBalancePre).toEqualNumber(0); + expect(sashimiBalancePost).toEqualNumber(sashimiRate.mul(deltaBlocks).sub(1)); // index is 8333... + }); + + it('should accrue sashimi and then transfer sashimi accrued in a single market', async () => { + const sashimiRemaining = sashimiRate.mul(100), mintAmount = etherUnsigned(12e18), deltaBlocks = 10; + await send(comptroller.sashimi, 'transfer', [comptroller._address, sashimiRemaining], {from: root}); + await pretendBorrow(slLOW, a1, 1, 1, 100); + await send(comptroller, 'refreshSashimiSpeeds'); + const speed = await call(comptroller, 'sashimiSpeeds', [slLOW._address]); + const a2AccruedPre = await sashimiAccrued(comptroller, a2); + const sashimiBalancePre = await sashimiBalance(comptroller, a2); + await quickMint(slLOW, a2, mintAmount); await fastForward(comptroller, deltaBlocks); - const tx = await send(comptroller, 'claimComp', [a2, [cLOW._address]]); - const a2AccruedPost = await compAccrued(comptroller, a2); - const compBalancePost = await compBalance(comptroller, a2); + const tx = await send(comptroller, 'claimSashimi', [a2, [slLOW._address]]); + const a2AccruedPost = await sashimiAccrued(comptroller, a2); + const sashimiBalancePost = await sashimiBalance(comptroller, a2); expect(tx.gasUsed).toBeLessThan(160000); - expect(speed).toEqualNumber(compRate); + expect(speed).toEqualNumber(sashimiRate); expect(a2AccruedPre).toEqualNumber(0); expect(a2AccruedPost).toEqualNumber(0); - expect(compBalancePre).toEqualNumber(0); - expect(compBalancePost).toEqualNumber(compRate.mul(deltaBlocks).sub(1)); // index is 8333... + expect(sashimiBalancePre).toEqualNumber(0); + expect(sashimiBalancePost).toEqualNumber(sashimiRate.mul(deltaBlocks).sub(1)); // index is 8333... }); - it('should claim when comp accrued is below threshold', async () => { - const compRemaining = etherExp(1), accruedAmt = etherUnsigned(0.0009e18) - await send(comptroller.comp, 'transfer', [comptroller._address, compRemaining], {from: root}); - await send(comptroller, 'setCompAccrued', [a1, accruedAmt]); - await send(comptroller, 'claimComp', [a1, [cLOW._address]]); - expect(await compAccrued(comptroller, a1)).toEqualNumber(0); - expect(await compBalance(comptroller, a1)).toEqualNumber(accruedAmt); + it('should claim when sashimi accrued is below threshold', async () => { + const sashimiRemaining = etherExp(1), accruedAmt = etherUnsigned(0.0009e18) + await send(comptroller.sashimi, 'transfer', [comptroller._address, sashimiRemaining], {from: root}); + await send(comptroller, 'setSashimiAccrued', [a1, accruedAmt]); + await send(comptroller, 'claimSashimi', [a1, [slLOW._address]]); + expect(await sashimiAccrued(comptroller, a1)).toEqualNumber(0); + expect(await sashimiBalance(comptroller, a1)).toEqualNumber(accruedAmt); }); it('should revert when a market is not listed', async () => { - const cNOT = await makeCToken({comptroller}); + const cNOT = await makeSLToken({comptroller}); await expect( - send(comptroller, 'claimComp', [a1, [cNOT._address]]) + send(comptroller, 'claimSashimi', [a1, [cNOT._address]]) ).rejects.toRevert('revert market must be listed'); }); }); - describe('claimComp batch', () => { - it('should revert when claiming comp from non-listed market', async () => { - const compRemaining = compRate.mul(100), deltaBlocks = 10, mintAmount = etherExp(10); - await send(comptroller.comp, 'transfer', [comptroller._address, compRemaining], {from: root}); + describe('claimSashimi batch', () => { + it('should revert when claiming sashimi from non-listed market', async () => { + const sashimiRemaining = sashimiRate.mul(100), deltaBlocks = 10, mintAmount = etherExp(10); + await send(comptroller.sashimi, 'transfer', [comptroller._address, sashimiRemaining], {from: root}); let [_, __, ...claimAccts] = saddle.accounts; for(let from of claimAccts) { - expect(await send(cLOW.underlying, 'harnessSetBalance', [from, mintAmount], { from })).toSucceed(); - send(cLOW.underlying, 'approve', [cLOW._address, mintAmount], { from }); - send(cLOW, 'mint', [mintAmount], { from }); + expect(await send(slLOW.underlying, 'harnessSetBalance', [from, mintAmount], { from })).toSucceed(); + send(slLOW.underlying, 'approve', [slLOW._address, mintAmount], { from }); + send(slLOW, 'mint', [mintAmount], { from }); } - await pretendBorrow(cLOW, root, 1, 1, etherExp(10)); - await send(comptroller, 'refreshCompSpeeds'); + await pretendBorrow(slLOW, root, 1, 1, etherExp(10)); + await send(comptroller, 'refreshSashimiSpeeds'); await fastForward(comptroller, deltaBlocks); - await expect(send(comptroller, 'claimComp', [claimAccts, [cLOW._address, cEVIL._address], true, true])).rejects.toRevert('revert market must be listed'); + await expect(send(comptroller, 'claimSashimi', [claimAccts, [slLOW._address, cEVIL._address], true, true])).rejects.toRevert('revert market must be listed'); }); - it('should claim the expected amount when holders and ctokens arg is duplicated', async () => { - const compRemaining = compRate.mul(100), deltaBlocks = 10, mintAmount = etherExp(10); - await send(comptroller.comp, 'transfer', [comptroller._address, compRemaining], {from: root}); + it('should claim the expected amount when holders and sltokens arg is duplicated', async () => { + const sashimiRemaining = sashimiRate.mul(100), deltaBlocks = 10, mintAmount = etherExp(10); + await send(comptroller.sashimi, 'transfer', [comptroller._address, sashimiRemaining], {from: root}); let [_, __, ...claimAccts] = saddle.accounts; for(let from of claimAccts) { - expect(await send(cLOW.underlying, 'harnessSetBalance', [from, mintAmount], { from })).toSucceed(); - send(cLOW.underlying, 'approve', [cLOW._address, mintAmount], { from }); - send(cLOW, 'mint', [mintAmount], { from }); + expect(await send(slLOW.underlying, 'harnessSetBalance', [from, mintAmount], { from })).toSucceed(); + send(slLOW.underlying, 'approve', [slLOW._address, mintAmount], { from }); + send(slLOW, 'mint', [mintAmount], { from }); } - await pretendBorrow(cLOW, root, 1, 1, etherExp(10)); - await send(comptroller, 'refreshCompSpeeds'); + await pretendBorrow(slLOW, root, 1, 1, etherExp(10)); + await send(comptroller, 'refreshSashimiSpeeds'); await fastForward(comptroller, deltaBlocks); - const tx = await send(comptroller, 'claimComp', [[...claimAccts, ...claimAccts], [cLOW._address, cLOW._address], false, true]); - // comp distributed => 10e18 + const tx = await send(comptroller, 'claimSashimi', [[...claimAccts, ...claimAccts], [slLOW._address, slLOW._address], false, true]); + // sashimi distributed => 10e18 for(let acct of claimAccts) { - expect(await call(comptroller, 'compSupplierIndex', [cLOW._address, acct])).toEqualNumber(etherDouble(1.125)); - expect(await compBalance(comptroller, acct)).toEqualNumber(etherExp(1.25)); + expect(await call(comptroller, 'sashimiSupplierIndex', [slLOW._address, acct])).toEqualNumber(etherDouble(1.125)); + expect(await sashimiBalance(comptroller, acct)).toEqualNumber(etherExp(1.25)); } }); - it('claims comp for multiple suppliers only', async () => { - const compRemaining = compRate.mul(100), deltaBlocks = 10, mintAmount = etherExp(10); - await send(comptroller.comp, 'transfer', [comptroller._address, compRemaining], {from: root}); + it('claims sashimi for multiple suppliers only', async () => { + const sashimiRemaining = sashimiRate.mul(100), deltaBlocks = 10, mintAmount = etherExp(10); + await send(comptroller.sashimi, 'transfer', [comptroller._address, sashimiRemaining], {from: root}); let [_, __, ...claimAccts] = saddle.accounts; for(let from of claimAccts) { - expect(await send(cLOW.underlying, 'harnessSetBalance', [from, mintAmount], { from })).toSucceed(); - send(cLOW.underlying, 'approve', [cLOW._address, mintAmount], { from }); - send(cLOW, 'mint', [mintAmount], { from }); + expect(await send(slLOW.underlying, 'harnessSetBalance', [from, mintAmount], { from })).toSucceed(); + send(slLOW.underlying, 'approve', [slLOW._address, mintAmount], { from }); + send(slLOW, 'mint', [mintAmount], { from }); } - await pretendBorrow(cLOW, root, 1, 1, etherExp(10)); - await send(comptroller, 'refreshCompSpeeds'); + await pretendBorrow(slLOW, root, 1, 1, etherExp(10)); + await send(comptroller, 'refreshSashimiSpeeds'); await fastForward(comptroller, deltaBlocks); - const tx = await send(comptroller, 'claimComp', [claimAccts, [cLOW._address], false, true]); - // comp distributed => 10e18 + const tx = await send(comptroller, 'claimSashimi', [claimAccts, [slLOW._address], false, true]); + // sashimi distributed => 10e18 for(let acct of claimAccts) { - expect(await call(comptroller, 'compSupplierIndex', [cLOW._address, acct])).toEqualNumber(etherDouble(1.125)); - expect(await compBalance(comptroller, acct)).toEqualNumber(etherExp(1.25)); + expect(await call(comptroller, 'sashimiSupplierIndex', [slLOW._address, acct])).toEqualNumber(etherDouble(1.125)); + expect(await sashimiBalance(comptroller, acct)).toEqualNumber(etherExp(1.25)); } }); - it('claims comp for multiple borrowers only, primes uninitiated', async () => { - const compRemaining = compRate.mul(100), deltaBlocks = 10, mintAmount = etherExp(10), borrowAmt = etherExp(1), borrowIdx = etherExp(1) - await send(comptroller.comp, 'transfer', [comptroller._address, compRemaining], {from: root}); + it('claims sashimi for multiple borrowers only, primes uninitiated', async () => { + const sashimiRemaining = sashimiRate.mul(100), deltaBlocks = 10, mintAmount = etherExp(10), borrowAmt = etherExp(1), borrowIdx = etherExp(1) + await send(comptroller.sashimi, 'transfer', [comptroller._address, sashimiRemaining], {from: root}); let [_,__, ...claimAccts] = saddle.accounts; for(let acct of claimAccts) { - await send(cLOW, 'harnessIncrementTotalBorrows', [borrowAmt]); - await send(cLOW, 'harnessSetAccountBorrows', [acct, borrowAmt, borrowIdx]); + await send(slLOW, 'harnessIncrementTotalBorrows', [borrowAmt]); + await send(slLOW, 'harnessSetAccountBorrows', [acct, borrowAmt, borrowIdx]); } - await send(comptroller, 'refreshCompSpeeds'); + await send(comptroller, 'refreshSashimiSpeeds'); await send(comptroller, 'harnessFastForward', [10]); - const tx = await send(comptroller, 'claimComp', [claimAccts, [cLOW._address], true, false]); + const tx = await send(comptroller, 'claimSashimi', [claimAccts, [slLOW._address], true, false]); for(let acct of claimAccts) { - expect(await call(comptroller, 'compBorrowerIndex', [cLOW._address, acct])).toEqualNumber(etherDouble(2.25)); - expect(await call(comptroller, 'compSupplierIndex', [cLOW._address, acct])).toEqualNumber(0); + expect(await call(comptroller, 'sashimiBorrowerIndex', [slLOW._address, acct])).toEqualNumber(etherDouble(2.25)); + expect(await call(comptroller, 'sashimiSupplierIndex', [slLOW._address, acct])).toEqualNumber(0); } }); it('should revert when a market is not listed', async () => { - const cNOT = await makeCToken({comptroller}); + const cNOT = await makeSLToken({comptroller}); await expect( - send(comptroller, 'claimComp', [[a1, a2], [cNOT._address], true, true]) + send(comptroller, 'claimSashimi', [[a1, a2], [cNOT._address], true, true]) ).rejects.toRevert('revert market must be listed'); }); }); - describe('refreshCompSpeeds', () => { + describe('refreshSashimiSpeeds', () => { it('should start out 0', async () => { - await send(comptroller, 'refreshCompSpeeds'); - const speed = await call(comptroller, 'compSpeeds', [cLOW._address]); + await send(comptroller, 'refreshSashimiSpeeds'); + const speed = await call(comptroller, 'sashimiSpeeds', [slLOW._address]); expect(speed).toEqualNumber(0); }); it('should get correct speeds with borrows', async () => { - await pretendBorrow(cLOW, a1, 1, 1, 100); - const tx = await send(comptroller, 'refreshCompSpeeds'); - const speed = await call(comptroller, 'compSpeeds', [cLOW._address]); - expect(speed).toEqualNumber(compRate); - expect(tx).toHaveLog(['CompSpeedUpdated', 0], { - cToken: cLOW._address, + await pretendBorrow(slLOW, a1, 1, 1, 100); + const tx = await send(comptroller, 'refreshSashimiSpeeds'); + const speed = await call(comptroller, 'sashimiSpeeds', [slLOW._address]); + expect(speed).toEqualNumber(sashimiRate); + expect(tx).toHaveLog(['SashimiSpeedUpdated', 0], { + slToken: slLOW._address, newSpeed: speed }); - expect(tx).toHaveLog(['CompSpeedUpdated', 1], { - cToken: cREP._address, + expect(tx).toHaveLog(['SashimiSpeedUpdated', 1], { + slToken: slREP._address, newSpeed: 0 }); - expect(tx).toHaveLog(['CompSpeedUpdated', 2], { - cToken: cZRX._address, + expect(tx).toHaveLog(['SashimiSpeedUpdated', 2], { + slToken: slZRX._address, newSpeed: 0 }); }); it('should get correct speeds for 2 assets', async () => { - await pretendBorrow(cLOW, a1, 1, 1, 100); - await pretendBorrow(cZRX, a1, 1, 1, 100); - await send(comptroller, 'refreshCompSpeeds'); - const speed1 = await call(comptroller, 'compSpeeds', [cLOW._address]); - const speed2 = await call(comptroller, 'compSpeeds', [cREP._address]); - const speed3 = await call(comptroller, 'compSpeeds', [cZRX._address]); - expect(speed1).toEqualNumber(compRate.div(4)); + await pretendBorrow(slLOW, a1, 1, 1, 100); + await pretendBorrow(slZRX, a1, 1, 1, 100); + await send(comptroller, 'refreshSashimiSpeeds'); + const speed1 = await call(comptroller, 'sashimiSpeeds', [slLOW._address]); + const speed2 = await call(comptroller, 'sashimiSpeeds', [slREP._address]); + const speed3 = await call(comptroller, 'sashimiSpeeds', [slZRX._address]); + expect(speed1).toEqualNumber(sashimiRate.div(4)); expect(speed2).toEqualNumber(0); - expect(speed3).toEqualNumber(compRate.div(4).mul(3)); + expect(speed3).toEqualNumber(sashimiRate.div(4).mul(3)); }); it('should not be callable inside a contract', async () => { - await pretendBorrow(cLOW, a1, 1, 1, 100); - await pretendBorrow(cZRX, a1, 1, 1, 100); + await pretendBorrow(slLOW, a1, 1, 1, 100); + await pretendBorrow(slZRX, a1, 1, 1, 100); await expect(deploy('RefreshSpeedsProxy', [comptroller._address])).rejects.toRevert('revert only externally owned accounts may refresh speeds'); }); }); - describe('_addCompMarkets', () => { - it('should correctly add a comp market if called by admin', async () => { - const cBAT = await makeCToken({comptroller, supportMarket: true}); - const tx = await send(comptroller, '_addCompMarkets', [[cBAT._address]]); - const markets = await call(comptroller, 'getCompMarkets'); - expect(markets).toEqual([cLOW, cREP, cZRX, cBAT].map((c) => c._address)); - expect(tx).toHaveLog('MarketComped', { - cToken: cBAT._address, - isComped: true + describe('_addSashimiMarkets', () => { + it('should correctly add a sashimi market if called by admin', async () => { + const slBAT = await makeSLToken({comptroller, supportMarket: true}); + const tx = await send(comptroller, '_addSashimiMarkets', [[slBAT._address]]); + const markets = await call(comptroller, 'getSashimiMarkets'); + expect(markets).toEqual([slLOW, slREP, slZRX, slBAT].map((c) => c._address)); + expect(tx).toHaveLog('MarketSashimied', { + slToken: slBAT._address, + isSashimied: true }); }); it('should revert if not called by admin', async () => { - const cBAT = await makeCToken({ comptroller, supportMarket: true }); + const slBAT = await makeSLToken({ comptroller, supportMarket: true }); await expect( - send(comptroller, '_addCompMarkets', [[cBAT._address]], {from: a1}) - ).rejects.toRevert('revert only admin can add comp market'); + send(comptroller, '_addSashimiMarkets', [[slBAT._address]], {from: a1}) + ).rejects.toRevert('revert only admin can add sashimi market'); }); it('should not add non-listed markets', async () => { - const cBAT = await makeCToken({ comptroller, supportMarket: false }); + const slBAT = await makeSLToken({ comptroller, supportMarket: false }); await expect( - send(comptroller, '_addCompMarkets', [[cBAT._address]]) - ).rejects.toRevert('revert comp market is not listed'); + send(comptroller, '_addSashimiMarkets', [[slBAT._address]]) + ).rejects.toRevert('revert sashimi market is not listed'); - const markets = await call(comptroller, 'getCompMarkets'); - expect(markets).toEqual([cLOW, cREP, cZRX].map((c) => c._address)); + const markets = await call(comptroller, 'getSashimiMarkets'); + expect(markets).toEqual([slLOW, slREP, slZRX].map((c) => c._address)); }); it('should not add duplicate markets', async () => { - const cBAT = await makeCToken({comptroller, supportMarket: true}); - await send(comptroller, '_addCompMarkets', [[cBAT._address]]); + const slBAT = await makeSLToken({comptroller, supportMarket: true}); + await send(comptroller, '_addSashimiMarkets', [[slBAT._address]]); await expect( - send(comptroller, '_addCompMarkets', [[cBAT._address]]) - ).rejects.toRevert('revert comp market already added'); + send(comptroller, '_addSashimiMarkets', [[slBAT._address]]) + ).rejects.toRevert('revert sashimi market already added'); }); it('should not write over a markets existing state', async () => { - const mkt = cLOW._address; + const mkt = slLOW._address; const bn0 = 10, bn1 = 20; const idx = etherUnsigned(1.5e36); - await send(comptroller, "setCompSupplyState", [mkt, idx, bn0]); - await send(comptroller, "setCompBorrowState", [mkt, idx, bn0]); + await send(comptroller, "setSashimiSupplyState", [mkt, idx, bn0]); + await send(comptroller, "setSashimiBorrowState", [mkt, idx, bn0]); await send(comptroller, "setBlockNumber", [bn1]); - await send(comptroller, "_dropCompMarket", [mkt]); - await send(comptroller, "_addCompMarkets", [[mkt]]); + await send(comptroller, "_dropSashimiMarket", [mkt]); + await send(comptroller, "_addSashimiMarkets", [[mkt]]); - const supplyState = await call(comptroller, 'compSupplyState', [mkt]); + const supplyState = await call(comptroller, 'sashimiSupplyState', [mkt]); expect(supplyState.block).toEqual(bn1.toString()); expect(supplyState.index).toEqual(idx.toString()); - const borrowState = await call(comptroller, 'compBorrowState', [mkt]); + const borrowState = await call(comptroller, 'sashimiBorrowState', [mkt]); expect(borrowState.block).toEqual(bn1.toString()); expect(borrowState.index).toEqual(idx.toString()); }); }); - describe('_dropCompMarket', () => { - it('should correctly drop a comp market if called by admin', async () => { - const tx = await send(comptroller, '_dropCompMarket', [cLOW._address]); - expect(await call(comptroller, 'getCompMarkets')).toEqual( - [cREP, cZRX].map((c) => c._address) + describe('_dropSashimiMarket', () => { + it('should correctly drop a sashimi market if called by admin', async () => { + const tx = await send(comptroller, '_dropSashimiMarket', [slLOW._address]); + expect(await call(comptroller, 'getSashimiMarkets')).toEqual( + [slREP, slZRX].map((c) => c._address) ); - expect(tx).toHaveLog('MarketComped', { - cToken: cLOW._address, - isComped: false + expect(tx).toHaveLog('MarketSashimied', { + slToken: slLOW._address, + isSashimied: false }); }); - it('should correctly drop a comp market from middle of array', async () => { - await send(comptroller, '_dropCompMarket', [cREP._address]); - expect(await call(comptroller, 'getCompMarkets')).toEqual( - [cLOW, cZRX].map((c) => c._address) + it('should correctly drop a sashimi market from middle of array', async () => { + await send(comptroller, '_dropSashimiMarket', [slREP._address]); + expect(await call(comptroller, 'getSashimiMarkets')).toEqual( + [slLOW, slZRX].map((c) => c._address) ); }); - it('should not drop a comp market unless called by admin', async () => { + it('should not drop a sashimi market unless called by admin', async () => { await expect( - send(comptroller, '_dropCompMarket', [cLOW._address], {from: a1}) - ).rejects.toRevert('revert only admin can drop comp market'); + send(comptroller, '_dropSashimiMarket', [slLOW._address], {from: a1}) + ).rejects.toRevert('revert only admin can drop sashimi market'); }); - it('should not drop a comp market already dropped', async () => { - await send(comptroller, '_dropCompMarket', [cLOW._address]); + it('should not drop a sashimi market already dropped', async () => { + await send(comptroller, '_dropSashimiMarket', [slLOW._address]); await expect( - send(comptroller, '_dropCompMarket', [cLOW._address]) - ).rejects.toRevert('revert market is not a comp market'); + send(comptroller, '_dropSashimiMarket', [slLOW._address]) + ).rejects.toRevert('revert market is not a sashimi market'); }); }); - describe('_setCompRate', () => { - it('should correctly change comp rate if called by admin', async () => { - expect(await call(comptroller, 'compRate')).toEqualNumber(etherUnsigned(1e18)); - const tx1 = await send(comptroller, '_setCompRate', [etherUnsigned(3e18)]); - expect(await call(comptroller, 'compRate')).toEqualNumber(etherUnsigned(3e18)); - const tx2 = await send(comptroller, '_setCompRate', [etherUnsigned(2e18)]); - expect(await call(comptroller, 'compRate')).toEqualNumber(etherUnsigned(2e18)); - expect(tx2).toHaveLog('NewCompRate', { - oldCompRate: etherUnsigned(3e18), - newCompRate: etherUnsigned(2e18) + describe('_setSashimiRate', () => { + it('should correctly change sashimi rate if called by admin', async () => { + expect(await call(comptroller, 'sashimiRate')).toEqualNumber(etherUnsigned(1e18)); + const tx1 = await send(comptroller, '_setSashimiRate', [etherUnsigned(3e18)]); + expect(await call(comptroller, 'sashimiRate')).toEqualNumber(etherUnsigned(3e18)); + const tx2 = await send(comptroller, '_setSashimiRate', [etherUnsigned(2e18)]); + expect(await call(comptroller, 'sashimiRate')).toEqualNumber(etherUnsigned(2e18)); + expect(tx2).toHaveLog('NewSashimiRate', { + oldSashimiRate: etherUnsigned(3e18), + newSashimiRate: etherUnsigned(2e18) }); }); - it('should not change comp rate unless called by admin', async () => { + it('should not change sashimi rate unless called by admin', async () => { await expect( - send(comptroller, '_setCompRate', [cLOW._address], {from: a1}) - ).rejects.toRevert('revert only admin can change comp rate'); + send(comptroller, '_setSashimiRate', [slLOW._address], {from: a1}) + ).rejects.toRevert('revert only admin can change sashimi rate'); }); }); }); diff --git a/tests/Flywheel/GasTest.js b/tests/Flywheel/GasTest.js index 8f55cb820..a8b8be7a8 100644 --- a/tests/Flywheel/GasTest.js +++ b/tests/Flywheel/GasTest.js @@ -1,7 +1,7 @@ const { makeComptroller, - makeCToken -} = require('../Utils/Compound'); + makeSLToken +} = require('../Utils/SashimiLending'); const { etherExp, etherDouble, @@ -17,16 +17,16 @@ describe.skip('Flywheel trace ops', () => { let interestRateModelOpts = {borrowRate: 0.000001}; [root, a1, a2, a3, ...accounts] = saddle.accounts; comptroller = await makeComptroller(); - market = await makeCToken({comptroller, supportMarket: true, underlyingPrice: 3, interestRateModelOpts}); - await send(comptroller, '_addCompMarkets', [[market].map(c => c._address)]); + market = await makeSLToken({comptroller, supportMarket: true, underlyingPrice: 3, interestRateModelOpts}); + await send(comptroller, '_addSashimiMarkets', [[market].map(sl => sl._address)]); }); it('update supply index SSTOREs', async () => { await send(comptroller, 'setBlockNumber', [100]); await send(market, 'harnessSetTotalBorrows', [etherUnsigned(11e18)]); - await send(comptroller, 'setCompSpeed', [market._address, etherExp(0.5)]); + await send(comptroller, 'setSashimiSpeed', [market._address, etherExp(0.5)]); - const tx = await send(comptroller, 'harnessUpdateCompSupplyIndex', [market._address]); + const tx = await send(comptroller, 'harnessUpdateSashimiSupplyIndex', [market._address]); const ops = {}; await saddle.trace(tx, { @@ -42,9 +42,9 @@ describe.skip('Flywheel trace ops', () => { it('update borrow index SSTOREs', async () => { await send(comptroller, 'setBlockNumber', [100]); await send(market, 'harnessSetTotalBorrows', [etherUnsigned(11e18)]); - await send(comptroller, 'setCompSpeed', [market._address, etherExp(0.5)]); + await send(comptroller, 'setSashimiSpeed', [market._address, etherExp(0.5)]); - const tx = await send(comptroller, 'harnessUpdateCompBorrowIndex', [market._address, etherExp(1.1)]); + const tx = await send(comptroller, 'harnessUpdateSashimiBorrowIndex', [market._address, etherExp(1.1)]); const ops = {}; await saddle.trace(tx, { diff --git a/tests/Fuzz/CompWheelFuzzTest.js b/tests/Fuzz/CompWheelFuzzTest.js index 837db67bd..87d4ba988 100644 --- a/tests/Fuzz/CompWheelFuzzTest.js +++ b/tests/Fuzz/CompWheelFuzzTest.js @@ -80,7 +80,7 @@ describe.skip('CompWheelFuzzTest', () => { let initialState = globals => { return { - // ctoken + // sltoken accrualBlockNumber: globals.blockNumber, borrowIndex: new bn(1), totalCash: new bn(0), diff --git a/tests/Governance/CompScenarioTest.js b/tests/Governance/CompScenarioTest.js deleted file mode 100644 index 6b088827b..000000000 --- a/tests/Governance/CompScenarioTest.js +++ /dev/null @@ -1,50 +0,0 @@ - -describe('CompScenario', () => { - let root, accounts; - let comp; - - beforeEach(async () => { - [root, ...accounts] = saddle.accounts; - comp = await deploy('CompScenario', [root]); - }); - - describe('lookup curve', () => { - [ - [1, 3], - [2, 5], - [20, 8], - [100, 10], - [500, 12], - ...(process.env['SLOW'] ? [ [5000, 16], [20000, 18] ] : []) - ].forEach(([checkpoints, expectedReads]) => { - it(`with ${checkpoints} checkpoints, has ${expectedReads} reads`, async () => { - let remaining = checkpoints; - let offset = 0; - while (remaining > 0) { - let amt = remaining > 1000 ? 1000 : remaining; - await comp.methods.generateCheckpoints(amt, offset).send({from: root, gas: 200000000}); - remaining -= amt; - offset += amt; - } - - let result = await comp.methods.getPriorVotes(root, 1).send(); - - await saddle.trace(result, { - constants: { - "account": root - }, - preFilter: ({op}) => op === 'SLOAD', - postFilter: ({source}) => !source || !source.includes('mockBlockNumber'), - execLog: (log) => { - if (process.env['VERBOSE']) { - log.show(); - } - }, - exec: (logs, info) => { - expect(logs.length).toEqual(expectedReads); - } - }); - }, 600000); - }); - }); -}); diff --git a/tests/Governance/CompTest.js b/tests/Governance/CompTest.js deleted file mode 100644 index 677e067f6..000000000 --- a/tests/Governance/CompTest.js +++ /dev/null @@ -1,182 +0,0 @@ -const { - address, - minerStart, - minerStop, - unlockedAccount, - mineBlock -} = require('../Utils/Ethereum'); - -const EIP712 = require('../Utils/EIP712'); - -describe('Comp', () => { - const name = 'Compound'; - const symbol = 'COMP'; - - let root, a1, a2, accounts, chainId; - let comp; - - beforeEach(async () => { - [root, a1, a2, ...accounts] = saddle.accounts; - chainId = 1; // await web3.eth.net.getId(); See: https://github.com/trufflesuite/ganache-core/issues/515 - comp = await deploy('Comp', [root]); - }); - - describe('metadata', () => { - it('has given name', async () => { - expect(await call(comp, 'name')).toEqual(name); - }); - - it('has given symbol', async () => { - expect(await call(comp, 'symbol')).toEqual(symbol); - }); - }); - - describe('balanceOf', () => { - it('grants to initial account', async () => { - expect(await call(comp, 'balanceOf', [root])).toEqual("10000000000000000000000000"); - }); - }); - - describe('delegateBySig', () => { - const Domain = (comp) => ({ name, chainId, verifyingContract: comp._address }); - const Types = { - Delegation: [ - { name: 'delegatee', type: 'address' }, - { name: 'nonce', type: 'uint256' }, - { name: 'expiry', type: 'uint256' } - ] - }; - - it('reverts if the signatory is invalid', async () => { - const delegatee = root, nonce = 0, expiry = 0; - await expect(send(comp, 'delegateBySig', [delegatee, nonce, expiry, 0, '0xbad', '0xbad'])).rejects.toRevert("revert Comp::delegateBySig: invalid signature"); - }); - - it('reverts if the nonce is bad ', async () => { - const delegatee = root, nonce = 1, expiry = 0; - const { v, r, s } = EIP712.sign(Domain(comp), 'Delegation', { delegatee, nonce, expiry }, Types, unlockedAccount(a1).secretKey); - await expect(send(comp, 'delegateBySig', [delegatee, nonce, expiry, v, r, s])).rejects.toRevert("revert Comp::delegateBySig: invalid nonce"); - }); - - it('reverts if the signature has expired', async () => { - const delegatee = root, nonce = 0, expiry = 0; - const { v, r, s } = EIP712.sign(Domain(comp), 'Delegation', { delegatee, nonce, expiry }, Types, unlockedAccount(a1).secretKey); - await expect(send(comp, 'delegateBySig', [delegatee, nonce, expiry, v, r, s])).rejects.toRevert("revert Comp::delegateBySig: signature expired"); - }); - - it('delegates on behalf of the signatory', async () => { - const delegatee = root, nonce = 0, expiry = 10e9; - const { v, r, s } = EIP712.sign(Domain(comp), 'Delegation', { delegatee, nonce, expiry }, Types, unlockedAccount(a1).secretKey); - expect(await call(comp, 'delegates', [a1])).toEqual(address(0)); - const tx = await send(comp, 'delegateBySig', [delegatee, nonce, expiry, v, r, s]); - expect(tx.gasUsed < 80000); - expect(await call(comp, 'delegates', [a1])).toEqual(root); - }); - }); - - describe('numCheckpoints', () => { - it('returns the number of checkpoints for a delegate', async () => { - let guy = accounts[0]; - await send(comp, 'transfer', [guy, '100']); //give an account a few tokens for readability - await expect(call(comp, 'numCheckpoints', [a1])).resolves.toEqual('0'); - - const t1 = await send(comp, 'delegate', [a1], { from: guy }); - await expect(call(comp, 'numCheckpoints', [a1])).resolves.toEqual('1'); - - const t2 = await send(comp, 'transfer', [a2, 10], { from: guy }); - await expect(call(comp, 'numCheckpoints', [a1])).resolves.toEqual('2'); - - const t3 = await send(comp, 'transfer', [a2, 10], { from: guy }); - await expect(call(comp, 'numCheckpoints', [a1])).resolves.toEqual('3'); - - const t4 = await send(comp, 'transfer', [guy, 20], { from: root }); - await expect(call(comp, 'numCheckpoints', [a1])).resolves.toEqual('4'); - - await expect(call(comp, 'checkpoints', [a1, 0])).resolves.toEqual(expect.objectContaining({ fromBlock: t1.blockNumber.toString(), votes: '100' })); - await expect(call(comp, 'checkpoints', [a1, 1])).resolves.toEqual(expect.objectContaining({ fromBlock: t2.blockNumber.toString(), votes: '90' })); - await expect(call(comp, 'checkpoints', [a1, 2])).resolves.toEqual(expect.objectContaining({ fromBlock: t3.blockNumber.toString(), votes: '80' })); - await expect(call(comp, 'checkpoints', [a1, 3])).resolves.toEqual(expect.objectContaining({ fromBlock: t4.blockNumber.toString(), votes: '100' })); - }); - - it('does not add more than one checkpoint in a block', async () => { - let guy = accounts[0]; - - await send(comp, 'transfer', [guy, '100']); //give an account a few tokens for readability - await expect(call(comp, 'numCheckpoints', [a1])).resolves.toEqual('0'); - await minerStop(); - - let t1 = send(comp, 'delegate', [a1], { from: guy }); - let t2 = send(comp, 'transfer', [a2, 10], { from: guy }); - let t3 = send(comp, 'transfer', [a2, 10], { from: guy }); - - await minerStart(); - t1 = await t1; - t2 = await t2; - t3 = await t3; - - await expect(call(comp, 'numCheckpoints', [a1])).resolves.toEqual('1'); - - await expect(call(comp, 'checkpoints', [a1, 0])).resolves.toEqual(expect.objectContaining({ fromBlock: t1.blockNumber.toString(), votes: '80' })); - await expect(call(comp, 'checkpoints', [a1, 1])).resolves.toEqual(expect.objectContaining({ fromBlock: '0', votes: '0' })); - await expect(call(comp, 'checkpoints', [a1, 2])).resolves.toEqual(expect.objectContaining({ fromBlock: '0', votes: '0' })); - - const t4 = await send(comp, 'transfer', [guy, 20], { from: root }); - await expect(call(comp, 'numCheckpoints', [a1])).resolves.toEqual('2'); - await expect(call(comp, 'checkpoints', [a1, 1])).resolves.toEqual(expect.objectContaining({ fromBlock: t4.blockNumber.toString(), votes: '100' })); - }); - }); - - describe('getPriorVotes', () => { - it('reverts if block number >= current block', async () => { - await expect(call(comp, 'getPriorVotes', [a1, 5e10])).rejects.toRevert("revert Comp::getPriorVotes: not yet determined"); - }); - - it('returns 0 if there are no checkpoints', async () => { - expect(await call(comp, 'getPriorVotes', [a1, 0])).toEqual('0'); - }); - - it('returns the latest block if >= last checkpoint block', async () => { - const t1 = await send(comp, 'delegate', [a1], { from: root }); - await mineBlock(); - await mineBlock(); - - expect(await call(comp, 'getPriorVotes', [a1, t1.blockNumber])).toEqual('10000000000000000000000000'); - expect(await call(comp, 'getPriorVotes', [a1, t1.blockNumber + 1])).toEqual('10000000000000000000000000'); - }); - - it('returns zero if < first checkpoint block', async () => { - await mineBlock(); - const t1 = await send(comp, 'delegate', [a1], { from: root }); - await mineBlock(); - await mineBlock(); - - expect(await call(comp, 'getPriorVotes', [a1, t1.blockNumber - 1])).toEqual('0'); - expect(await call(comp, 'getPriorVotes', [a1, t1.blockNumber + 1])).toEqual('10000000000000000000000000'); - }); - - it('generally returns the voting balance at the appropriate checkpoint', async () => { - const t1 = await send(comp, 'delegate', [a1], { from: root }); - await mineBlock(); - await mineBlock(); - const t2 = await send(comp, 'transfer', [a2, 10], { from: root }); - await mineBlock(); - await mineBlock(); - const t3 = await send(comp, 'transfer', [a2, 10], { from: root }); - await mineBlock(); - await mineBlock(); - const t4 = await send(comp, 'transfer', [root, 20], { from: a2 }); - await mineBlock(); - await mineBlock(); - - expect(await call(comp, 'getPriorVotes', [a1, t1.blockNumber - 1])).toEqual('0'); - expect(await call(comp, 'getPriorVotes', [a1, t1.blockNumber])).toEqual('10000000000000000000000000'); - expect(await call(comp, 'getPriorVotes', [a1, t1.blockNumber + 1])).toEqual('10000000000000000000000000'); - expect(await call(comp, 'getPriorVotes', [a1, t2.blockNumber])).toEqual('9999999999999999999999990'); - expect(await call(comp, 'getPriorVotes', [a1, t2.blockNumber + 1])).toEqual('9999999999999999999999990'); - expect(await call(comp, 'getPriorVotes', [a1, t3.blockNumber])).toEqual('9999999999999999999999980'); - expect(await call(comp, 'getPriorVotes', [a1, t3.blockNumber + 1])).toEqual('9999999999999999999999980'); - expect(await call(comp, 'getPriorVotes', [a1, t4.blockNumber])).toEqual('10000000000000000000000000'); - expect(await call(comp, 'getPriorVotes', [a1, t4.blockNumber + 1])).toEqual('10000000000000000000000000'); - }); - }); -}); diff --git a/tests/Governance/GovernorAlpha/CastVoteTest.js b/tests/Governance/GovernorAlpha/CastVoteTest.js deleted file mode 100644 index 8281dfafa..000000000 --- a/tests/Governance/GovernorAlpha/CastVoteTest.js +++ /dev/null @@ -1,184 +0,0 @@ -const { - address, - etherMantissa, - encodeParameters, - mineBlock, - unlockedAccount -} = require('../../Utils/Ethereum'); -const EIP712 = require('../../Utils/EIP712'); -const BigNumber = require('bignumber.js'); -const chalk = require('chalk'); - -async function enfranchise(comp, actor, amount) { - await send(comp, 'transfer', [actor, etherMantissa(amount)]); - await send(comp, 'delegate', [actor], { from: actor }); -} - -describe("governorAlpha#castVote/2", () => { - let comp, gov, root, a1, accounts; - let targets, values, signatures, callDatas, proposalId; - - beforeAll(async () => { - [root, a1, ...accounts] = saddle.accounts; - comp = await deploy('Comp', [root]); - gov = await deploy('GovernorAlpha', [address(0), comp._address, root]); - - targets = [a1]; - values = ["0"]; - signatures = ["getBalanceOf(address)"]; - callDatas = [encodeParameters(['address'], [a1])]; - await send(comp, 'delegate', [root]); - await send(gov, 'propose', [targets, values, signatures, callDatas, "do nothing"]); - proposalId = await call(gov, 'latestProposalIds', [root]); - }); - - describe("We must revert if:", () => { - it("There does not exist a proposal with matching proposal id where the current block number is between the proposal's start block (exclusive) and end block (inclusive)", async () => { - await expect( - call(gov, 'castVote', [proposalId, true]) - ).rejects.toRevert("revert GovernorAlpha::_castVote: voting is closed"); - }); - - it("Such proposal already has an entry in its voters set matching the sender", async () => { - await mineBlock(); - await mineBlock(); - - await send(gov, 'castVote', [proposalId, true], { from: accounts[4] }); - await expect( - gov.methods['castVote'](proposalId, true).call({ from: accounts[4] }) - ).rejects.toRevert("revert GovernorAlpha::_castVote: voter already voted"); - }); - }); - - describe("Otherwise", () => { - it("we add the sender to the proposal's voters set", async () => { - await expect(call(gov, 'getReceipt', [proposalId, accounts[2]])).resolves.toPartEqual({hasVoted: false}); - await send(gov, 'castVote', [proposalId, true], { from: accounts[2] }); - await expect(call(gov, 'getReceipt', [proposalId, accounts[2]])).resolves.toPartEqual({hasVoted: true}); - }); - - describe("and we take the balance returned by GetPriorVotes for the given sender and the proposal's start block, which may be zero,", () => { - let actor; // an account that will propose, receive tokens, delegate to self, and vote on own proposal - - it("and we add that ForVotes", async () => { - actor = accounts[1]; - await enfranchise(comp, actor, 400001); - - await send(gov, 'propose', [targets, values, signatures, callDatas, "do nothing"], { from: actor }); - proposalId = await call(gov, 'latestProposalIds', [actor]); - - let beforeFors = (await call(gov, 'proposals', [proposalId])).forVotes; - await mineBlock(); - await send(gov, 'castVote', [proposalId, true], { from: actor }); - - let afterFors = (await call(gov, 'proposals', [proposalId])).forVotes; - expect(new BigNumber(afterFors)).toEqual(new BigNumber(beforeFors).plus(etherMantissa(400001))); - }) - - it("or AgainstVotes corresponding to the caller's support flag.", async () => { - actor = accounts[3]; - await enfranchise(comp, actor, 400001); - - await send(gov, 'propose', [targets, values, signatures, callDatas, "do nothing"], { from: actor }); - proposalId = await call(gov, 'latestProposalIds', [actor]);; - - let beforeAgainsts = (await call(gov, 'proposals', [proposalId])).againstVotes; - await mineBlock(); - await send(gov, 'castVote', [proposalId, false], { from: actor }); - - let afterAgainsts = (await call(gov, 'proposals', [proposalId])).againstVotes; - expect(new BigNumber(afterAgainsts)).toEqual(new BigNumber(beforeAgainsts).plus(etherMantissa(400001))); - }); - }); - - describe('castVoteBySig', () => { - const Domain = (gov) => ({ - name: 'Compound Governor Alpha', - chainId: 1, // await web3.eth.net.getId(); See: https://github.com/trufflesuite/ganache-core/issues/515 - verifyingContract: gov._address - }); - const Types = { - Ballot: [ - { name: 'proposalId', type: 'uint256' }, - { name: 'support', type: 'bool' } - ] - }; - - it('reverts if the signatory is invalid', async () => { - await expect(send(gov, 'castVoteBySig', [proposalId, false, 0, '0xbad', '0xbad'])).rejects.toRevert("revert GovernorAlpha::castVoteBySig: invalid signature"); - }); - - it('casts vote on behalf of the signatory', async () => { - await enfranchise(comp, a1, 400001); - await send(gov, 'propose', [targets, values, signatures, callDatas, "do nothing"], { from: a1 }); - proposalId = await call(gov, 'latestProposalIds', [a1]);; - - const { v, r, s } = EIP712.sign(Domain(gov), 'Ballot', { proposalId, support: true }, Types, unlockedAccount(a1).secretKey); - - let beforeFors = (await call(gov, 'proposals', [proposalId])).forVotes; - await mineBlock(); - const tx = await send(gov, 'castVoteBySig', [proposalId, true, v, r, s]); - expect(tx.gasUsed < 80000); - - let afterFors = (await call(gov, 'proposals', [proposalId])).forVotes; - expect(new BigNumber(afterFors)).toEqual(new BigNumber(beforeFors).plus(etherMantissa(400001))); - }); - }); - - it("receipt uses one load", async () => { - let actor = accounts[2]; - let actor2 = accounts[3]; - await enfranchise(comp, actor, 400001); - await enfranchise(comp, actor2, 400001); - await send(gov, 'propose', [targets, values, signatures, callDatas, "do nothing"], { from: actor }); - proposalId = await call(gov, 'latestProposalIds', [actor]); - - await mineBlock(); - await mineBlock(); - await send(gov, 'castVote', [proposalId, true], { from: actor }); - await send(gov, 'castVote', [proposalId, false], { from: actor2 }); - - let trxReceipt = await send(gov, 'getReceipt', [proposalId, actor]); - let trxReceipt2 = await send(gov, 'getReceipt', [proposalId, actor2]); - - await saddle.trace(trxReceipt, { - constants: { - "account": actor - }, - preFilter: ({op}) => op === 'SLOAD', - postFilter: ({source}) => !source || source.includes('receipts'), - execLog: (log) => { - let [output] = log.outputs; - let votes = "000000000000000000000000000000000000000054b419003bdf81640000"; - let voted = "01"; - let support = "01"; - - expect(output).toEqual( - `${votes}${support}${voted}` - ); - }, - exec: (logs) => { - expect(logs.length).toEqual(1); // require only one read - } - }); - - await saddle.trace(trxReceipt2, { - constants: { - "account": actor2 - }, - preFilter: ({op}) => op === 'SLOAD', - postFilter: ({source}) => !source || source.includes('receipts'), - execLog: (log) => { - let [output] = log.outputs; - let votes = "0000000000000000000000000000000000000000a968320077bf02c80000"; - let voted = "01"; - let support = "00"; - - expect(output).toEqual( - `${votes}${support}${voted}` - ); - } - }); - }); - }); -}); \ No newline at end of file diff --git a/tests/Governance/GovernorAlpha/ProposeTest.js b/tests/Governance/GovernorAlpha/ProposeTest.js deleted file mode 100644 index 744892609..000000000 --- a/tests/Governance/GovernorAlpha/ProposeTest.js +++ /dev/null @@ -1,153 +0,0 @@ -const { - address, - etherMantissa, - encodeParameters, - mineBlock -} = require('../../Utils/Ethereum'); - -describe('GovernorAlpha#propose/5', () => { - let gov, root, acct; - - beforeAll(async () => { - [root, acct, ...accounts] = accounts; - comp = await deploy('Comp', [root]); - gov = await deploy('GovernorAlpha', [address(0), comp._address, address(0)]); - }); - - let trivialProposal, targets, values, signatures, callDatas; - let proposalBlock; - beforeAll(async () => { - targets = [root]; - values = ["0"]; - signatures = ["getBalanceOf(address)"]; - callDatas = [encodeParameters(['address'], [acct])]; - await send(comp, 'delegate', [root]); - await send(gov, 'propose', [targets, values, signatures, callDatas, "do nothing"]); - proposalBlock = +(await web3.eth.getBlockNumber()); - proposalId = await call(gov, 'latestProposalIds', [root]); - trivialProposal = await call(gov, "proposals", [proposalId]); - }); - - it("Given the sender's GetPriorVotes for the immediately previous block is above the Proposal Threshold (e.g. 2%), the given proposal is added to all proposals, given the following settings", async () => { - test.todo('depends on get prior votes and delegation and voting'); - }); - - describe("simple initialization", () => { - it("ID is set to a globally unique identifier", async () => { - expect(trivialProposal.id).toEqual(proposalId); - }); - - it("Proposer is set to the sender", async () => { - expect(trivialProposal.proposer).toEqual(root); - }); - - it("Start block is set to the current block number plus vote delay", async () => { - expect(trivialProposal.startBlock).toEqual(proposalBlock + 1 + ""); - }); - - it("End block is set to the current block number plus the sum of vote delay and vote period", async () => { - expect(trivialProposal.endBlock).toEqual(proposalBlock + 1 + 17280 + ""); - }); - - it("ForVotes and AgainstVotes are initialized to zero", async () => { - expect(trivialProposal.forVotes).toEqual("0"); - expect(trivialProposal.againstVotes).toEqual("0"); - }); - - xit("Voters is initialized to the empty set", async () => { - test.todo('mmm probably nothing to prove here unless we add a counter or something'); - }); - - it("Executed and Canceled flags are initialized to false", async () => { - expect(trivialProposal.canceled).toEqual(false); - expect(trivialProposal.executed).toEqual(false); - }); - - it("ETA is initialized to zero", async () => { - expect(trivialProposal.eta).toEqual("0"); - }); - - it("Targets, Values, Signatures, Calldatas are set according to parameters", async () => { - let dynamicFields = await call(gov, 'getActions', [trivialProposal.id]); - expect(dynamicFields.targets).toEqual(targets); - expect(dynamicFields.values).toEqual(values); - expect(dynamicFields.signatures).toEqual(signatures); - expect(dynamicFields.calldatas).toEqual(callDatas); - }); - - describe("This function must revert if", () => { - it("the length of the values, signatures or calldatas arrays are not the same length,", async () => { - await expect( - call(gov, 'propose', [targets.concat(root), values, signatures, callDatas, "do nothing"]) - ).rejects.toRevert("revert GovernorAlpha::propose: proposal function information arity mismatch"); - - await expect( - call(gov, 'propose', [targets, values.concat(values), signatures, callDatas, "do nothing"]) - ).rejects.toRevert("revert GovernorAlpha::propose: proposal function information arity mismatch"); - - await expect( - call(gov, 'propose', [targets, values, signatures.concat(signatures), callDatas, "do nothing"]) - ).rejects.toRevert("revert GovernorAlpha::propose: proposal function information arity mismatch"); - - await expect( - call(gov, 'propose', [targets, values, signatures, callDatas.concat(callDatas), "do nothing"]) - ).rejects.toRevert("revert GovernorAlpha::propose: proposal function information arity mismatch"); - }); - - it("or if that length is zero or greater than Max Operations.", async () => { - await expect( - call(gov, 'propose', [[], [], [], [], "do nothing"]) - ).rejects.toRevert("revert GovernorAlpha::propose: must provide actions"); - }); - - describe("Additionally, if there exists a pending or active proposal from the same proposer, we must revert.", () => { - it("reverts with pending", async () => { - await expect( - call(gov, 'propose', [targets, values, signatures, callDatas, "do nothing"]) - ).rejects.toRevert("revert GovernorAlpha::propose: one live proposal per proposer, found an already pending proposal"); - }); - - it("reverts with active", async () => { - await mineBlock(); - await mineBlock(); - - await expect( - call(gov, 'propose', [targets, values, signatures, callDatas, "do nothing"]) - ).rejects.toRevert("revert GovernorAlpha::propose: one live proposal per proposer, found an already active proposal"); - }); - }); - }); - - it("This function returns the id of the newly created proposal. # proposalId(n) = succ(proposalId(n-1))", async () => { - await send(comp, 'transfer', [accounts[2], etherMantissa(400001)]); - await send(comp, 'delegate', [accounts[2]], { from: accounts[2] }); - - await mineBlock(); - let nextProposalId = await gov.methods['propose'](targets, values, signatures, callDatas, "yoot").call({ from: accounts[2] }); - // let nextProposalId = await call(gov, 'propose', [targets, values, signatures, callDatas, "second proposal"], { from: accounts[2] }); - - expect(+nextProposalId).toEqual(+trivialProposal.id + 1); - }); - - it("emits log with id and description", async () => { - await send(comp, 'transfer', [accounts[3], etherMantissa(400001)]); - await send(comp, 'delegate', [accounts[3]], { from: accounts[3] }); - await mineBlock(); - let nextProposalId = await gov.methods['propose'](targets, values, signatures, callDatas, "yoot").call({ from: accounts[3] }); - - expect( - await send(gov, 'propose', [targets, values, signatures, callDatas, "second proposal"], { from: accounts[3] }) - ).toHaveLog("ProposalCreated", { - id: nextProposalId, - targets: targets, - values: values, - signatures: signatures, - calldatas: callDatas, - startBlock: 14, - endBlock: 17294, - description: "second proposal", - proposer: accounts[3] - }); - }); - }); -}); diff --git a/tests/Governance/GovernorAlpha/QueueTest.js b/tests/Governance/GovernorAlpha/QueueTest.js deleted file mode 100644 index 8eed12512..000000000 --- a/tests/Governance/GovernorAlpha/QueueTest.js +++ /dev/null @@ -1,78 +0,0 @@ -const { - both, - etherMantissa, - encodeParameters, - advanceBlocks, - freezeTime, - mineBlock -} = require('../../Utils/Ethereum'); - -async function enfranchise(comp, actor, amount) { - await send(comp, 'transfer', [actor, etherMantissa(amount)]); - await send(comp, 'delegate', [actor], {from: actor}); -} - -describe('GovernorAlpha#queue/1', () => { - let root, a1, a2, accounts; - beforeAll(async () => { - [root, a1, a2, ...accounts] = saddle.accounts; - }); - - describe("overlapping actions", () => { - it("reverts on queueing overlapping actions in same proposal", async () => { - const timelock = await deploy('TimelockHarness', [root, 86400 * 2]); - const comp = await deploy('Comp', [root]); - const gov = await deploy('GovernorAlpha', [timelock._address, comp._address, root]); - const txAdmin = await send(timelock, 'harnessSetAdmin', [gov._address]); - - await enfranchise(comp, a1, 3e6); - await mineBlock(); - - const targets = [comp._address, comp._address]; - const values = ["0", "0"]; - const signatures = ["getBalanceOf(address)", "getBalanceOf(address)"]; - const calldatas = [encodeParameters(['address'], [root]), encodeParameters(['address'], [root])]; - const {reply: proposalId1} = await both(gov, 'propose', [targets, values, signatures, calldatas, "do nothing"], {from: a1}); - await mineBlock(); - - const txVote1 = await send(gov, 'castVote', [proposalId1, true], {from: a1}); - await advanceBlocks(20000); - - await expect( - send(gov, 'queue', [proposalId1]) - ).rejects.toRevert("revert GovernorAlpha::_queueOrRevert: proposal action already queued at eta"); - }); - - it("reverts on queueing overlapping actions in different proposals, works if waiting", async () => { - const timelock = await deploy('TimelockHarness', [root, 86400 * 2]); - const comp = await deploy('Comp', [root]); - const gov = await deploy('GovernorAlpha', [timelock._address, comp._address, root]); - const txAdmin = await send(timelock, 'harnessSetAdmin', [gov._address]); - - await enfranchise(comp, a1, 3e6); - await enfranchise(comp, a2, 3e6); - await mineBlock(); - - const targets = [comp._address]; - const values = ["0"]; - const signatures = ["getBalanceOf(address)"]; - const calldatas = [encodeParameters(['address'], [root])]; - const {reply: proposalId1} = await both(gov, 'propose', [targets, values, signatures, calldatas, "do nothing"], {from: a1}); - const {reply: proposalId2} = await both(gov, 'propose', [targets, values, signatures, calldatas, "do nothing"], {from: a2}); - await mineBlock(); - - const txVote1 = await send(gov, 'castVote', [proposalId1, true], {from: a1}); - const txVote2 = await send(gov, 'castVote', [proposalId2, true], {from: a2}); - await advanceBlocks(20000); - await freezeTime(100); - - const txQueue1 = await send(gov, 'queue', [proposalId1]); - await expect( - send(gov, 'queue', [proposalId2]) - ).rejects.toRevert("revert GovernorAlpha::_queueOrRevert: proposal action already queued at eta"); - - await freezeTime(101); - const txQueue2 = await send(gov, 'queue', [proposalId2]); - }); - }); -}); diff --git a/tests/Governance/GovernorAlpha/StateTest.js b/tests/Governance/GovernorAlpha/StateTest.js deleted file mode 100644 index d35392852..000000000 --- a/tests/Governance/GovernorAlpha/StateTest.js +++ /dev/null @@ -1,160 +0,0 @@ -const { - advanceBlocks, - etherUnsigned, - both, - encodeParameters, - etherMantissa, - mineBlock, - freezeTime, - increaseTime -} = require('../../Utils/Ethereum'); - -const path = require('path'); -const solparse = require('solparse'); - -const governorAlphaPath = path.join(__dirname, '../../..', 'contracts', 'Governance/GovernorAlpha.sol'); - -const statesInverted = solparse - .parseFile(governorAlphaPath) - .body - .find(k => k.type === 'ContractStatement') - .body - .find(k => k.name == 'ProposalState') - .members - -const states = Object.entries(statesInverted).reduce((obj, [key, value]) => ({ ...obj, [value]: key }), {}); - -describe('GovernorAlpha#state/1', () => { - let comp, gov, root, acct, delay, timelock; - - beforeAll(async () => { - await freezeTime(100); - [root, acct, ...accounts] = accounts; - comp = await deploy('Comp', [root]); - delay = etherUnsigned(2 * 24 * 60 * 60).mul(2) - timelock = await deploy('TimelockHarness', [root, delay]); - gov = await deploy('GovernorAlpha', [timelock._address, comp._address, root]); - await send(timelock, "harnessSetAdmin", [gov._address]) - await send(comp, 'transfer', [acct, etherMantissa(4000000)]); - await send(comp, 'delegate', [acct], { from: acct }); - }); - - let trivialProposal, targets, values, signatures, callDatas; - beforeAll(async () => { - targets = [root]; - values = ["0"]; - signatures = ["getBalanceOf(address)"] - callDatas = [encodeParameters(['address'], [acct])]; - await send(comp, 'delegate', [root]); - await send(gov, 'propose', [targets, values, signatures, callDatas, "do nothing"]); - proposalId = await call(gov, 'latestProposalIds', [root]); - trivialProposal = await call(gov, "proposals", [proposalId]) - }) - - it("Invalid for proposal not found", async () => { - await expect(call(gov, 'state', ["5"])).rejects.toRevert("revert GovernorAlpha::state: invalid proposal id") - }) - - it("Pending", async () => { - expect(await call(gov, 'state', [trivialProposal.id], {})).toEqual(states["Pending"]) - }) - - it("Active", async () => { - await mineBlock() - await mineBlock() - expect(await call(gov, 'state', [trivialProposal.id], {})).toEqual(states["Active"]) - }) - - it("Canceled", async () => { - await send(comp, 'transfer', [accounts[0], etherMantissa(4000000)]); - await send(comp, 'delegate', [accounts[0]], { from: accounts[0] }); - await mineBlock() - await send(gov, 'propose', [targets, values, signatures, callDatas, "do nothing"], { from: accounts[0] }) - let newProposalId = await call(gov, 'proposalCount') - - // send away the delegates - await send(comp, 'delegate', [root], { from: accounts[0] }); - await send(gov, 'cancel', [newProposalId]) - - expect(await call(gov, 'state', [+newProposalId])).toEqual(states["Canceled"]) - }) - - it("Defeated", async () => { - // travel to end block - await advanceBlocks(20000) - - expect(await call(gov, 'state', [trivialProposal.id])).toEqual(states["Defeated"]) - }) - - it("Succeeded", async () => { - await mineBlock() - const { reply: newProposalId } = await both(gov, 'propose', [targets, values, signatures, callDatas, "do nothing"], { from: acct }) - await mineBlock() - await send(gov, 'castVote', [newProposalId, true]) - await advanceBlocks(20000) - - expect(await call(gov, 'state', [newProposalId])).toEqual(states["Succeeded"]) - }) - - it("Queued", async () => { - await mineBlock() - const { reply: newProposalId } = await both(gov, 'propose', [targets, values, signatures, callDatas, "do nothing"], { from: acct }) - await mineBlock() - await send(gov, 'castVote', [newProposalId, true]) - await advanceBlocks(20000) - - await send(gov, 'queue', [newProposalId], { from: acct }) - expect(await call(gov, 'state', [newProposalId])).toEqual(states["Queued"]) - }) - - it("Expired", async () => { - await mineBlock() - const { reply: newProposalId } = await both(gov, 'propose', [targets, values, signatures, callDatas, "do nothing"], { from: acct }) - await mineBlock() - await send(gov, 'castVote', [newProposalId, true]) - await advanceBlocks(20000) - - await increaseTime(1) - await send(gov, 'queue', [newProposalId], { from: acct }) - - let gracePeriod = await call(timelock, 'GRACE_PERIOD') - let p = await call(gov, "proposals", [newProposalId]); - let eta = etherUnsigned(p.eta) - - await freezeTime(eta.add(gracePeriod).sub(1).toNumber()) - - expect(await call(gov, 'state', [newProposalId])).toEqual(states["Queued"]) - - await freezeTime(eta.add(gracePeriod).toNumber()) - - expect(await call(gov, 'state', [newProposalId])).toEqual(states["Expired"]) - }) - - it("Executed", async () => { - await mineBlock() - const { reply: newProposalId } = await both(gov, 'propose', [targets, values, signatures, callDatas, "do nothing"], { from: acct }) - await mineBlock() - await send(gov, 'castVote', [newProposalId, true]) - await advanceBlocks(20000) - - await increaseTime(1) - await send(gov, 'queue', [newProposalId], { from: acct }) - - let gracePeriod = await call(timelock, 'GRACE_PERIOD') - let p = await call(gov, "proposals", [newProposalId]); - let eta = etherUnsigned(p.eta) - - await freezeTime(eta.add(gracePeriod).sub(1).toNumber()) - - expect(await call(gov, 'state', [newProposalId])).toEqual(states["Queued"]) - await send(gov, 'execute', [newProposalId], { from: acct }) - - expect(await call(gov, 'state', [newProposalId])).toEqual(states["Executed"]) - - // still executed even though would be expired - await freezeTime(eta.add(gracePeriod).toNumber()) - - expect(await call(gov, 'state', [newProposalId])).toEqual(states["Executed"]) - }) - -}) \ No newline at end of file diff --git a/tests/Lens/CompoundLensTest.js b/tests/Lens/CompoundLensTest.js index de26de925..a2428c052 100644 --- a/tests/Lens/CompoundLensTest.js +++ b/tests/Lens/CompoundLensTest.js @@ -4,8 +4,8 @@ const { } = require('../Utils/Ethereum'); const { makeComptroller, - makeCToken, -} = require('../Utils/Compound'); + makeSLToken, +} = require('../Utils/SashimiLending'); function cullTuple(tuple) { return Object.keys(tuple).reduce((acc, key) => { @@ -20,23 +20,23 @@ function cullTuple(tuple) { }, {}); } -describe('CompoundLens', () => { - let compoundLens; +describe('SashimiLendingLens', () => { + let sashimiLendingLens; let acct; beforeEach(async () => { - compoundLens = await deploy('CompoundLens'); + sashimiLendingLens = await deploy('SashimiLendingLens'); acct = accounts[0]; }); - describe('cTokenMetadata', () => { - it('is correct for a cErc20', async () => { - let cErc20 = await makeCToken(); + describe('slTokenMetadata', () => { + it('is correct for a slErc20', async () => { + let slErc20 = await makeSLToken(); expect( - cullTuple(await call(compoundLens, 'cTokenMetadata', [cErc20._address])) + cullTuple(await call(sashimiLendingLens, 'slTokenMetadata', [slErc20._address])) ).toEqual( { - cToken: cErc20._address, + slToken: slErc20._address, exchangeRateCurrent: "1000000000000000000", supplyRatePerBlock: "0", borrowRatePerBlock: "0", @@ -47,21 +47,21 @@ describe('CompoundLens', () => { totalCash: "0", isListed:false, collateralFactorMantissa: "0", - underlyingAssetAddress: await call(cErc20, 'underlying', []), - cTokenDecimals: "8", + underlyingAssetAddress: await call(slErc20, 'underlying', []), + slTokenDecimals: "8", underlyingDecimals: "18" } ); }); - it('is correct for cEth', async () => { - let cEth = await makeCToken({kind: 'cether'}); + it('is correct for slEth', async () => { + let slEth = await makeSLToken({kind: 'slether'}); expect( - cullTuple(await call(compoundLens, 'cTokenMetadata', [cEth._address])) + cullTuple(await call(sashimiLendingLens, 'slTokenMetadata', [slEth._address])) ).toEqual({ borrowRatePerBlock: "0", - cToken: cEth._address, - cTokenDecimals: "8", + slToken: slEth._address, + slTokenDecimals: "8", collateralFactorMantissa: "0", exchangeRateCurrent: "1000000000000000000", isListed: false, @@ -77,15 +77,15 @@ describe('CompoundLens', () => { }); }); - describe('cTokenMetadataAll', () => { - it('is correct for a cErc20 and cEther', async () => { - let cErc20 = await makeCToken(); - let cEth = await makeCToken({kind: 'cether'}); + describe('slTokenMetadataAll', () => { + it('is correct for a slErc20 and slEther', async () => { + let slErc20 = await makeSLToken(); + let slEth = await makeSLToken({kind: 'slether'}); expect( - (await call(compoundLens, 'cTokenMetadataAll', [[cErc20._address, cEth._address]])).map(cullTuple) + (await call(sashimiLendingLens, 'slTokenMetadataAll', [[slErc20._address, slEth._address]])).map(cullTuple) ).toEqual([ { - cToken: cErc20._address, + slToken: slErc20._address, exchangeRateCurrent: "1000000000000000000", supplyRatePerBlock: "0", borrowRatePerBlock: "0", @@ -96,14 +96,14 @@ describe('CompoundLens', () => { totalCash: "0", isListed:false, collateralFactorMantissa: "0", - underlyingAssetAddress: await call(cErc20, 'underlying', []), - cTokenDecimals: "8", + underlyingAssetAddress: await call(slErc20, 'underlying', []), + slTokenDecimals: "8", underlyingDecimals: "18" }, { borrowRatePerBlock: "0", - cToken: cEth._address, - cTokenDecimals: "8", + slToken: slEth._address, + slTokenDecimals: "8", collateralFactorMantissa: "0", exchangeRateCurrent: "1000000000000000000", isListed: false, @@ -120,34 +120,34 @@ describe('CompoundLens', () => { }); }); - describe('cTokenBalances', () => { - it('is correct for cERC20', async () => { - let cErc20 = await makeCToken(); + describe('slTokenBalances', () => { + it('is correct for slERC20', async () => { + let slErc20 = await makeSLToken(); expect( - cullTuple(await call(compoundLens, 'cTokenBalances', [cErc20._address, acct])) + cullTuple(await call(sashimiLendingLens, 'slTokenBalances', [slErc20._address, acct])) ).toEqual( { balanceOf: "0", balanceOfUnderlying: "0", borrowBalanceCurrent: "0", - cToken: cErc20._address, + slToken: slErc20._address, tokenAllowance: "0", tokenBalance: "10000000000000000000000000", } ); }); - it('is correct for cETH', async () => { - let cEth = await makeCToken({kind: 'cether'}); + it('is correct for slETH', async () => { + let slEth = await makeSLToken({kind: 'slether'}); let ethBalance = await web3.eth.getBalance(acct); expect( - cullTuple(await call(compoundLens, 'cTokenBalances', [cEth._address, acct], {gasPrice: '0'})) + cullTuple(await call(sashimiLendingLens, 'slTokenBalances', [slEth._address, acct], {gasPrice: '0'})) ).toEqual( { balanceOf: "0", balanceOfUnderlying: "0", borrowBalanceCurrent: "0", - cToken: cEth._address, + slToken: slEth._address, tokenAllowance: ethBalance, tokenBalance: ethBalance, } @@ -155,20 +155,20 @@ describe('CompoundLens', () => { }); }); - describe('cTokenBalancesAll', () => { - it('is correct for cEth and cErc20', async () => { - let cErc20 = await makeCToken(); - let cEth = await makeCToken({kind: 'cether'}); + describe('slTokenBalancesAll', () => { + it('is correct for slEth and slErc20', async () => { + let slErc20 = await makeSLToken(); + let slEth = await makeSLToken({kind: 'slether'}); let ethBalance = await web3.eth.getBalance(acct); expect( - (await call(compoundLens, 'cTokenBalancesAll', [[cErc20._address, cEth._address], acct], {gasPrice: '0'})).map(cullTuple) + (await call(sashimiLendingLens, 'slTokenBalancesAll', [[slErc20._address, slEth._address], acct], {gasPrice: '0'})).map(cullTuple) ).toEqual([ { balanceOf: "0", balanceOfUnderlying: "0", borrowBalanceCurrent: "0", - cToken: cErc20._address, + slToken: slErc20._address, tokenAllowance: "0", tokenBalance: "10000000000000000000000000", }, @@ -176,7 +176,7 @@ describe('CompoundLens', () => { balanceOf: "0", balanceOfUnderlying: "0", borrowBalanceCurrent: "0", - cToken: cEth._address, + slToken: slEth._address, tokenAllowance: ethBalance, tokenBalance: ethBalance, } @@ -184,45 +184,45 @@ describe('CompoundLens', () => { }) }); - describe('cTokenUnderlyingPrice', () => { - it('gets correct price for cErc20', async () => { - let cErc20 = await makeCToken(); + describe('slTokenUnderlyingPrice', () => { + it('gets correct price for slErc20', async () => { + let slErc20 = await makeSLToken(); expect( - cullTuple(await call(compoundLens, 'cTokenUnderlyingPrice', [cErc20._address])) + cullTuple(await call(sashimiLendingLens, 'slTokenUnderlyingPrice', [slErc20._address])) ).toEqual( { - cToken: cErc20._address, + slToken: slErc20._address, underlyingPrice: "0", } ); }); - it('gets correct price for cEth', async () => { - let cEth = await makeCToken({kind: 'cether'}); + it('gets correct price for slEth', async () => { + let slEth = await makeSLToken({kind: 'slether'}); expect( - cullTuple(await call(compoundLens, 'cTokenUnderlyingPrice', [cEth._address])) + cullTuple(await call(sashimiLendingLens, 'slTokenUnderlyingPrice', [slEth._address])) ).toEqual( { - cToken: cEth._address, + slToken: slEth._address, underlyingPrice: "1000000000000000000", } ); }); }); - describe('cTokenUnderlyingPriceAll', () => { + describe('slTokenUnderlyingPriceAll', () => { it('gets correct price for both', async () => { - let cErc20 = await makeCToken(); - let cEth = await makeCToken({kind: 'cether'}); + let slErc20 = await makeSLToken(); + let slEth = await makeSLToken({kind: 'slether'}); expect( - (await call(compoundLens, 'cTokenUnderlyingPriceAll', [[cErc20._address, cEth._address]])).map(cullTuple) + (await call(sashimiLendingLens, 'slTokenUnderlyingPriceAll', [[slErc20._address, slEth._address]])).map(cullTuple) ).toEqual([ { - cToken: cErc20._address, + slToken: slErc20._address, underlyingPrice: "0", }, { - cToken: cEth._address, + slToken: slEth._address, underlyingPrice: "1000000000000000000", } ]); @@ -234,7 +234,7 @@ describe('CompoundLens', () => { let comptroller = await makeComptroller(); expect( - cullTuple(await call(compoundLens, 'getAccountLimits', [comptroller._address, acct])) + cullTuple(await call(sashimiLendingLens, 'getAccountLimits', [comptroller._address, acct])) ).toEqual({ liquidity: "0", markets: [], @@ -243,75 +243,20 @@ describe('CompoundLens', () => { }); }); - describe('governance', () => { - let comp, gov; - let targets, values, signatures, callDatas; - let proposalBlock, proposalId; + - beforeEach(async () => { - comp = await deploy('Comp', [acct]); - gov = await deploy('GovernorAlpha', [address(0), comp._address, address(0)]); - targets = [acct]; - values = ["0"]; - signatures = ["getBalanceOf(address)"]; - callDatas = [encodeParameters(['address'], [acct])]; - await send(comp, 'delegate', [acct]); - await send(gov, 'propose', [targets, values, signatures, callDatas, "do nothing"]); - proposalBlock = +(await web3.eth.getBlockNumber()); - proposalId = await call(gov, 'latestProposalIds', [acct]); - }); - - describe('getGovReceipts', () => { - it('gets correct values', async () => { - expect( - (await call(compoundLens, 'getGovReceipts', [gov._address, acct, [proposalId]])).map(cullTuple) - ).toEqual([ - { - hasVoted: false, - proposalId: proposalId, - support: false, - votes: "0", - } - ]); - }) - }); - - describe('getGovProposals', () => { - it('gets correct values', async () => { - expect( - (await call(compoundLens, 'getGovProposals', [gov._address, [proposalId]])).map(cullTuple) - ).toEqual([ - { - againstVotes: "0", - calldatas: callDatas, - canceled: false, - endBlock: (Number(proposalBlock) + 17281).toString(), - eta: "0", - executed: false, - forVotes: "0", - proposalId: proposalId, - proposer: acct, - signatures: signatures, - startBlock: (Number(proposalBlock) + 1).toString(), - targets: targets - } - ]); - }) - }); - }); - - describe('comp', () => { - let comp, currentBlock; + describe('sashimi', () => { + let sashimi, currentBlock; beforeEach(async () => { currentBlock = +(await web3.eth.getBlockNumber()); - comp = await deploy('Comp', [acct]); + sashimi = await deploy('SashimiToken', [acct]); }); describe('getCompBalanceMetadata', () => { it('gets correct values', async () => { expect( - cullTuple(await call(compoundLens, 'getCompBalanceMetadata', [comp._address, acct])) + cullTuple(await call(sashimiLendingLens, 'getSashimiBalanceMetadata', [sashimi._address, acct])) ).toEqual({ balance: "10000000000000000000000000", delegate: "0x0000000000000000000000000000000000000000", @@ -320,13 +265,13 @@ describe('CompoundLens', () => { }); }); - describe('getCompBalanceMetadataExt', () => { + describe('getSashimiBalanceMetadataExt', () => { it('gets correct values', async () => { let comptroller = await makeComptroller(); - await send(comptroller, 'setCompAccrued', [acct, 5]); // harness only + await send(comptroller, 'setSashimiAccrued', [acct, 5]); // harness only expect( - cullTuple(await call(compoundLens, 'getCompBalanceMetadataExt', [comp._address, comptroller._address, acct])) + cullTuple(await call(sashimiLendingLens, 'getSashimiBalanceMetadataExt', [sashimi._address, comptroller._address, acct])) ).toEqual({ balance: "10000000000000000000000000", delegate: "0x0000000000000000000000000000000000000000", @@ -335,28 +280,5 @@ describe('CompoundLens', () => { }); }); }); - - describe('getCompVotes', () => { - it('gets correct values', async () => { - expect( - (await call(compoundLens, 'getCompVotes', [comp._address, acct, [currentBlock, currentBlock - 1]])).map(cullTuple) - ).toEqual([ - { - blockNumber: currentBlock.toString(), - votes: "0", - }, - { - blockNumber: (Number(currentBlock) - 1).toString(), - votes: "0", - } - ]); - }); - - it('reverts on future value', async () => { - await expect( - call(compoundLens, 'getCompVotes', [comp._address, acct, [currentBlock + 1]]) - ).rejects.toRevert('revert Comp::getPriorVotes: not yet determined') - }); - }); }); }); diff --git a/tests/MaximillionTest.js b/tests/MaximillionTest.js index 16b2674c3..6bb2140ea 100644 --- a/tests/MaximillionTest.js +++ b/tests/MaximillionTest.js @@ -6,24 +6,24 @@ const { const { makeComptroller, - makeCToken, + makeSLToken, makePriceOracle, pretendBorrow, borrowSnapshot -} = require('./Utils/Compound'); +} = require('./Utils/SashimiLending'); describe('Maximillion', () => { let root, borrower; - let maximillion, cEther; + let maximillion, slEther; beforeEach(async () => { [root, borrower] = saddle.accounts; - cEther = await makeCToken({kind: "cether", supportMarket: true}); - maximillion = await deploy('Maximillion', [cEther._address]); + slEther = await makeSLToken({kind: "slether", supportMarket: true}); + maximillion = await deploy('Maximillion', [slEther._address]); }); describe("constructor", () => { - it("sets address of cEther", async () => { - expect(await call(maximillion, "cEther")).toEqual(cEther._address); + it("sets address of slEther", async () => { + expect(await call(maximillion, "slEther")).toEqual(slEther._address); }); }); @@ -38,24 +38,24 @@ describe('Maximillion', () => { }); it("repays part of a borrow", async () => { - await pretendBorrow(cEther, borrower, 1, 1, 150); + await pretendBorrow(slEther, borrower, 1, 1, 150); const beforeBalance = await etherBalance(root); const result = await send(maximillion, "repayBehalf", [borrower], {value: 100}); const gasCost = await etherGasCost(result); const afterBalance = await etherBalance(root); - const afterBorrowSnap = await borrowSnapshot(cEther, borrower); + const afterBorrowSnap = await borrowSnapshot(slEther, borrower); expect(result).toSucceed(); expect(afterBalance).toEqualNumber(beforeBalance.sub(gasCost).sub(100)); expect(afterBorrowSnap.principal).toEqualNumber(50); }); it("repays a full borrow and refunds the rest", async () => { - await pretendBorrow(cEther, borrower, 1, 1, 90); + await pretendBorrow(slEther, borrower, 1, 1, 90); const beforeBalance = await etherBalance(root); const result = await send(maximillion, "repayBehalf", [borrower], {value: 100}); const gasCost = await etherGasCost(result); const afterBalance = await etherBalance(root); - const afterBorrowSnap = await borrowSnapshot(cEther, borrower); + const afterBorrowSnap = await borrowSnapshot(slEther, borrower); expect(result).toSucceed(); expect(afterBalance).toEqualNumber(beforeBalance.sub(gasCost).sub(90)); expect(afterBorrowSnap.principal).toEqualNumber(0); diff --git a/tests/Models/DAIInterestRateModelTest.js b/tests/Models/DAIInterestRateModelTest.js index da00535b9..45d17fa93 100644 --- a/tests/Models/DAIInterestRateModelTest.js +++ b/tests/Models/DAIInterestRateModelTest.js @@ -5,7 +5,7 @@ const { makeInterestRateModel, getBorrowRate, getSupplyRate -} = require('../Utils/Compound'); +} = require('../Utils/SashimiLending'); const blocksPerYear = 2102400; const secondsPerYear = 60 * 60 * 24 * 365; diff --git a/tests/Models/InterestRateModelTest.js b/tests/Models/InterestRateModelTest.js index 53059b596..ec7025786 100644 --- a/tests/Models/InterestRateModelTest.js +++ b/tests/Models/InterestRateModelTest.js @@ -2,7 +2,7 @@ const { makeInterestRateModel, getBorrowRate, getSupplyRate -} = require('../Utils/Compound'); +} = require('../Utils/SashimiLending'); function utilizationRate(cash, borrows, reserves) { return borrows ? borrows / (cash + borrows - reserves) : 0; diff --git a/tests/PriceOracleProxyTest.js b/tests/PriceOracleProxyTest.js index 42d5b3885..c308e4f07 100644 --- a/tests/PriceOracleProxyTest.js +++ b/tests/PriceOracleProxyTest.js @@ -6,34 +6,34 @@ const { } = require('./Utils/Ethereum'); const { - makeCToken, + makeSLToken, makePriceOracle, -} = require('./Utils/Compound'); +} = require('./Utils/SashimiLending'); describe('PriceOracleProxy', () => { let root, accounts; - let oracle, backingOracle, cEth, cUsdc, cSai, cDai, cUsdt, cOther; + let oracle, backingOracle, slEth, slUsdc, slSai, slDai, slUsdt, cOther; let daiOracleKey = address(2); beforeEach(async () => { [root, ...accounts] = saddle.accounts; - cEth = await makeCToken({kind: "cether", comptrollerOpts: {kind: "v1-no-proxy"}, supportMarket: true}); - cUsdc = await makeCToken({comptroller: cEth.comptroller, supportMarket: true}); - cSai = await makeCToken({comptroller: cEth.comptroller, supportMarket: true}); - cDai = await makeCToken({comptroller: cEth.comptroller, supportMarket: true}); - cUsdt = await makeCToken({comptroller: cEth.comptroller, supportMarket: true}); - cOther = await makeCToken({comptroller: cEth.comptroller, supportMarket: true}); + slEth = await makeSLToken({kind: "slether", comptrollerOpts: {kind: "v1-no-proxy"}, supportMarket: true}); + slUsdc = await makeSLToken({comptroller: slEth.comptroller, supportMarket: true}); + slSai = await makeSLToken({comptroller: slEth.comptroller, supportMarket: true}); + slDai = await makeSLToken({comptroller: slEth.comptroller, supportMarket: true}); + slUsdt = await makeSLToken({comptroller: slEth.comptroller, supportMarket: true}); + cOther = await makeSLToken({comptroller: slEth.comptroller, supportMarket: true}); backingOracle = await makePriceOracle(); oracle = await deploy('PriceOracleProxy', [ root, backingOracle._address, - cEth._address, - cUsdc._address, - cSai._address, - cDai._address, - cUsdt._address + slEth._address, + slUsdc._address, + slSai._address, + slDai._address, + slUsdt._address ] ); }); @@ -49,43 +49,43 @@ describe('PriceOracleProxy', () => { expect(configuredOracle).toEqual(backingOracle._address); }); - it("sets address of cEth", async () => { - let configuredCEther = await call(oracle, "cEthAddress"); - expect(configuredCEther).toEqual(cEth._address); + it("sets address of slEth", async () => { + let configuredSLEther = await call(oracle, "slEthAddress"); + expect(configuredSLEther).toEqual(slEth._address); }); - it("sets address of cUSDC", async () => { - let configuredCUSD = await call(oracle, "cUsdcAddress"); - expect(configuredCUSD).toEqual(cUsdc._address); + it("sets address of slUSDC", async () => { + let configuredSLUSD = await call(oracle, "slUsdcAddress"); + expect(configuredSLUSD).toEqual(slUsdc._address); }); - it("sets address of cSAI", async () => { - let configuredCSAI = await call(oracle, "cSaiAddress"); - expect(configuredCSAI).toEqual(cSai._address); + it("sets address of slSAI", async () => { + let configuredSLSAI = await call(oracle, "slSaiAddress"); + expect(configuredSLSAI).toEqual(slSai._address); }); - it("sets address of cDAI", async () => { - let configuredCDAI = await call(oracle, "cDaiAddress"); - expect(configuredCDAI).toEqual(cDai._address); + it("sets address of slDAI", async () => { + let configuredSLDAI = await call(oracle, "slDaiAddress"); + expect(configuredSLDAI).toEqual(slDai._address); }); - it("sets address of cUSDT", async () => { - let configuredCUSDT = await call(oracle, "cUsdtAddress"); - expect(configuredCUSDT).toEqual(cUsdt._address); + it("sets address of slUSDT", async () => { + let configuredSLUSDT = await call(oracle, "slUsdtAddress"); + expect(configuredSLUSDT).toEqual(slUsdt._address); }); }); describe("getUnderlyingPrice", () => { - let setAndVerifyBackingPrice = async (cToken, price) => { + let setAndVerifyBackingPrice = async (slToken, price) => { await send( backingOracle, "setUnderlyingPrice", - [cToken._address, etherMantissa(price)]); + [slToken._address, etherMantissa(price)]); let backingOraclePrice = await call( backingOracle, "assetPrices", - [cToken.underlying._address]); + [slToken.underlying._address]); expect(Number(backingOraclePrice)).toEqual(price * 1e18); }; @@ -95,16 +95,16 @@ describe('PriceOracleProxy', () => { expect(Number(proxyPrice)).toEqual(price * 1e18);; }; - it("always returns 1e18 for cEth", async () => { - await readAndVerifyProxyPrice(cEth, 1); + it("always returns 1e18 for slEth", async () => { + await readAndVerifyProxyPrice(slEth, 1); }); it("uses address(1) for USDC and address(2) for cdai", async () => { await send(backingOracle, "setDirectPrice", [address(1), etherMantissa(5e12)]); await send(backingOracle, "setDirectPrice", [address(2), etherMantissa(8)]); - await readAndVerifyProxyPrice(cDai, 8); - await readAndVerifyProxyPrice(cUsdc, 5e12); - await readAndVerifyProxyPrice(cUsdt, 5e12); + await readAndVerifyProxyPrice(slDai, 8); + await readAndVerifyProxyPrice(slUsdc, 5e12); + await readAndVerifyProxyPrice(slUsdt, 5e12); }); it("proxies for whitelisted tokens", async () => { @@ -116,7 +116,7 @@ describe('PriceOracleProxy', () => { }); it("returns 0 for token without a price", async () => { - let unlistedToken = await makeCToken({comptroller: cEth.comptroller}); + let unlistedToken = await makeSLToken({comptroller: slEth.comptroller}); await readAndVerifyProxyPrice(unlistedToken, 0); }); @@ -124,13 +124,13 @@ describe('PriceOracleProxy', () => { it("correctly handle setting SAI price", async () => { await send(backingOracle, "setDirectPrice", [daiOracleKey, etherMantissa(0.01)]); - await readAndVerifyProxyPrice(cDai, 0.01); - await readAndVerifyProxyPrice(cSai, 0.01); + await readAndVerifyProxyPrice(slDai, 0.01); + await readAndVerifyProxyPrice(slSai, 0.01); await send(oracle, "setSaiPrice", [etherMantissa(0.05)]); - await readAndVerifyProxyPrice(cDai, 0.01); - await readAndVerifyProxyPrice(cSai, 0.05); + await readAndVerifyProxyPrice(slDai, 0.01); + await readAndVerifyProxyPrice(slSai, 0.05); await expect(send(oracle, "setSaiPrice", [1])).rejects.toRevert("revert SAI price may only be set once"); }); diff --git a/tests/SpinaramaTest.js b/tests/SpinaramaTest.js index 798ed7a27..509458e4e 100644 --- a/tests/SpinaramaTest.js +++ b/tests/SpinaramaTest.js @@ -5,11 +5,11 @@ const { } = require('./Utils/Ethereum'); const { - makeCToken, + makeSLToken, balanceOf, borrowSnapshot, enterMarkets -} = require('./Utils/Compound'); +} = require('./Utils/SashimiLending'); describe('Spinarama', () => { let root, from, accounts; @@ -20,25 +20,25 @@ describe('Spinarama', () => { describe('#mintMint', () => { it('should succeed', async () => { - const cToken = await makeCToken({supportMarket: true}); - await send(cToken.underlying, 'harnessSetBalance', [from, 100], {from}); - await send(cToken.underlying, 'approve', [cToken._address, -1], {from}); + const slToken = await makeSLToken({supportMarket: true}); + await send(slToken.underlying, 'harnessSetBalance', [from, 100], {from}); + await send(slToken.underlying, 'approve', [slToken._address, -1], {from}); await minerStop(); - const p1 = send(cToken, 'mint', [1], {from}); - const p2 = send(cToken, 'mint', [2], {from}); + const p1 = send(slToken, 'mint', [1], {from}); + const p2 = send(slToken, 'mint', [2], {from}); await minerStart(); expect(await p1).toSucceed(); expect(await p2).toSucceed(); - expect(await balanceOf(cToken, from)).toEqualNumber(3); + expect(await balanceOf(slToken, from)).toEqualNumber(3); }); it('should partial succeed', async () => { - const cToken = await makeCToken({supportMarket: true}); - await send(cToken.underlying, 'harnessSetBalance', [from, 100], {from}); - await send(cToken.underlying, 'approve', [cToken._address, 10], {from}); + const slToken = await makeSLToken({supportMarket: true}); + await send(slToken.underlying, 'harnessSetBalance', [from, 100], {from}); + await send(slToken.underlying, 'approve', [slToken._address, 10], {from}); await minerStop(); - const p1 = send(cToken, 'mint', [11], {from}); - const p2 = send(cToken, 'mint', [10], {from}); + const p1 = send(slToken, 'mint', [11], {from}); + const p2 = send(slToken, 'mint', [10], {from}); await expect(minerStart()).rejects.toRevert("revert Insufficient allowance"); try { await p1; @@ -47,63 +47,63 @@ describe('Spinarama', () => { expect(err.toString()).toContain("reverted by the EVM"); } await expect(p2).resolves.toSucceed(); - expect(await balanceOf(cToken, from)).toEqualNumber(10); + expect(await balanceOf(slToken, from)).toEqualNumber(10); }); }); describe('#mintRedeem', () => { it('should succeed', async () => { - const cToken = await makeCToken({supportMarket: true}); - await send(cToken.underlying, 'harnessSetBalance', [from, 100], {from}); - await send(cToken.underlying, 'approve', [cToken._address, 10], {from}); + const slToken = await makeSLToken({supportMarket: true}); + await send(slToken.underlying, 'harnessSetBalance', [from, 100], {from}); + await send(slToken.underlying, 'approve', [slToken._address, 10], {from}); await minerStop(); - const p1 = send(cToken, 'mint', [10], {from}); - const p2 = send(cToken, 'redeemUnderlying', [10], {from}); + const p1 = send(slToken, 'mint', [10], {from}); + const p2 = send(slToken, 'redeemUnderlying', [10], {from}); await minerStart(); expect(await p1).toSucceed(); expect(await p2).toSucceed(); - expect(await balanceOf(cToken, from)).toEqualNumber(0); + expect(await balanceOf(slToken, from)).toEqualNumber(0); }); }); describe('#redeemMint', () => { it('should succeed', async () => { - const cToken = await makeCToken({supportMarket: true}); - await send(cToken, 'harnessSetTotalSupply', [10]); - await send(cToken, 'harnessSetExchangeRate', [etherMantissa(1)]); - await send(cToken, 'harnessSetBalance', [from, 10]); - await send(cToken.underlying, 'harnessSetBalance', [cToken._address, 10]); - await send(cToken.underlying, 'approve', [cToken._address, 10], {from}); + const slToken = await makeSLToken({supportMarket: true}); + await send(slToken, 'harnessSetTotalSupply', [10]); + await send(slToken, 'harnessSetExchangeRate', [etherMantissa(1)]); + await send(slToken, 'harnessSetBalance', [from, 10]); + await send(slToken.underlying, 'harnessSetBalance', [slToken._address, 10]); + await send(slToken.underlying, 'approve', [slToken._address, 10], {from}); await minerStop(); - const p1 = send(cToken, 'redeem', [10], {from}); - const p2 = send(cToken, 'mint', [10], {from}); + const p1 = send(slToken, 'redeem', [10], {from}); + const p2 = send(slToken, 'mint', [10], {from}); await minerStart(); expect(await p1).toSucceed(); expect(await p2).toSucceed(); - expect(await balanceOf(cToken, from)).toEqualNumber(10); + expect(await balanceOf(slToken, from)).toEqualNumber(10); }); }); describe('#repayRepay', () => { it('should succeed', async () => { - const cToken1 = await makeCToken({supportMarket: true, underlyingPrice: 1, collateralFactor: .5}); - const cToken2 = await makeCToken({supportMarket: true, underlyingPrice: 1, comptroller: cToken1.comptroller}); - await send(cToken1.underlying, 'harnessSetBalance', [from, 10]); - await send(cToken1.underlying, 'approve', [cToken1._address, 10], {from}); - await send(cToken2.underlying, 'harnessSetBalance', [cToken2._address, 10]); - await send(cToken2, 'harnessSetTotalSupply', [100]); - await send(cToken2.underlying, 'approve', [cToken2._address, 10], {from}); - await send(cToken2, 'harnessSetExchangeRate', [etherMantissa(1)]); - expect(await enterMarkets([cToken1, cToken2], from)).toSucceed(); - expect(await send(cToken1, 'mint', [10], {from})).toSucceed(); - expect(await send(cToken2, 'borrow', [2], {from})).toSucceed(); + const slToken1 = await makeSLToken({supportMarket: true, underlyingPrice: 1, collateralFactor: .5}); + const slToken2 = await makeSLToken({supportMarket: true, underlyingPrice: 1, comptroller: slToken1.comptroller}); + await send(slToken1.underlying, 'harnessSetBalance', [from, 10]); + await send(slToken1.underlying, 'approve', [slToken1._address, 10], {from}); + await send(slToken2.underlying, 'harnessSetBalance', [slToken2._address, 10]); + await send(slToken2, 'harnessSetTotalSupply', [100]); + await send(slToken2.underlying, 'approve', [slToken2._address, 10], {from}); + await send(slToken2, 'harnessSetExchangeRate', [etherMantissa(1)]); + expect(await enterMarkets([slToken1, slToken2], from)).toSucceed(); + expect(await send(slToken1, 'mint', [10], {from})).toSucceed(); + expect(await send(slToken2, 'borrow', [2], {from})).toSucceed(); await minerStop(); - const p1 = send(cToken2, 'repayBorrow', [1], {from}); - const p2 = send(cToken2, 'repayBorrow', [1], {from}); + const p1 = send(slToken2, 'repayBorrow', [1], {from}); + const p2 = send(slToken2, 'repayBorrow', [1], {from}); await minerStart(); expect(await p1).toSucceed(); expect(await p2).toSucceed(); - expect((await borrowSnapshot(cToken2, from)).principal).toEqualNumber(0); + expect((await borrowSnapshot(slToken2, from)).principal).toEqualNumber(0); }); // XXX not yet converted below this point...moving on to certora diff --git a/tests/Tokens/accrueInterestTest.js b/tests/Tokens/accrueInterestTest.js index 1d080b0d1..9a6cb8990 100644 --- a/tests/Tokens/accrueInterestTest.js +++ b/tests/Tokens/accrueInterestTest.js @@ -3,95 +3,95 @@ const { etherUnsigned } = require('../Utils/Ethereum'); const { - makeCToken, + makeSLToken, setBorrowRate -} = require('../Utils/Compound'); +} = require('../Utils/SashimiLending'); const blockNumber = 2e7; const borrowIndex = 1e18; const borrowRate = .000001; -async function pretendBlock(cToken, accrualBlock = blockNumber, deltaBlocks = 1) { - await send(cToken, 'harnessSetAccrualBlockNumber', [etherUnsigned(blockNumber)]); - await send(cToken, 'harnessSetBlockNumber', [etherUnsigned(blockNumber + deltaBlocks)]); - await send(cToken, 'harnessSetBorrowIndex', [etherUnsigned(borrowIndex)]); +async function pretendBlock(slToken, accrualBlock = blockNumber, deltaBlocks = 1) { + await send(slToken, 'harnessSetAccrualBlockNumber', [etherUnsigned(blockNumber)]); + await send(slToken, 'harnessSetBlockNumber', [etherUnsigned(blockNumber + deltaBlocks)]); + await send(slToken, 'harnessSetBorrowIndex', [etherUnsigned(borrowIndex)]); } -async function preAccrue(cToken) { - await setBorrowRate(cToken, borrowRate); - await send(cToken.interestRateModel, 'setFailBorrowRate', [false]); - await send(cToken, 'harnessExchangeRateDetails', [0, 0, 0]); +async function preAccrue(slToken) { + await setBorrowRate(slToken, borrowRate); + await send(slToken.interestRateModel, 'setFailBorrowRate', [false]); + await send(slToken, 'harnessExchangeRateDetails', [0, 0, 0]); } -describe('CToken', () => { +describe('SLToken', () => { let root, accounts; - let cToken; + let slToken; beforeEach(async () => { [root, ...accounts] = saddle.accounts; - cToken = await makeCToken({comptrollerOpts: {kind: 'bool'}}); + slToken = await makeSLToken({comptrollerOpts: {kind: 'bool'}}); }); beforeEach(async () => { - await preAccrue(cToken); + await preAccrue(slToken); }); describe('accrueInterest', () => { it('reverts if the interest rate is absurdly high', async () => { - await pretendBlock(cToken, blockNumber, 1); - expect(await call(cToken, 'getBorrowRateMaxMantissa')).toEqualNumber(etherMantissa(0.000005)); // 0.0005% per block - await setBorrowRate(cToken, 0.001e-2); // 0.0010% per block - await expect(send(cToken, 'accrueInterest')).rejects.toRevert("revert borrow rate is absurdly high"); + await pretendBlock(slToken, blockNumber, 1); + expect(await call(slToken, 'getBorrowRateMaxMantissa')).toEqualNumber(etherMantissa(0.000005)); // 0.0005% per block + await setBorrowRate(slToken, 0.001e-2); // 0.0010% per block + await expect(send(slToken, 'accrueInterest')).rejects.toRevert("revert borrow rate is absurdly high"); }); it('fails if new borrow rate calculation fails', async () => { - await pretendBlock(cToken, blockNumber, 1); - await send(cToken.interestRateModel, 'setFailBorrowRate', [true]); - await expect(send(cToken, 'accrueInterest')).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); + await pretendBlock(slToken, blockNumber, 1); + await send(slToken.interestRateModel, 'setFailBorrowRate', [true]); + await expect(send(slToken, 'accrueInterest')).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); }); it('fails if simple interest factor calculation fails', async () => { - await pretendBlock(cToken, blockNumber, 5e70); - expect(await send(cToken, 'accrueInterest')).toHaveTokenFailure('MATH_ERROR', 'ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED'); + await pretendBlock(slToken, blockNumber, 5e70); + expect(await send(slToken, 'accrueInterest')).toHaveTokenFailure('MATH_ERROR', 'ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED'); }); it('fails if new borrow index calculation fails', async () => { - await pretendBlock(cToken, blockNumber, 5e60); - expect(await send(cToken, 'accrueInterest')).toHaveTokenFailure('MATH_ERROR', 'ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED'); + await pretendBlock(slToken, blockNumber, 5e60); + expect(await send(slToken, 'accrueInterest')).toHaveTokenFailure('MATH_ERROR', 'ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED'); }); it('fails if new borrow interest index calculation fails', async () => { - await pretendBlock(cToken) - await send(cToken, 'harnessSetBorrowIndex', [-1]); - expect(await send(cToken, 'accrueInterest')).toHaveTokenFailure('MATH_ERROR', 'ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED'); + await pretendBlock(slToken) + await send(slToken, 'harnessSetBorrowIndex', [-1]); + expect(await send(slToken, 'accrueInterest')).toHaveTokenFailure('MATH_ERROR', 'ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED'); }); it('fails if interest accumulated calculation fails', async () => { - await send(cToken, 'harnessExchangeRateDetails', [0, -1, 0]); - await pretendBlock(cToken) - expect(await send(cToken, 'accrueInterest')).toHaveTokenFailure('MATH_ERROR', 'ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED'); + await send(slToken, 'harnessExchangeRateDetails', [0, -1, 0]); + await pretendBlock(slToken) + expect(await send(slToken, 'accrueInterest')).toHaveTokenFailure('MATH_ERROR', 'ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED'); }); it('fails if new total borrows calculation fails', async () => { - await setBorrowRate(cToken, 1e-18); - await pretendBlock(cToken) - await send(cToken, 'harnessExchangeRateDetails', [0, -1, 0]); - expect(await send(cToken, 'accrueInterest')).toHaveTokenFailure('MATH_ERROR', 'ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED'); + await setBorrowRate(slToken, 1e-18); + await pretendBlock(slToken) + await send(slToken, 'harnessExchangeRateDetails', [0, -1, 0]); + expect(await send(slToken, 'accrueInterest')).toHaveTokenFailure('MATH_ERROR', 'ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED'); }); it('fails if interest accumulated for reserves calculation fails', async () => { - await setBorrowRate(cToken, .000001); - await send(cToken, 'harnessExchangeRateDetails', [0, etherUnsigned(1e30), -1]); - await send(cToken, 'harnessSetReserveFactorFresh', [etherUnsigned(1e10)]); - await pretendBlock(cToken, blockNumber, 5e20) - expect(await send(cToken, 'accrueInterest')).toHaveTokenFailure('MATH_ERROR', 'ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED'); + await setBorrowRate(slToken, .000001); + await send(slToken, 'harnessExchangeRateDetails', [0, etherUnsigned(1e30), -1]); + await send(slToken, 'harnessSetReserveFactorFresh', [etherUnsigned(1e10)]); + await pretendBlock(slToken, blockNumber, 5e20) + expect(await send(slToken, 'accrueInterest')).toHaveTokenFailure('MATH_ERROR', 'ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED'); }); it('fails if new total reserves calculation fails', async () => { - await setBorrowRate(cToken, 1e-18); - await send(cToken, 'harnessExchangeRateDetails', [0, etherUnsigned(1e56), -1]); - await send(cToken, 'harnessSetReserveFactorFresh', [etherUnsigned(1e17)]); - await pretendBlock(cToken) - expect(await send(cToken, 'accrueInterest')).toHaveTokenFailure('MATH_ERROR', 'ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED'); + await setBorrowRate(slToken, 1e-18); + await send(slToken, 'harnessExchangeRateDetails', [0, etherUnsigned(1e56), -1]); + await send(slToken, 'harnessSetReserveFactorFresh', [etherUnsigned(1e17)]); + await pretendBlock(slToken) + expect(await send(slToken, 'accrueInterest')).toHaveTokenFailure('MATH_ERROR', 'ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED'); }); it('succeeds and saves updated values in storage on success', async () => { @@ -99,16 +99,16 @@ describe('CToken', () => { const startingTotalReserves = 1e20; const reserveFactor = 1e17; - await send(cToken, 'harnessExchangeRateDetails', [0, etherUnsigned(startingTotalBorrows), etherUnsigned(startingTotalReserves)]); - await send(cToken, 'harnessSetReserveFactorFresh', [etherUnsigned(reserveFactor)]); - await pretendBlock(cToken) + await send(slToken, 'harnessExchangeRateDetails', [0, etherUnsigned(startingTotalBorrows), etherUnsigned(startingTotalReserves)]); + await send(slToken, 'harnessSetReserveFactorFresh', [etherUnsigned(reserveFactor)]); + await pretendBlock(slToken) const expectedAccrualBlockNumber = blockNumber + 1; const expectedBorrowIndex = borrowIndex + borrowIndex * borrowRate; const expectedTotalBorrows = startingTotalBorrows + startingTotalBorrows * borrowRate; const expectedTotalReserves = startingTotalReserves + startingTotalBorrows * borrowRate * reserveFactor / 1e18; - const receipt = await send(cToken, 'accrueInterest') + const receipt = await send(slToken, 'accrueInterest') expect(receipt).toSucceed(); expect(receipt).toHaveLog('AccrueInterest', { cashPrior: 0, @@ -116,10 +116,10 @@ describe('CToken', () => { borrowIndex: etherUnsigned(expectedBorrowIndex), totalBorrows: etherUnsigned(expectedTotalBorrows) }) - expect(await call(cToken, 'accrualBlockNumber')).toEqualNumber(expectedAccrualBlockNumber); - expect(await call(cToken, 'borrowIndex')).toEqualNumber(expectedBorrowIndex); - expect(await call(cToken, 'totalBorrows')).toEqualNumber(expectedTotalBorrows); - expect(await call(cToken, 'totalReserves')).toEqualNumber(expectedTotalReserves); + expect(await call(slToken, 'accrualBlockNumber')).toEqualNumber(expectedAccrualBlockNumber); + expect(await call(slToken, 'borrowIndex')).toEqualNumber(expectedBorrowIndex); + expect(await call(slToken, 'totalBorrows')).toEqualNumber(expectedTotalBorrows); + expect(await call(slToken, 'totalReserves')).toEqualNumber(expectedTotalReserves); }); }); }); diff --git a/tests/Tokens/adminTest.js b/tests/Tokens/adminTest.js index 8e57d2f02..6300d0120 100644 --- a/tests/Tokens/adminTest.js +++ b/tests/Tokens/adminTest.js @@ -1,59 +1,59 @@ const {address} = require('../Utils/Ethereum'); -const {makeCToken} = require('../Utils/Compound'); +const {makeSLToken} = require('../Utils/SashimiLending'); describe('admin / _setPendingAdmin / _acceptAdmin', () => { - let cToken, root, accounts; + let slToken, root, accounts; beforeEach(async () => { [root, ...accounts] = saddle.accounts; - cToken = await makeCToken(); + slToken = await makeSLToken(); }); describe('admin()', () => { it('should return correct admin', async () => { - expect(await call(cToken, 'admin')).toEqual(root); + expect(await call(slToken, 'admin')).toEqual(root); }); }); describe('pendingAdmin()', () => { it('should return correct pending admin', async () => { - expect(await call(cToken, 'pendingAdmin')).toBeAddressZero(); + expect(await call(slToken, 'pendingAdmin')).toBeAddressZero(); }); }); describe('_setPendingAdmin()', () => { it('should only be callable by admin', async () => { expect( - await send(cToken, '_setPendingAdmin', [accounts[0]], {from: accounts[0]}) + await send(slToken, '_setPendingAdmin', [accounts[0]], {from: accounts[0]}) ).toHaveTokenFailure( 'UNAUTHORIZED', 'SET_PENDING_ADMIN_OWNER_CHECK' ); // Check admin stays the same - expect(await call(cToken, 'admin')).toEqual(root); - expect(await call(cToken, 'pendingAdmin')).toBeAddressZero(); + expect(await call(slToken, 'admin')).toEqual(root); + expect(await call(slToken, 'pendingAdmin')).toBeAddressZero(); }); it('should properly set pending admin', async () => { - expect(await send(cToken, '_setPendingAdmin', [accounts[0]])).toSucceed(); + expect(await send(slToken, '_setPendingAdmin', [accounts[0]])).toSucceed(); // Check admin stays the same - expect(await call(cToken, 'admin')).toEqual(root); - expect(await call(cToken, 'pendingAdmin')).toEqual(accounts[0]); + expect(await call(slToken, 'admin')).toEqual(root); + expect(await call(slToken, 'pendingAdmin')).toEqual(accounts[0]); }); it('should properly set pending admin twice', async () => { - expect(await send(cToken, '_setPendingAdmin', [accounts[0]])).toSucceed(); - expect(await send(cToken, '_setPendingAdmin', [accounts[1]])).toSucceed(); + expect(await send(slToken, '_setPendingAdmin', [accounts[0]])).toSucceed(); + expect(await send(slToken, '_setPendingAdmin', [accounts[1]])).toSucceed(); // Check admin stays the same - expect(await call(cToken, 'admin')).toEqual(root); - expect(await call(cToken, 'pendingAdmin')).toEqual(accounts[1]); + expect(await call(slToken, 'admin')).toEqual(root); + expect(await call(slToken, 'pendingAdmin')).toEqual(accounts[1]); }); it('should emit event', async () => { - const result = await send(cToken, '_setPendingAdmin', [accounts[0]]); + const result = await send(slToken, '_setPendingAdmin', [accounts[0]]); expect(result).toHaveLog('NewPendingAdmin', { oldPendingAdmin: address(0), newPendingAdmin: accounts[0], @@ -64,43 +64,43 @@ describe('admin / _setPendingAdmin / _acceptAdmin', () => { describe('_acceptAdmin()', () => { it('should fail when pending admin is zero', async () => { expect( - await send(cToken, '_acceptAdmin') + await send(slToken, '_acceptAdmin') ).toHaveTokenFailure( 'UNAUTHORIZED', 'ACCEPT_ADMIN_PENDING_ADMIN_CHECK' ); // Check admin stays the same - expect(await call(cToken, 'admin')).toEqual(root); - expect(await call(cToken, 'pendingAdmin')).toBeAddressZero(); + expect(await call(slToken, 'admin')).toEqual(root); + expect(await call(slToken, 'pendingAdmin')).toBeAddressZero(); }); it('should fail when called by another account (e.g. root)', async () => { - expect(await send(cToken, '_setPendingAdmin', [accounts[0]])).toSucceed(); + expect(await send(slToken, '_setPendingAdmin', [accounts[0]])).toSucceed(); expect( - await send(cToken, '_acceptAdmin') + await send(slToken, '_acceptAdmin') ).toHaveTokenFailure( 'UNAUTHORIZED', 'ACCEPT_ADMIN_PENDING_ADMIN_CHECK' ); // Check admin stays the same - expect(await call(cToken, 'admin')).toEqual(root); - expect(await call(cToken, 'pendingAdmin') [accounts[0]]).toEqual(); + expect(await call(slToken, 'admin')).toEqual(root); + expect(await call(slToken, 'pendingAdmin') [accounts[0]]).toEqual(); }); it('should succeed and set admin and clear pending admin', async () => { - expect(await send(cToken, '_setPendingAdmin', [accounts[0]])).toSucceed(); - expect(await send(cToken, '_acceptAdmin', [], {from: accounts[0]})).toSucceed(); + expect(await send(slToken, '_setPendingAdmin', [accounts[0]])).toSucceed(); + expect(await send(slToken, '_acceptAdmin', [], {from: accounts[0]})).toSucceed(); // Check admin stays the same - expect(await call(cToken, 'admin')).toEqual(accounts[0]); - expect(await call(cToken, 'pendingAdmin')).toBeAddressZero(); + expect(await call(slToken, 'admin')).toEqual(accounts[0]); + expect(await call(slToken, 'pendingAdmin')).toBeAddressZero(); }); it('should emit log on success', async () => { - expect(await send(cToken, '_setPendingAdmin', [accounts[0]])).toSucceed(); - const result = await send(cToken, '_acceptAdmin', [], {from: accounts[0]}); + expect(await send(slToken, '_setPendingAdmin', [accounts[0]])).toSucceed(); + const result = await send(slToken, '_acceptAdmin', [], {from: accounts[0]}); expect(result).toHaveLog('NewAdmin', { oldAdmin: root, newAdmin: accounts[0], diff --git a/tests/Tokens/borrowAndRepayCEtherTest.js b/tests/Tokens/borrowAndRepayCEtherTest.js index edff95ddd..c5ff3079f 100644 --- a/tests/Tokens/borrowAndRepayCEtherTest.js +++ b/tests/Tokens/borrowAndRepayCEtherTest.js @@ -5,7 +5,7 @@ const { } = require('../Utils/Ethereum'); const { - makeCToken, + makeSLToken, balanceOf, borrowSnapshot, totalBorrows, @@ -16,123 +16,123 @@ const { setEtherBalance, getBalances, adjustBalances -} = require('../Utils/Compound'); +} = require('../Utils/SashimiLending'); const BigNumber = require('bignumber.js'); const borrowAmount = etherUnsigned(10e3); const repayAmount = etherUnsigned(10e2); -async function preBorrow(cToken, borrower, borrowAmount) { - await send(cToken.comptroller, 'setBorrowAllowed', [true]); - await send(cToken.comptroller, 'setBorrowVerify', [true]); - await send(cToken.interestRateModel, 'setFailBorrowRate', [false]); - await send(cToken, 'harnessSetFailTransferToAddress', [borrower, false]); - await send(cToken, 'harnessSetAccountBorrows', [borrower, 0, 0]); - await send(cToken, 'harnessSetTotalBorrows', [0]); - await setEtherBalance(cToken, borrowAmount); +async function preBorrow(slToken, borrower, borrowAmount) { + await send(slToken.comptroller, 'setBorrowAllowed', [true]); + await send(slToken.comptroller, 'setBorrowVerify', [true]); + await send(slToken.interestRateModel, 'setFailBorrowRate', [false]); + await send(slToken, 'harnessSetFailTransferToAddress', [borrower, false]); + await send(slToken, 'harnessSetAccountBorrows', [borrower, 0, 0]); + await send(slToken, 'harnessSetTotalBorrows', [0]); + await setEtherBalance(slToken, borrowAmount); } -async function borrowFresh(cToken, borrower, borrowAmount) { - return send(cToken, 'harnessBorrowFresh', [borrower, borrowAmount], {from: borrower}); +async function borrowFresh(slToken, borrower, borrowAmount) { + return send(slToken, 'harnessBorrowFresh', [borrower, borrowAmount], {from: borrower}); } -async function borrow(cToken, borrower, borrowAmount, opts = {}) { - await send(cToken, 'harnessFastForward', [1]); - return send(cToken, 'borrow', [borrowAmount], {from: borrower}); +async function borrow(slToken, borrower, borrowAmount, opts = {}) { + await send(slToken, 'harnessFastForward', [1]); + return send(slToken, 'borrow', [borrowAmount], {from: borrower}); } -async function preRepay(cToken, benefactor, borrower, repayAmount) { +async function preRepay(slToken, benefactor, borrower, repayAmount) { // setup either benefactor OR borrower for success in repaying - await send(cToken.comptroller, 'setRepayBorrowAllowed', [true]); - await send(cToken.comptroller, 'setRepayBorrowVerify', [true]); - await send(cToken.interestRateModel, 'setFailBorrowRate', [false]); - await pretendBorrow(cToken, borrower, 1, 1, repayAmount); + await send(slToken.comptroller, 'setRepayBorrowAllowed', [true]); + await send(slToken.comptroller, 'setRepayBorrowVerify', [true]); + await send(slToken.interestRateModel, 'setFailBorrowRate', [false]); + await pretendBorrow(slToken, borrower, 1, 1, repayAmount); } -async function repayBorrowFresh(cToken, payer, borrower, repayAmount) { - return send(cToken, 'harnessRepayBorrowFresh', [payer, borrower, repayAmount], {from: payer, value: repayAmount}); +async function repayBorrowFresh(slToken, payer, borrower, repayAmount) { + return send(slToken, 'harnessRepayBorrowFresh', [payer, borrower, repayAmount], {from: payer, value: repayAmount}); } -async function repayBorrow(cToken, borrower, repayAmount) { - await send(cToken, 'harnessFastForward', [1]); - return send(cToken, 'repayBorrow', [], {from: borrower, value: repayAmount}); +async function repayBorrow(slToken, borrower, repayAmount) { + await send(slToken, 'harnessFastForward', [1]); + return send(slToken, 'repayBorrow', [], {from: borrower, value: repayAmount}); } -async function repayBorrowBehalf(cToken, payer, borrower, repayAmount) { - await send(cToken, 'harnessFastForward', [1]); - return send(cToken, 'repayBorrowBehalf', [borrower], {from: payer, value: repayAmount}); +async function repayBorrowBehalf(slToken, payer, borrower, repayAmount) { + await send(slToken, 'harnessFastForward', [1]); + return send(slToken, 'repayBorrowBehalf', [borrower], {from: payer, value: repayAmount}); } -describe('CEther', function () { - let cToken, root, borrower, benefactor, accounts; +describe('SLEther', function () { + let slToken, root, borrower, benefactor, accounts; beforeEach(async () => { [root, borrower, benefactor, ...accounts] = saddle.accounts; - cToken = await makeCToken({kind: 'cether', comptrollerOpts: {kind: 'bool'}}); + slToken = await makeSLToken({kind: 'slether', comptrollerOpts: {kind: 'bool'}}); }); describe('borrowFresh', () => { - beforeEach(async () => await preBorrow(cToken, borrower, borrowAmount)); + beforeEach(async () => await preBorrow(slToken, borrower, borrowAmount)); it("fails if comptroller tells it to", async () => { - await send(cToken.comptroller, 'setBorrowAllowed', [false]); - expect(await borrowFresh(cToken, borrower, borrowAmount)).toHaveTrollReject('BORROW_COMPTROLLER_REJECTION'); + await send(slToken.comptroller, 'setBorrowAllowed', [false]); + expect(await borrowFresh(slToken, borrower, borrowAmount)).toHaveTrollReject('BORROW_COMPTROLLER_REJECTION'); }); it("proceeds if comptroller tells it to", async () => { - await expect(await borrowFresh(cToken, borrower, borrowAmount)).toSucceed(); + await expect(await borrowFresh(slToken, borrower, borrowAmount)).toSucceed(); }); it("fails if market not fresh", async () => { - await fastForward(cToken); - expect(await borrowFresh(cToken, borrower, borrowAmount)).toHaveTokenFailure('MARKET_NOT_FRESH', 'BORROW_FRESHNESS_CHECK'); + await fastForward(slToken); + expect(await borrowFresh(slToken, borrower, borrowAmount)).toHaveTokenFailure('MARKET_NOT_FRESH', 'BORROW_FRESHNESS_CHECK'); }); it("continues if fresh", async () => { - await expect(await send(cToken, 'accrueInterest')).toSucceed(); - await expect(await borrowFresh(cToken, borrower, borrowAmount)).toSucceed(); + await expect(await send(slToken, 'accrueInterest')).toSucceed(); + await expect(await borrowFresh(slToken, borrower, borrowAmount)).toSucceed(); }); it("fails if protocol has less than borrowAmount of underlying", async () => { - expect(await borrowFresh(cToken, borrower, borrowAmount.add(1))).toHaveTokenFailure('TOKEN_INSUFFICIENT_CASH', 'BORROW_CASH_NOT_AVAILABLE'); + expect(await borrowFresh(slToken, borrower, borrowAmount.add(1))).toHaveTokenFailure('TOKEN_INSUFFICIENT_CASH', 'BORROW_CASH_NOT_AVAILABLE'); }); it("fails if borrowBalanceStored fails (due to non-zero stored principal with zero account index)", async () => { - await pretendBorrow(cToken, borrower, 0, 3e18, 5e18); - expect(await borrowFresh(cToken, borrower, borrowAmount)).toHaveTokenFailure('MATH_ERROR', 'BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED'); + await pretendBorrow(slToken, borrower, 0, 3e18, 5e18); + expect(await borrowFresh(slToken, borrower, borrowAmount)).toHaveTokenFailure('MATH_ERROR', 'BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED'); }); it("fails if calculating account new total borrow balance overflows", async () => { - await pretendBorrow(cToken, borrower, 1e-18, 1e-18, -1); - expect(await borrowFresh(cToken, borrower, borrowAmount)).toHaveTokenFailure('MATH_ERROR', 'BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED'); + await pretendBorrow(slToken, borrower, 1e-18, 1e-18, -1); + expect(await borrowFresh(slToken, borrower, borrowAmount)).toHaveTokenFailure('MATH_ERROR', 'BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED'); }); it("fails if calculation of new total borrow balance overflows", async () => { - await send(cToken, 'harnessSetTotalBorrows', [-1]); - expect(await borrowFresh(cToken, borrower, borrowAmount)).toHaveTokenFailure('MATH_ERROR', 'BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED'); + await send(slToken, 'harnessSetTotalBorrows', [-1]); + expect(await borrowFresh(slToken, borrower, borrowAmount)).toHaveTokenFailure('MATH_ERROR', 'BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED'); }); it("reverts if transfer out fails", async () => { - await send(cToken, 'harnessSetFailTransferToAddress', [borrower, true]); - await expect(borrowFresh(cToken, borrower, borrowAmount)).rejects.toRevert("revert TOKEN_TRANSFER_OUT_FAILED"); + await send(slToken, 'harnessSetFailTransferToAddress', [borrower, true]); + await expect(borrowFresh(slToken, borrower, borrowAmount)).rejects.toRevert("revert TOKEN_TRANSFER_OUT_FAILED"); }); it("reverts if borrowVerify fails", async() => { - await send(cToken.comptroller, 'setBorrowVerify', [false]); - await expect(borrowFresh(cToken, borrower, borrowAmount)).rejects.toRevert("revert borrowVerify rejected borrow"); + await send(slToken.comptroller, 'setBorrowVerify', [false]); + await expect(borrowFresh(slToken, borrower, borrowAmount)).rejects.toRevert("revert borrowVerify rejected borrow"); }); it("transfers the underlying cash, tokens, and emits Borrow event", async () => { - const beforeBalances = await getBalances([cToken], [borrower]); - const beforeProtocolBorrows = await totalBorrows(cToken); - const result = await borrowFresh(cToken, borrower, borrowAmount); - const afterBalances = await getBalances([cToken], [borrower]); + const beforeBalances = await getBalances([slToken], [borrower]); + const beforeProtocolBorrows = await totalBorrows(slToken); + const result = await borrowFresh(slToken, borrower, borrowAmount); + const afterBalances = await getBalances([slToken], [borrower]); expect(result).toSucceed(); expect(afterBalances).toEqual(await adjustBalances(beforeBalances, [ - [cToken, 'eth', -borrowAmount], - [cToken, 'borrows', borrowAmount], - [cToken, borrower, 'eth', borrowAmount.sub(await etherGasCost(result))], - [cToken, borrower, 'borrows', borrowAmount] + [slToken, 'eth', -borrowAmount], + [slToken, 'borrows', borrowAmount], + [slToken, borrower, 'eth', borrowAmount.sub(await etherGasCost(result))], + [slToken, borrower, 'borrows', borrowAmount] ])); expect(result).toHaveLog('Borrow', { borrower: borrower, @@ -143,40 +143,40 @@ describe('CEther', function () { }); it("stores new borrow principal and interest index", async () => { - const beforeProtocolBorrows = await totalBorrows(cToken); - await pretendBorrow(cToken, borrower, 0, 3, 0); - await borrowFresh(cToken, borrower, borrowAmount); - const borrowSnap = await borrowSnapshot(cToken, borrower); + const beforeProtocolBorrows = await totalBorrows(slToken); + await pretendBorrow(slToken, borrower, 0, 3, 0); + await borrowFresh(slToken, borrower, borrowAmount); + const borrowSnap = await borrowSnapshot(slToken, borrower); expect(borrowSnap.principal).toEqualNumber(borrowAmount); expect(borrowSnap.interestIndex).toEqualNumber(etherMantissa(3)); - expect(await totalBorrows(cToken)).toEqualNumber(beforeProtocolBorrows.add(borrowAmount)); + expect(await totalBorrows(slToken)).toEqualNumber(beforeProtocolBorrows.add(borrowAmount)); }); }); describe('borrow', () => { - beforeEach(async () => await preBorrow(cToken, borrower, borrowAmount)); + beforeEach(async () => await preBorrow(slToken, borrower, borrowAmount)); it("emits a borrow failure if interest accrual fails", async () => { - await send(cToken.interestRateModel, 'setFailBorrowRate', [true]); - await send(cToken, 'harnessFastForward', [1]); - await expect(borrow(cToken, borrower, borrowAmount)).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); + await send(slToken.interestRateModel, 'setFailBorrowRate', [true]); + await send(slToken, 'harnessFastForward', [1]); + await expect(borrow(slToken, borrower, borrowAmount)).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); }); it("returns error from borrowFresh without emitting any extra logs", async () => { - expect(await borrow(cToken, borrower, borrowAmount.add(1))).toHaveTokenFailure('TOKEN_INSUFFICIENT_CASH', 'BORROW_CASH_NOT_AVAILABLE'); + expect(await borrow(slToken, borrower, borrowAmount.add(1))).toHaveTokenFailure('TOKEN_INSUFFICIENT_CASH', 'BORROW_CASH_NOT_AVAILABLE'); }); it("returns success from borrowFresh and transfers the correct amount", async () => { - const beforeBalances = await getBalances([cToken], [borrower]); - await fastForward(cToken); - const result = await borrow(cToken, borrower, borrowAmount); - const afterBalances = await getBalances([cToken], [borrower]); + const beforeBalances = await getBalances([slToken], [borrower]); + await fastForward(slToken); + const result = await borrow(slToken, borrower, borrowAmount); + const afterBalances = await getBalances([slToken], [borrower]); expect(result).toSucceed(); expect(afterBalances).toEqual(await adjustBalances(beforeBalances, [ - [cToken, 'eth', -borrowAmount], - [cToken, 'borrows', borrowAmount], - [cToken, borrower, 'eth', borrowAmount.sub(await etherGasCost(result))], - [cToken, borrower, 'borrows', borrowAmount] + [slToken, 'eth', -borrowAmount], + [slToken, 'borrows', borrowAmount], + [slToken, borrower, 'eth', borrowAmount.sub(await etherGasCost(result))], + [slToken, borrower, 'borrows', borrowAmount] ])); }); }); @@ -189,60 +189,60 @@ describe('CEther', function () { beforeEach(async () => { payer = benefactorPaying ? benefactor : borrower; - await preRepay(cToken, payer, borrower, repayAmount); + await preRepay(slToken, payer, borrower, repayAmount); }); it("fails if repay is not allowed", async () => { - await send(cToken.comptroller, 'setRepayBorrowAllowed', [false]); - expect(await repayBorrowFresh(cToken, payer, borrower, repayAmount)).toHaveTrollReject('REPAY_BORROW_COMPTROLLER_REJECTION', 'MATH_ERROR'); + await send(slToken.comptroller, 'setRepayBorrowAllowed', [false]); + expect(await repayBorrowFresh(slToken, payer, borrower, repayAmount)).toHaveTrollReject('REPAY_BORROW_COMPTROLLER_REJECTION', 'MATH_ERROR'); }); it("fails if block number ≠ current block number", async () => { - await fastForward(cToken); - expect(await repayBorrowFresh(cToken, payer, borrower, repayAmount)).toHaveTokenFailure('MARKET_NOT_FRESH', 'REPAY_BORROW_FRESHNESS_CHECK'); + await fastForward(slToken); + expect(await repayBorrowFresh(slToken, payer, borrower, repayAmount)).toHaveTokenFailure('MARKET_NOT_FRESH', 'REPAY_BORROW_FRESHNESS_CHECK'); }); it("returns an error if calculating account new account borrow balance fails", async () => { - await pretendBorrow(cToken, borrower, 1, 1, 1); - await expect(repayBorrowFresh(cToken, payer, borrower, repayAmount)).rejects.toRevert('revert REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED'); + await pretendBorrow(slToken, borrower, 1, 1, 1); + await expect(repayBorrowFresh(slToken, payer, borrower, repayAmount)).rejects.toRevert('revert REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED'); }); it("returns an error if calculation of new total borrow balance fails", async () => { - await send(cToken, 'harnessSetTotalBorrows', [1]); - await expect(repayBorrowFresh(cToken, payer, borrower, repayAmount)).rejects.toRevert('revert REPAY_BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED'); + await send(slToken, 'harnessSetTotalBorrows', [1]); + await expect(repayBorrowFresh(slToken, payer, borrower, repayAmount)).rejects.toRevert('revert REPAY_BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED'); }); it("reverts if checkTransferIn fails", async () => { await expect( - send(cToken, 'harnessRepayBorrowFresh', [payer, borrower, repayAmount], {from: root, value: repayAmount}) + send(slToken, 'harnessRepayBorrowFresh', [payer, borrower, repayAmount], {from: root, value: repayAmount}) ).rejects.toRevert("revert sender mismatch"); await expect( - send(cToken, 'harnessRepayBorrowFresh', [payer, borrower, repayAmount], {from: payer, value: 1}) + send(slToken, 'harnessRepayBorrowFresh', [payer, borrower, repayAmount], {from: payer, value: 1}) ).rejects.toRevert("revert value mismatch"); }); it("reverts if repayBorrowVerify fails", async() => { - await send(cToken.comptroller, 'setRepayBorrowVerify', [false]); - await expect(repayBorrowFresh(cToken, payer, borrower, repayAmount)).rejects.toRevert("revert repayBorrowVerify rejected repayBorrow"); + await send(slToken.comptroller, 'setRepayBorrowVerify', [false]); + await expect(repayBorrowFresh(slToken, payer, borrower, repayAmount)).rejects.toRevert("revert repayBorrowVerify rejected repayBorrow"); }); it("transfers the underlying cash, and emits RepayBorrow event", async () => { - const beforeBalances = await getBalances([cToken], [borrower]); - const result = await repayBorrowFresh(cToken, payer, borrower, repayAmount); - const afterBalances = await getBalances([cToken], [borrower]); + const beforeBalances = await getBalances([slToken], [borrower]); + const result = await repayBorrowFresh(slToken, payer, borrower, repayAmount); + const afterBalances = await getBalances([slToken], [borrower]); expect(result).toSucceed(); if (borrower == payer) { expect(afterBalances).toEqual(await adjustBalances(beforeBalances, [ - [cToken, 'eth', repayAmount], - [cToken, 'borrows', -repayAmount], - [cToken, borrower, 'borrows', -repayAmount], - [cToken, borrower, 'eth', -repayAmount.add(await etherGasCost(result))] + [slToken, 'eth', repayAmount], + [slToken, 'borrows', -repayAmount], + [slToken, borrower, 'borrows', -repayAmount], + [slToken, borrower, 'eth', -repayAmount.add(await etherGasCost(result))] ])); } else { expect(afterBalances).toEqual(await adjustBalances(beforeBalances, [ - [cToken, 'eth', repayAmount], - [cToken, 'borrows', -repayAmount], - [cToken, borrower, 'borrows', -repayAmount], + [slToken, 'eth', repayAmount], + [slToken, 'borrows', -repayAmount], + [slToken, borrower, 'borrows', -repayAmount], ])); } expect(result).toHaveLog('RepayBorrow', { @@ -255,13 +255,13 @@ describe('CEther', function () { }); it("stores new borrow principal and interest index", async () => { - const beforeProtocolBorrows = await totalBorrows(cToken); - const beforeAccountBorrowSnap = await borrowSnapshot(cToken, borrower); - expect(await repayBorrowFresh(cToken, payer, borrower, repayAmount)).toSucceed(); - const afterAccountBorrows = await borrowSnapshot(cToken, borrower); + const beforeProtocolBorrows = await totalBorrows(slToken); + const beforeAccountBorrowSnap = await borrowSnapshot(slToken, borrower); + expect(await repayBorrowFresh(slToken, payer, borrower, repayAmount)).toSucceed(); + const afterAccountBorrows = await borrowSnapshot(slToken, borrower); expect(afterAccountBorrows.principal).toEqualNumber(beforeAccountBorrowSnap.principal.sub(repayAmount)); expect(afterAccountBorrows.interestIndex).toEqualNumber(etherMantissa(1)); - expect(await totalBorrows(cToken)).toEqualNumber(beforeProtocolBorrows.sub(repayAmount)); + expect(await totalBorrows(slToken)).toEqualNumber(beforeProtocolBorrows.sub(repayAmount)); }); }); }); @@ -269,32 +269,32 @@ describe('CEther', function () { describe('repayBorrow', () => { beforeEach(async () => { - await preRepay(cToken, borrower, borrower, repayAmount); + await preRepay(slToken, borrower, borrower, repayAmount); }); it("reverts if interest accrual fails", async () => { - await send(cToken.interestRateModel, 'setFailBorrowRate', [true]); - await expect(repayBorrow(cToken, borrower, repayAmount)).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); + await send(slToken.interestRateModel, 'setFailBorrowRate', [true]); + await expect(repayBorrow(slToken, borrower, repayAmount)).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); }); it("reverts when repay borrow fresh fails", async () => { - await send(cToken.comptroller, 'setRepayBorrowAllowed', [false]); - await expect(repayBorrow(cToken, borrower, repayAmount)).rejects.toRevertWithError('COMPTROLLER_REJECTION', "revert repayBorrow failed"); + await send(slToken.comptroller, 'setRepayBorrowAllowed', [false]); + await expect(repayBorrow(slToken, borrower, repayAmount)).rejects.toRevertWithError('COMPTROLLER_REJECTION', "revert repayBorrow failed"); }); it("returns success from repayBorrowFresh and repays the right amount", async () => { - await fastForward(cToken); - const beforeAccountBorrowSnap = await borrowSnapshot(cToken, borrower); - expect(await repayBorrow(cToken, borrower, repayAmount)).toSucceed(); - const afterAccountBorrowSnap = await borrowSnapshot(cToken, borrower); + await fastForward(slToken); + const beforeAccountBorrowSnap = await borrowSnapshot(slToken, borrower); + expect(await repayBorrow(slToken, borrower, repayAmount)).toSucceed(); + const afterAccountBorrowSnap = await borrowSnapshot(slToken, borrower); expect(afterAccountBorrowSnap.principal).toEqualNumber(beforeAccountBorrowSnap.principal.sub(repayAmount)); }); it("reverts if overpaying", async () => { - const beforeAccountBorrowSnap = await borrowSnapshot(cToken, borrower); + const beforeAccountBorrowSnap = await borrowSnapshot(slToken, borrower); let tooMuch = new BigNumber(beforeAccountBorrowSnap.principal).plus(1); - await expect(repayBorrow(cToken, borrower, tooMuch)).rejects.toRevert("revert REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED"); - // await assert.toRevertWithError(repayBorrow(cToken, borrower, tooMuch), 'MATH_ERROR', "revert repayBorrow failed"); + await expect(repayBorrow(slToken, borrower, tooMuch)).rejects.toRevert("revert REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED"); + // await assert.toRevertWithError(repayBorrow(slToken, borrower, tooMuch), 'MATH_ERROR', "revert repayBorrow failed"); }); }); @@ -303,24 +303,24 @@ describe('CEther', function () { beforeEach(async () => { payer = benefactor; - await preRepay(cToken, payer, borrower, repayAmount); + await preRepay(slToken, payer, borrower, repayAmount); }); it("reverts if interest accrual fails", async () => { - await send(cToken.interestRateModel, 'setFailBorrowRate', [true]); - await expect(repayBorrowBehalf(cToken, payer, borrower, repayAmount)).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); + await send(slToken.interestRateModel, 'setFailBorrowRate', [true]); + await expect(repayBorrowBehalf(slToken, payer, borrower, repayAmount)).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); }); it("reverts from within repay borrow fresh", async () => { - await send(cToken.comptroller, 'setRepayBorrowAllowed', [false]); - await expect(repayBorrowBehalf(cToken, payer, borrower, repayAmount)).rejects.toRevertWithError('COMPTROLLER_REJECTION', "revert repayBorrowBehalf failed"); + await send(slToken.comptroller, 'setRepayBorrowAllowed', [false]); + await expect(repayBorrowBehalf(slToken, payer, borrower, repayAmount)).rejects.toRevertWithError('COMPTROLLER_REJECTION', "revert repayBorrowBehalf failed"); }); it("returns success from repayBorrowFresh and repays the right amount", async () => { - await fastForward(cToken); - const beforeAccountBorrowSnap = await borrowSnapshot(cToken, borrower); - expect(await repayBorrowBehalf(cToken, payer, borrower, repayAmount)).toSucceed(); - const afterAccountBorrowSnap = await borrowSnapshot(cToken, borrower); + await fastForward(slToken); + const beforeAccountBorrowSnap = await borrowSnapshot(slToken, borrower); + expect(await repayBorrowBehalf(slToken, payer, borrower, repayAmount)).toSucceed(); + const afterAccountBorrowSnap = await borrowSnapshot(slToken, borrower); expect(afterAccountBorrowSnap.principal).toEqualNumber(beforeAccountBorrowSnap.principal.sub(repayAmount)); }); }); diff --git a/tests/Tokens/borrowAndRepayTest.js b/tests/Tokens/borrowAndRepayTest.js index 7ada8eeca..72d384d97 100644 --- a/tests/Tokens/borrowAndRepayTest.js +++ b/tests/Tokens/borrowAndRepayTest.js @@ -4,7 +4,7 @@ const { } = require('../Utils/Ethereum'); const { - makeCToken, + makeSLToken, balanceOf, borrowSnapshot, totalBorrows, @@ -12,128 +12,128 @@ const { setBalance, preApprove, pretendBorrow -} = require('../Utils/Compound'); +} = require('../Utils/SashimiLending'); const borrowAmount = etherUnsigned(10e3); const repayAmount = etherUnsigned(10e2); -async function preBorrow(cToken, borrower, borrowAmount) { - await send(cToken.comptroller, 'setBorrowAllowed', [true]); - await send(cToken.comptroller, 'setBorrowVerify', [true]); - await send(cToken.interestRateModel, 'setFailBorrowRate', [false]); - await send(cToken.underlying, 'harnessSetBalance', [cToken._address, borrowAmount]); - await send(cToken, 'harnessSetFailTransferToAddress', [borrower, false]); - await send(cToken, 'harnessSetAccountBorrows', [borrower, 0, 0]); - await send(cToken, 'harnessSetTotalBorrows', [0]); +async function preBorrow(slToken, borrower, borrowAmount) { + await send(slToken.comptroller, 'setBorrowAllowed', [true]); + await send(slToken.comptroller, 'setBorrowVerify', [true]); + await send(slToken.interestRateModel, 'setFailBorrowRate', [false]); + await send(slToken.underlying, 'harnessSetBalance', [slToken._address, borrowAmount]); + await send(slToken, 'harnessSetFailTransferToAddress', [borrower, false]); + await send(slToken, 'harnessSetAccountBorrows', [borrower, 0, 0]); + await send(slToken, 'harnessSetTotalBorrows', [0]); } -async function borrowFresh(cToken, borrower, borrowAmount) { - return send(cToken, 'harnessBorrowFresh', [borrower, borrowAmount]); +async function borrowFresh(slToken, borrower, borrowAmount) { + return send(slToken, 'harnessBorrowFresh', [borrower, borrowAmount]); } -async function borrow(cToken, borrower, borrowAmount, opts = {}) { +async function borrow(slToken, borrower, borrowAmount, opts = {}) { // make sure to have a block delta so we accrue interest - await send(cToken, 'harnessFastForward', [1]); - return send(cToken, 'borrow', [borrowAmount], {from: borrower}); + await send(slToken, 'harnessFastForward', [1]); + return send(slToken, 'borrow', [borrowAmount], {from: borrower}); } -async function preRepay(cToken, benefactor, borrower, repayAmount) { +async function preRepay(slToken, benefactor, borrower, repayAmount) { // setup either benefactor OR borrower for success in repaying - await send(cToken.comptroller, 'setRepayBorrowAllowed', [true]); - await send(cToken.comptroller, 'setRepayBorrowVerify', [true]); - await send(cToken.interestRateModel, 'setFailBorrowRate', [false]); - await send(cToken.underlying, 'harnessSetFailTransferFromAddress', [benefactor, false]); - await send(cToken.underlying, 'harnessSetFailTransferFromAddress', [borrower, false]); - await pretendBorrow(cToken, borrower, 1, 1, repayAmount); - await preApprove(cToken, benefactor, repayAmount); - await preApprove(cToken, borrower, repayAmount); + await send(slToken.comptroller, 'setRepayBorrowAllowed', [true]); + await send(slToken.comptroller, 'setRepayBorrowVerify', [true]); + await send(slToken.interestRateModel, 'setFailBorrowRate', [false]); + await send(slToken.underlying, 'harnessSetFailTransferFromAddress', [benefactor, false]); + await send(slToken.underlying, 'harnessSetFailTransferFromAddress', [borrower, false]); + await pretendBorrow(slToken, borrower, 1, 1, repayAmount); + await preApprove(slToken, benefactor, repayAmount); + await preApprove(slToken, borrower, repayAmount); } -async function repayBorrowFresh(cToken, payer, borrower, repayAmount) { - return send(cToken, 'harnessRepayBorrowFresh', [payer, borrower, repayAmount], {from: payer}); +async function repayBorrowFresh(slToken, payer, borrower, repayAmount) { + return send(slToken, 'harnessRepayBorrowFresh', [payer, borrower, repayAmount], {from: payer}); } -async function repayBorrow(cToken, borrower, repayAmount) { +async function repayBorrow(slToken, borrower, repayAmount) { // make sure to have a block delta so we accrue interest - await send(cToken, 'harnessFastForward', [1]); - return send(cToken, 'repayBorrow', [repayAmount], {from: borrower}); + await send(slToken, 'harnessFastForward', [1]); + return send(slToken, 'repayBorrow', [repayAmount], {from: borrower}); } -async function repayBorrowBehalf(cToken, payer, borrower, repayAmount) { +async function repayBorrowBehalf(slToken, payer, borrower, repayAmount) { // make sure to have a block delta so we accrue interest - await send(cToken, 'harnessFastForward', [1]); - return send(cToken, 'repayBorrowBehalf', [borrower, repayAmount], {from: payer}); + await send(slToken, 'harnessFastForward', [1]); + return send(slToken, 'repayBorrowBehalf', [borrower, repayAmount], {from: payer}); } -describe('CToken', function () { - let cToken, root, borrower, benefactor, accounts; +describe('SLToken', function () { + let slToken, root, borrower, benefactor, accounts; beforeEach(async () => { [root, borrower, benefactor, ...accounts] = saddle.accounts; - cToken = await makeCToken({comptrollerOpts: {kind: 'bool'}}); + slToken = await makeSLToken({comptrollerOpts: {kind: 'bool'}}); }); describe('borrowFresh', () => { - beforeEach(async () => await preBorrow(cToken, borrower, borrowAmount)); + beforeEach(async () => await preBorrow(slToken, borrower, borrowAmount)); it("fails if comptroller tells it to", async () => { - await send(cToken.comptroller, 'setBorrowAllowed', [false]); - expect(await borrowFresh(cToken, borrower, borrowAmount)).toHaveTrollReject('BORROW_COMPTROLLER_REJECTION'); + await send(slToken.comptroller, 'setBorrowAllowed', [false]); + expect(await borrowFresh(slToken, borrower, borrowAmount)).toHaveTrollReject('BORROW_COMPTROLLER_REJECTION'); }); it("proceeds if comptroller tells it to", async () => { - await expect(await borrowFresh(cToken, borrower, borrowAmount)).toSucceed(); + await expect(await borrowFresh(slToken, borrower, borrowAmount)).toSucceed(); }); it("fails if market not fresh", async () => { - await fastForward(cToken); - expect(await borrowFresh(cToken, borrower, borrowAmount)).toHaveTokenFailure('MARKET_NOT_FRESH', 'BORROW_FRESHNESS_CHECK'); + await fastForward(slToken); + expect(await borrowFresh(slToken, borrower, borrowAmount)).toHaveTokenFailure('MARKET_NOT_FRESH', 'BORROW_FRESHNESS_CHECK'); }); it("continues if fresh", async () => { - await expect(await send(cToken, 'accrueInterest')).toSucceed(); - await expect(await borrowFresh(cToken, borrower, borrowAmount)).toSucceed(); + await expect(await send(slToken, 'accrueInterest')).toSucceed(); + await expect(await borrowFresh(slToken, borrower, borrowAmount)).toSucceed(); }); it("fails if error if protocol has less than borrowAmount of underlying", async () => { - expect(await borrowFresh(cToken, borrower, borrowAmount.add(1))).toHaveTokenFailure('TOKEN_INSUFFICIENT_CASH', 'BORROW_CASH_NOT_AVAILABLE'); + expect(await borrowFresh(slToken, borrower, borrowAmount.add(1))).toHaveTokenFailure('TOKEN_INSUFFICIENT_CASH', 'BORROW_CASH_NOT_AVAILABLE'); }); it("fails if borrowBalanceStored fails (due to non-zero stored principal with zero account index)", async () => { - await pretendBorrow(cToken, borrower, 0, 3e18, 5e18); - expect(await borrowFresh(cToken, borrower, borrowAmount)).toHaveTokenFailure('MATH_ERROR', 'BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED'); + await pretendBorrow(slToken, borrower, 0, 3e18, 5e18); + expect(await borrowFresh(slToken, borrower, borrowAmount)).toHaveTokenFailure('MATH_ERROR', 'BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED'); }); it("fails if calculating account new total borrow balance overflows", async () => { - await pretendBorrow(cToken, borrower, 1e-18, 1e-18, -1); - expect(await borrowFresh(cToken, borrower, borrowAmount)).toHaveTokenFailure('MATH_ERROR', 'BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED'); + await pretendBorrow(slToken, borrower, 1e-18, 1e-18, -1); + expect(await borrowFresh(slToken, borrower, borrowAmount)).toHaveTokenFailure('MATH_ERROR', 'BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED'); }); it("fails if calculation of new total borrow balance overflows", async () => { - await send(cToken, 'harnessSetTotalBorrows', [-1]); - expect(await borrowFresh(cToken, borrower, borrowAmount)).toHaveTokenFailure('MATH_ERROR', 'BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED'); + await send(slToken, 'harnessSetTotalBorrows', [-1]); + expect(await borrowFresh(slToken, borrower, borrowAmount)).toHaveTokenFailure('MATH_ERROR', 'BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED'); }); it("reverts if transfer out fails", async () => { - await send(cToken, 'harnessSetFailTransferToAddress', [borrower, true]); - await expect(borrowFresh(cToken, borrower, borrowAmount)).rejects.toRevert("revert TOKEN_TRANSFER_OUT_FAILED"); + await send(slToken, 'harnessSetFailTransferToAddress', [borrower, true]); + await expect(borrowFresh(slToken, borrower, borrowAmount)).rejects.toRevert("revert TOKEN_TRANSFER_OUT_FAILED"); }); it("reverts if borrowVerify fails", async() => { - await send(cToken.comptroller, 'setBorrowVerify', [false]); - await expect(borrowFresh(cToken, borrower, borrowAmount)).rejects.toRevert("revert borrowVerify rejected borrow"); + await send(slToken.comptroller, 'setBorrowVerify', [false]); + await expect(borrowFresh(slToken, borrower, borrowAmount)).rejects.toRevert("revert borrowVerify rejected borrow"); }); it("transfers the underlying cash, tokens, and emits Transfer, Borrow events", async () => { - const beforeProtocolCash = await balanceOf(cToken.underlying, cToken._address); - const beforeProtocolBorrows = await totalBorrows(cToken); - const beforeAccountCash = await balanceOf(cToken.underlying, borrower); - const result = await borrowFresh(cToken, borrower, borrowAmount); + const beforeProtocolCash = await balanceOf(slToken.underlying, slToken._address); + const beforeProtocolBorrows = await totalBorrows(slToken); + const beforeAccountCash = await balanceOf(slToken.underlying, borrower); + const result = await borrowFresh(slToken, borrower, borrowAmount); expect(result).toSucceed(); - expect(await balanceOf(cToken.underlying, borrower)).toEqualNumber(beforeAccountCash.add(borrowAmount)); - expect(await balanceOf(cToken.underlying, cToken._address)).toEqualNumber(beforeProtocolCash.sub(borrowAmount)); - expect(await totalBorrows(cToken)).toEqualNumber(beforeProtocolBorrows.add(borrowAmount)); + expect(await balanceOf(slToken.underlying, borrower)).toEqualNumber(beforeAccountCash.add(borrowAmount)); + expect(await balanceOf(slToken.underlying, slToken._address)).toEqualNumber(beforeProtocolCash.sub(borrowAmount)); + expect(await totalBorrows(slToken)).toEqualNumber(beforeProtocolBorrows.add(borrowAmount)); expect(result).toHaveLog('Transfer', { - from: cToken._address, + from: slToken._address, to: borrower, amount: borrowAmount.toString() }); @@ -146,33 +146,33 @@ describe('CToken', function () { }); it("stores new borrow principal and interest index", async () => { - const beforeProtocolBorrows = await totalBorrows(cToken); - await pretendBorrow(cToken, borrower, 0, 3, 0); - await borrowFresh(cToken, borrower, borrowAmount); - const borrowSnap = await borrowSnapshot(cToken, borrower); + const beforeProtocolBorrows = await totalBorrows(slToken); + await pretendBorrow(slToken, borrower, 0, 3, 0); + await borrowFresh(slToken, borrower, borrowAmount); + const borrowSnap = await borrowSnapshot(slToken, borrower); expect(borrowSnap.principal).toEqualNumber(borrowAmount); expect(borrowSnap.interestIndex).toEqualNumber(etherMantissa(3)); - expect(await totalBorrows(cToken)).toEqualNumber(beforeProtocolBorrows.add(borrowAmount)); + expect(await totalBorrows(slToken)).toEqualNumber(beforeProtocolBorrows.add(borrowAmount)); }); }); describe('borrow', () => { - beforeEach(async () => await preBorrow(cToken, borrower, borrowAmount)); + beforeEach(async () => await preBorrow(slToken, borrower, borrowAmount)); it("emits a borrow failure if interest accrual fails", async () => { - await send(cToken.interestRateModel, 'setFailBorrowRate', [true]); - await expect(borrow(cToken, borrower, borrowAmount)).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); + await send(slToken.interestRateModel, 'setFailBorrowRate', [true]); + await expect(borrow(slToken, borrower, borrowAmount)).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); }); it("returns error from borrowFresh without emitting any extra logs", async () => { - expect(await borrow(cToken, borrower, borrowAmount.add(1))).toHaveTokenFailure('TOKEN_INSUFFICIENT_CASH', 'BORROW_CASH_NOT_AVAILABLE'); + expect(await borrow(slToken, borrower, borrowAmount.add(1))).toHaveTokenFailure('TOKEN_INSUFFICIENT_CASH', 'BORROW_CASH_NOT_AVAILABLE'); }); it("returns success from borrowFresh and transfers the correct amount", async () => { - const beforeAccountCash = await balanceOf(cToken.underlying, borrower); - await fastForward(cToken); - expect(await borrow(cToken, borrower, borrowAmount)).toSucceed(); - expect(await balanceOf(cToken.underlying, borrower)).toEqualNumber(beforeAccountCash.add(borrowAmount)); + const beforeAccountCash = await balanceOf(slToken.underlying, borrower); + await fastForward(slToken); + expect(await borrow(slToken, borrower, borrowAmount)).toSucceed(); + expect(await balanceOf(slToken.underlying, borrower)).toEqualNumber(beforeAccountCash.add(borrowAmount)); }); }); @@ -183,58 +183,58 @@ describe('CToken', function () { describe(label, () => { beforeEach(async () => { payer = benefactorIsPayer ? benefactor : borrower; - await preRepay(cToken, payer, borrower, repayAmount); + await preRepay(slToken, payer, borrower, repayAmount); }); it("fails if repay is not allowed", async () => { - await send(cToken.comptroller, 'setRepayBorrowAllowed', [false]); - expect(await repayBorrowFresh(cToken, payer, borrower, repayAmount)).toHaveTrollReject('REPAY_BORROW_COMPTROLLER_REJECTION', 'MATH_ERROR'); + await send(slToken.comptroller, 'setRepayBorrowAllowed', [false]); + expect(await repayBorrowFresh(slToken, payer, borrower, repayAmount)).toHaveTrollReject('REPAY_BORROW_COMPTROLLER_REJECTION', 'MATH_ERROR'); }); it("fails if block number ≠ current block number", async () => { - await fastForward(cToken); - expect(await repayBorrowFresh(cToken, payer, borrower, repayAmount)).toHaveTokenFailure('MARKET_NOT_FRESH', 'REPAY_BORROW_FRESHNESS_CHECK'); + await fastForward(slToken); + expect(await repayBorrowFresh(slToken, payer, borrower, repayAmount)).toHaveTokenFailure('MARKET_NOT_FRESH', 'REPAY_BORROW_FRESHNESS_CHECK'); }); it("fails if insufficient approval", async() => { - await preApprove(cToken, payer, 1); - await expect(repayBorrowFresh(cToken, payer, borrower, repayAmount)).rejects.toRevert('revert Insufficient allowance'); + await preApprove(slToken, payer, 1); + await expect(repayBorrowFresh(slToken, payer, borrower, repayAmount)).rejects.toRevert('revert Insufficient allowance'); }); it("fails if insufficient balance", async() => { - await setBalance(cToken.underlying, payer, 1); - await expect(repayBorrowFresh(cToken, payer, borrower, repayAmount)).rejects.toRevert('revert Insufficient balance'); + await setBalance(slToken.underlying, payer, 1); + await expect(repayBorrowFresh(slToken, payer, borrower, repayAmount)).rejects.toRevert('revert Insufficient balance'); }); it("returns an error if calculating account new account borrow balance fails", async () => { - await pretendBorrow(cToken, borrower, 1, 1, 1); - await expect(repayBorrowFresh(cToken, payer, borrower, repayAmount)).rejects.toRevert("revert REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED"); + await pretendBorrow(slToken, borrower, 1, 1, 1); + await expect(repayBorrowFresh(slToken, payer, borrower, repayAmount)).rejects.toRevert("revert REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED"); }); it("returns an error if calculation of new total borrow balance fails", async () => { - await send(cToken, 'harnessSetTotalBorrows', [1]); - await expect(repayBorrowFresh(cToken, payer, borrower, repayAmount)).rejects.toRevert("revert REPAY_BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED"); + await send(slToken, 'harnessSetTotalBorrows', [1]); + await expect(repayBorrowFresh(slToken, payer, borrower, repayAmount)).rejects.toRevert("revert REPAY_BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED"); }); it("reverts if doTransferIn fails", async () => { - await send(cToken.underlying, 'harnessSetFailTransferFromAddress', [payer, true]); - await expect(repayBorrowFresh(cToken, payer, borrower, repayAmount)).rejects.toRevert("revert TOKEN_TRANSFER_IN_FAILED"); + await send(slToken.underlying, 'harnessSetFailTransferFromAddress', [payer, true]); + await expect(repayBorrowFresh(slToken, payer, borrower, repayAmount)).rejects.toRevert("revert TOKEN_TRANSFER_IN_FAILED"); }); it("reverts if repayBorrowVerify fails", async() => { - await send(cToken.comptroller, 'setRepayBorrowVerify', [false]); - await expect(repayBorrowFresh(cToken, payer, borrower, repayAmount)).rejects.toRevert("revert repayBorrowVerify rejected repayBorrow"); + await send(slToken.comptroller, 'setRepayBorrowVerify', [false]); + await expect(repayBorrowFresh(slToken, payer, borrower, repayAmount)).rejects.toRevert("revert repayBorrowVerify rejected repayBorrow"); }); it("transfers the underlying cash, and emits Transfer, RepayBorrow events", async () => { - const beforeProtocolCash = await balanceOf(cToken.underlying, cToken._address); - const result = await repayBorrowFresh(cToken, payer, borrower, repayAmount); - expect(await balanceOf(cToken.underlying, cToken._address)).toEqualNumber(beforeProtocolCash.add(repayAmount)); + const beforeProtocolCash = await balanceOf(slToken.underlying, slToken._address); + const result = await repayBorrowFresh(slToken, payer, borrower, repayAmount); + expect(await balanceOf(slToken.underlying, slToken._address)).toEqualNumber(beforeProtocolCash.add(repayAmount)); expect(result).toHaveLog('Transfer', { from: payer, - to: cToken._address, + to: slToken._address, amount: repayAmount.toString() }); expect(result).toHaveLog('RepayBorrow', { @@ -247,13 +247,13 @@ describe('CToken', function () { }); it("stores new borrow principal and interest index", async () => { - const beforeProtocolBorrows = await totalBorrows(cToken); - const beforeAccountBorrowSnap = await borrowSnapshot(cToken, borrower); - expect(await repayBorrowFresh(cToken, payer, borrower, repayAmount)).toSucceed(); - const afterAccountBorrows = await borrowSnapshot(cToken, borrower); + const beforeProtocolBorrows = await totalBorrows(slToken); + const beforeAccountBorrowSnap = await borrowSnapshot(slToken, borrower); + expect(await repayBorrowFresh(slToken, payer, borrower, repayAmount)).toSucceed(); + const afterAccountBorrows = await borrowSnapshot(slToken, borrower); expect(afterAccountBorrows.principal).toEqualNumber(beforeAccountBorrowSnap.principal.sub(repayAmount)); expect(afterAccountBorrows.interestIndex).toEqualNumber(etherMantissa(1)); - expect(await totalBorrows(cToken)).toEqualNumber(beforeProtocolBorrows.sub(repayAmount)); + expect(await totalBorrows(slToken)).toEqualNumber(beforeProtocolBorrows.sub(repayAmount)); }); }); }); @@ -261,38 +261,38 @@ describe('CToken', function () { describe('repayBorrow', () => { beforeEach(async () => { - await preRepay(cToken, borrower, borrower, repayAmount); + await preRepay(slToken, borrower, borrower, repayAmount); }); it("emits a repay borrow failure if interest accrual fails", async () => { - await send(cToken.interestRateModel, 'setFailBorrowRate', [true]); - await expect(repayBorrow(cToken, borrower, repayAmount)).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); + await send(slToken.interestRateModel, 'setFailBorrowRate', [true]); + await expect(repayBorrow(slToken, borrower, repayAmount)).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); }); it("returns error from repayBorrowFresh without emitting any extra logs", async () => { - await setBalance(cToken.underlying, borrower, 1); - await expect(repayBorrow(cToken, borrower, repayAmount)).rejects.toRevert('revert Insufficient balance'); + await setBalance(slToken.underlying, borrower, 1); + await expect(repayBorrow(slToken, borrower, repayAmount)).rejects.toRevert('revert Insufficient balance'); }); it("returns success from repayBorrowFresh and repays the right amount", async () => { - await fastForward(cToken); - const beforeAccountBorrowSnap = await borrowSnapshot(cToken, borrower); - expect(await repayBorrow(cToken, borrower, repayAmount)).toSucceed(); - const afterAccountBorrowSnap = await borrowSnapshot(cToken, borrower); + await fastForward(slToken); + const beforeAccountBorrowSnap = await borrowSnapshot(slToken, borrower); + expect(await repayBorrow(slToken, borrower, repayAmount)).toSucceed(); + const afterAccountBorrowSnap = await borrowSnapshot(slToken, borrower); expect(afterAccountBorrowSnap.principal).toEqualNumber(beforeAccountBorrowSnap.principal.sub(repayAmount)); }); it("repays the full amount owed if payer has enough", async () => { - await fastForward(cToken); - expect(await repayBorrow(cToken, borrower, -1)).toSucceed(); - const afterAccountBorrowSnap = await borrowSnapshot(cToken, borrower); + await fastForward(slToken); + expect(await repayBorrow(slToken, borrower, -1)).toSucceed(); + const afterAccountBorrowSnap = await borrowSnapshot(slToken, borrower); expect(afterAccountBorrowSnap.principal).toEqualNumber(0); }); it("fails gracefully if payer does not have enough", async () => { - await setBalance(cToken.underlying, borrower, 3); - await fastForward(cToken); - await expect(repayBorrow(cToken, borrower, -1)).rejects.toRevert('revert Insufficient balance'); + await setBalance(slToken.underlying, borrower, 3); + await fastForward(slToken); + await expect(repayBorrow(slToken, borrower, -1)).rejects.toRevert('revert Insufficient balance'); }); }); @@ -301,24 +301,24 @@ describe('CToken', function () { beforeEach(async () => { payer = benefactor; - await preRepay(cToken, payer, borrower, repayAmount); + await preRepay(slToken, payer, borrower, repayAmount); }); it("emits a repay borrow failure if interest accrual fails", async () => { - await send(cToken.interestRateModel, 'setFailBorrowRate', [true]); - await expect(repayBorrowBehalf(cToken, payer, borrower, repayAmount)).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); + await send(slToken.interestRateModel, 'setFailBorrowRate', [true]); + await expect(repayBorrowBehalf(slToken, payer, borrower, repayAmount)).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); }); it("returns error from repayBorrowFresh without emitting any extra logs", async () => { - await setBalance(cToken.underlying, payer, 1); - await expect(repayBorrowBehalf(cToken, payer, borrower, repayAmount)).rejects.toRevert('revert Insufficient balance'); + await setBalance(slToken.underlying, payer, 1); + await expect(repayBorrowBehalf(slToken, payer, borrower, repayAmount)).rejects.toRevert('revert Insufficient balance'); }); it("returns success from repayBorrowFresh and repays the right amount", async () => { - await fastForward(cToken); - const beforeAccountBorrowSnap = await borrowSnapshot(cToken, borrower); - expect(await repayBorrowBehalf(cToken, payer, borrower, repayAmount)).toSucceed(); - const afterAccountBorrowSnap = await borrowSnapshot(cToken, borrower); + await fastForward(slToken); + const beforeAccountBorrowSnap = await borrowSnapshot(slToken, borrower); + expect(await repayBorrowBehalf(slToken, payer, borrower, repayAmount)).toSucceed(); + const afterAccountBorrowSnap = await borrowSnapshot(slToken, borrower); expect(afterAccountBorrowSnap.principal).toEqualNumber(beforeAccountBorrowSnap.principal.sub(repayAmount)); }); }); diff --git a/tests/Tokens/cTokenTest.js b/tests/Tokens/cTokenTest.js deleted file mode 100644 index efe13910b..000000000 --- a/tests/Tokens/cTokenTest.js +++ /dev/null @@ -1,227 +0,0 @@ -const { - etherUnsigned, - etherMantissa -} = require('../Utils/Ethereum'); - -const { - makeCToken, - setBorrowRate, - pretendBorrow -} = require('../Utils/Compound'); - -describe('CToken', function () { - let root, admin, accounts; - beforeEach(async () => { - [root, admin, ...accounts] = saddle.accounts; - }); - - describe('constructor', () => { - it("fails when non erc-20 underlying", async () => { - await expect(makeCToken({ underlying: { _address: root } })).rejects.toRevert("revert"); - }); - - it("fails when 0 initial exchange rate", async () => { - await expect(makeCToken({ exchangeRate: 0 })).rejects.toRevert("revert initial exchange rate must be greater than zero."); - }); - - it("succeeds with erc-20 underlying and non-zero exchange rate", async () => { - const cToken = await makeCToken(); - expect(await call(cToken, 'underlying')).toEqual(cToken.underlying._address); - expect(await call(cToken, 'admin')).toEqual(root); - }); - - it("succeeds when setting admin to contructor argument", async () => { - const cToken = await makeCToken({ admin: admin }); - expect(await call(cToken, 'admin')).toEqual(admin); - }); - }); - - describe('name, symbol, decimals', () => { - let cToken; - - beforeEach(async () => { - cToken = await makeCToken({ name: "CToken Foo", symbol: "cFOO", decimals: 10 }); - }); - - it('should return correct name', async () => { - expect(await call(cToken, 'name')).toEqual("CToken Foo"); - }); - - it('should return correct symbol', async () => { - expect(await call(cToken, 'symbol')).toEqual("cFOO"); - }); - - it('should return correct decimals', async () => { - expect(await call(cToken, 'decimals')).toEqualNumber(10); - }); - }); - - describe('balanceOfUnderlying', () => { - it("has an underlying balance", async () => { - const cToken = await makeCToken({ supportMarket: true, exchangeRate: 2 }); - await send(cToken, 'harnessSetBalance', [root, 100]); - expect(await call(cToken, 'balanceOfUnderlying', [root])).toEqualNumber(200); - }); - }); - - describe('borrowRatePerBlock', () => { - it("has a borrow rate", async () => { - const cToken = await makeCToken({ supportMarket: true, interestRateModelOpts: { kind: 'jump-rate', baseRate: .05, multiplier: 0.45, kink: 0.95, jump: 5 } }); - const perBlock = await call(cToken, 'borrowRatePerBlock'); - expect(Math.abs(perBlock * 2102400 - 5e16)).toBeLessThanOrEqual(1e8); - }); - }); - - describe('supplyRatePerBlock', () => { - it("returns 0 if there's no supply", async () => { - const cToken = await makeCToken({ supportMarket: true, interestRateModelOpts: { kind: 'jump-rate', baseRate: .05, multiplier: 0.45, kink: 0.95, jump: 5 } }); - const perBlock = await call(cToken, 'supplyRatePerBlock'); - await expect(perBlock).toEqualNumber(0); - }); - - it("has a supply rate", async () => { - const baseRate = 0.05; - const multiplier = 0.45; - const kink = 0.95; - const jump = 5 * multiplier; - const cToken = await makeCToken({ supportMarket: true, interestRateModelOpts: { kind: 'jump-rate', baseRate, multiplier, kink, jump } }); - await send(cToken, 'harnessSetReserveFactorFresh', [etherMantissa(.01)]); - await send(cToken, 'harnessExchangeRateDetails', [1, 1, 0]); - await send(cToken, 'harnessSetExchangeRate', [etherMantissa(1)]); - // Full utilization (Over the kink so jump is included), 1% reserves - const borrowRate = baseRate + multiplier * kink + jump * .05; - const expectedSuplyRate = borrowRate * .99; - - const perBlock = await call(cToken, 'supplyRatePerBlock'); - expect(Math.abs(perBlock * 2102400 - expectedSuplyRate * 1e18)).toBeLessThanOrEqual(1e8); - }); - }); - - describe("borrowBalanceCurrent", () => { - let borrower; - let cToken; - - beforeEach(async () => { - borrower = accounts[0]; - cToken = await makeCToken(); - }); - - beforeEach(async () => { - await setBorrowRate(cToken, .001) - await send(cToken.interestRateModel, 'setFailBorrowRate', [false]); - }); - - it("reverts if interest accrual fails", async () => { - await send(cToken.interestRateModel, 'setFailBorrowRate', [true]); - // make sure we accrue interest - await send(cToken, 'harnessFastForward', [1]); - await expect(send(cToken, 'borrowBalanceCurrent', [borrower])).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); - }); - - it("returns successful result from borrowBalanceStored with no interest", async () => { - await setBorrowRate(cToken, 0); - await pretendBorrow(cToken, borrower, 1, 1, 5e18); - expect(await call(cToken, 'borrowBalanceCurrent', [borrower])).toEqualNumber(5e18) - }); - - it("returns successful result from borrowBalanceCurrent with no interest", async () => { - await setBorrowRate(cToken, 0); - await pretendBorrow(cToken, borrower, 1, 3, 5e18); - expect(await send(cToken, 'harnessFastForward', [5])).toSucceed(); - expect(await call(cToken, 'borrowBalanceCurrent', [borrower])).toEqualNumber(5e18 * 3) - }); - }); - - describe("borrowBalanceStored", () => { - let borrower; - let cToken; - - beforeEach(async () => { - borrower = accounts[0]; - cToken = await makeCToken({ comptrollerOpts: { kind: 'bool' } }); - }); - - it("returns 0 for account with no borrows", async () => { - expect(await call(cToken, 'borrowBalanceStored', [borrower])).toEqualNumber(0) - }); - - it("returns stored principal when account and market indexes are the same", async () => { - await pretendBorrow(cToken, borrower, 1, 1, 5e18); - expect(await call(cToken, 'borrowBalanceStored', [borrower])).toEqualNumber(5e18); - }); - - it("returns calculated balance when market index is higher than account index", async () => { - await pretendBorrow(cToken, borrower, 1, 3, 5e18); - expect(await call(cToken, 'borrowBalanceStored', [borrower])).toEqualNumber(5e18 * 3); - }); - - it("has undefined behavior when market index is lower than account index", async () => { - // The market index < account index should NEVER happen, so we don't test this case - }); - - it("reverts on overflow of principal", async () => { - await pretendBorrow(cToken, borrower, 1, 3, -1); - await expect(call(cToken, 'borrowBalanceStored', [borrower])).rejects.toRevert("revert borrowBalanceStored: borrowBalanceStoredInternal failed"); - }); - - it("reverts on non-zero stored principal with zero account index", async () => { - await pretendBorrow(cToken, borrower, 0, 3, 5); - await expect(call(cToken, 'borrowBalanceStored', [borrower])).rejects.toRevert("revert borrowBalanceStored: borrowBalanceStoredInternal failed"); - }); - }); - - describe('exchangeRateStored', () => { - let cToken, exchangeRate = 2; - - beforeEach(async () => { - cToken = await makeCToken({ exchangeRate }); - }); - - it("returns initial exchange rate with zero cTokenSupply", async () => { - const result = await call(cToken, 'exchangeRateStored'); - expect(result).toEqualNumber(etherMantissa(exchangeRate)); - }); - - it("calculates with single cTokenSupply and single total borrow", async () => { - const cTokenSupply = 1, totalBorrows = 1, totalReserves = 0; - await send(cToken, 'harnessExchangeRateDetails', [cTokenSupply, totalBorrows, totalReserves]); - const result = await call(cToken, 'exchangeRateStored'); - expect(result).toEqualNumber(etherMantissa(1)); - }); - - it("calculates with cTokenSupply and total borrows", async () => { - const cTokenSupply = 100e18, totalBorrows = 10e18, totalReserves = 0; - await send(cToken, 'harnessExchangeRateDetails', [cTokenSupply, totalBorrows, totalReserves].map(etherUnsigned)); - const result = await call(cToken, 'exchangeRateStored'); - expect(result).toEqualNumber(etherMantissa(.1)); - }); - - it("calculates with cash and cTokenSupply", async () => { - const cTokenSupply = 5e18, totalBorrows = 0, totalReserves = 0; - expect( - await send(cToken.underlying, 'transfer', [cToken._address, etherMantissa(500)]) - ).toSucceed(); - await send(cToken, 'harnessExchangeRateDetails', [cTokenSupply, totalBorrows, totalReserves].map(etherUnsigned)); - const result = await call(cToken, 'exchangeRateStored'); - expect(result).toEqualNumber(etherMantissa(100)); - }); - - it("calculates with cash, borrows, reserves and cTokenSupply", async () => { - const cTokenSupply = 500e18, totalBorrows = 500e18, totalReserves = 5e18; - expect( - await send(cToken.underlying, 'transfer', [cToken._address, etherMantissa(500)]) - ).toSucceed(); - await send(cToken, 'harnessExchangeRateDetails', [cTokenSupply, totalBorrows, totalReserves].map(etherUnsigned)); - const result = await call(cToken, 'exchangeRateStored'); - expect(result).toEqualNumber(etherMantissa(1.99)); - }); - }); - - describe('getCash', () => { - it("gets the cash", async () => { - const cToken = await makeCToken(); - const result = await call(cToken, 'getCash'); - expect(result).toEqualNumber(0); - }); - }); -}); diff --git a/tests/Tokens/liquidateTest.js b/tests/Tokens/liquidateTest.js index ac22a114d..ab267e1b1 100644 --- a/tests/Tokens/liquidateTest.js +++ b/tests/Tokens/liquidateTest.js @@ -4,154 +4,154 @@ const { } = require('../Utils/Ethereum'); const { - makeCToken, + makeSLToken, fastForward, setBalance, getBalances, adjustBalances, pretendBorrow, preApprove -} = require('../Utils/Compound'); +} = require('../Utils/SashimiLending'); const repayAmount = etherUnsigned(10e2); const seizeAmount = repayAmount; const seizeTokens = seizeAmount.mul(4); // forced -async function preLiquidate(cToken, liquidator, borrower, repayAmount, cTokenCollateral) { +async function preLiquidate(slToken, liquidator, borrower, repayAmount, slTokenCollateral) { // setup for success in liquidating - await send(cToken.comptroller, 'setLiquidateBorrowAllowed', [true]); - await send(cToken.comptroller, 'setLiquidateBorrowVerify', [true]); - await send(cToken.comptroller, 'setRepayBorrowAllowed', [true]); - await send(cToken.comptroller, 'setRepayBorrowVerify', [true]); - await send(cToken.comptroller, 'setSeizeAllowed', [true]); - await send(cToken.comptroller, 'setSeizeVerify', [true]); - await send(cToken.comptroller, 'setFailCalculateSeizeTokens', [false]); - await send(cToken.underlying, 'harnessSetFailTransferFromAddress', [liquidator, false]); - await send(cToken.interestRateModel, 'setFailBorrowRate', [false]); - await send(cTokenCollateral.interestRateModel, 'setFailBorrowRate', [false]); - await send(cTokenCollateral.comptroller, 'setCalculatedSeizeTokens', [seizeTokens]); - await setBalance(cTokenCollateral, liquidator, 0); - await setBalance(cTokenCollateral, borrower, seizeTokens); - await pretendBorrow(cTokenCollateral, borrower, 0, 1, 0); - await pretendBorrow(cToken, borrower, 1, 1, repayAmount); - await preApprove(cToken, liquidator, repayAmount); + await send(slToken.comptroller, 'setLiquidateBorrowAllowed', [true]); + await send(slToken.comptroller, 'setLiquidateBorrowVerify', [true]); + await send(slToken.comptroller, 'setRepayBorrowAllowed', [true]); + await send(slToken.comptroller, 'setRepayBorrowVerify', [true]); + await send(slToken.comptroller, 'setSeizeAllowed', [true]); + await send(slToken.comptroller, 'setSeizeVerify', [true]); + await send(slToken.comptroller, 'setFailCalculateSeizeTokens', [false]); + await send(slToken.underlying, 'harnessSetFailTransferFromAddress', [liquidator, false]); + await send(slToken.interestRateModel, 'setFailBorrowRate', [false]); + await send(slTokenCollateral.interestRateModel, 'setFailBorrowRate', [false]); + await send(slTokenCollateral.comptroller, 'setCalculatedSeizeTokens', [seizeTokens]); + await setBalance(slTokenCollateral, liquidator, 0); + await setBalance(slTokenCollateral, borrower, seizeTokens); + await pretendBorrow(slTokenCollateral, borrower, 0, 1, 0); + await pretendBorrow(slToken, borrower, 1, 1, repayAmount); + await preApprove(slToken, liquidator, repayAmount); } -async function liquidateFresh(cToken, liquidator, borrower, repayAmount, cTokenCollateral) { - return send(cToken, 'harnessLiquidateBorrowFresh', [liquidator, borrower, repayAmount, cTokenCollateral._address]); +async function liquidateFresh(slToken, liquidator, borrower, repayAmount, slTokenCollateral) { + return send(slToken, 'harnessLiquidateBorrowFresh', [liquidator, borrower, repayAmount, slTokenCollateral._address]); } -async function liquidate(cToken, liquidator, borrower, repayAmount, cTokenCollateral) { +async function liquidate(slToken, liquidator, borrower, repayAmount, slTokenCollateral) { // make sure to have a block delta so we accrue interest - await fastForward(cToken, 1); - await fastForward(cTokenCollateral, 1); - return send(cToken, 'liquidateBorrow', [borrower, repayAmount, cTokenCollateral._address], {from: liquidator}); + await fastForward(slToken, 1); + await fastForward(slTokenCollateral, 1); + return send(slToken, 'liquidateBorrow', [borrower, repayAmount, slTokenCollateral._address], {from: liquidator}); } -async function seize(cToken, liquidator, borrower, seizeAmount) { - return send(cToken, 'seize', [liquidator, borrower, seizeAmount]); +async function seize(slToken, liquidator, borrower, seizeAmount) { + return send(slToken, 'seize', [liquidator, borrower, seizeAmount]); } -describe('CToken', function () { +describe('SLToken', function () { let root, liquidator, borrower, accounts; - let cToken, cTokenCollateral; + let slToken, slTokenCollateral; beforeEach(async () => { [root, liquidator, borrower, ...accounts] = saddle.accounts; - cToken = await makeCToken({comptrollerOpts: {kind: 'bool'}}); - cTokenCollateral = await makeCToken({comptroller: cToken.comptroller}); + slToken = await makeSLToken({comptrollerOpts: {kind: 'bool'}}); + slTokenCollateral = await makeSLToken({comptroller: slToken.comptroller}); }); beforeEach(async () => { - await preLiquidate(cToken, liquidator, borrower, repayAmount, cTokenCollateral); + await preLiquidate(slToken, liquidator, borrower, repayAmount, slTokenCollateral); }); describe('liquidateBorrowFresh', () => { it("fails if comptroller tells it to", async () => { - await send(cToken.comptroller, 'setLiquidateBorrowAllowed', [false]); + await send(slToken.comptroller, 'setLiquidateBorrowAllowed', [false]); expect( - await liquidateFresh(cToken, liquidator, borrower, repayAmount, cTokenCollateral) + await liquidateFresh(slToken, liquidator, borrower, repayAmount, slTokenCollateral) ).toHaveTrollReject('LIQUIDATE_COMPTROLLER_REJECTION', 'MATH_ERROR'); }); it("proceeds if comptroller tells it to", async () => { expect( - await liquidateFresh(cToken, liquidator, borrower, repayAmount, cTokenCollateral) + await liquidateFresh(slToken, liquidator, borrower, repayAmount, slTokenCollateral) ).toSucceed(); }); it("fails if market not fresh", async () => { - await fastForward(cToken); + await fastForward(slToken); expect( - await liquidateFresh(cToken, liquidator, borrower, repayAmount, cTokenCollateral) + await liquidateFresh(slToken, liquidator, borrower, repayAmount, slTokenCollateral) ).toHaveTokenFailure('MARKET_NOT_FRESH', 'LIQUIDATE_FRESHNESS_CHECK'); }); it("fails if collateral market not fresh", async () => { - await fastForward(cToken); - await fastForward(cTokenCollateral); - await send(cToken, 'accrueInterest'); + await fastForward(slToken); + await fastForward(slTokenCollateral); + await send(slToken, 'accrueInterest'); expect( - await liquidateFresh(cToken, liquidator, borrower, repayAmount, cTokenCollateral) + await liquidateFresh(slToken, liquidator, borrower, repayAmount, slTokenCollateral) ).toHaveTokenFailure('MARKET_NOT_FRESH', 'LIQUIDATE_COLLATERAL_FRESHNESS_CHECK'); }); it("fails if borrower is equal to liquidator", async () => { expect( - await liquidateFresh(cToken, borrower, borrower, repayAmount, cTokenCollateral) + await liquidateFresh(slToken, borrower, borrower, repayAmount, slTokenCollateral) ).toHaveTokenFailure('INVALID_ACCOUNT_PAIR', 'LIQUIDATE_LIQUIDATOR_IS_BORROWER'); }); it("fails if repayAmount = 0", async () => { - expect(await liquidateFresh(cToken, liquidator, borrower, 0, cTokenCollateral)).toHaveTokenFailure('INVALID_CLOSE_AMOUNT_REQUESTED', 'LIQUIDATE_CLOSE_AMOUNT_IS_ZERO'); + expect(await liquidateFresh(slToken, liquidator, borrower, 0, slTokenCollateral)).toHaveTokenFailure('INVALID_CLOSE_AMOUNT_REQUESTED', 'LIQUIDATE_CLOSE_AMOUNT_IS_ZERO'); }); it("fails if calculating seize tokens fails and does not adjust balances", async () => { - const beforeBalances = await getBalances([cToken, cTokenCollateral], [liquidator, borrower]); - await send(cToken.comptroller, 'setFailCalculateSeizeTokens', [true]); + const beforeBalances = await getBalances([slToken, slTokenCollateral], [liquidator, borrower]); + await send(slToken.comptroller, 'setFailCalculateSeizeTokens', [true]); await expect( - liquidateFresh(cToken, liquidator, borrower, repayAmount, cTokenCollateral) + liquidateFresh(slToken, liquidator, borrower, repayAmount, slTokenCollateral) ).rejects.toRevert('revert LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED'); - const afterBalances = await getBalances([cToken, cTokenCollateral], [liquidator, borrower]); + const afterBalances = await getBalances([slToken, slTokenCollateral], [liquidator, borrower]); expect(afterBalances).toEqual(beforeBalances); }); it("fails if repay fails", async () => { - await send(cToken.comptroller, 'setRepayBorrowAllowed', [false]); + await send(slToken.comptroller, 'setRepayBorrowAllowed', [false]); expect( - await liquidateFresh(cToken, liquidator, borrower, repayAmount, cTokenCollateral) + await liquidateFresh(slToken, liquidator, borrower, repayAmount, slTokenCollateral) ).toHaveTrollReject('LIQUIDATE_REPAY_BORROW_FRESH_FAILED'); }); it("reverts if seize fails", async () => { - await send(cToken.comptroller, 'setSeizeAllowed', [false]); + await send(slToken.comptroller, 'setSeizeAllowed', [false]); await expect( - liquidateFresh(cToken, liquidator, borrower, repayAmount, cTokenCollateral) + liquidateFresh(slToken, liquidator, borrower, repayAmount, slTokenCollateral) ).rejects.toRevert("revert token seizure failed"); }); it("reverts if liquidateBorrowVerify fails", async() => { - await send(cToken.comptroller, 'setLiquidateBorrowVerify', [false]); + await send(slToken.comptroller, 'setLiquidateBorrowVerify', [false]); await expect( - liquidateFresh(cToken, liquidator, borrower, repayAmount, cTokenCollateral) + liquidateFresh(slToken, liquidator, borrower, repayAmount, slTokenCollateral) ).rejects.toRevert("revert liquidateBorrowVerify rejected liquidateBorrow"); }); it("transfers the cash, borrows, tokens, and emits Transfer, LiquidateBorrow events", async () => { - const beforeBalances = await getBalances([cToken, cTokenCollateral], [liquidator, borrower]); - const result = await liquidateFresh(cToken, liquidator, borrower, repayAmount, cTokenCollateral); - const afterBalances = await getBalances([cToken, cTokenCollateral], [liquidator, borrower]); + const beforeBalances = await getBalances([slToken, slTokenCollateral], [liquidator, borrower]); + const result = await liquidateFresh(slToken, liquidator, borrower, repayAmount, slTokenCollateral); + const afterBalances = await getBalances([slToken, slTokenCollateral], [liquidator, borrower]); expect(result).toSucceed(); expect(result).toHaveLog('LiquidateBorrow', { liquidator: liquidator, borrower: borrower, repayAmount: repayAmount.toString(), - cTokenCollateral: cTokenCollateral._address, + slTokenCollateral: slTokenCollateral._address, seizeTokens: seizeTokens.toString() }); expect(result).toHaveLog(['Transfer', 0], { from: liquidator, - to: cToken._address, + to: slToken._address, amount: repayAmount.toString() }); expect(result).toHaveLog(['Transfer', 1], { @@ -160,46 +160,46 @@ describe('CToken', function () { amount: seizeTokens.toString() }); expect(afterBalances).toEqual(await adjustBalances(beforeBalances, [ - [cToken, 'cash', repayAmount], - [cToken, 'borrows', -repayAmount], - [cToken, liquidator, 'cash', -repayAmount], - [cTokenCollateral, liquidator, 'tokens', seizeTokens], - [cToken, borrower, 'borrows', -repayAmount], - [cTokenCollateral, borrower, 'tokens', -seizeTokens] + [slToken, 'cash', repayAmount], + [slToken, 'borrows', -repayAmount], + [slToken, liquidator, 'cash', -repayAmount], + [slTokenCollateral, liquidator, 'tokens', seizeTokens], + [slToken, borrower, 'borrows', -repayAmount], + [slTokenCollateral, borrower, 'tokens', -seizeTokens] ])); }); }); describe('liquidateBorrow', () => { it("emits a liquidation failure if borrowed asset interest accrual fails", async () => { - await send(cToken.interestRateModel, 'setFailBorrowRate', [true]); - await expect(liquidate(cToken, liquidator, borrower, repayAmount, cTokenCollateral)).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); + await send(slToken.interestRateModel, 'setFailBorrowRate', [true]); + await expect(liquidate(slToken, liquidator, borrower, repayAmount, slTokenCollateral)).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); }); it("emits a liquidation failure if collateral asset interest accrual fails", async () => { - await send(cTokenCollateral.interestRateModel, 'setFailBorrowRate', [true]); - await expect(liquidate(cToken, liquidator, borrower, repayAmount, cTokenCollateral)).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); + await send(slTokenCollateral.interestRateModel, 'setFailBorrowRate', [true]); + await expect(liquidate(slToken, liquidator, borrower, repayAmount, slTokenCollateral)).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); }); it("returns error from liquidateBorrowFresh without emitting any extra logs", async () => { - expect(await liquidate(cToken, liquidator, borrower, 0, cTokenCollateral)).toHaveTokenFailure('INVALID_CLOSE_AMOUNT_REQUESTED', 'LIQUIDATE_CLOSE_AMOUNT_IS_ZERO'); + expect(await liquidate(slToken, liquidator, borrower, 0, slTokenCollateral)).toHaveTokenFailure('INVALID_CLOSE_AMOUNT_REQUESTED', 'LIQUIDATE_CLOSE_AMOUNT_IS_ZERO'); }); it("returns success from liquidateBorrowFresh and transfers the correct amounts", async () => { - const beforeBalances = await getBalances([cToken, cTokenCollateral], [liquidator, borrower]); - const result = await liquidate(cToken, liquidator, borrower, repayAmount, cTokenCollateral); + const beforeBalances = await getBalances([slToken, slTokenCollateral], [liquidator, borrower]); + const result = await liquidate(slToken, liquidator, borrower, repayAmount, slTokenCollateral); const gasCost = await etherGasCost(result); - const afterBalances = await getBalances([cToken, cTokenCollateral], [liquidator, borrower]); + const afterBalances = await getBalances([slToken, slTokenCollateral], [liquidator, borrower]); expect(result).toSucceed(); expect(afterBalances).toEqual(await adjustBalances(beforeBalances, [ - [cToken, 'cash', repayAmount], - [cToken, 'borrows', -repayAmount], - [cToken, liquidator, 'eth', -gasCost], - [cToken, liquidator, 'cash', -repayAmount], - [cTokenCollateral, liquidator, 'eth', -gasCost], - [cTokenCollateral, liquidator, 'tokens', seizeTokens], - [cToken, borrower, 'borrows', -repayAmount], - [cTokenCollateral, borrower, 'tokens', -seizeTokens] + [slToken, 'cash', repayAmount], + [slToken, 'borrows', -repayAmount], + [slToken, liquidator, 'eth', -gasCost], + [slToken, liquidator, 'cash', -repayAmount], + [slTokenCollateral, liquidator, 'eth', -gasCost], + [slTokenCollateral, liquidator, 'tokens', seizeTokens], + [slToken, borrower, 'borrows', -repayAmount], + [slTokenCollateral, borrower, 'tokens', -seizeTokens] ])); }); }); @@ -208,24 +208,24 @@ describe('CToken', function () { // XXX verify callers are properly checked it("fails if seize is not allowed", async () => { - await send(cToken.comptroller, 'setSeizeAllowed', [false]); - expect(await seize(cTokenCollateral, liquidator, borrower, seizeTokens)).toHaveTrollReject('LIQUIDATE_SEIZE_COMPTROLLER_REJECTION', 'MATH_ERROR'); + await send(slToken.comptroller, 'setSeizeAllowed', [false]); + expect(await seize(slTokenCollateral, liquidator, borrower, seizeTokens)).toHaveTrollReject('LIQUIDATE_SEIZE_COMPTROLLER_REJECTION', 'MATH_ERROR'); }); - it("fails if cTokenBalances[borrower] < amount", async () => { - await setBalance(cTokenCollateral, borrower, 1); - expect(await seize(cTokenCollateral, liquidator, borrower, seizeTokens)).toHaveTokenMathFailure('LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED', 'INTEGER_UNDERFLOW'); + it("fails if slTokenBalances[borrower] < amount", async () => { + await setBalance(slTokenCollateral, borrower, 1); + expect(await seize(slTokenCollateral, liquidator, borrower, seizeTokens)).toHaveTokenMathFailure('LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED', 'INTEGER_UNDERFLOW'); }); - it("fails if cTokenBalances[liquidator] overflows", async () => { - await setBalance(cTokenCollateral, liquidator, -1); - expect(await seize(cTokenCollateral, liquidator, borrower, seizeTokens)).toHaveTokenMathFailure('LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED', 'INTEGER_OVERFLOW'); + it("fails if slTokenBalances[liquidator] overflows", async () => { + await setBalance(slTokenCollateral, liquidator, -1); + expect(await seize(slTokenCollateral, liquidator, borrower, seizeTokens)).toHaveTokenMathFailure('LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED', 'INTEGER_OVERFLOW'); }); it("succeeds, updates balances, and emits Transfer event", async () => { - const beforeBalances = await getBalances([cTokenCollateral], [liquidator, borrower]); - const result = await seize(cTokenCollateral, liquidator, borrower, seizeTokens); - const afterBalances = await getBalances([cTokenCollateral], [liquidator, borrower]); + const beforeBalances = await getBalances([slTokenCollateral], [liquidator, borrower]); + const result = await seize(slTokenCollateral, liquidator, borrower, seizeTokens); + const afterBalances = await getBalances([slTokenCollateral], [liquidator, borrower]); expect(result).toSucceed(); expect(result).toHaveLog('Transfer', { from: borrower, @@ -233,8 +233,8 @@ describe('CToken', function () { amount: seizeTokens.toString() }); expect(afterBalances).toEqual(await adjustBalances(beforeBalances, [ - [cTokenCollateral, liquidator, 'tokens', seizeTokens], - [cTokenCollateral, borrower, 'tokens', -seizeTokens] + [slTokenCollateral, liquidator, 'tokens', seizeTokens], + [slTokenCollateral, borrower, 'tokens', -seizeTokens] ])); }); }); diff --git a/tests/Tokens/mintAndRedeemCEtherTest.js b/tests/Tokens/mintAndRedeemCEtherTest.js index baf5b3401..cd68dea72 100644 --- a/tests/Tokens/mintAndRedeemCEtherTest.js +++ b/tests/Tokens/mintAndRedeemCEtherTest.js @@ -6,14 +6,14 @@ const { } = require('../Utils/Ethereum'); const { - makeCToken, + makeSLToken, balanceOf, fastForward, setBalance, setEtherBalance, getBalances, adjustBalances, -} = require('../Utils/Compound'); +} = require('../Utils/SashimiLending'); const exchangeRate = 5; const mintAmount = etherUnsigned(1e5); @@ -21,103 +21,103 @@ const mintTokens = mintAmount.div(exchangeRate); const redeemTokens = etherUnsigned(10e3); const redeemAmount = redeemTokens.mul(exchangeRate); -async function preMint(cToken, minter, mintAmount, mintTokens, exchangeRate) { - await send(cToken.comptroller, 'setMintAllowed', [true]); - await send(cToken.comptroller, 'setMintVerify', [true]); - await send(cToken.interestRateModel, 'setFailBorrowRate', [false]); - await send(cToken, 'harnessSetExchangeRate', [etherMantissa(exchangeRate)]); +async function preMint(slToken, minter, mintAmount, mintTokens, exchangeRate) { + await send(slToken.comptroller, 'setMintAllowed', [true]); + await send(slToken.comptroller, 'setMintVerify', [true]); + await send(slToken.interestRateModel, 'setFailBorrowRate', [false]); + await send(slToken, 'harnessSetExchangeRate', [etherMantissa(exchangeRate)]); } -async function mintExplicit(cToken, minter, mintAmount) { - return send(cToken, 'mint', [], {from: minter, value: mintAmount}); +async function mintExplicit(slToken, minter, mintAmount) { + return send(slToken, 'mint', [], {from: minter, value: mintAmount}); } -async function mintFallback(cToken, minter, mintAmount) { - return sendFallback(cToken, {from: minter, value: mintAmount}); +async function mintFallback(slToken, minter, mintAmount) { + return sendFallback(slToken, {from: minter, value: mintAmount}); } -async function preRedeem(cToken, redeemer, redeemTokens, redeemAmount, exchangeRate) { - await send(cToken.comptroller, 'setRedeemAllowed', [true]); - await send(cToken.comptroller, 'setRedeemVerify', [true]); - await send(cToken.interestRateModel, 'setFailBorrowRate', [false]); - await send(cToken, 'harnessSetExchangeRate', [etherMantissa(exchangeRate)]); - await setEtherBalance(cToken, redeemAmount); - await send(cToken, 'harnessSetTotalSupply', [redeemTokens]); - await setBalance(cToken, redeemer, redeemTokens); +async function preRedeem(slToken, redeemer, redeemTokens, redeemAmount, exchangeRate) { + await send(slToken.comptroller, 'setRedeemAllowed', [true]); + await send(slToken.comptroller, 'setRedeemVerify', [true]); + await send(slToken.interestRateModel, 'setFailBorrowRate', [false]); + await send(slToken, 'harnessSetExchangeRate', [etherMantissa(exchangeRate)]); + await setEtherBalance(slToken, redeemAmount); + await send(slToken, 'harnessSetTotalSupply', [redeemTokens]); + await setBalance(slToken, redeemer, redeemTokens); } -async function redeemCTokens(cToken, redeemer, redeemTokens, redeemAmount) { - return send(cToken, 'redeem', [redeemTokens], {from: redeemer}); +async function redeemSLTokens(slToken, redeemer, redeemTokens, redeemAmount) { + return send(slToken, 'redeem', [redeemTokens], {from: redeemer}); } -async function redeemUnderlying(cToken, redeemer, redeemTokens, redeemAmount) { - return send(cToken, 'redeemUnderlying', [redeemAmount], {from: redeemer}); +async function redeemUnderlying(slToken, redeemer, redeemTokens, redeemAmount) { + return send(slToken, 'redeemUnderlying', [redeemAmount], {from: redeemer}); } -describe('CEther', () => { +describe('SLEther', () => { let root, minter, redeemer, accounts; - let cToken; + let slToken; beforeEach(async () => { [root, minter, redeemer, ...accounts] = saddle.accounts; - cToken = await makeCToken({kind: 'cether', comptrollerOpts: {kind: 'bool'}}); - await fastForward(cToken, 1); + slToken = await makeSLToken({kind: 'slether', comptrollerOpts: {kind: 'bool'}}); + await fastForward(slToken, 1); }); [mintExplicit, mintFallback].forEach((mint) => { describe(mint.name, () => { beforeEach(async () => { - await preMint(cToken, minter, mintAmount, mintTokens, exchangeRate); + await preMint(slToken, minter, mintAmount, mintTokens, exchangeRate); }); it("reverts if interest accrual fails", async () => { - await send(cToken.interestRateModel, 'setFailBorrowRate', [true]); - await expect(mint(cToken, minter, mintAmount)).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); + await send(slToken.interestRateModel, 'setFailBorrowRate', [true]); + await expect(mint(slToken, minter, mintAmount)).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); }); it("returns success from mintFresh and mints the correct number of tokens", async () => { - const beforeBalances = await getBalances([cToken], [minter]); - const receipt = await mint(cToken, minter, mintAmount); - const afterBalances = await getBalances([cToken], [minter]); + const beforeBalances = await getBalances([slToken], [minter]); + const receipt = await mint(slToken, minter, mintAmount); + const afterBalances = await getBalances([slToken], [minter]); expect(receipt).toSucceed(); expect(mintTokens).not.toEqualNumber(0); expect(afterBalances).toEqual(await adjustBalances(beforeBalances, [ - [cToken, 'eth', mintAmount], - [cToken, 'tokens', mintTokens], - [cToken, minter, 'eth', -mintAmount.add(await etherGasCost(receipt))], - [cToken, minter, 'tokens', mintTokens] + [slToken, 'eth', mintAmount], + [slToken, 'tokens', mintTokens], + [slToken, minter, 'eth', -mintAmount.add(await etherGasCost(receipt))], + [slToken, minter, 'tokens', mintTokens] ])); }); }); }); - [redeemCTokens, redeemUnderlying].forEach((redeem) => { + [redeemSLTokens, redeemUnderlying].forEach((redeem) => { describe(redeem.name, () => { beforeEach(async () => { - await preRedeem(cToken, redeemer, redeemTokens, redeemAmount, exchangeRate); + await preRedeem(slToken, redeemer, redeemTokens, redeemAmount, exchangeRate); }); it("emits a redeem failure if interest accrual fails", async () => { - await send(cToken.interestRateModel, 'setFailBorrowRate', [true]); - await expect(redeem(cToken, redeemer, redeemTokens, redeemAmount)).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); + await send(slToken.interestRateModel, 'setFailBorrowRate', [true]); + await expect(redeem(slToken, redeemer, redeemTokens, redeemAmount)).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); }); it("returns error from redeemFresh without emitting any extra logs", async () => { - expect(await redeem(cToken, redeemer, redeemTokens.mul(5), redeemAmount.mul(5))).toHaveTokenFailure('MATH_ERROR', 'REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED'); + expect(await redeem(slToken, redeemer, redeemTokens.mul(5), redeemAmount.mul(5))).toHaveTokenFailure('MATH_ERROR', 'REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED'); }); it("returns success from redeemFresh and redeems the correct amount", async () => { - await fastForward(cToken); - const beforeBalances = await getBalances([cToken], [redeemer]); - const receipt = await redeem(cToken, redeemer, redeemTokens, redeemAmount); + await fastForward(slToken); + const beforeBalances = await getBalances([slToken], [redeemer]); + const receipt = await redeem(slToken, redeemer, redeemTokens, redeemAmount); expect(receipt).toTokenSucceed(); - const afterBalances = await getBalances([cToken], [redeemer]); + const afterBalances = await getBalances([slToken], [redeemer]); expect(redeemTokens).not.toEqualNumber(0); expect(afterBalances).toEqual(await adjustBalances(beforeBalances, [ - [cToken, 'eth', -redeemAmount], - [cToken, 'tokens', -redeemTokens], - [cToken, redeemer, 'eth', redeemAmount.sub(await etherGasCost(receipt))], - [cToken, redeemer, 'tokens', -redeemTokens] + [slToken, 'eth', -redeemAmount], + [slToken, 'tokens', -redeemTokens], + [slToken, redeemer, 'eth', redeemAmount.sub(await etherGasCost(receipt))], + [slToken, redeemer, 'tokens', -redeemTokens] ])); }); }); diff --git a/tests/Tokens/mintAndRedeemTest.js b/tests/Tokens/mintAndRedeemTest.js index a1ef70e25..268d58177 100644 --- a/tests/Tokens/mintAndRedeemTest.js +++ b/tests/Tokens/mintAndRedeemTest.js @@ -4,7 +4,7 @@ const { } = require('../Utils/Ethereum'); const { - makeCToken, + makeSLToken, balanceOf, fastForward, setBalance, @@ -15,7 +15,7 @@ const { preSupply, quickRedeem, quickRedeemUnderlying -} = require('../Utils/Compound'); +} = require('../Utils/SashimiLending'); const exchangeRate = 50e3; const mintAmount = etherUnsigned(10e4); @@ -23,101 +23,101 @@ const mintTokens = mintAmount.div(exchangeRate); const redeemTokens = etherUnsigned(10e3); const redeemAmount = redeemTokens.mul(exchangeRate); -async function preMint(cToken, minter, mintAmount, mintTokens, exchangeRate) { - await preApprove(cToken, minter, mintAmount); - await send(cToken.comptroller, 'setMintAllowed', [true]); - await send(cToken.comptroller, 'setMintVerify', [true]); - await send(cToken.interestRateModel, 'setFailBorrowRate', [false]); - await send(cToken.underlying, 'harnessSetFailTransferFromAddress', [minter, false]); - await send(cToken, 'harnessSetBalance', [minter, 0]); - await send(cToken, 'harnessSetExchangeRate', [etherMantissa(exchangeRate)]); +async function preMint(slToken, minter, mintAmount, mintTokens, exchangeRate) { + await preApprove(slToken, minter, mintAmount); + await send(slToken.comptroller, 'setMintAllowed', [true]); + await send(slToken.comptroller, 'setMintVerify', [true]); + await send(slToken.interestRateModel, 'setFailBorrowRate', [false]); + await send(slToken.underlying, 'harnessSetFailTransferFromAddress', [minter, false]); + await send(slToken, 'harnessSetBalance', [minter, 0]); + await send(slToken, 'harnessSetExchangeRate', [etherMantissa(exchangeRate)]); } -async function mintFresh(cToken, minter, mintAmount) { - return send(cToken, 'harnessMintFresh', [minter, mintAmount]); +async function mintFresh(slToken, minter, mintAmount) { + return send(slToken, 'harnessMintFresh', [minter, mintAmount]); } -async function preRedeem(cToken, redeemer, redeemTokens, redeemAmount, exchangeRate) { - await preSupply(cToken, redeemer, redeemTokens); - await send(cToken.comptroller, 'setRedeemAllowed', [true]); - await send(cToken.comptroller, 'setRedeemVerify', [true]); - await send(cToken.interestRateModel, 'setFailBorrowRate', [false]); - await send(cToken.underlying, 'harnessSetBalance', [cToken._address, redeemAmount]); - await send(cToken.underlying, 'harnessSetBalance', [redeemer, 0]); - await send(cToken.underlying, 'harnessSetFailTransferToAddress', [redeemer, false]); - await send(cToken, 'harnessSetExchangeRate', [etherMantissa(exchangeRate)]); +async function preRedeem(slToken, redeemer, redeemTokens, redeemAmount, exchangeRate) { + await preSupply(slToken, redeemer, redeemTokens); + await send(slToken.comptroller, 'setRedeemAllowed', [true]); + await send(slToken.comptroller, 'setRedeemVerify', [true]); + await send(slToken.interestRateModel, 'setFailBorrowRate', [false]); + await send(slToken.underlying, 'harnessSetBalance', [slToken._address, redeemAmount]); + await send(slToken.underlying, 'harnessSetBalance', [redeemer, 0]); + await send(slToken.underlying, 'harnessSetFailTransferToAddress', [redeemer, false]); + await send(slToken, 'harnessSetExchangeRate', [etherMantissa(exchangeRate)]); } -async function redeemFreshTokens(cToken, redeemer, redeemTokens, redeemAmount) { - return send(cToken, 'harnessRedeemFresh', [redeemer, redeemTokens, 0]); +async function redeemFreshTokens(slToken, redeemer, redeemTokens, redeemAmount) { + return send(slToken, 'harnessRedeemFresh', [redeemer, redeemTokens, 0]); } -async function redeemFreshAmount(cToken, redeemer, redeemTokens, redeemAmount) { - return send(cToken, 'harnessRedeemFresh', [redeemer, 0, redeemAmount]); +async function redeemFreshAmount(slToken, redeemer, redeemTokens, redeemAmount) { + return send(slToken, 'harnessRedeemFresh', [redeemer, 0, redeemAmount]); } -describe('CToken', function () { +describe('SLToken', function () { let root, minter, redeemer, accounts; - let cToken; + let slToken; beforeEach(async () => { [root, minter, redeemer, ...accounts] = saddle.accounts; - cToken = await makeCToken({comptrollerOpts: {kind: 'bool'}, exchangeRate}); + slToken = await makeSLToken({comptrollerOpts: {kind: 'bool'}, exchangeRate}); }); describe('mintFresh', () => { beforeEach(async () => { - await preMint(cToken, minter, mintAmount, mintTokens, exchangeRate); + await preMint(slToken, minter, mintAmount, mintTokens, exchangeRate); }); it("fails if comptroller tells it to", async () => { - await send(cToken.comptroller, 'setMintAllowed', [false]); - expect(await mintFresh(cToken, minter, mintAmount)).toHaveTrollReject('MINT_COMPTROLLER_REJECTION', 'MATH_ERROR'); + await send(slToken.comptroller, 'setMintAllowed', [false]); + expect(await mintFresh(slToken, minter, mintAmount)).toHaveTrollReject('MINT_COMPTROLLER_REJECTION', 'MATH_ERROR'); }); it("proceeds if comptroller tells it to", async () => { - await expect(await mintFresh(cToken, minter, mintAmount)).toSucceed(); + await expect(await mintFresh(slToken, minter, mintAmount)).toSucceed(); }); it("fails if not fresh", async () => { - await fastForward(cToken); - expect(await mintFresh(cToken, minter, mintAmount)).toHaveTokenFailure('MARKET_NOT_FRESH', 'MINT_FRESHNESS_CHECK'); + await fastForward(slToken); + expect(await mintFresh(slToken, minter, mintAmount)).toHaveTokenFailure('MARKET_NOT_FRESH', 'MINT_FRESHNESS_CHECK'); }); it("continues if fresh", async () => { - await expect(await send(cToken, 'accrueInterest')).toSucceed(); - expect(await mintFresh(cToken, minter, mintAmount)).toSucceed(); + await expect(await send(slToken, 'accrueInterest')).toSucceed(); + expect(await mintFresh(slToken, minter, mintAmount)).toSucceed(); }); it("fails if insufficient approval", async () => { expect( - await send(cToken.underlying, 'approve', [cToken._address, 1], {from: minter}) + await send(slToken.underlying, 'approve', [slToken._address, 1], {from: minter}) ).toSucceed(); - await expect(mintFresh(cToken, minter, mintAmount)).rejects.toRevert('revert Insufficient allowance'); + await expect(mintFresh(slToken, minter, mintAmount)).rejects.toRevert('revert Insufficient allowance'); }); it("fails if insufficient balance", async() => { - await setBalance(cToken.underlying, minter, 1); - await expect(mintFresh(cToken, minter, mintAmount)).rejects.toRevert('revert Insufficient balance'); + await setBalance(slToken.underlying, minter, 1); + await expect(mintFresh(slToken, minter, mintAmount)).rejects.toRevert('revert Insufficient balance'); }); it("proceeds if sufficient approval and balance", async () =>{ - expect(await mintFresh(cToken, minter, mintAmount)).toSucceed(); + expect(await mintFresh(slToken, minter, mintAmount)).toSucceed(); }); it("fails if exchange calculation fails", async () => { - expect(await send(cToken, 'harnessSetExchangeRate', [0])).toSucceed(); - await expect(mintFresh(cToken, minter, mintAmount)).rejects.toRevert('revert MINT_EXCHANGE_CALCULATION_FAILED'); + expect(await send(slToken, 'harnessSetExchangeRate', [0])).toSucceed(); + await expect(mintFresh(slToken, minter, mintAmount)).rejects.toRevert('revert MINT_EXCHANGE_CALCULATION_FAILED'); }); it("fails if transferring in fails", async () => { - await send(cToken.underlying, 'harnessSetFailTransferFromAddress', [minter, true]); - await expect(mintFresh(cToken, minter, mintAmount)).rejects.toRevert('revert TOKEN_TRANSFER_IN_FAILED'); + await send(slToken.underlying, 'harnessSetFailTransferFromAddress', [minter, true]); + await expect(mintFresh(slToken, minter, mintAmount)).rejects.toRevert('revert TOKEN_TRANSFER_IN_FAILED'); }); it("transfers the underlying cash, tokens, and emits Mint, Transfer events", async () => { - const beforeBalances = await getBalances([cToken], [minter]); - const result = await mintFresh(cToken, minter, mintAmount); - const afterBalances = await getBalances([cToken], [minter]); + const beforeBalances = await getBalances([slToken], [minter]); + const result = await mintFresh(slToken, minter, mintAmount); + const afterBalances = await getBalances([slToken], [minter]); expect(result).toSucceed(); expect(result).toHaveLog('Mint', { minter, @@ -125,42 +125,42 @@ describe('CToken', function () { mintTokens: mintTokens.toString() }); expect(result).toHaveLog(['Transfer', 1], { - from: cToken._address, + from: slToken._address, to: minter, amount: mintTokens.toString() }); expect(afterBalances).toEqual(await adjustBalances(beforeBalances, [ - [cToken, minter, 'cash', -mintAmount], - [cToken, minter, 'tokens', mintTokens], - [cToken, 'cash', mintAmount], - [cToken, 'tokens', mintTokens] + [slToken, minter, 'cash', -mintAmount], + [slToken, minter, 'tokens', mintTokens], + [slToken, 'cash', mintAmount], + [slToken, 'tokens', mintTokens] ])); }); }); describe('mint', () => { beforeEach(async () => { - await preMint(cToken, minter, mintAmount, mintTokens, exchangeRate); + await preMint(slToken, minter, mintAmount, mintTokens, exchangeRate); }); it("emits a mint failure if interest accrual fails", async () => { - await send(cToken.interestRateModel, 'setFailBorrowRate', [true]); - await expect(quickMint(cToken, minter, mintAmount)).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); + await send(slToken.interestRateModel, 'setFailBorrowRate', [true]); + await expect(quickMint(slToken, minter, mintAmount)).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); }); it("returns error from mintFresh without emitting any extra logs", async () => { - await send(cToken.underlying, 'harnessSetBalance', [minter, 1]); - await expect(mintFresh(cToken, minter, mintAmount)).rejects.toRevert('revert Insufficient balance'); + await send(slToken.underlying, 'harnessSetBalance', [minter, 1]); + await expect(mintFresh(slToken, minter, mintAmount)).rejects.toRevert('revert Insufficient balance'); }); it("returns success from mintFresh and mints the correct number of tokens", async () => { - expect(await quickMint(cToken, minter, mintAmount)).toSucceed(); + expect(await quickMint(slToken, minter, mintAmount)).toSucceed(); expect(mintTokens).not.toEqualNumber(0); - expect(await balanceOf(cToken, minter)).toEqualNumber(mintTokens); + expect(await balanceOf(slToken, minter)).toEqualNumber(mintTokens); }); it("emits an AccrueInterest event", async () => { - expect(await quickMint(cToken, minter, mintAmount)).toHaveLog('AccrueInterest', { + expect(await quickMint(slToken, minter, mintAmount)).toHaveLog('AccrueInterest', { borrowIndex: "1000000000000000000", cashPrior: "0", interestAccumulated: "0", @@ -172,58 +172,58 @@ describe('CToken', function () { [redeemFreshTokens, redeemFreshAmount].forEach((redeemFresh) => { describe(redeemFresh.name, () => { beforeEach(async () => { - await preRedeem(cToken, redeemer, redeemTokens, redeemAmount, exchangeRate); + await preRedeem(slToken, redeemer, redeemTokens, redeemAmount, exchangeRate); }); it("fails if comptroller tells it to", async () =>{ - await send(cToken.comptroller, 'setRedeemAllowed', [false]); - expect(await redeemFresh(cToken, redeemer, redeemTokens, redeemAmount)).toHaveTrollReject('REDEEM_COMPTROLLER_REJECTION'); + await send(slToken.comptroller, 'setRedeemAllowed', [false]); + expect(await redeemFresh(slToken, redeemer, redeemTokens, redeemAmount)).toHaveTrollReject('REDEEM_COMPTROLLER_REJECTION'); }); it("fails if not fresh", async () => { - await fastForward(cToken); - expect(await redeemFresh(cToken, redeemer, redeemTokens, redeemAmount)).toHaveTokenFailure('MARKET_NOT_FRESH', 'REDEEM_FRESHNESS_CHECK'); + await fastForward(slToken); + expect(await redeemFresh(slToken, redeemer, redeemTokens, redeemAmount)).toHaveTokenFailure('MARKET_NOT_FRESH', 'REDEEM_FRESHNESS_CHECK'); }); it("continues if fresh", async () => { - await expect(await send(cToken, 'accrueInterest')).toSucceed(); - expect(await redeemFresh(cToken, redeemer, redeemTokens, redeemAmount)).toSucceed(); + await expect(await send(slToken, 'accrueInterest')).toSucceed(); + expect(await redeemFresh(slToken, redeemer, redeemTokens, redeemAmount)).toSucceed(); }); it("fails if insufficient protocol cash to transfer out", async() => { - await send(cToken.underlying, 'harnessSetBalance', [cToken._address, 1]); - expect(await redeemFresh(cToken, redeemer, redeemTokens, redeemAmount)).toHaveTokenFailure('TOKEN_INSUFFICIENT_CASH', 'REDEEM_TRANSFER_OUT_NOT_POSSIBLE'); + await send(slToken.underlying, 'harnessSetBalance', [slToken._address, 1]); + expect(await redeemFresh(slToken, redeemer, redeemTokens, redeemAmount)).toHaveTokenFailure('TOKEN_INSUFFICIENT_CASH', 'REDEEM_TRANSFER_OUT_NOT_POSSIBLE'); }); it("fails if exchange calculation fails", async () => { if (redeemFresh == redeemFreshTokens) { - expect(await send(cToken, 'harnessSetExchangeRate', [-1])).toSucceed(); - expect(await redeemFresh(cToken, redeemer, redeemTokens, redeemAmount)).toHaveTokenFailure('MATH_ERROR', 'REDEEM_EXCHANGE_TOKENS_CALCULATION_FAILED'); + expect(await send(slToken, 'harnessSetExchangeRate', [-1])).toSucceed(); + expect(await redeemFresh(slToken, redeemer, redeemTokens, redeemAmount)).toHaveTokenFailure('MATH_ERROR', 'REDEEM_EXCHANGE_TOKENS_CALCULATION_FAILED'); } else { - expect(await send(cToken, 'harnessSetExchangeRate', [0])).toSucceed(); - expect(await redeemFresh(cToken, redeemer, redeemTokens, redeemAmount)).toHaveTokenFailure('MATH_ERROR', 'REDEEM_EXCHANGE_AMOUNT_CALCULATION_FAILED'); + expect(await send(slToken, 'harnessSetExchangeRate', [0])).toSucceed(); + expect(await redeemFresh(slToken, redeemer, redeemTokens, redeemAmount)).toHaveTokenFailure('MATH_ERROR', 'REDEEM_EXCHANGE_AMOUNT_CALCULATION_FAILED'); } }); it("fails if transferring out fails", async () => { - await send(cToken.underlying, 'harnessSetFailTransferToAddress', [redeemer, true]); - await expect(redeemFresh(cToken, redeemer, redeemTokens, redeemAmount)).rejects.toRevert("revert TOKEN_TRANSFER_OUT_FAILED"); + await send(slToken.underlying, 'harnessSetFailTransferToAddress', [redeemer, true]); + await expect(redeemFresh(slToken, redeemer, redeemTokens, redeemAmount)).rejects.toRevert("revert TOKEN_TRANSFER_OUT_FAILED"); }); it("fails if total supply < redemption amount", async () => { - await send(cToken, 'harnessExchangeRateDetails', [0, 0, 0]); - expect(await redeemFresh(cToken, redeemer, redeemTokens, redeemAmount)).toHaveTokenFailure('MATH_ERROR', 'REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED'); + await send(slToken, 'harnessExchangeRateDetails', [0, 0, 0]); + expect(await redeemFresh(slToken, redeemer, redeemTokens, redeemAmount)).toHaveTokenFailure('MATH_ERROR', 'REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED'); }); it("reverts if new account balance underflows", async () => { - await send(cToken, 'harnessSetBalance', [redeemer, 0]); - expect(await redeemFresh(cToken, redeemer, redeemTokens, redeemAmount)).toHaveTokenFailure('MATH_ERROR', 'REDEEM_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED'); + await send(slToken, 'harnessSetBalance', [redeemer, 0]); + expect(await redeemFresh(slToken, redeemer, redeemTokens, redeemAmount)).toHaveTokenFailure('MATH_ERROR', 'REDEEM_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED'); }); it("transfers the underlying cash, tokens, and emits Redeem, Transfer events", async () => { - const beforeBalances = await getBalances([cToken], [redeemer]); - const result = await redeemFresh(cToken, redeemer, redeemTokens, redeemAmount); - const afterBalances = await getBalances([cToken], [redeemer]); + const beforeBalances = await getBalances([slToken], [redeemer]); + const result = await redeemFresh(slToken, redeemer, redeemTokens, redeemAmount); + const afterBalances = await getBalances([slToken], [redeemer]); expect(result).toSucceed(); expect(result).toHaveLog('Redeem', { redeemer, @@ -232,14 +232,14 @@ describe('CToken', function () { }); expect(result).toHaveLog(['Transfer', 1], { from: redeemer, - to: cToken._address, + to: slToken._address, amount: redeemTokens.toString() }); expect(afterBalances).toEqual(await adjustBalances(beforeBalances, [ - [cToken, redeemer, 'cash', redeemAmount], - [cToken, redeemer, 'tokens', -redeemTokens], - [cToken, 'cash', -redeemAmount], - [cToken, 'tokens', -redeemTokens] + [slToken, redeemer, 'cash', redeemAmount], + [slToken, redeemer, 'tokens', -redeemTokens], + [slToken, 'cash', -redeemAmount], + [slToken, 'tokens', -redeemTokens] ])); }); }); @@ -247,41 +247,41 @@ describe('CToken', function () { describe('redeem', () => { beforeEach(async () => { - await preRedeem(cToken, redeemer, redeemTokens, redeemAmount, exchangeRate); + await preRedeem(slToken, redeemer, redeemTokens, redeemAmount, exchangeRate); }); it("emits a redeem failure if interest accrual fails", async () => { - await send(cToken.interestRateModel, 'setFailBorrowRate', [true]); - await expect(quickRedeem(cToken, redeemer, redeemTokens)).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); + await send(slToken.interestRateModel, 'setFailBorrowRate', [true]); + await expect(quickRedeem(slToken, redeemer, redeemTokens)).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); }); it("returns error from redeemFresh without emitting any extra logs", async () => { - await setBalance(cToken.underlying, cToken._address, 0); - expect(await quickRedeem(cToken, redeemer, redeemTokens, {exchangeRate})).toHaveTokenFailure('TOKEN_INSUFFICIENT_CASH', 'REDEEM_TRANSFER_OUT_NOT_POSSIBLE'); + await setBalance(slToken.underlying, slToken._address, 0); + expect(await quickRedeem(slToken, redeemer, redeemTokens, {exchangeRate})).toHaveTokenFailure('TOKEN_INSUFFICIENT_CASH', 'REDEEM_TRANSFER_OUT_NOT_POSSIBLE'); }); it("returns success from redeemFresh and redeems the right amount", async () => { expect( - await send(cToken.underlying, 'harnessSetBalance', [cToken._address, redeemAmount]) + await send(slToken.underlying, 'harnessSetBalance', [slToken._address, redeemAmount]) ).toSucceed(); - expect(await quickRedeem(cToken, redeemer, redeemTokens, {exchangeRate})).toSucceed(); + expect(await quickRedeem(slToken, redeemer, redeemTokens, {exchangeRate})).toSucceed(); expect(redeemAmount).not.toEqualNumber(0); - expect(await balanceOf(cToken.underlying, redeemer)).toEqualNumber(redeemAmount); + expect(await balanceOf(slToken.underlying, redeemer)).toEqualNumber(redeemAmount); }); it("returns success from redeemFresh and redeems the right amount of underlying", async () => { expect( - await send(cToken.underlying, 'harnessSetBalance', [cToken._address, redeemAmount]) + await send(slToken.underlying, 'harnessSetBalance', [slToken._address, redeemAmount]) ).toSucceed(); expect( - await quickRedeemUnderlying(cToken, redeemer, redeemAmount, {exchangeRate}) + await quickRedeemUnderlying(slToken, redeemer, redeemAmount, {exchangeRate}) ).toSucceed(); expect(redeemAmount).not.toEqualNumber(0); - expect(await balanceOf(cToken.underlying, redeemer)).toEqualNumber(redeemAmount); + expect(await balanceOf(slToken.underlying, redeemer)).toEqualNumber(redeemAmount); }); it("emits an AccrueInterest event", async () => { - expect(await quickMint(cToken, minter, mintAmount)).toHaveLog('AccrueInterest', { + expect(await quickMint(slToken, minter, mintAmount)).toHaveLog('AccrueInterest', { borrowIndex: "1000000000000000000", cashPrior: "500000000", interestAccumulated: "0", diff --git a/tests/Tokens/reservesTest.js b/tests/Tokens/reservesTest.js index 8effe1e4a..f8fc0b806 100644 --- a/tests/Tokens/reservesTest.js +++ b/tests/Tokens/reservesTest.js @@ -4,7 +4,7 @@ const { both } = require('../Utils/Ethereum'); -const {fastForward, makeCToken} = require('../Utils/Compound'); +const {fastForward, makeSLToken} = require('../Utils/SashimiLending'); const factor = etherMantissa(.02); @@ -12,40 +12,40 @@ const reserves = etherUnsigned(3e12); const cash = etherUnsigned(reserves.mul(2)); const reduction = etherUnsigned(2e12); -describe('CToken', function () { +describe('SLToken', function () { let root, accounts; beforeEach(async () => { [root, ...accounts] = saddle.accounts; }); describe('_setReserveFactorFresh', () => { - let cToken; + let slToken; beforeEach(async () => { - cToken = await makeCToken(); + slToken = await makeSLToken(); }); it("rejects change by non-admin", async () => { expect( - await send(cToken, 'harnessSetReserveFactorFresh', [factor], {from: accounts[0]}) + await send(slToken, 'harnessSetReserveFactorFresh', [factor], {from: accounts[0]}) ).toHaveTokenFailure('UNAUTHORIZED', 'SET_RESERVE_FACTOR_ADMIN_CHECK'); - expect(await call(cToken, 'reserveFactorMantissa')).toEqualNumber(0); + expect(await call(slToken, 'reserveFactorMantissa')).toEqualNumber(0); }); it("rejects change if market not fresh", async () => { - expect(await send(cToken, 'harnessFastForward', [5])).toSucceed(); - expect(await send(cToken, 'harnessSetReserveFactorFresh', [factor])).toHaveTokenFailure('MARKET_NOT_FRESH', 'SET_RESERVE_FACTOR_FRESH_CHECK'); - expect(await call(cToken, 'reserveFactorMantissa')).toEqualNumber(0); + expect(await send(slToken, 'harnessFastForward', [5])).toSucceed(); + expect(await send(slToken, 'harnessSetReserveFactorFresh', [factor])).toHaveTokenFailure('MARKET_NOT_FRESH', 'SET_RESERVE_FACTOR_FRESH_CHECK'); + expect(await call(slToken, 'reserveFactorMantissa')).toEqualNumber(0); }); it("rejects newReserveFactor that descales to 1", async () => { - expect(await send(cToken, 'harnessSetReserveFactorFresh', [etherMantissa(1.01)])).toHaveTokenFailure('BAD_INPUT', 'SET_RESERVE_FACTOR_BOUNDS_CHECK'); - expect(await call(cToken, 'reserveFactorMantissa')).toEqualNumber(0); + expect(await send(slToken, 'harnessSetReserveFactorFresh', [etherMantissa(1.01)])).toHaveTokenFailure('BAD_INPUT', 'SET_RESERVE_FACTOR_BOUNDS_CHECK'); + expect(await call(slToken, 'reserveFactorMantissa')).toEqualNumber(0); }); it("accepts newReserveFactor in valid range and emits log", async () => { - const result = await send(cToken, 'harnessSetReserveFactorFresh', [factor]) + const result = await send(slToken, 'harnessSetReserveFactorFresh', [factor]) expect(result).toSucceed(); - expect(await call(cToken, 'reserveFactorMantissa')).toEqualNumber(factor); + expect(await call(slToken, 'reserveFactorMantissa')).toEqualNumber(factor); expect(result).toHaveLog("NewReserveFactor", { oldReserveFactorMantissa: '0', newReserveFactorMantissa: factor.toString(), @@ -53,95 +53,95 @@ describe('CToken', function () { }); it("accepts a change back to zero", async () => { - const result1 = await send(cToken, 'harnessSetReserveFactorFresh', [factor]); - const result2 = await send(cToken, 'harnessSetReserveFactorFresh', [0]); + const result1 = await send(slToken, 'harnessSetReserveFactorFresh', [factor]); + const result2 = await send(slToken, 'harnessSetReserveFactorFresh', [0]); expect(result1).toSucceed(); expect(result2).toSucceed(); expect(result2).toHaveLog("NewReserveFactor", { oldReserveFactorMantissa: factor.toString(), newReserveFactorMantissa: '0', }); - expect(await call(cToken, 'reserveFactorMantissa')).toEqualNumber(0); + expect(await call(slToken, 'reserveFactorMantissa')).toEqualNumber(0); }); }); describe('_setReserveFactor', () => { - let cToken; + let slToken; beforeEach(async () => { - cToken = await makeCToken(); + slToken = await makeSLToken(); }); beforeEach(async () => { - await send(cToken.interestRateModel, 'setFailBorrowRate', [false]); - await send(cToken, '_setReserveFactor', [0]); + await send(slToken.interestRateModel, 'setFailBorrowRate', [false]); + await send(slToken, '_setReserveFactor', [0]); }); it("emits a reserve factor failure if interest accrual fails", async () => { - await send(cToken.interestRateModel, 'setFailBorrowRate', [true]); - await fastForward(cToken, 1); - await expect(send(cToken, '_setReserveFactor', [factor])).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); - expect(await call(cToken, 'reserveFactorMantissa')).toEqualNumber(0); + await send(slToken.interestRateModel, 'setFailBorrowRate', [true]); + await fastForward(slToken, 1); + await expect(send(slToken, '_setReserveFactor', [factor])).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); + expect(await call(slToken, 'reserveFactorMantissa')).toEqualNumber(0); }); it("returns error from setReserveFactorFresh without emitting any extra logs", async () => { - const {reply, receipt} = await both(cToken, '_setReserveFactor', [etherMantissa(2)]); + const {reply, receipt} = await both(slToken, '_setReserveFactor', [etherMantissa(2)]); expect(reply).toHaveTokenError('BAD_INPUT'); expect(receipt).toHaveTokenFailure('BAD_INPUT', 'SET_RESERVE_FACTOR_BOUNDS_CHECK'); - expect(await call(cToken, 'reserveFactorMantissa')).toEqualNumber(0); + expect(await call(slToken, 'reserveFactorMantissa')).toEqualNumber(0); }); it("returns success from setReserveFactorFresh", async () => { - expect(await call(cToken, 'reserveFactorMantissa')).toEqualNumber(0); - expect(await send(cToken, 'harnessFastForward', [5])).toSucceed(); - expect(await send(cToken, '_setReserveFactor', [factor])).toSucceed(); - expect(await call(cToken, 'reserveFactorMantissa')).toEqualNumber(factor); + expect(await call(slToken, 'reserveFactorMantissa')).toEqualNumber(0); + expect(await send(slToken, 'harnessFastForward', [5])).toSucceed(); + expect(await send(slToken, '_setReserveFactor', [factor])).toSucceed(); + expect(await call(slToken, 'reserveFactorMantissa')).toEqualNumber(factor); }); }); describe("_reduceReservesFresh", () => { - let cToken; + let slToken; beforeEach(async () => { - cToken = await makeCToken(); - expect(await send(cToken, 'harnessSetTotalReserves', [reserves])).toSucceed(); + slToken = await makeSLToken(); + expect(await send(slToken, 'harnessSetTotalReserves', [reserves])).toSucceed(); expect( - await send(cToken.underlying, 'harnessSetBalance', [cToken._address, cash]) + await send(slToken.underlying, 'harnessSetBalance', [slToken._address, cash]) ).toSucceed(); }); it("fails if called by non-admin", async () => { expect( - await send(cToken, 'harnessReduceReservesFresh', [reduction], {from: accounts[0]}) + await send(slToken, 'harnessReduceReservesFresh', [reduction], {from: accounts[0]}) ).toHaveTokenFailure('UNAUTHORIZED', 'REDUCE_RESERVES_ADMIN_CHECK'); - expect(await call(cToken, 'totalReserves')).toEqualNumber(reserves); + expect(await call(slToken, 'totalReserves')).toEqualNumber(reserves); }); it("fails if market not fresh", async () => { - expect(await send(cToken, 'harnessFastForward', [5])).toSucceed(); - expect(await send(cToken, 'harnessReduceReservesFresh', [reduction])).toHaveTokenFailure('MARKET_NOT_FRESH', 'REDUCE_RESERVES_FRESH_CHECK'); - expect(await call(cToken, 'totalReserves')).toEqualNumber(reserves); + expect(await send(slToken, 'harnessFastForward', [5])).toSucceed(); + expect(await send(slToken, 'harnessReduceReservesFresh', [reduction])).toHaveTokenFailure('MARKET_NOT_FRESH', 'REDUCE_RESERVES_FRESH_CHECK'); + expect(await call(slToken, 'totalReserves')).toEqualNumber(reserves); }); it("fails if amount exceeds reserves", async () => { - expect(await send(cToken, 'harnessReduceReservesFresh', [reserves.add(1)])).toHaveTokenFailure('BAD_INPUT', 'REDUCE_RESERVES_VALIDATION'); - expect(await call(cToken, 'totalReserves')).toEqualNumber(reserves); + expect(await send(slToken, 'harnessReduceReservesFresh', [reserves.add(1)])).toHaveTokenFailure('BAD_INPUT', 'REDUCE_RESERVES_VALIDATION'); + expect(await call(slToken, 'totalReserves')).toEqualNumber(reserves); }); it("fails if amount exceeds available cash", async () => { const cashLessThanReserves = reserves.sub(2); - await send(cToken.underlying, 'harnessSetBalance', [cToken._address, cashLessThanReserves]); - expect(await send(cToken, 'harnessReduceReservesFresh', [reserves])).toHaveTokenFailure('TOKEN_INSUFFICIENT_CASH', 'REDUCE_RESERVES_CASH_NOT_AVAILABLE'); - expect(await call(cToken, 'totalReserves')).toEqualNumber(reserves); + await send(slToken.underlying, 'harnessSetBalance', [slToken._address, cashLessThanReserves]); + expect(await send(slToken, 'harnessReduceReservesFresh', [reserves])).toHaveTokenFailure('TOKEN_INSUFFICIENT_CASH', 'REDUCE_RESERVES_CASH_NOT_AVAILABLE'); + expect(await call(slToken, 'totalReserves')).toEqualNumber(reserves); }); it("increases admin balance and reduces reserves on success", async () => { - const balance = etherUnsigned(await call(cToken.underlying, 'balanceOf', [root])); - expect(await send(cToken, 'harnessReduceReservesFresh', [reserves])).toSucceed(); - expect(await call(cToken.underlying, 'balanceOf', [root])).toEqualNumber(balance.add(reserves)); - expect(await call(cToken, 'totalReserves')).toEqualNumber(0); + const balance = etherUnsigned(await call(slToken.underlying, 'balanceOf', [root])); + expect(await send(slToken, 'harnessReduceReservesFresh', [reserves])).toSucceed(); + expect(await call(slToken.underlying, 'balanceOf', [root])).toEqualNumber(balance.add(reserves)); + expect(await call(slToken, 'totalReserves')).toEqualNumber(0); }); it("emits an event on success", async () => { - const result = await send(cToken, 'harnessReduceReservesFresh', [reserves]); + const result = await send(slToken, 'harnessReduceReservesFresh', [reserves]); expect(result).toHaveLog('ReservesReduced', { admin: root, reduceAmount: reserves.toString(), @@ -151,32 +151,32 @@ describe('CToken', function () { }); describe("_reduceReserves", () => { - let cToken; + let slToken; beforeEach(async () => { - cToken = await makeCToken(); - await send(cToken.interestRateModel, 'setFailBorrowRate', [false]); - expect(await send(cToken, 'harnessSetTotalReserves', [reserves])).toSucceed(); + slToken = await makeSLToken(); + await send(slToken.interestRateModel, 'setFailBorrowRate', [false]); + expect(await send(slToken, 'harnessSetTotalReserves', [reserves])).toSucceed(); expect( - await send(cToken.underlying, 'harnessSetBalance', [cToken._address, cash]) + await send(slToken.underlying, 'harnessSetBalance', [slToken._address, cash]) ).toSucceed(); }); it("emits a reserve-reduction failure if interest accrual fails", async () => { - await send(cToken.interestRateModel, 'setFailBorrowRate', [true]); - await fastForward(cToken, 1); - await expect(send(cToken, '_reduceReserves', [reduction])).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); + await send(slToken.interestRateModel, 'setFailBorrowRate', [true]); + await fastForward(slToken, 1); + await expect(send(slToken, '_reduceReserves', [reduction])).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); }); it("returns error from _reduceReservesFresh without emitting any extra logs", async () => { - const {reply, receipt} = await both(cToken, 'harnessReduceReservesFresh', [reserves.add(1)]); + const {reply, receipt} = await both(slToken, 'harnessReduceReservesFresh', [reserves.add(1)]); expect(reply).toHaveTokenError('BAD_INPUT'); expect(receipt).toHaveTokenFailure('BAD_INPUT', 'REDUCE_RESERVES_VALIDATION'); }); it("returns success code from _reduceReservesFresh and reduces the correct amount", async () => { - expect(await call(cToken, 'totalReserves')).toEqualNumber(reserves); - expect(await send(cToken, 'harnessFastForward', [5])).toSucceed(); - expect(await send(cToken, '_reduceReserves', [reduction])).toSucceed(); + expect(await call(slToken, 'totalReserves')).toEqualNumber(reserves); + expect(await send(slToken, 'harnessFastForward', [5])).toSucceed(); + expect(await send(slToken, '_reduceReserves', [reduction])).toSucceed(); }); }); }); diff --git a/tests/Tokens/safeTokenTest.js b/tests/Tokens/safeTokenTest.js index b38d3904e..35f99a190 100644 --- a/tests/Tokens/safeTokenTest.js +++ b/tests/Tokens/safeTokenTest.js @@ -1,51 +1,51 @@ const { - makeCToken, + makeSLToken, getBalances, adjustBalances -} = require('../Utils/Compound'); +} = require('../Utils/SashimiLending'); const exchangeRate = 5; -describe('CEther', function () { +describe('SLEther', function () { let root, nonRoot, accounts; - let cToken; + let slToken; beforeEach(async () => { [root, nonRoot, ...accounts] = saddle.accounts; - cToken = await makeCToken({kind: 'cether', comptrollerOpts: {kind: 'bool'}}); + slToken = await makeSLToken({kind: 'slether', comptrollerOpts: {kind: 'bool'}}); }); describe("getCashPrior", () => { - it("returns the amount of ether held by the cEther contract before the current message", async () => { - expect(await call(cToken, 'harnessGetCashPrior', [], {value: 100})).toEqualNumber(0); + it("returns the amount of ether held by the slEther contract before the current message", async () => { + expect(await call(slToken, 'harnessGetCashPrior', [], {value: 100})).toEqualNumber(0); }); }); describe("doTransferIn", () => { it("succeeds if from is msg.nonRoot and amount is msg.value", async () => { - expect(await call(cToken, 'harnessDoTransferIn', [root, 100], {value: 100})).toEqualNumber(100); + expect(await call(slToken, 'harnessDoTransferIn', [root, 100], {value: 100})).toEqualNumber(100); }); it("reverts if from != msg.sender", async () => { - await expect(call(cToken, 'harnessDoTransferIn', [nonRoot, 100], {value: 100})).rejects.toRevert("revert sender mismatch"); + await expect(call(slToken, 'harnessDoTransferIn', [nonRoot, 100], {value: 100})).rejects.toRevert("revert sender mismatch"); }); it("reverts if amount != msg.value", async () => { - await expect(call(cToken, 'harnessDoTransferIn', [root, 77], {value: 100})).rejects.toRevert("revert value mismatch"); + await expect(call(slToken, 'harnessDoTransferIn', [root, 77], {value: 100})).rejects.toRevert("revert value mismatch"); }); describe("doTransferOut", () => { it("transfers ether out", async () => { - const beforeBalances = await getBalances([cToken], [nonRoot]); - const receipt = await send(cToken, 'harnessDoTransferOut', [nonRoot, 77], {value: 77}); - const afterBalances = await getBalances([cToken], [nonRoot]); + const beforeBalances = await getBalances([slToken], [nonRoot]); + const receipt = await send(slToken, 'harnessDoTransferOut', [nonRoot, 77], {value: 77}); + const afterBalances = await getBalances([slToken], [nonRoot]); expect(receipt).toSucceed(); expect(afterBalances).toEqual(await adjustBalances(beforeBalances, [ - [cToken, nonRoot, 'eth', 77] + [slToken, nonRoot, 'eth', 77] ])); }); it("reverts if it fails", async () => { - await expect(call(cToken, 'harnessDoTransferOut', [root, 77], {value: 0})).rejects.toRevert(); + await expect(call(slToken, 'harnessDoTransferOut', [root, 77], {value: 0})).rejects.toRevert(); }); }); }); diff --git a/tests/Tokens/setComptrollerTest.js b/tests/Tokens/setComptrollerTest.js index 1df2839b0..34b0148dc 100644 --- a/tests/Tokens/setComptrollerTest.js +++ b/tests/Tokens/setComptrollerTest.js @@ -1,15 +1,15 @@ const { makeComptroller, - makeCToken -} = require('../Utils/Compound'); + makeSLToken +} = require('../Utils/SashimiLending'); -describe('CToken', function () { +describe('SLToken', function () { let root, accounts; - let cToken, oldComptroller, newComptroller; + let slToken, oldComptroller, newComptroller; beforeEach(async () => { [root, ...accounts] = saddle.accounts; - cToken = await makeCToken(); - oldComptroller = cToken.comptroller; + slToken = await makeSLToken(); + oldComptroller = slToken.comptroller; newComptroller = await makeComptroller(); expect(newComptroller._address).not.toEqual(oldComptroller._address); }); @@ -17,31 +17,31 @@ describe('CToken', function () { describe('_setComptroller', () => { it("should fail if called by non-admin", async () => { expect( - await send(cToken, '_setComptroller', [newComptroller._address], { from: accounts[0] }) + await send(slToken, '_setComptroller', [newComptroller._address], { from: accounts[0] }) ).toHaveTokenFailure('UNAUTHORIZED', 'SET_COMPTROLLER_OWNER_CHECK'); - expect(await call(cToken, 'comptroller')).toEqual(oldComptroller._address); + expect(await call(slToken, 'comptroller')).toEqual(oldComptroller._address); }); it("reverts if passed a contract that doesn't implement isComptroller", async () => { - await expect(send(cToken, '_setComptroller', [cToken.underlying._address])).rejects.toRevert("revert"); - expect(await call(cToken, 'comptroller')).toEqual(oldComptroller._address); + await expect(send(slToken, '_setComptroller', [slToken.underlying._address])).rejects.toRevert("revert"); + expect(await call(slToken, 'comptroller')).toEqual(oldComptroller._address); }); it("reverts if passed a contract that implements isComptroller as false", async () => { // extremely unlikely to occur, of course, but let's be exhaustive const badComptroller = await makeComptroller({ kind: 'false-marker' }); - await expect(send(cToken, '_setComptroller', [badComptroller._address])).rejects.toRevert("revert marker method returned false"); - expect(await call(cToken, 'comptroller')).toEqual(oldComptroller._address); + await expect(send(slToken, '_setComptroller', [badComptroller._address])).rejects.toRevert("revert marker method returned false"); + expect(await call(slToken, 'comptroller')).toEqual(oldComptroller._address); }); it("updates comptroller and emits log on success", async () => { - const result = await send(cToken, '_setComptroller', [newComptroller._address]); + const result = await send(slToken, '_setComptroller', [newComptroller._address]); expect(result).toSucceed(); expect(result).toHaveLog('NewComptroller', { oldComptroller: oldComptroller._address, newComptroller: newComptroller._address }); - expect(await call(cToken, 'comptroller')).toEqual(newComptroller._address); + expect(await call(slToken, 'comptroller')).toEqual(newComptroller._address); }); }); }); diff --git a/tests/Tokens/setInterestRateModelTest.js b/tests/Tokens/setInterestRateModelTest.js index f48b0e3ce..8ec790be3 100644 --- a/tests/Tokens/setInterestRateModelTest.js +++ b/tests/Tokens/setInterestRateModelTest.js @@ -1,11 +1,11 @@ const {both} = require('../Utils/Ethereum'); const { fastForward, - makeCToken, + makeSLToken, makeInterestRateModel -} = require('../Utils/Compound'); +} = require('../Utils/SashimiLending'); -describe('CToken', function () { +describe('SLToken', function () { let root, accounts; let newModel; beforeEach(async () => { @@ -14,87 +14,87 @@ describe('CToken', function () { }); describe("_setInterestRateModelFresh", () => { - let cToken, oldModel; + let slToken, oldModel; beforeEach(async () => { - cToken = await makeCToken(); - oldModel = cToken.interestRateModel; + slToken = await makeSLToken(); + oldModel = slToken.interestRateModel; expect(oldModel._address).not.toEqual(newModel._address); }); it("fails if called by non-admin", async () => { expect( - await send(cToken, 'harnessSetInterestRateModelFresh', [newModel._address], {from: accounts[0]}) + await send(slToken, 'harnessSetInterestRateModelFresh', [newModel._address], {from: accounts[0]}) ).toHaveTokenFailure('UNAUTHORIZED', 'SET_INTEREST_RATE_MODEL_OWNER_CHECK'); - expect(await call(cToken, 'interestRateModel')).toEqual(oldModel._address); + expect(await call(slToken, 'interestRateModel')).toEqual(oldModel._address); }); it("fails if market not fresh", async () => { - expect(await send(cToken, 'harnessFastForward', [5])).toSucceed(); + expect(await send(slToken, 'harnessFastForward', [5])).toSucceed(); expect( - await send(cToken, 'harnessSetInterestRateModelFresh', [newModel._address]) + await send(slToken, 'harnessSetInterestRateModelFresh', [newModel._address]) ).toHaveTokenFailure('MARKET_NOT_FRESH', 'SET_INTEREST_RATE_MODEL_FRESH_CHECK'); - expect(await call(cToken, 'interestRateModel')).toEqual(oldModel._address); + expect(await call(slToken, 'interestRateModel')).toEqual(oldModel._address); }); it("reverts if passed a contract that doesn't implement isInterestRateModel", async () => { await expect( - send(cToken, 'harnessSetInterestRateModelFresh', [cToken.underlying._address]) + send(slToken, 'harnessSetInterestRateModelFresh', [slToken.underlying._address]) ).rejects.toRevert(); - expect(await call(cToken, 'interestRateModel')).toEqual(oldModel._address); + expect(await call(slToken, 'interestRateModel')).toEqual(oldModel._address); }); it("reverts if passed a contract that implements isInterestRateModel as false", async () => { // extremely unlikely to occur, of course, but let's be exhaustive const badModel = await makeInterestRateModel({kind: 'false-marker'}); - await expect(send(cToken, 'harnessSetInterestRateModelFresh', [badModel._address])).rejects.toRevert("revert marker method returned false"); - expect(await call(cToken, 'interestRateModel')).toEqual(oldModel._address); + await expect(send(slToken, 'harnessSetInterestRateModelFresh', [badModel._address])).rejects.toRevert("revert marker method returned false"); + expect(await call(slToken, 'interestRateModel')).toEqual(oldModel._address); }); it("accepts new valid interest rate model", async () => { expect( - await send(cToken, 'harnessSetInterestRateModelFresh', [newModel._address]) + await send(slToken, 'harnessSetInterestRateModelFresh', [newModel._address]) ).toSucceed(); - expect(await call(cToken, 'interestRateModel')).toEqual(newModel._address); + expect(await call(slToken, 'interestRateModel')).toEqual(newModel._address); }); it("emits expected log when accepting a new valid interest rate model", async () => { - const result = await send(cToken, 'harnessSetInterestRateModelFresh', [newModel._address]); + const result = await send(slToken, 'harnessSetInterestRateModelFresh', [newModel._address]); expect(result).toSucceed(); expect(result).toHaveLog('NewMarketInterestRateModel', { oldInterestRateModel: oldModel._address, newInterestRateModel: newModel._address, }); - expect(await call(cToken, 'interestRateModel')).toEqual(newModel._address); + expect(await call(slToken, 'interestRateModel')).toEqual(newModel._address); }); }); describe("_setInterestRateModel", () => { - let cToken; + let slToken; beforeEach(async () => { - cToken = await makeCToken(); + slToken = await makeSLToken(); }); beforeEach(async () => { - await send(cToken.interestRateModel, 'setFailBorrowRate', [false]); + await send(slToken.interestRateModel, 'setFailBorrowRate', [false]); }); it("emits a set market interest rate model failure if interest accrual fails", async () => { - await send(cToken.interestRateModel, 'setFailBorrowRate', [true]); - await fastForward(cToken, 1); - await expect(send(cToken, '_setInterestRateModel', [newModel._address])).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); + await send(slToken.interestRateModel, 'setFailBorrowRate', [true]); + await fastForward(slToken, 1); + await expect(send(slToken, '_setInterestRateModel', [newModel._address])).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); }); it("returns error from _setInterestRateModelFresh without emitting any extra logs", async () => { - const {reply, receipt} = await both(cToken, '_setInterestRateModel', [newModel._address], {from: accounts[0]}); + const {reply, receipt} = await both(slToken, '_setInterestRateModel', [newModel._address], {from: accounts[0]}); expect(reply).toHaveTokenError('UNAUTHORIZED'); expect(receipt).toHaveTokenFailure('UNAUTHORIZED', 'SET_INTEREST_RATE_MODEL_OWNER_CHECK'); }); it("reports success when _setInterestRateModelFresh succeeds", async () => { - const {reply, receipt} = await both(cToken, '_setInterestRateModel', [newModel._address]); + const {reply, receipt} = await both(slToken, '_setInterestRateModel', [newModel._address]); expect(reply).toEqualNumber(0); expect(receipt).toSucceed(); - expect(await call(cToken, 'interestRateModel')).toEqual(newModel._address); + expect(await call(slToken, 'interestRateModel')).toEqual(newModel._address); }); }); }); diff --git a/tests/Tokens/slTokenTest.js b/tests/Tokens/slTokenTest.js new file mode 100644 index 000000000..dedeeae9d --- /dev/null +++ b/tests/Tokens/slTokenTest.js @@ -0,0 +1,227 @@ +const { + etherUnsigned, + etherMantissa +} = require('../Utils/Ethereum'); + +const { + makeSLToken, + setBorrowRate, + pretendBorrow +} = require('../Utils/SashimiLending'); + +describe('SLToken', function () { + let root, admin, accounts; + beforeEach(async () => { + [root, admin, ...accounts] = saddle.accounts; + }); + + describe('constructor', () => { + it("fails when non erc-20 underlying", async () => { + await expect(makeSLToken({ underlying: { _address: root } })).rejects.toRevert("revert"); + }); + + it("fails when 0 initial exchange rate", async () => { + await expect(makeSLToken({ exchangeRate: 0 })).rejects.toRevert("revert initial exchange rate must be greater than zero."); + }); + + it("succeeds with erc-20 underlying and non-zero exchange rate", async () => { + const slToken = await makeSLToken(); + expect(await call(slToken, 'underlying')).toEqual(slToken.underlying._address); + expect(await call(slToken, 'admin')).toEqual(root); + }); + + it("succeeds when setting admin to contructor argument", async () => { + const slToken = await makeSLToken({ admin: admin }); + expect(await call(slToken, 'admin')).toEqual(admin); + }); + }); + + describe('name, symbol, decimals', () => { + let slToken; + + beforeEach(async () => { + slToken = await makeSLToken({ name: "SLToken Foo", symbol: "slFOO", decimals: 10 }); + }); + + it('should return correct name', async () => { + expect(await call(slToken, 'name')).toEqual("SLToken Foo"); + }); + + it('should return correct symbol', async () => { + expect(await call(slToken, 'symbol')).toEqual("slFOO"); + }); + + it('should return correct decimals', async () => { + expect(await call(slToken, 'decimals')).toEqualNumber(10); + }); + }); + + describe('balanceOfUnderlying', () => { + it("has an underlying balance", async () => { + const slToken = await makeSLToken({ supportMarket: true, exchangeRate: 2 }); + await send(slToken, 'harnessSetBalance', [root, 100]); + expect(await call(slToken, 'balanceOfUnderlying', [root])).toEqualNumber(200); + }); + }); + + describe('borrowRatePerBlock', () => { + it("has a borrow rate", async () => { + const slToken = await makeSLToken({ supportMarket: true, interestRateModelOpts: { kind: 'jump-rate', baseRate: .05, multiplier: 0.45, kink: 0.95, jump: 5 } }); + const perBlock = await call(slToken, 'borrowRatePerBlock'); + expect(Math.abs(perBlock * 2102400 - 5e16)).toBeLessThanOrEqual(1e8); + }); + }); + + describe('supplyRatePerBlock', () => { + it("returns 0 if there's no supply", async () => { + const slToken = await makeSLToken({ supportMarket: true, interestRateModelOpts: { kind: 'jump-rate', baseRate: .05, multiplier: 0.45, kink: 0.95, jump: 5 } }); + const perBlock = await call(slToken, 'supplyRatePerBlock'); + await expect(perBlock).toEqualNumber(0); + }); + + it("has a supply rate", async () => { + const baseRate = 0.05; + const multiplier = 0.45; + const kink = 0.95; + const jump = 5 * multiplier; + const slToken = await makeSLToken({ supportMarket: true, interestRateModelOpts: { kind: 'jump-rate', baseRate, multiplier, kink, jump } }); + await send(slToken, 'harnessSetReserveFactorFresh', [etherMantissa(.01)]); + await send(slToken, 'harnessExchangeRateDetails', [1, 1, 0]); + await send(slToken, 'harnessSetExchangeRate', [etherMantissa(1)]); + // Full utilization (Over the kink so jump is included), 1% reserves + const borrowRate = baseRate + multiplier * kink + jump * .05; + const expectedSuplyRate = borrowRate * .99; + + const perBlock = await call(slToken, 'supplyRatePerBlock'); + expect(Math.abs(perBlock * 2102400 - expectedSuplyRate * 1e18)).toBeLessThanOrEqual(1e8); + }); + }); + + describe("borrowBalanceCurrent", () => { + let borrower; + let slToken; + + beforeEach(async () => { + borrower = accounts[0]; + slToken = await makeSLToken(); + }); + + beforeEach(async () => { + await setBorrowRate(slToken, .001) + await send(slToken.interestRateModel, 'setFailBorrowRate', [false]); + }); + + it("reverts if interest accrual fails", async () => { + await send(slToken.interestRateModel, 'setFailBorrowRate', [true]); + // make sure we accrue interest + await send(slToken, 'harnessFastForward', [1]); + await expect(send(slToken, 'borrowBalanceCurrent', [borrower])).rejects.toRevert("revert INTEREST_RATE_MODEL_ERROR"); + }); + + it("returns successful result from borrowBalanceStored with no interest", async () => { + await setBorrowRate(slToken, 0); + await pretendBorrow(slToken, borrower, 1, 1, 5e18); + expect(await call(slToken, 'borrowBalanceCurrent', [borrower])).toEqualNumber(5e18) + }); + + it("returns successful result from borrowBalanceCurrent with no interest", async () => { + await setBorrowRate(slToken, 0); + await pretendBorrow(slToken, borrower, 1, 3, 5e18); + expect(await send(slToken, 'harnessFastForward', [5])).toSucceed(); + expect(await call(slToken, 'borrowBalanceCurrent', [borrower])).toEqualNumber(5e18 * 3) + }); + }); + + describe("borrowBalanceStored", () => { + let borrower; + let slToken; + + beforeEach(async () => { + borrower = accounts[0]; + slToken = await makeSLToken({ comptrollerOpts: { kind: 'bool' } }); + }); + + it("returns 0 for account with no borrows", async () => { + expect(await call(slToken, 'borrowBalanceStored', [borrower])).toEqualNumber(0) + }); + + it("returns stored principal when account and market indexes are the same", async () => { + await pretendBorrow(slToken, borrower, 1, 1, 5e18); + expect(await call(slToken, 'borrowBalanceStored', [borrower])).toEqualNumber(5e18); + }); + + it("returns calculated balance when market index is higher than account index", async () => { + await pretendBorrow(slToken, borrower, 1, 3, 5e18); + expect(await call(slToken, 'borrowBalanceStored', [borrower])).toEqualNumber(5e18 * 3); + }); + + it("has undefined behavior when market index is lower than account index", async () => { + // The market index < account index should NEVER happen, so we don't test this case + }); + + it("reverts on overflow of principal", async () => { + await pretendBorrow(slToken, borrower, 1, 3, -1); + await expect(call(slToken, 'borrowBalanceStored', [borrower])).rejects.toRevert("revert borrowBalanceStored: borrowBalanceStoredInternal failed"); + }); + + it("reverts on non-zero stored principal with zero account index", async () => { + await pretendBorrow(slToken, borrower, 0, 3, 5); + await expect(call(slToken, 'borrowBalanceStored', [borrower])).rejects.toRevert("revert borrowBalanceStored: borrowBalanceStoredInternal failed"); + }); + }); + + describe('exchangeRateStored', () => { + let slToken, exchangeRate = 2; + + beforeEach(async () => { + slToken = await makeSLToken({ exchangeRate }); + }); + + it("returns initial exchange rate with zero cTokenSupply", async () => { + const result = await call(slToken, 'exchangeRateStored'); + expect(result).toEqualNumber(etherMantissa(exchangeRate)); + }); + + it("calculates with single cTokenSupply and single total borrow", async () => { + const cTokenSupply = 1, totalBorrows = 1, totalReserves = 0; + await send(slToken, 'harnessExchangeRateDetails', [cTokenSupply, totalBorrows, totalReserves]); + const result = await call(slToken, 'exchangeRateStored'); + expect(result).toEqualNumber(etherMantissa(1)); + }); + + it("calculates with cTokenSupply and total borrows", async () => { + const cTokenSupply = 100e18, totalBorrows = 10e18, totalReserves = 0; + await send(slToken, 'harnessExchangeRateDetails', [cTokenSupply, totalBorrows, totalReserves].map(etherUnsigned)); + const result = await call(slToken, 'exchangeRateStored'); + expect(result).toEqualNumber(etherMantissa(.1)); + }); + + it("calculates with cash and cTokenSupply", async () => { + const cTokenSupply = 5e18, totalBorrows = 0, totalReserves = 0; + expect( + await send(slToken.underlying, 'transfer', [slToken._address, etherMantissa(500)]) + ).toSucceed(); + await send(slToken, 'harnessExchangeRateDetails', [cTokenSupply, totalBorrows, totalReserves].map(etherUnsigned)); + const result = await call(slToken, 'exchangeRateStored'); + expect(result).toEqualNumber(etherMantissa(100)); + }); + + it("calculates with cash, borrows, reserves and cTokenSupply", async () => { + const cTokenSupply = 500e18, totalBorrows = 500e18, totalReserves = 5e18; + expect( + await send(slToken.underlying, 'transfer', [slToken._address, etherMantissa(500)]) + ).toSucceed(); + await send(slToken, 'harnessExchangeRateDetails', [cTokenSupply, totalBorrows, totalReserves].map(etherUnsigned)); + const result = await call(slToken, 'exchangeRateStored'); + expect(result).toEqualNumber(etherMantissa(1.99)); + }); + }); + + describe('getCash', () => { + it("gets the cash", async () => { + const slToken = await makeSLToken(); + const result = await call(slToken, 'getCash'); + expect(result).toEqualNumber(0); + }); + }); +}); diff --git a/tests/Tokens/transferTest.js b/tests/Tokens/transferTest.js index f7d309cb8..444bec7eb 100644 --- a/tests/Tokens/transferTest.js +++ b/tests/Tokens/transferTest.js @@ -1,6 +1,6 @@ -const {makeCToken} = require('../Utils/Compound'); +const {makeSLToken} = require('../Utils/SashimiLending'); -describe('CToken', function () { +describe('SLToken', function () { let root, accounts; beforeEach(async () => { [root, ...accounts] = saddle.accounts; @@ -8,38 +8,38 @@ describe('CToken', function () { describe('transfer', () => { it("cannot transfer from a zero balance", async () => { - const cToken = await makeCToken({supportMarket: true}); - expect(await call(cToken, 'balanceOf', [root])).toEqualNumber(0); - expect(await send(cToken, 'transfer', [accounts[0], 100])).toHaveTokenFailure('MATH_ERROR', 'TRANSFER_NOT_ENOUGH'); + const slToken = await makeSLToken({supportMarket: true}); + expect(await call(slToken, 'balanceOf', [root])).toEqualNumber(0); + expect(await send(slToken, 'transfer', [accounts[0], 100])).toHaveTokenFailure('MATH_ERROR', 'TRANSFER_NOT_ENOUGH'); }); it("transfers 50 tokens", async () => { - const cToken = await makeCToken({supportMarket: true}); - await send(cToken, 'harnessSetBalance', [root, 100]); - expect(await call(cToken, 'balanceOf', [root])).toEqualNumber(100); - await send(cToken, 'transfer', [accounts[0], 50]); - expect(await call(cToken, 'balanceOf', [root])).toEqualNumber(50); - expect(await call(cToken, 'balanceOf', [accounts[0]])).toEqualNumber(50); + const slToken = await makeSLToken({supportMarket: true}); + await send(slToken, 'harnessSetBalance', [root, 100]); + expect(await call(slToken, 'balanceOf', [root])).toEqualNumber(100); + await send(slToken, 'transfer', [accounts[0], 50]); + expect(await call(slToken, 'balanceOf', [root])).toEqualNumber(50); + expect(await call(slToken, 'balanceOf', [accounts[0]])).toEqualNumber(50); }); it("doesn't transfer when src == dst", async () => { - const cToken = await makeCToken({supportMarket: true}); - await send(cToken, 'harnessSetBalance', [root, 100]); - expect(await call(cToken, 'balanceOf', [root])).toEqualNumber(100); - expect(await send(cToken, 'transfer', [root, 50])).toHaveTokenFailure('BAD_INPUT', 'TRANSFER_NOT_ALLOWED'); + const slToken = await makeSLToken({supportMarket: true}); + await send(slToken, 'harnessSetBalance', [root, 100]); + expect(await call(slToken, 'balanceOf', [root])).toEqualNumber(100); + expect(await send(slToken, 'transfer', [root, 50])).toHaveTokenFailure('BAD_INPUT', 'TRANSFER_NOT_ALLOWED'); }); it("rejects transfer when not allowed and reverts if not verified", async () => { - const cToken = await makeCToken({comptrollerOpts: {kind: 'bool'}}); - await send(cToken, 'harnessSetBalance', [root, 100]); - expect(await call(cToken, 'balanceOf', [root])).toEqualNumber(100); + const slToken = await makeSLToken({comptrollerOpts: {kind: 'bool'}}); + await send(slToken, 'harnessSetBalance', [root, 100]); + expect(await call(slToken, 'balanceOf', [root])).toEqualNumber(100); - await send(cToken.comptroller, 'setTransferAllowed', [false]) - expect(await send(cToken, 'transfer', [root, 50])).toHaveTrollReject('TRANSFER_COMPTROLLER_REJECTION'); + await send(slToken.comptroller, 'setTransferAllowed', [false]) + expect(await send(slToken, 'transfer', [root, 50])).toHaveTrollReject('TRANSFER_COMPTROLLER_REJECTION'); - await send(cToken.comptroller, 'setTransferAllowed', [true]) - await send(cToken.comptroller, 'setTransferVerify', [false]) - await expect(send(cToken, 'transfer', [accounts[0], 50])).rejects.toRevert("revert transferVerify rejected transfer"); + await send(slToken.comptroller, 'setTransferAllowed', [true]) + await send(slToken.comptroller, 'setTransferVerify', [false]) + await expect(send(slToken, 'transfer', [accounts[0], 50])).rejects.toRevert("revert transferVerify rejected transfer"); }); }); }); \ No newline at end of file diff --git a/tests/Utils/Compound.js b/tests/Utils/SashimiLending.js similarity index 58% rename from tests/Utils/Compound.js rename to tests/Utils/SashimiLending.js index 0eb8f8132..46c21e353 100644 --- a/tests/Utils/Compound.js +++ b/tests/Utils/SashimiLending.js @@ -62,12 +62,12 @@ async function makeComptroller(opts = {}) { const closeFactor = etherMantissa(dfn(opts.closeFactor, .051)); const maxAssets = etherUnsigned(dfn(opts.maxAssets, 10)); const liquidationIncentive = etherMantissa(1); - const compRate = etherUnsigned(dfn(opts.compRate, 1e18)); - const compMarkets = opts.compMarkets || []; + const sashimiRate = etherUnsigned(dfn(opts.sashimiRate, 1e18)); + const sashimiMarkets = opts.sashimiMarkets || []; const otherMarkets = opts.otherMarkets || []; await send(unitroller, '_setPendingImplementation', [comptroller._address]); - await send(comptroller, '_become', [unitroller._address, compRate, compMarkets, otherMarkets]); + await send(comptroller, '_become', [unitroller._address, sashimiRate, sashimiMarkets, otherMarkets]); mergeInterface(unitroller, comptroller); await send(unitroller, '_setLiquidationIncentive', [liquidationIncentive]); await send(unitroller, '_setCloseFactor', [closeFactor]); @@ -84,8 +84,8 @@ async function makeComptroller(opts = {}) { const closeFactor = etherMantissa(dfn(opts.closeFactor, .051)); const maxAssets = etherUnsigned(dfn(opts.maxAssets, 10)); const liquidationIncentive = etherMantissa(1); - const comp = opts.comp || await deploy('Comp', [opts.compOwner || root]); - const compRate = etherUnsigned(dfn(opts.compRate, 1e18)); + const sashimi = opts.sashimi || await deploy('SashimiToken'); + const sashimiRate = etherUnsigned(dfn(opts.sashimiRate, 1e18)); await send(unitroller, '_setPendingImplementation', [comptroller._address]); await send(comptroller, '_become', [unitroller._address]); @@ -94,33 +94,33 @@ async function makeComptroller(opts = {}) { await send(unitroller, '_setCloseFactor', [closeFactor]); await send(unitroller, '_setMaxAssets', [maxAssets]); await send(unitroller, '_setPriceOracle', [priceOracle._address]); - await send(unitroller, 'setCompAddress', [comp._address]); // harness only - await send(unitroller, '_setCompRate', [compRate]); + await send(unitroller, 'setSashimiAddress', [sashimi._address]); // harness only + await send(unitroller, '_setSashimiRate', [sashimiRate]); - return Object.assign(unitroller, { priceOracle, comp }); + return Object.assign(unitroller, { priceOracle, sashimi }); } } -async function makeCToken(opts = {}) { +async function makeSLToken(opts = {}) { const { root = saddle.account, - kind = 'cerc20' + kind = 'slerc20' } = opts || {}; const comptroller = opts.comptroller || await makeComptroller(opts.comptrollerOpts); const interestRateModel = opts.interestRateModel || await makeInterestRateModel(opts.interestRateModelOpts); const exchangeRate = etherMantissa(dfn(opts.exchangeRate, 1)); const decimals = etherUnsigned(dfn(opts.decimals, 8)); - const symbol = opts.symbol || (kind === 'cether' ? 'cETH' : 'cOMG'); - const name = opts.name || `CToken ${symbol}`; + const symbol = opts.symbol || (kind === 'slether' ? 'slETH' : 'slOMG'); + const name = opts.name || `SLToken ${symbol}`; const admin = opts.admin || root; - let cToken, underlying; - let cDelegator, cDelegatee, cDaiMaker; + let slToken, underlying; + let slDelegator, slDelegatee, slDaiMaker; switch (kind) { - case 'cether': - cToken = await deploy('CEtherHarness', + case 'slether': + slToken = await deploy('SLEtherHarness', [ comptroller._address, interestRateModel._address, @@ -132,11 +132,11 @@ async function makeCToken(opts = {}) { ]) break; - case 'cdai': - cDaiMaker = await deploy('CDaiDelegateMakerHarness'); - underlying = cDaiMaker; - cDelegatee = await deploy('CDaiDelegateHarness'); - cDelegator = await deploy('CErc20Delegator', + case 'sldai': + slDaiMaker = await deploy('SLDaiDelegateMakerHarness'); + underlying = slDaiMaker; + slDelegatee = await deploy('SLDaiDelegateHarness'); + slDelegator = await deploy('SLErc20Delegator', [ underlying._address, comptroller._address, @@ -146,18 +146,18 @@ async function makeCToken(opts = {}) { symbol, decimals, admin, - cDelegatee._address, - encodeParameters(['address', 'address'], [cDaiMaker._address, cDaiMaker._address]) + slDelegatee._address, + encodeParameters(['address', 'address'], [slDaiMaker._address, slDaiMaker._address]) ] ); - cToken = await saddle.getContractAt('CDaiDelegateHarness', cDelegator._address); // XXXS at + slToken = await saddle.getContractAt('SLDaiDelegateHarness', slDelegator._address); // XXXS at break; - case 'cerc20': + case 'slerc20': default: underlying = opts.underlying || await makeToken(opts.underlyingOpts); - cDelegatee = await deploy('CErc20DelegateHarness'); - cDelegator = await deploy('CErc20Delegator', + slDelegatee = await deploy('SLErc20DelegateHarness'); + slDelegator = await deploy('SLErc20Delegator', [ underlying._address, comptroller._address, @@ -167,33 +167,33 @@ async function makeCToken(opts = {}) { symbol, decimals, admin, - cDelegatee._address, + slDelegatee._address, "0x0" ] ); - cToken = await saddle.getContractAt('CErc20DelegateHarness', cDelegator._address); // XXXS at + slToken = await saddle.getContractAt('SLErc20DelegateHarness', slDelegator._address); // XXXS at break; } if (opts.supportMarket) { - await send(comptroller, '_supportMarket', [cToken._address]); + await send(comptroller, '_supportMarket', [slToken._address]); } if (opts.addCompMarket) { - await send(comptroller, '_addCompMarket', [cToken._address]); + await send(comptroller, '_addSashimiMarket', [slToken._address]); } if (opts.underlyingPrice) { const price = etherMantissa(opts.underlyingPrice); - await send(comptroller.priceOracle, 'setUnderlyingPrice', [cToken._address, price]); + await send(comptroller.priceOracle, 'setUnderlyingPrice', [slToken._address, price]); } if (opts.collateralFactor) { const factor = etherMantissa(opts.collateralFactor); - expect(await send(comptroller, '_setCollateralFactor', [cToken._address, factor])).toSucceed(); + expect(await send(comptroller, '_setCollateralFactor', [slToken._address, factor])).toSucceed(); } - return Object.assign(cToken, { name, symbol, underlying, comptroller, interestRateModel }); + return Object.assign(slToken, { name, symbol, underlying, comptroller, interestRateModel }); } async function makeInterestRateModel(opts = {}) { @@ -261,56 +261,56 @@ async function totalSupply(token) { return etherUnsigned(await call(token, 'totalSupply')); } -async function borrowSnapshot(cToken, account) { - const { principal, interestIndex } = await call(cToken, 'harnessAccountBorrows', [account]); +async function borrowSnapshot(slToken, account) { + const { principal, interestIndex } = await call(slToken, 'harnessAccountBorrows', [account]); return { principal: etherUnsigned(principal), interestIndex: etherUnsigned(interestIndex) }; } -async function totalBorrows(cToken) { - return etherUnsigned(await call(cToken, 'totalBorrows')); +async function totalBorrows(slToken) { + return etherUnsigned(await call(slToken, 'totalBorrows')); } -async function totalReserves(cToken) { - return etherUnsigned(await call(cToken, 'totalReserves')); +async function totalReserves(slToken) { + return etherUnsigned(await call(slToken, 'totalReserves')); } -async function enterMarkets(cTokens, from) { - return await send(cTokens[0].comptroller, 'enterMarkets', [cTokens.map(c => c._address)], { from }); +async function enterMarkets(slTokens, from) { + return await send(slTokens[0].comptroller, 'enterMarkets', [slTokens.map(sl => sl._address)], { from }); } -async function fastForward(cToken, blocks = 5) { - return await send(cToken, 'harnessFastForward', [blocks]); +async function fastForward(slToken, blocks = 5) { + return await send(slToken, 'harnessFastForward', [blocks]); } -async function setBalance(cToken, account, balance) { - return await send(cToken, 'harnessSetBalance', [account, balance]); +async function setBalance(slToken, account, balance) { + return await send(slToken, 'harnessSetBalance', [account, balance]); } -async function setEtherBalance(cEther, balance) { - const current = await etherBalance(cEther._address); +async function setEtherBalance(slEther, balance) { + const current = await etherBalance(slEther._address); const root = saddle.account; - expect(await send(cEther, 'harnessDoTransferOut', [root, current])).toSucceed(); - expect(await send(cEther, 'harnessDoTransferIn', [root, balance], { value: balance })).toSucceed(); + expect(await send(slEther, 'harnessDoTransferOut', [root, current])).toSucceed(); + expect(await send(slEther, 'harnessDoTransferIn', [root, balance], { value: balance })).toSucceed(); } -async function getBalances(cTokens, accounts) { +async function getBalances(slTokens, accounts) { const balances = {}; - for (let cToken of cTokens) { - const cBalances = balances[cToken._address] = {}; + for (let slToken of slTokens) { + const cBalances = balances[slToken._address] = {}; for (let account of accounts) { cBalances[account] = { eth: await etherBalance(account), - cash: cToken.underlying && await balanceOf(cToken.underlying, account), - tokens: await balanceOf(cToken, account), - borrows: (await borrowSnapshot(cToken, account)).principal + cash: slToken.underlying && await balanceOf(slToken.underlying, account), + tokens: await balanceOf(slToken, account), + borrows: (await borrowSnapshot(slToken, account)).principal }; } - cBalances[cToken._address] = { - eth: await etherBalance(cToken._address), - cash: cToken.underlying && await balanceOf(cToken.underlying, cToken._address), - tokens: await totalSupply(cToken), - borrows: await totalBorrows(cToken), - reserves: await totalReserves(cToken) + cBalances[slToken._address] = { + eth: await etherBalance(slToken._address), + cash: slToken.underlying && await balanceOf(slToken.underlying, slToken._address), + tokens: await totalSupply(slToken), + borrows: await totalBorrows(slToken), + reserves: await totalReserves(slToken) }; } return balances; @@ -318,75 +318,75 @@ async function getBalances(cTokens, accounts) { async function adjustBalances(balances, deltas) { for (let delta of deltas) { - let cToken, account, key, diff; + let slToken, account, key, diff; if (delta.length == 4) { - ([cToken, account, key, diff] = delta); + ([slToken, account, key, diff] = delta); } else { - ([cToken, key, diff] = delta); - account = cToken._address; + ([slToken, key, diff] = delta); + account = slToken._address; } - balances[cToken._address][account][key] = balances[cToken._address][account][key].add(diff); + balances[slToken._address][account][key] = balances[slToken._address][account][key].add(diff); } return balances; } -async function preApprove(cToken, from, amount, opts = {}) { +async function preApprove(slToken, from, amount, opts = {}) { if (dfn(opts.faucet, true)) { - expect(await send(cToken.underlying, 'harnessSetBalance', [from, amount], { from })).toSucceed(); + expect(await send(slToken.underlying, 'harnessSetBalance', [from, amount], { from })).toSucceed(); } - return send(cToken.underlying, 'approve', [cToken._address, amount], { from }); + return send(slToken.underlying, 'approve', [slToken._address, amount], { from }); } -async function quickMint(cToken, minter, mintAmount, opts = {}) { +async function quickMint(slToken, minter, mintAmount, opts = {}) { // make sure to accrue interest - await fastForward(cToken, 1); + await fastForward(slToken, 1); if (dfn(opts.approve, true)) { - expect(await preApprove(cToken, minter, mintAmount, opts)).toSucceed(); + expect(await preApprove(slToken, minter, mintAmount, opts)).toSucceed(); } if (dfn(opts.exchangeRate)) { - expect(await send(cToken, 'harnessSetExchangeRate', [etherMantissa(opts.exchangeRate)])).toSucceed(); + expect(await send(slToken, 'harnessSetExchangeRate', [etherMantissa(opts.exchangeRate)])).toSucceed(); } - return send(cToken, 'mint', [mintAmount], { from: minter }); + return send(slToken, 'mint', [mintAmount], { from: minter }); } -async function preSupply(cToken, account, tokens, opts = {}) { +async function preSupply(slToken, account, tokens, opts = {}) { if (dfn(opts.total, true)) { - expect(await send(cToken, 'harnessSetTotalSupply', [tokens])).toSucceed(); + expect(await send(slToken, 'harnessSetTotalSupply', [tokens])).toSucceed(); } - return send(cToken, 'harnessSetBalance', [account, tokens]); + return send(slToken, 'harnessSetBalance', [account, tokens]); } -async function quickRedeem(cToken, redeemer, redeemTokens, opts = {}) { - await fastForward(cToken, 1); +async function quickRedeem(slToken, redeemer, redeemTokens, opts = {}) { + await fastForward(slToken, 1); if (dfn(opts.supply, true)) { - expect(await preSupply(cToken, redeemer, redeemTokens, opts)).toSucceed(); + expect(await preSupply(slToken, redeemer, redeemTokens, opts)).toSucceed(); } if (dfn(opts.exchangeRate)) { - expect(await send(cToken, 'harnessSetExchangeRate', [etherMantissa(opts.exchangeRate)])).toSucceed(); + expect(await send(slToken, 'harnessSetExchangeRate', [etherMantissa(opts.exchangeRate)])).toSucceed(); } - return send(cToken, 'redeem', [redeemTokens], { from: redeemer }); + return send(slToken, 'redeem', [redeemTokens], { from: redeemer }); } -async function quickRedeemUnderlying(cToken, redeemer, redeemAmount, opts = {}) { - await fastForward(cToken, 1); +async function quickRedeemUnderlying(slToken, redeemer, redeemAmount, opts = {}) { + await fastForward(slToken, 1); if (dfn(opts.exchangeRate)) { - expect(await send(cToken, 'harnessSetExchangeRate', [etherMantissa(opts.exchangeRate)])).toSucceed(); + expect(await send(slToken, 'harnessSetExchangeRate', [etherMantissa(opts.exchangeRate)])).toSucceed(); } - return send(cToken, 'redeemUnderlying', [redeemAmount], { from: redeemer }); + return send(slToken, 'redeemUnderlying', [redeemAmount], { from: redeemer }); } -async function setOraclePrice(cToken, price) { - return send(cToken.comptroller.priceOracle, 'setUnderlyingPrice', [cToken._address, etherMantissa(price)]); +async function setOraclePrice(slToken, price) { + return send(slToken.comptroller.priceOracle, 'setUnderlyingPrice', [slToken._address, etherMantissa(price)]); } -async function setBorrowRate(cToken, rate) { - return send(cToken.interestRateModel, 'setBorrowRate', [etherMantissa(rate)]); +async function setBorrowRate(slToken, rate) { + return send(slToken.interestRateModel, 'setBorrowRate', [etherMantissa(rate)]); } async function getBorrowRate(interestRateModel, cash, borrows, reserves) { @@ -397,17 +397,17 @@ async function getSupplyRate(interestRateModel, cash, borrows, reserves, reserve return call(interestRateModel, 'getSupplyRate', [cash, borrows, reserves, reserveFactor].map(etherUnsigned)); } -async function pretendBorrow(cToken, borrower, accountIndex, marketIndex, principalRaw, blockNumber = 2e7) { - await send(cToken, 'harnessSetTotalBorrows', [etherUnsigned(principalRaw)]); - await send(cToken, 'harnessSetAccountBorrows', [borrower, etherUnsigned(principalRaw), etherMantissa(accountIndex)]); - await send(cToken, 'harnessSetBorrowIndex', [etherMantissa(marketIndex)]); - await send(cToken, 'harnessSetAccrualBlockNumber', [etherUnsigned(blockNumber)]); - await send(cToken, 'harnessSetBlockNumber', [etherUnsigned(blockNumber)]); +async function pretendBorrow(slToken, borrower, accountIndex, marketIndex, principalRaw, blockNumber = 2e7) { + await send(slToken, 'harnessSetTotalBorrows', [etherUnsigned(principalRaw)]); + await send(slToken, 'harnessSetAccountBorrows', [borrower, etherUnsigned(principalRaw), etherMantissa(accountIndex)]); + await send(slToken, 'harnessSetBorrowIndex', [etherMantissa(marketIndex)]); + await send(slToken, 'harnessSetAccrualBlockNumber', [etherUnsigned(blockNumber)]); + await send(slToken, 'harnessSetBlockNumber', [etherUnsigned(blockNumber)]); } module.exports = { makeComptroller, - makeCToken, + makeSLToken, makeInterestRateModel, makePriceOracle, makeToken, diff --git a/tests/gasProfiler.js b/tests/gasProfiler.js index 92d6ebfd9..ce49b8558 100644 --- a/tests/gasProfiler.js +++ b/tests/gasProfiler.js @@ -4,12 +4,12 @@ const { } = require('./Utils/Ethereum'); const { - makeCToken, + makeSLToken, fastForward, preApprove, preSupply, quickRedeem, -} = require('./Utils/Compound'); +} = require('./Utils/SashimiLending'); const fs = require('fs'); const util = require('util'); @@ -17,15 +17,15 @@ const diffStringsUnified = require('jest-diff'); async function preRedeem( - cToken, + slToken, redeemer, redeemTokens, redeemAmount, exchangeRate ) { - await preSupply(cToken, redeemer, redeemTokens); - await send(cToken.underlying, 'harnessSetBalance', [ - cToken._address, + await preSupply(slToken, redeemer, redeemTokens); + await send(slToken.underlying, 'harnessSetBalance', [ + slToken._address, redeemAmount ]); } @@ -54,16 +54,16 @@ const recordGasCost = (totalFee, key, filename, opcodes = {}) => { fs.writeFileSync(filename, JSON.stringify(fileObj, null, ' '), 'utf-8'); }; -async function mint(cToken, minter, mintAmount, exchangeRate) { - expect(await preApprove(cToken, minter, mintAmount, {})).toSucceed(); - return send(cToken, 'mint', [mintAmount], { from: minter }); +async function mint(slToken, minter, mintAmount, exchangeRate) { + expect(await preApprove(slToken, minter, mintAmount, {})).toSucceed(); + return send(slToken, 'mint', [mintAmount], { from: minter }); } -/// GAS PROFILER: saves a digest of the gas prices of common CToken operations +/// GAS PROFILER: saves a digest of the gas prices of common SLToken operations /// transiently fails, not sure why -describe('CToken', () => { - let root, minter, redeemer, accounts, cToken; +describe('SLToken', () => { + let root, minter, redeemer, accounts, slToken; const exchangeRate = 50e3; const preMintAmount = etherUnsigned(30e4); const mintAmount = etherUnsigned(10e4); @@ -74,7 +74,7 @@ describe('CToken', () => { beforeEach(async () => { [root, minter, redeemer, ...accounts] = saddle.accounts; - cToken = await makeCToken({ + slToken = await makeSLToken({ comptrollerOpts: { kind: 'bool' }, interestRateModelOpts: { kind: 'white-paper'}, exchangeRate @@ -82,20 +82,20 @@ describe('CToken', () => { }); it('first mint', async () => { - await send(cToken, 'harnessSetAccrualBlockNumber', [40]); - await send(cToken, 'harnessSetBlockNumber', [41]); + await send(slToken, 'harnessSetAccrualBlockNumber', [40]); + await send(slToken, 'harnessSetBlockNumber', [41]); - const trxReceipt = await mint(cToken, minter, mintAmount, exchangeRate); + const trxReceipt = await mint(slToken, minter, mintAmount, exchangeRate); recordGasCost(trxReceipt.gasUsed, 'first mint', filename); }); it.only('second mint', async () => { - await mint(cToken, minter, mintAmount, exchangeRate); + await mint(slToken, minter, mintAmount, exchangeRate); - await send(cToken, 'harnessSetAccrualBlockNumber', [40]); - await send(cToken, 'harnessSetBlockNumber', [41]); + await send(slToken, 'harnessSetAccrualBlockNumber', [40]); + await send(slToken, 'harnessSetBlockNumber', [41]); - const mint2Receipt = await mint(cToken, minter, mintAmount, exchangeRate); + const mint2Receipt = await mint(slToken, minter, mintAmount, exchangeRate); expect(Object.keys(mint2Receipt.events)).toEqual(['AccrueInterest', 'Transfer', 'Mint']); console.log(mint2Receipt.gasUsed); @@ -114,12 +114,12 @@ describe('CToken', () => { }); it('second mint, no interest accrued', async () => { - await mint(cToken, minter, mintAmount, exchangeRate); + await mint(slToken, minter, mintAmount, exchangeRate); - await send(cToken, 'harnessSetAccrualBlockNumber', [40]); - await send(cToken, 'harnessSetBlockNumber', [40]); + await send(slToken, 'harnessSetAccrualBlockNumber', [40]); + await send(slToken, 'harnessSetBlockNumber', [40]); - const mint2Receipt = await mint(cToken, minter, mintAmount, exchangeRate); + const mint2Receipt = await mint(slToken, minter, mintAmount, exchangeRate); expect(Object.keys(mint2Receipt.events)).toEqual(['Transfer', 'Mint']); recordGasCost(mint2Receipt.gasUsed, 'second mint, no interest accrued', filename); @@ -134,14 +134,14 @@ describe('CToken', () => { }); it('redeem', async () => { - await preRedeem(cToken, redeemer, redeemTokens, redeemAmount, exchangeRate); - const trxReceipt = await quickRedeem(cToken, redeemer, redeemTokens); + await preRedeem(slToken, redeemer, redeemTokens, redeemAmount, exchangeRate); + const trxReceipt = await quickRedeem(slToken, redeemer, redeemTokens); recordGasCost(trxReceipt.gasUsed, 'redeem', filename); }); it.skip('print mint opcode list', async () => { - await preMint(cToken, minter, mintAmount, mintTokens, exchangeRate); - const trxReceipt = await quickMint(cToken, minter, mintAmount); + await preMint(slToken, minter, mintAmount, mintTokens, exchangeRate); + const trxReceipt = await quickMint(slToken, minter, mintAmount); const opcodeCount = {}; await saddle.trace(trxReceipt, { execLog: log => {