编译器
0.5.16+commit.9c3226ce
文件 1 的 25:Address.sol
pragma solidity ^0.5.5;
library Address {
function isContract(address account) internal view returns (bool) {
bytes32 codehash;
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
assembly { codehash := extcodehash(account) }
return (codehash != accountHash && codehash != 0x0);
}
function toPayable(address account) internal pure returns (address payable) {
return address(uint160(account));
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call.value(amount)("");
require(success, "Address: unable to send value, recipient may have reverted");
}
}
文件 2 的 25:CarefulMath.sol
pragma solidity ^0.5.16;
contract CarefulMath {
enum MathError {
NO_ERROR,
DIVISION_BY_ZERO,
INTEGER_OVERFLOW,
INTEGER_UNDERFLOW
}
function mulUInt(uint a, uint b) internal pure returns (MathError, uint) {
if (a == 0) {
return (MathError.NO_ERROR, 0);
}
uint c = a * b;
if (c / a != b) {
return (MathError.INTEGER_OVERFLOW, 0);
} else {
return (MathError.NO_ERROR, c);
}
}
function divUInt(uint a, uint b) internal pure returns (MathError, uint) {
if (b == 0) {
return (MathError.DIVISION_BY_ZERO, 0);
}
return (MathError.NO_ERROR, a / b);
}
function subUInt(uint a, uint b) internal pure returns (MathError, uint) {
if (b <= a) {
return (MathError.NO_ERROR, a - b);
} else {
return (MathError.INTEGER_UNDERFLOW, 0);
}
}
function addUInt(uint a, uint b) internal pure returns (MathError, uint) {
uint c = a + b;
if (c >= a) {
return (MathError.NO_ERROR, c);
} else {
return (MathError.INTEGER_OVERFLOW, 0);
}
}
function addThenSubUInt(uint a, uint b, uint c) internal pure returns (MathError, uint) {
(MathError err0, uint sum) = addUInt(a, b);
if (err0 != MathError.NO_ERROR) {
return (err0, 0);
}
return subUInt(sum, c);
}
}
文件 3 的 25:Context.sol
pragma solidity ^0.5.0;
contract Context {
constructor () internal { }
function _msgSender() internal view returns (address payable) {
return msg.sender;
}
function _msgData() internal view returns (bytes memory) {
this;
return msg.data;
}
}
文件 4 的 25:Counters.sol
pragma solidity ^0.5.0;
import "../math/ZSafeMath.sol";
library Counters {
using ZSafeMath for uint256;
struct Counter {
uint256 _value;
}
function current(Counter storage counter) internal view returns (uint256) {
return counter._value;
}
function increment(Counter storage counter) internal {
counter._value += 1;
}
function decrement(Counter storage counter) internal {
counter._value = counter._value.sub(1);
}
}
文件 5 的 25:EIP20NonStandardInterface.sol
pragma solidity ^0.5.16;
interface EIP20NonStandardInterface {
function totalSupply() external view returns (uint256);
function balanceOf(address owner) external view returns (uint256 balance);
function transfer(address dst, uint256 amount) external;
function transferFrom(address src, address dst, uint256 amount) external;
function approve(address spender, uint256 amount) external returns (bool success);
function allowance(address owner, address spender) external view returns (uint256 remaining);
event Transfer(address indexed from, address indexed to, uint256 amount);
event Approval(address indexed owner, address indexed spender, uint256 amount);
}
文件 6 的 25:ERC165.sol
pragma solidity ^0.5.0;
import "./IERC165.sol";
contract ERC165 is IERC165 {
bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
mapping(bytes4 => bool) private _supportedInterfaces;
constructor () internal {
_registerInterface(_INTERFACE_ID_ERC165);
}
function supportsInterface(bytes4 interfaceId) external view returns (bool) {
return _supportedInterfaces[interfaceId];
}
function _registerInterface(bytes4 interfaceId) internal {
require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}
}
文件 7 的 25:ERC20.sol
pragma solidity ^0.5.0;
import "../../GSN/Context.sol";
import "./IERC20.sol";
import "../../math/ZSafeMath.sol";
contract ERC20 is Context, IERC20 {
using ZSafeMath for uint256;
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
constructor(string memory name_, string memory symbol_) public {
_name = name_;
_symbol = symbol_;
}
function totalSupply() public view returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view returns (uint256) {
return _balances[account];
}
function transfer(address recipient, uint256 amount) public returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
function allowance(address owner, address spender) public view returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 amount) public returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) {
_transfer(sender, recipient, amount);
_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
return true;
}
function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
return true;
}
function _transfer(address sender, address recipient, uint256 amount) internal {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}
function _mint(address account, uint256 amount) internal {
require(account != address(0), "ERC20: mint to the zero address");
_totalSupply = _totalSupply.add(amount);
_balances[account] = _balances[account].add(amount);
emit Transfer(address(0), account, amount);
}
function _burn(address account, uint256 amount) internal {
require(account != address(0), "ERC20: burn from the zero address");
_balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
_totalSupply = _totalSupply.sub(amount);
emit Transfer(account, address(0), amount);
}
function _approve(address owner, address spender, uint256 amount) internal {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function _burnFrom(address account, uint256 amount) internal {
_burn(account, amount);
_approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, "ERC20: burn amount exceeds allowance"));
}
}
文件 8 的 25:ERC721.sol
pragma solidity ^0.5.0;
import "../../GSN/Context.sol";
import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "../../math/ZSafeMath.sol";
import "../../utils/Address.sol";
import "../../drafts/Counters.sol";
import "../../introspection/ERC165.sol";
contract ERC721 is Context, ERC165, IERC721 {
using ZSafeMath for uint256;
using Address for address;
using Counters for Counters.Counter;
string private _name;
string private _symbol;
bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;
mapping (uint256 => address) private _tokenOwner;
mapping (uint256 => address) internal _tokenApprovals;
mapping (address => Counters.Counter) private _ownedTokensCount;
mapping (address => mapping (address => bool)) private _operatorApprovals;
bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;
constructor(string memory name_, string memory symbol_) public {
_name = name_;
_symbol = symbol_;
_registerInterface(_INTERFACE_ID_ERC721);
}
function balanceOf(address owner) public view returns (uint256) {
require(owner != address(0), "ERC721: balance query for the zero address");
return _ownedTokensCount[owner].current();
}
function ownerOf(uint256 tokenId) public view returns (address) {
address owner = _tokenOwner[tokenId];
require(owner != address(0), "ERC721: owner query for nonexistent token");
return owner;
}
function approve(address to, uint256 tokenId) public {
address owner = ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
"ERC721: approve caller is not owner nor approved for all"
);
_tokenApprovals[tokenId] = to;
emit Approval(owner, to, tokenId);
}
function getApproved(uint256 tokenId) public view returns (address) {
require(_exists(tokenId), "ERC721: approved query for nonexistent token");
return _tokenApprovals[tokenId];
}
function setApprovalForAll(address to, bool approved) public {
require(to != _msgSender(), "ERC721: approve to caller");
_operatorApprovals[_msgSender()][to] = approved;
emit ApprovalForAll(_msgSender(), to, approved);
}
function isApprovedForAll(address owner, address operator) public view returns (bool) {
return _operatorApprovals[owner][operator];
}
function transferFrom(address from, address to, uint256 tokenId) public {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_transferFrom(from, to, tokenId);
}
function safeTransferFrom(address from, address to, uint256 tokenId) public {
safeTransferFrom(from, to, tokenId, "");
}
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_safeTransferFrom(from, to, tokenId, _data);
}
function _safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) internal {
_transferFrom(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
}
function _exists(uint256 tokenId) internal view returns (bool) {
address owner = _tokenOwner[tokenId];
return owner != address(0);
}
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) {
require(_exists(tokenId), "ERC721: operator query for nonexistent token");
address owner = ownerOf(tokenId);
return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
}
function _safeMint(address to, uint256 tokenId) internal {
_safeMint(to, tokenId, "");
}
function _safeMint(address to, uint256 tokenId, bytes memory _data) internal {
_mint(to, tokenId);
require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
}
function _mint(address to, uint256 tokenId) internal {
require(to != address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: token already minted");
_tokenOwner[tokenId] = to;
_ownedTokensCount[to].increment();
emit Transfer(address(0), to, tokenId);
}
function _burn(address owner, uint256 tokenId) internal {
require(ownerOf(tokenId) == owner, "ERC721: burn of token that is not own");
_clearApproval(tokenId);
_ownedTokensCount[owner].decrement();
_tokenOwner[tokenId] = address(0);
emit Transfer(owner, address(0), tokenId);
}
function _burn(uint256 tokenId) internal {
_burn(ownerOf(tokenId), tokenId);
}
function _transferFrom(address from, address to, uint256 tokenId) internal {
require(ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
require(to != address(0), "ERC721: transfer to the zero address");
_clearApproval(tokenId);
_ownedTokensCount[from].decrement();
_ownedTokensCount[to].increment();
_tokenOwner[tokenId] = to;
emit Transfer(from, to, tokenId);
}
function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
internal returns (bool)
{
if (!to.isContract()) {
return true;
}
(bool success, bytes memory returndata) = to.call(abi.encodeWithSelector(
IERC721Receiver(to).onERC721Received.selector,
_msgSender(),
from,
tokenId,
_data
));
if (!success) {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert("ERC721: transfer to non ERC721Receiver implementer");
}
} else {
bytes4 retval = abi.decode(returndata, (bytes4));
return (retval == _ERC721_RECEIVED);
}
}
function _clearApproval(uint256 tokenId) private {
if (_tokenApprovals[tokenId] != address(0)) {
_tokenApprovals[tokenId] = address(0);
}
}
}
文件 9 的 25:ErrorReporter.sol
pragma solidity ^0.5.16;
contract MtrollerErrorReporter {
enum Error {
NO_ERROR,
UNAUTHORIZED,
MTROLLER_MISMATCH,
INSUFFICIENT_SHORTFALL,
INSUFFICIENT_LIQUIDITY,
INVALID_CLOSE_FACTOR,
INVALID_COLLATERAL_FACTOR,
INVALID_LIQUIDATION_INCENTIVE,
MARKET_NOT_ENTERED,
MARKET_NOT_LISTED,
MARKET_ALREADY_LISTED,
MATH_ERROR,
NONZERO_BORROW_BALANCE,
PRICE_ERROR,
REJECTION,
SNAPSHOT_ERROR,
TOO_MANY_ASSETS,
TOO_MUCH_REPAY,
INVALID_TOKEN_TYPE
}
enum FailureInfo {
ACCEPT_ADMIN_PENDING_ADMIN_CHECK,
ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,
EXIT_MARKET_BALANCE_OWED,
EXIT_MARKET_REJECTION,
SET_CLOSE_FACTOR_OWNER_CHECK,
SET_CLOSE_FACTOR_VALIDATION,
SET_COLLATERAL_FACTOR_OWNER_CHECK,
SET_COLLATERAL_FACTOR_NO_EXISTS,
SET_COLLATERAL_FACTOR_VALIDATION,
SET_COLLATERAL_FACTOR_WITHOUT_PRICE,
SET_IMPLEMENTATION_OWNER_CHECK,
SET_LIQUIDATION_INCENTIVE_OWNER_CHECK,
SET_LIQUIDATION_INCENTIVE_VALIDATION,
SET_MAX_ASSETS_OWNER_CHECK,
SET_PENDING_ADMIN_OWNER_CHECK,
SET_PENDING_IMPLEMENTATION_OWNER_CHECK,
SET_PRICE_ORACLE_OWNER_CHECK,
SUPPORT_MARKET_EXISTS,
SUPPORT_MARKET_OWNER_CHECK,
SET_PAUSE_GUARDIAN_OWNER_CHECK
}
event Failure(uint error, uint info, uint detail);
function fail(Error err, FailureInfo info) internal returns (uint) {
emit Failure(uint(err), uint(info), 0);
return uint(err);
}
function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {
emit Failure(uint(err), uint(info), opaqueError);
return uint(err);
}
}
contract TokenErrorReporter {
enum Error {
NO_ERROR,
UNAUTHORIZED,
BAD_INPUT,
MTROLLER_REJECTION,
MTROLLER_CALCULATION_ERROR,
INTEREST_RATE_MODEL_ERROR,
INVALID_ACCOUNT_PAIR,
INVALID_CLOSE_AMOUNT_REQUESTED,
INVALID_COLLATERAL_FACTOR,
INVALID_COLLATERAL,
MATH_ERROR,
MARKET_NOT_FRESH,
MARKET_NOT_LISTED,
TOKEN_INSUFFICIENT_ALLOWANCE,
TOKEN_INSUFFICIENT_BALANCE,
TOKEN_INSUFFICIENT_CASH,
TOKEN_TRANSFER_IN_FAILED,
TOKEN_TRANSFER_OUT_FAILED
}
enum FailureInfo {
ACCEPT_ADMIN_PENDING_ADMIN_CHECK,
ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,
ACCRUE_INTEREST_BORROW_RATE_CALCULATION_FAILED,
ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,
ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,
ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,
ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,
AUCTION_NOT_ALLOWED,
BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,
BORROW_ACCRUE_INTEREST_FAILED,
BORROW_CASH_NOT_AVAILABLE,
BORROW_FRESHNESS_CHECK,
BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,
BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,
BORROW_NEW_PLATFORM_FEE_CALCULATION_FAILED,
BORROW_MARKET_NOT_LISTED,
BORROW_MTROLLER_REJECTION,
FLASH_LOAN_BORROW_FAILED,
FLASH_OPERATION_NOT_DEFINED,
LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,
LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,
LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,
LIQUIDATE_COLLATERAL_NOT_FUNGIBLE,
LIQUIDATE_COLLATERAL_NOT_EXISTING,
LIQUIDATE_MTROLLER_REJECTION,
LIQUIDATE_MTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,
LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,
LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,
LIQUIDATE_FRESHNESS_CHECK,
LIQUIDATE_GRACE_PERIOD_NOT_EXPIRED,
LIQUIDATE_LIQUIDATOR_IS_BORROWER,
LIQUIDATE_NOT_PREFERRED_LIQUIDATOR,
LIQUIDATE_REPAY_BORROW_FRESH_FAILED,
LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,
LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,
LIQUIDATE_SEIZE_MTROLLER_REJECTION,
LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,
LIQUIDATE_SEIZE_TOO_MUCH,
LIQUIDATE_SEIZE_NON_FUNGIBLE_ASSET,
MINT_ACCRUE_INTEREST_FAILED,
MINT_MTROLLER_REJECTION,
MINT_EXCHANGE_CALCULATION_FAILED,
MINT_EXCHANGE_RATE_READ_FAILED,
MINT_FRESHNESS_CHECK,
MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,
MINT_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,
MINT_NEW_TOTAL_CASH_CALCULATION_FAILED,
MINT_TRANSFER_IN_FAILED,
MINT_TRANSFER_IN_NOT_POSSIBLE,
REDEEM_ACCRUE_INTEREST_FAILED,
REDEEM_MTROLLER_REJECTION,
REDEEM_EXCHANGE_TOKENS_CALCULATION_FAILED,
REDEEM_EXCHANGE_AMOUNT_CALCULATION_FAILED,
REDEEM_EXCHANGE_RATE_READ_FAILED,
REDEEM_FRESHNESS_CHECK,
REDEEM_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,
REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,
REDEEM_TRANSFER_OUT_NOT_POSSIBLE,
REDEEM_MARKET_EXIT_NOT_POSSIBLE,
REDEEM_NOT_OWNER,
REDUCE_RESERVES_ACCRUE_INTEREST_FAILED,
REDUCE_RESERVES_ADMIN_CHECK,
REDUCE_RESERVES_CASH_NOT_AVAILABLE,
REDUCE_RESERVES_FRESH_CHECK,
REDUCE_RESERVES_VALIDATION,
REPAY_BEHALF_ACCRUE_INTEREST_FAILED,
REPAY_BORROW_ACCRUE_INTEREST_FAILED,
REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,
REPAY_BORROW_MTROLLER_REJECTION,
REPAY_BORROW_FRESHNESS_CHECK,
REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,
REPAY_BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,
REPAY_BORROW_NEW_TOTAL_CASH_CALCULATION_FAILED,
REPAY_BORROW_TRANSFER_IN_NOT_POSSIBLE,
SET_COLLATERAL_FACTOR_OWNER_CHECK,
SET_COLLATERAL_FACTOR_VALIDATION,
SET_GLOBAL_PARAMETERS_VALUE_CHECK,
SET_MTROLLER_OWNER_CHECK,
SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED,
SET_INTEREST_RATE_MODEL_FRESH_CHECK,
SET_INTEREST_RATE_MODEL_OWNER_CHECK,
SET_FLASH_WHITELIST_OWNER_CHECK,
SET_MAX_ASSETS_OWNER_CHECK,
SET_ORACLE_MARKET_NOT_LISTED,
SET_PENDING_ADMIN_OWNER_CHECK,
SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED,
SET_RESERVE_FACTOR_ADMIN_CHECK,
SET_RESERVE_FACTOR_FRESH_CHECK,
SET_RESERVE_FACTOR_BOUNDS_CHECK,
SET_TOKEN_AUCTION_OWNER_CHECK,
TRANSFER_MTROLLER_REJECTION,
TRANSFER_NOT_ALLOWED,
TRANSFER_NOT_ENOUGH,
TRANSFER_TOO_MUCH,
ADD_RESERVES_ACCRUE_INTEREST_FAILED,
ADD_RESERVES_FRESH_CHECK,
ADD_RESERVES_TOTAL_CASH_CALCULATION_FAILED,
ADD_RESERVES_TOTAL_RESERVES_CALCULATION_FAILED,
ADD_RESERVES_TRANSFER_IN_NOT_POSSIBLE
}
event Failure(uint error, uint info, uint detail);
function fail(Error err, FailureInfo info) internal returns (uint) {
emit Failure(uint(err), uint(info), 0);
return uint(err);
}
function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {
emit Failure(uint(err), uint(info), opaqueError);
return uint(err);
}
}
文件 10 的 25:Exponential.sol
pragma solidity ^0.5.16;
import "./CarefulMath.sol";
import "./ExponentialNoError.sol";
contract Exponential is CarefulMath, ExponentialNoError {
function getExp(uint num, uint denom) pure internal returns (MathError, Exp memory) {
(MathError err0, uint scaledNumerator) = mulUInt(num, expScale);
if (err0 != MathError.NO_ERROR) {
return (err0, Exp({mantissa: 0}));
}
(MathError err1, uint rational) = divUInt(scaledNumerator, denom);
if (err1 != MathError.NO_ERROR) {
return (err1, Exp({mantissa: 0}));
}
return (MathError.NO_ERROR, Exp({mantissa: rational}));
}
function addExp(Exp memory a, Exp memory b) pure internal returns (MathError, Exp memory) {
(MathError error, uint result) = addUInt(a.mantissa, b.mantissa);
return (error, Exp({mantissa: result}));
}
function subExp(Exp memory a, Exp memory b) pure internal returns (MathError, Exp memory) {
(MathError error, uint result) = subUInt(a.mantissa, b.mantissa);
return (error, Exp({mantissa: result}));
}
function mulScalar(Exp memory a, uint scalar) pure internal returns (MathError, Exp memory) {
(MathError err0, uint scaledMantissa) = mulUInt(a.mantissa, scalar);
if (err0 != MathError.NO_ERROR) {
return (err0, Exp({mantissa: 0}));
}
return (MathError.NO_ERROR, Exp({mantissa: scaledMantissa}));
}
function mulScalarTruncate(Exp memory a, uint scalar) pure internal returns (MathError, uint) {
(MathError err, Exp memory product) = mulScalar(a, scalar);
if (err != MathError.NO_ERROR) {
return (err, 0);
}
return (MathError.NO_ERROR, truncate(product));
}
function mulScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) pure internal returns (MathError, uint) {
(MathError err, Exp memory product) = mulScalar(a, scalar);
if (err != MathError.NO_ERROR) {
return (err, 0);
}
return addUInt(truncate(product), addend);
}
function divScalar(Exp memory a, uint scalar) pure internal returns (MathError, Exp memory) {
(MathError err0, uint descaledMantissa) = divUInt(a.mantissa, scalar);
if (err0 != MathError.NO_ERROR) {
return (err0, Exp({mantissa: 0}));
}
return (MathError.NO_ERROR, Exp({mantissa: descaledMantissa}));
}
function divScalarByExp(uint scalar, Exp memory divisor) pure internal returns (MathError, Exp memory) {
(MathError err0, uint numerator) = mulUInt(expScale, scalar);
if (err0 != MathError.NO_ERROR) {
return (err0, Exp({mantissa: 0}));
}
return getExp(numerator, divisor.mantissa);
}
function divScalarByExpTruncate(uint scalar, Exp memory divisor) pure internal returns (MathError, uint) {
(MathError err, Exp memory fraction) = divScalarByExp(scalar, divisor);
if (err != MathError.NO_ERROR) {
return (err, 0);
}
return (MathError.NO_ERROR, truncate(fraction));
}
function mulExp(Exp memory a, Exp memory b) pure internal returns (MathError, Exp memory) {
(MathError err0, uint doubleScaledProduct) = mulUInt(a.mantissa, b.mantissa);
if (err0 != MathError.NO_ERROR) {
return (err0, Exp({mantissa: 0}));
}
(MathError err1, uint doubleScaledProductWithHalfScale) = addUInt(halfExpScale, doubleScaledProduct);
if (err1 != MathError.NO_ERROR) {
return (err1, Exp({mantissa: 0}));
}
(MathError err2, uint product) = divUInt(doubleScaledProductWithHalfScale, expScale);
assert(err2 == MathError.NO_ERROR);
return (MathError.NO_ERROR, Exp({mantissa: product}));
}
function mulExp(uint a, uint b) pure internal returns (MathError, Exp memory) {
return mulExp(Exp({mantissa: a}), Exp({mantissa: b}));
}
function mulExp3(Exp memory a, Exp memory b, Exp memory c) pure internal returns (MathError, Exp memory) {
(MathError err, Exp memory ab) = mulExp(a, b);
if (err != MathError.NO_ERROR) {
return (err, ab);
}
return mulExp(ab, c);
}
function divExp(Exp memory a, Exp memory b) pure internal returns (MathError, Exp memory) {
return getExp(a.mantissa, b.mantissa);
}
}
文件 11 的 25:ExponentialNoError.sol
pragma solidity ^0.5.16;
contract ExponentialNoError {
uint constant expScale = 1e18;
uint constant doubleScale = 1e36;
uint constant halfExpScale = expScale/2;
uint constant mantissaOne = expScale;
struct Exp {
uint mantissa;
}
struct Double {
uint mantissa;
}
function truncate(Exp memory exp) pure internal returns (uint) {
return exp.mantissa / expScale;
}
function mul_ScalarTruncate(Exp memory a, uint scalar) pure internal returns (uint) {
Exp memory product = mul_(a, scalar);
return truncate(product);
}
function mul_ScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) pure internal returns (uint) {
Exp memory product = mul_(a, scalar);
return add_(truncate(product), addend);
}
function lessThanExp(Exp memory left, Exp memory right) pure internal returns (bool) {
return left.mantissa < right.mantissa;
}
function lessThanOrEqualExp(Exp memory left, Exp memory right) pure internal returns (bool) {
return left.mantissa <= right.mantissa;
}
function greaterThanExp(Exp memory left, Exp memory right) pure internal returns (bool) {
return left.mantissa > right.mantissa;
}
function isZeroExp(Exp memory value) pure internal returns (bool) {
return value.mantissa == 0;
}
function safe224(uint n, string memory errorMessage) pure internal returns (uint224) {
require(n < 2**224, errorMessage);
return uint224(n);
}
function safe32(uint n, string memory errorMessage) pure internal returns (uint32) {
require(n < 2**32, errorMessage);
return uint32(n);
}
function add_(Exp memory a, Exp memory b) pure internal returns (Exp memory) {
return Exp({mantissa: add_(a.mantissa, b.mantissa)});
}
function add_(Double memory a, Double memory b) pure internal returns (Double memory) {
return Double({mantissa: add_(a.mantissa, b.mantissa)});
}
function add_(uint a, uint b) pure internal returns (uint) {
return add_(a, b, "addition overflow");
}
function add_(uint a, uint b, string memory errorMessage) pure internal returns (uint) {
uint c = a + b;
require(c >= a, errorMessage);
return c;
}
function sub_(Exp memory a, Exp memory b) pure internal returns (Exp memory) {
return Exp({mantissa: sub_(a.mantissa, b.mantissa)});
}
function sub_(Double memory a, Double memory b) pure internal returns (Double memory) {
return Double({mantissa: sub_(a.mantissa, b.mantissa)});
}
function sub_(uint a, uint b) pure internal returns (uint) {
return sub_(a, b, "subtraction underflow");
}
function sub_(uint a, uint b, string memory errorMessage) pure internal returns (uint) {
require(b <= a, errorMessage);
return a - b;
}
function mul_(Exp memory a, Exp memory b) pure internal returns (Exp memory) {
return Exp({mantissa: mul_(a.mantissa, b.mantissa) / expScale});
}
function mul_(Exp memory a, uint b) pure internal returns (Exp memory) {
return Exp({mantissa: mul_(a.mantissa, b)});
}
function mul_(uint a, Exp memory b) pure internal returns (uint) {
return mul_(a, b.mantissa) / expScale;
}
function mul_(Double memory a, Double memory b) pure internal returns (Double memory) {
return Double({mantissa: mul_(a.mantissa, b.mantissa) / doubleScale});
}
function mul_(Double memory a, uint b) pure internal returns (Double memory) {
return Double({mantissa: mul_(a.mantissa, b)});
}
function mul_(uint a, Double memory b) pure internal returns (uint) {
return mul_(a, b.mantissa) / doubleScale;
}
function mul_(uint a, uint b) pure internal returns (uint) {
return mul_(a, b, "multiplication overflow");
}
function mul_(uint a, uint b, string memory errorMessage) pure internal returns (uint) {
if (a == 0 || b == 0) {
return 0;
}
uint c = a * b;
require(c / a == b, errorMessage);
return c;
}
function div_(Exp memory a, Exp memory b) pure internal returns (Exp memory) {
return Exp({mantissa: div_(mul_(a.mantissa, expScale), b.mantissa)});
}
function div_(Exp memory a, uint b) pure internal returns (Exp memory) {
return Exp({mantissa: div_(a.mantissa, b)});
}
function div_(uint a, Exp memory b) pure internal returns (uint) {
return div_(mul_(a, expScale), b.mantissa);
}
function div_(Double memory a, Double memory b) pure internal returns (Double memory) {
return Double({mantissa: div_(mul_(a.mantissa, doubleScale), b.mantissa)});
}
function div_(Double memory a, uint b) pure internal returns (Double memory) {
return Double({mantissa: div_(a.mantissa, b)});
}
function div_(uint a, Double memory b) pure internal returns (uint) {
return div_(mul_(a, doubleScale), b.mantissa);
}
function div_(uint a, uint b) pure internal returns (uint) {
return div_(a, b, "divide by zero");
}
function div_(uint a, uint b, string memory errorMessage) pure internal returns (uint) {
require(b > 0, errorMessage);
return a / b;
}
function fraction(uint a, uint b) pure internal returns (Double memory) {
return Double({mantissa: div_(mul_(a, doubleScale), b)});
}
}
文件 12 的 25:IERC165.sol
pragma solidity ^0.5.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 13 的 25:IERC20.sol
pragma solidity ^0.5.0;
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
文件 14 的 25:IERC721.sol
pragma solidity ^0.5.0;
import "../../introspection/IERC165.sol";
contract IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) public view returns (uint256 balance);
function ownerOf(uint256 tokenId) public view returns (address owner);
function safeTransferFrom(address from, address to, uint256 tokenId) public;
function transferFrom(address from, address to, uint256 tokenId) public;
function approve(address to, uint256 tokenId) public;
function getApproved(uint256 tokenId) public view returns (address operator);
function setApprovalForAll(address operator, bool _approved) public;
function isApprovedForAll(address owner, address operator) public view returns (bool);
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public;
}
文件 15 的 25:IERC721Metadata.sol
pragma solidity ^0.5.0;
import "./IERC721.sol";
contract IERC721Metadata is IERC721 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
}
文件 16 的 25:IERC721Receiver.sol
pragma solidity ^0.5.0;
contract IERC721Receiver {
function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data)
public returns (bytes4);
}
文件 17 的 25:InterestRateModel.sol
pragma solidity ^0.5.16;
contract InterestRateModel {
bool public constant isInterestRateModel = true;
function getBorrowRate(uint cash, uint borrows, uint reserves) external view returns (uint);
function getSupplyRate(uint cash, uint borrows, uint reserves, uint reserveFactorMantissa) external view returns (uint);
}
文件 18 的 25:MDelegator.sol
pragma solidity ^0.5.16;
import "./ErrorReporter.sol";
import "./MtrollerInterface.sol";
import "./MTokenInterfaces.sol";
import "./MTokenStorage.sol";
contract MDelegator is MDelegatorIdentifier {
bytes32 private constant mDelegatorUserImplementationPosition =
keccak256("com.mmo-finance.mDelegator.user.implementation.address");
bytes32 private constant mDelegatorAdminImplementationPosition =
keccak256("com.mmo-finance.mDelegator.admin.implementation.address");
bytes32 private constant mDelegatorAdminImplementationSelectorPosition =
keccak256("com.mmo-finance.mDelegator.admin.implementation.selector.bool");
bytes32 private constant mDelegatorEnableUpdate =
keccak256("com.mmo-finance.mDelegator.enableUpdate.bool");
constructor() public {
_setMDelegatorAdmin(msg.sender);
bool _enable = true;
bytes32 position = mDelegatorEnableUpdate;
assembly {
sstore(position, _enable)
}
}
function mDelegatorUserImplementation() public view returns (address implementation) {
bytes32 position = mDelegatorUserImplementationPosition;
assembly {
implementation := sload(position)
}
}
function mDelegatorAdminImplementation() public view returns (address implementation) {
bytes32 position = mDelegatorAdminImplementationPosition;
assembly {
implementation := sload(position)
}
}
function mDelegatorAdminImplementationSelectorSupported(bytes4 selector) public view returns (bool supported) {
bytes32 position = keccak256(abi.encode(selector, mDelegatorAdminImplementationSelectorPosition));
assembly {
supported := sload(position)
}
}
function mDelegatorImplementationUpdateEnabled() public view returns (bool enabled) {
bytes32 position = mDelegatorEnableUpdate;
assembly {
enabled := sload(position)
}
}
function mDelegatorAdmin() public view returns (address admin) {
bytes32 position = mDelegatorAdminPosition;
assembly {
admin := sload(position)
}
}
function _setImplementation(address _newUserImplementation, address _newAdminImplementation) public {
require(msg.sender == mDelegatorAdmin(), "only admin");
require(mDelegatorImplementationUpdateEnabled(), "update disabled");
require(MTokenInterface(_newUserImplementation).isMDelegatorUserImplementation(), "invalid user implementation");
require(MTokenInterface(_newAdminImplementation).isMDelegatorAdminImplementation(), "invalid admin implementation");
MDelegateeStorage oldAdminImpl = MDelegateeStorage(mDelegatorAdminImplementation());
MDelegateeStorage newAdminImpl = MDelegateeStorage(_newAdminImplementation);
if (address(oldAdminImpl) != address(0)) {
uint len = oldAdminImpl.implementedSelectorsLength();
for (uint i = 0; i < len; i++) {
_setAdminSelectorSupported(oldAdminImpl.implementedSelectors(i), false);
}
}
bytes32 positionUser = mDelegatorUserImplementationPosition;
bytes32 positionAdmin = mDelegatorAdminImplementationPosition;
assembly {
sstore(positionUser, _newUserImplementation)
sstore(positionAdmin, _newAdminImplementation)
}
uint len = newAdminImpl.implementedSelectorsLength();
for (uint i = 0; i < len; i++) {
_setAdminSelectorSupported(newAdminImpl.implementedSelectors(i), true);
}
}
function _setAdminSelectorSupported(bytes4 selector, bool supported) public {
require(msg.sender == mDelegatorAdmin(), "only admin");
bytes32 position = keccak256(abi.encode(selector, mDelegatorAdminImplementationSelectorPosition));
assembly {
sstore(position, supported)
}
}
function _disableFurtherImplementationUpdates() public {
require(msg.sender == mDelegatorAdmin(), "only admin");
bool _enable = false;
bytes32 position = mDelegatorEnableUpdate;
assembly {
sstore(position, _enable)
}
}
function _setMDelegatorAdmin(address _newAdmin) public {
if (mDelegatorAdmin() != address(0)) {
require(msg.sender == mDelegatorAdmin(), "only admin");
require(_newAdmin != address(0), "invalid new admin");
}
bytes32 position = mDelegatorAdminPosition;
assembly {
sstore(position, _newAdmin)
}
}
function () payable external {
address implementation;
if (mDelegatorAdminImplementationSelectorSupported(msg.sig)) {
implementation = mDelegatorAdminImplementation();
}
else {
implementation = mDelegatorUserImplementation();
}
(bool success, ) = implementation.delegatecall(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(free_mem_ptr, returndatasize) }
}
}
}
contract Mtroller is MDelegator {
constructor(MtrollerUserInterface userImpl, MtrollerAdminInterface adminImpl) public MDelegator() {
_setImplementation(address(userImpl), address(adminImpl));
}
}
contract MEther is MDelegator {
constructor(MEtherUserInterface userImpl, MEtherAdminInterface adminImpl) public MDelegator() {
_setImplementation(address(userImpl), address(adminImpl));
}
}
contract MERC721Token is MDelegator {
constructor(MERC721UserInterface userImpl, MERC721AdminInterface adminImpl) public MDelegator() {
_setImplementation(address(userImpl), address(adminImpl));
}
}
文件 19 的 25:MTokenInterfaces.sol
pragma solidity ^0.5.16;
import "./PriceOracle.sol";
import "./MtrollerInterface.sol";
import "./TokenAuction.sol";
import "./compound/InterestRateModel.sol";
import "./compound/EIP20NonStandardInterface.sol";
import "./open-zeppelin/token/ERC721/IERC721Metadata.sol";
contract MTokenCommonInterface is MTokenIdentifier, MDelegatorIdentifier {
event AccrueInterest(uint240 mToken, uint cashPrior, uint interestAccumulated, uint borrowIndex, uint totalBorrows);
event Mint(address minter, address beneficiary, uint mintAmountUnderlying, uint240 mTokenMinted, uint amountTokensMinted);
event Transfer(address from, address to, uint240 mToken, uint amountTokens);
event Redeem(address redeemer, uint240 mToken, uint redeemTokens, uint256 underlyingID, uint underlyingRedeemAmount);
event Borrow(address borrower, uint256 underlyingID, uint borrowAmount, uint paidOutAmount, uint accountBorrows, uint totalBorrows);
event FlashBorrow(address borrower, uint256 underlyingID, address receiver, uint downPayment, uint borrowAmount, uint paidOutAmount);
event RepayBorrow(address payer, address borrower, uint256 underlyingID, uint repayAmount, uint accountBorrows, uint totalBorrows);
event LiquidateBorrow(address liquidator, address borrower, uint240 mTokenBorrowed, uint repayAmountUnderlying, uint240 mTokenCollateral, uint seizeTokens);
event GracePeriod(uint240 mTokenCollateral, uint lastBlockOfGracePeriod);
event FlashReceiverWhitelistChanged(address receiver, bool newState);
event NewMarketInterestRateModel(InterestRateModel oldInterestRateModel, InterestRateModel newInterestRateModel);
event NewTokenAuction(TokenAuction oldTokenAuction, TokenAuction newTokenAuction);
event NewMtroller(MtrollerInterface oldMtroller, MtrollerInterface newMtroller);
event NewGlobalProtocolParameters(uint newInitialExchangeRateMantissa, uint newReserveFactorMantissa, uint newProtocolSeizeShareMantissa, uint newBorrowFeeMantissa);
event NewGlobalAuctionParameters(uint newAuctionGracePeriod, uint newPreferredLiquidatorHeadstart, uint newMinimumOfferMantissa, uint newLiquidatorAuctionFeeMantissa, uint newProtocolAuctionFeeMantissa);
event ReservesAdded(address benefactor, uint240 mToken, uint addAmount, uint newTotalReserves);
event ReservesReduced(address admin, uint240 mToken, uint reduceAmount, uint newTotalReserves);
event Failure(uint error, uint info, uint detail);
function getAdmin() public view returns (address payable admin);
function accrueInterest(uint240 mToken) public returns (uint);
}
contract MTokenAdminInterface is MTokenCommonInterface {
function isMDelegatorAdminImplementation() public pure returns (bool);
function _setInterestRateModel(InterestRateModel newInterestRateModel) public returns (uint);
function _setTokenAuction(TokenAuction newTokenAuction) public returns (uint);
function _setMtroller(MtrollerInterface newMtroller) public returns (uint);
function _setGlobalProtocolParameters(uint _initialExchangeRateMantissa, uint _reserveFactorMantissa, uint _protocolSeizeShareMantissa, uint _borrowFeeMantissa) public returns (uint);
function _setGlobalAuctionParameters(uint _auctionGracePeriod, uint _preferredLiquidatorHeadstart, uint _minimumOfferMantissa, uint _liquidatorAuctionFeeMantissa, uint _protocolAuctionFeeMantissa) public returns (uint);
function _reduceReserves(uint240 mToken, uint reduceAmount) external returns (uint);
function _sweepERC20(address tokenContract) external returns (uint);
function _sweepERC721(address tokenContract, uint256 tokenID) external;
}
contract MTokenUserInterface is MTokenCommonInterface {
function isMDelegatorUserImplementation() public pure returns (bool);
function balanceOf(address owner, uint240 mToken) external view returns (uint);
function getAccountSnapshot(address account, uint240 mToken) external view returns (uint, uint, uint, uint);
function borrowRatePerBlock(uint240 mToken) external view returns (uint);
function supplyRatePerBlock(uint240 mToken) external view returns (uint);
function totalBorrowsCurrent(uint240 mToken) external returns (uint);
function borrowBalanceCurrent(address account, uint240 mToken) external returns (uint);
function borrowBalanceStored(address account, uint240 mToken) public view returns (uint);
function exchangeRateCurrent(uint240 mToken) external returns (uint);
function exchangeRateStored(uint240 mToken) external view returns (uint);
function getCash(uint240 mToken) external view returns (uint);
function seize(uint240 mTokenBorrowed, address liquidator, address borrower, uint240 mTokenCollateral, uint seizeTokens) external returns (uint);
}
contract MTokenInterface is MTokenAdminInterface, MTokenUserInterface {}
contract MFungibleTokenAdminInterface is MTokenAdminInterface {
}
contract MFungibleTokenUserInterface is MTokenUserInterface{
event Transfer(address indexed from, address indexed to, uint amount);
event Approval(address indexed owner, address indexed spender, uint amount);
function transfer(address dst, uint amount) external returns (bool);
function transferFrom(address src, address dst, uint amount) external returns (bool);
function approve(address spender, uint amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint);
function balanceOf(address owner) external view returns (uint);
function balanceOfUnderlying(address owner) external returns (uint);
}
contract MFungibleTokenInterface is MFungibleTokenAdminInterface, MFungibleTokenUserInterface {}
contract MEtherAdminInterface is MFungibleTokenAdminInterface {
function initialize(MtrollerInterface mtroller_,
InterestRateModel interestRateModel_,
uint reserveFactorMantissa_,
uint initialExchangeRateMantissa_,
uint protocolSeizeShareMantissa_,
string memory name_,
string memory symbol_,
uint8 decimals_) public;
function redeem(uint redeemTokens) external returns (uint);
function redeemUnderlying(uint redeemAmount) external returns (uint);
function borrow(uint borrowAmount) external returns (uint);
function flashBorrow(uint borrowAmount, address payable receiver, bytes calldata flashParams) external payable returns (uint);
function name() public view returns (string memory);
function symbol() public view returns (string memory);
function decimals() public view returns (uint8);
}
contract MEtherUserInterface is MFungibleTokenUserInterface {
function getProtocolAuctionFeeMantissa() external view returns (uint);
function _addReserves() external payable returns (uint);
function mint() external payable returns (uint);
function mintTo(address beneficiary) external payable returns (uint);
function repayBorrow() external payable returns (uint);
function repayBorrowBehalf(address borrower) external payable returns (uint);
function liquidateBorrow(address borrower, uint240 mTokenCollateral) external payable returns (uint);
}
contract MEtherInterface is MEtherAdminInterface, MEtherUserInterface {}
contract MERC721AdminInterface is MTokenAdminInterface, IERC721, IERC721Metadata {
event NewTokenAuctionContract(TokenAuction oldTokenAuction, TokenAuction newTokenAuction);
function initialize(address underlyingContract_,
MtrollerInterface mtroller_,
InterestRateModel interestRateModel_,
TokenAuction tokenAuction_,
string memory name_,
string memory symbol_) public;
function redeem(uint240 mToken) public returns (uint);
function redeemUnderlying(uint256 underlyingID) external returns (uint);
function redeemAndSell(uint240 mToken, uint sellPrice, address payable transferHandler, bytes memory transferParams) public returns (uint);
function borrow(uint256 borrowUnderlyingID) external returns (uint);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
}
contract MERC721UserInterface is MTokenUserInterface, IERC721 {
event LiquidateToPaymentToken(address indexed oldOwner, address indexed newOwner, uint240 mToken, uint256 auctioneerTokens, uint256 oldOwnerTokens);
function mintAndCollateralizeTo(address beneficiary, uint256 underlyingTokenID) external returns (uint240);
function mintTo(address beneficiary, uint256 underlyingTokenID) public returns (uint240);
function addAuctionBid(uint240 mToken) external payable;
function instantSellToHighestBidder(uint240 mToken, uint256 minimumPrice, address favoriteBidder) public;
function setAskingPrice(uint240 mToken, uint256 newAskingPrice) external;
function startGracePeriod(uint240 mToken) external returns (uint);
function liquidateToPaymentToken(uint240 mToken) external returns (uint);
}
contract MERC721Interface is MERC721AdminInterface, MERC721UserInterface {}
contract FlashLoanReceiverInterface {
function executeFlashOperation(address payable borrower, uint240 mToken, uint borrowAmount, uint paidOutAmount, bytes calldata flashParams) external returns (uint);
function executeTransfer(uint256 tokenId, address payable seller, uint sellPrice, bytes calldata transferParams) external returns (uint);
}
文件 20 的 25:MTokenStorage.sol
pragma solidity ^0.5.16;
import "./MtrollerInterface.sol";
import "./TokenAuction.sol";
import "./compound/InterestRateModel.sol";
contract MDelegateeStorage {
bytes4[] public implementedSelectors;
function implementedSelectorsLength() public view returns (uint) {
return implementedSelectors.length;
}
}
contract MTokenV1Storage is MDelegateeStorage {
bool internal _notEntered;
bool internal _notEntered2;
address public underlyingContract;
InterestRateModel public interestRateModel;
TokenAuction public tokenAuction;
MtrollerInterface public mtroller;
string public mName;
string public mSymbol;
uint8 public mDecimals;
uint internal initialExchangeRateMantissa;
uint internal constant reserveFactorMaxMantissa = 50e16;
uint public reserveFactorMantissa;
uint internal constant protocolSeizeShareMaxMantissa = 5e16;
uint public protocolSeizeShareMantissa;
uint internal constant borrowFeeMaxMantissa = 50e16;
uint public borrowFeeMantissa;
mapping (address => bool) public flashReceiverIsWhitelisted;
uint256 public constant auctionMinGracePeriod = 2000;
uint256 public constant auctionMaxGracePeriod = 50000;
uint256 public auctionGracePeriod;
uint256 public constant preferredLiquidatorMaxHeadstart = 2000;
uint256 public preferredLiquidatorHeadstart;
uint public constant minimumOfferMaxMantissa = 80e16;
uint public minimumOfferMantissa;
uint public constant liquidatorAuctionFeeMaxMantissa = 10e16;
uint public liquidatorAuctionFeeMantissa;
uint public constant protocolAuctionFeeMaxMantissa = 20e16;
uint public protocolAuctionFeeMantissa;
mapping (uint240 => uint256) public underlyingIDs;
mapping (uint256 => uint240) public mTokenFromUnderlying;
uint256 public totalCreatedMarkets;
mapping (uint240 => uint) public accrualBlockNumber;
mapping (uint240 => uint) public borrowIndex;
mapping (uint240 => mapping (address => uint)) internal accountTokens;
struct BorrowSnapshot {
uint principal;
uint interestIndex;
}
mapping(uint240 => mapping(address => BorrowSnapshot)) internal accountBorrows;
uint internal constant borrowRateMaxMantissa = 0.0005e16;
mapping (uint240 => uint) public totalCashUnderlying;
mapping (uint240 => uint) public totalBorrows;
mapping (uint240 => uint) public totalReserves;
mapping (uint240 => uint) public totalSupply;
uint256 internal constant dummyTokenID = 1;
uint240 public thisFungibleMToken;
mapping (address => mapping (address => uint)) internal transferAllowances;
uint internal constant oneUnit = 1e18;
mapping (uint240 => uint256) public lastBlockGracePeriod;
mapping (uint240 => address) public preferredLiquidator;
mapping (uint240 => uint256) public askingPrice;
}
文件 21 的 25:MTokenTest_coins.sol
pragma solidity ^0.5.16;
import "./open-zeppelin/token/ERC721/ERC721.sol";
import "./open-zeppelin/token/ERC721/IERC721Metadata.sol";
import "./open-zeppelin/token/ERC20/ERC20.sol";
contract TestNFT is ERC721, IERC721Metadata {
string internal constant _name = "Glasses";
string internal constant _symbol = "GLSS";
uint256 public constant price = 0.1e18;
uint256 public constant maxSupply = 1000;
uint256 public nextTokenID;
address payable public admin;
string internal _baseURI;
uint internal _digits;
string internal _suffix;
constructor(address payable _admin) ERC721(_name, _symbol) public {
admin = msg.sender;
_setMetadata("ipfs://QmWNi2ByeUbY1fWbMq841nvNW2tDTpNzyGAhxWDqoXTAEr", 0, "");
admin = _admin;
}
function mint() public payable returns (uint256 newTokenID) {
require(nextTokenID < maxSupply, "all Glasses sold out");
require(msg.value >= price, "payment too low");
newTokenID = nextTokenID;
nextTokenID++;
_safeMint(msg.sender, newTokenID);
}
function () external payable {
mint();
}
function buyAndRedeem(uint256 vaultId, uint256 amount, uint256[] calldata specificIds, address[] calldata path, address to) external payable {
path;
require(vaultId == 2, "wrong vault");
require(amount == 1, "wrong amount");
require(specificIds[0] == nextTokenID, "wrong ID");
require(to == msg.sender, "wrong to");
mint();
}
function name() external view returns (string memory) {
return _name;
}
function symbol() external view returns (string memory) {
return _symbol;
}
function tokenURI(uint256 tokenId) external view returns (string memory) {
require(_exists(tokenId), "URI query for nonexistent token");
if (_digits == 0) {
return string(abi.encodePacked(_baseURI, _suffix));
}
else {
bytes memory _tokenID = new bytes(_digits);
uint _i = _digits;
while (_i != 0) {
_i--;
_tokenID[_i] = bytes1(48 + uint8(tokenId % 10));
tokenId /= 10;
}
return string(abi.encodePacked(_baseURI, string(_tokenID), _suffix));
}
}
function _setMetadata(string memory newBaseURI, uint newDigits, string memory newSuffix) public {
require(msg.sender == admin, "only admin");
require(newDigits < 10, "newDigits too big");
_baseURI = newBaseURI;
_digits = newDigits;
_suffix = newSuffix;
}
function _setAdmin(address payable newAdmin) public {
require(msg.sender == admin, "only admin");
admin = newAdmin;
}
function _withdraw() external {
require(msg.sender == admin, "only admin");
admin.transfer(address(this).balance);
}
}
contract TestERC20 is ERC20 {
constructor(string memory name_, string memory symbol_) ERC20(name_, symbol_) public {
}
function mint(uint256 amount) external {
_mint(msg.sender, amount);
}
}
文件 22 的 25:MtrollerInterface.sol
pragma solidity ^0.5.16;
import "./PriceOracle.sol";
contract MTokenIdentifier {
enum MTokenType {
INVALID_MTOKEN,
FUNGIBLE_MTOKEN,
ERC721_MTOKEN
}
function getTokenType() public pure returns (MTokenType) {
return MTokenType.INVALID_MTOKEN;
}
}
contract MDelegatorIdentifier {
bytes32 internal constant mDelegatorAdminPosition =
keccak256("com.mmo-finance.mDelegator.admin.address");
}
contract MtrollerCommonInterface is MTokenIdentifier, MDelegatorIdentifier {
event MarketListed(uint240 mToken);
event NewCollateralFactor(uint240 mToken, uint oldCollateralFactorMantissa, uint newCollateralFactorMantissa);
event MarketEntered(uint240 mToken, address account);
event MarketExited(uint240 mToken, address account);
event MmoSpeedUpdated(uint240 indexed mToken, uint newSpeed);
event ContributorMmoSpeedUpdated(address indexed contributor, uint newSpeed);
event DistributedSupplierMmo(uint240 indexed mToken, address indexed supplier, uint mmoDelta, uint MmoSupplyIndex);
event DistributedBorrowerMmo(uint240 indexed mToken, address indexed borrower, uint mmoDelta, uint mmoBorrowIndex);
event MmoGranted(address recipient, uint amount);
event NewCloseFactor(uint oldCloseFactorMantissa, uint newCloseFactorMantissa);
event NewLiquidationIncentive(uint oldLiquidationIncentiveMantissa, uint newLiquidationIncentiveMantissa);
event NewMaxAssets(uint oldMaxAssets, uint newMaxAssets);
event NewPriceOracle(PriceOracle oldPriceOracle, PriceOracle newPriceOracle);
event NewPauseGuardian(address oldPauseGuardian, address newPauseGuardian);
event ActionPaused(string action, bool pauseState);
event ActionPaused(uint240 mToken, string action, bool pauseState);
event NewBorrowCap(uint240 indexed mToken, uint newBorrowCap);
event NewBorrowCapGuardian(address oldBorrowCapGuardian, address newBorrowCapGuardian);
function getAdmin() public view returns (address payable admin);
function underlyingContractETH() public pure returns (address);
function getAnchorToken(address mTokenContract) public pure returns (uint240);
function assembleToken(MTokenType mTokenType, uint72 mTokenSeqNr, address mTokenAddress) public pure returns (uint240 mToken);
function parseToken(uint240 mToken) public pure returns (MTokenType mTokenType, uint72 mTokenSeqNr, address mTokenAddress);
function collateralFactorMantissa(uint240 mToken) public view returns (uint);
}
contract MtrollerUserInterface is MtrollerCommonInterface {
function isMDelegatorUserImplementation() public pure returns (bool);
function getAssetsIn(address account) external view returns (uint240[] memory);
function checkMembership(address account, uint240 mToken) external view returns (bool);
function enterMarkets(uint240[] calldata mTokens) external returns (uint[] memory);
function enterMarketOnBehalf(uint240 mToken, address owner) external returns (uint);
function exitMarket(uint240 mToken) external returns (uint);
function exitMarketOnBehalf(uint240 mToken, address owner) external returns (uint);
function _setCollateralFactor(uint240 mToken, uint newCollateralFactorMantissa) external returns (uint);
function auctionAllowed(uint240 mToken, address bidder) public view returns (uint);
function mintAllowed(uint240 mToken, address minter, uint mintAmount) external returns (uint);
function mintVerify(uint240 mToken, address minter, uint actualMintAmount, uint mintTokens) external view;
function redeemAllowed(uint240 mToken, address redeemer, uint redeemTokens) external view returns (uint);
function redeemVerify(uint240 mToken, address redeemer, uint redeemAmount, uint redeemTokens) external view;
function borrowAllowed(uint240 mToken, address borrower, uint borrowAmount) external view returns (uint);
function borrowVerify(uint240 mToken, address borrower, uint borrowAmount) external view;
function repayBorrowAllowed(uint240 mToken, address payer, address borrower, uint repayAmount) external view returns (uint);
function repayBorrowVerify(uint240 mToken, address payer, address borrower, uint actualRepayAmount, uint borrowerIndex) external view;
function liquidateBorrowAllowed(uint240 mTokenBorrowed, uint240 mTokenCollateral, address liquidator, address borrower, uint repayAmount) external view returns (uint);
function liquidateERC721Allowed(uint240 mToken) external view returns (uint);
function liquidateBorrowVerify(uint240 mTokenBorrowed, uint240 mTokenCollateral, address liquidator, address borrower, uint actualRepayAmount, uint seizeTokens) external view;
function seizeAllowed(uint240 mTokenCollateral, uint240 mTokenBorrowed, address liquidator, address borrower, uint seizeTokens) external view returns (uint);
function seizeVerify(uint240 mTokenCollateral, uint240 mTokenBorrowed, address liquidator, address borrower, uint seizeTokens) external view;
function transferAllowed(uint240 mToken, address src, address dst, uint transferTokens) external view returns (uint);
function transferVerify(uint240 mToken, address src, address dst, uint transferTokens) external view;
function getAccountLiquidity(address account) public view returns (uint, uint, uint);
function getHypotheticalAccountLiquidity(address account, uint240 mTokenModify, uint redeemTokens, uint borrowAmount) public view returns (uint, uint, uint);
function liquidateCalculateSeizeTokens(uint240 mTokenBorrowed, uint240 mTokenCollateral, uint actualRepayAmount) external view returns (uint, uint);
function getBlockNumber() public view returns (uint);
function getPrice(uint240 mToken) public view returns (uint);
function updateContributorRewards(address contributor) public;
function claimMmo(address holder, uint240[] memory mTokens) public;
function claimMmo(address[] memory holders, uint240[] memory mTokens, bool borrowers, bool suppliers) public;
function _grantMmo(address recipient, uint amount) public;
function _setMmoSpeed(uint240 mToken, uint mmoSpeed) public;
function _setContributorMmoSpeed(address contributor, uint mmoSpeed) public;
function getMmoAddress() public view returns (address);
}
contract MtrollerAdminInterface is MtrollerCommonInterface {
function initialize(address _mmoTokenAddress, uint _maxAssets) public;
function isMDelegatorAdminImplementation() public pure returns (bool);
function _supportMarket(uint240 mToken) external returns (uint);
function _setPriceOracle(PriceOracle newOracle) external returns (uint);
function _setCloseFactor(uint newCloseFactorMantissa) external returns (uint);
function _setLiquidationIncentive(uint newLiquidationIncentiveMantissa) external returns (uint);
function _setMaxAssets(uint newMaxAssets) external;
function _setBorrowCapGuardian(address newBorrowCapGuardian) external;
function _setMarketBorrowCaps(uint240[] calldata mTokens, uint[] calldata newBorrowCaps) external;
function _setPauseGuardian(address newPauseGuardian) public returns (uint);
function _setAuctionPaused(uint240 mToken, bool state) public returns (bool);
function _setMintPaused(uint240 mToken, bool state) public returns (bool);
function _setBorrowPaused(uint240 mToken, bool state) public returns (bool);
function _setTransferPaused(uint240 mToken, bool state) public returns (bool);
function _setSeizePaused(uint240 mToken, bool state) public returns (bool);
}
contract MtrollerInterface is MtrollerAdminInterface, MtrollerUserInterface {}
文件 23 的 25:PriceOracle.sol
pragma solidity ^0.5.16;
import "./MTokenTest_coins.sol";
contract PriceOracle {
bool public constant isPriceOracle = true;
function getUnderlyingPrice(address underlyingToken, uint256 tokenID) public view returns (uint);
}
contract PriceOracleV0_1 is PriceOracle {
event NewCollectionFloorPrice(uint oldFloorPrice, uint newFloorPrice);
address admin;
TestNFT glassesContract;
IERC721 collectionContract;
uint collectionFloorPrice;
constructor(address _admin, TestNFT _glassesContract, IERC721 _collectionContract) public {
admin = _admin;
glassesContract = _glassesContract;
collectionContract = _collectionContract;
}
function getUnderlyingPrice(address underlyingToken, uint256 tokenID) public view returns (uint) {
tokenID;
if (underlyingToken == address(uint160(-1))) {
return 1.0e18;
}
else if (underlyingToken == address(glassesContract)) {
return glassesContract.price();
}
else if (underlyingToken == address(collectionContract)) {
return collectionFloorPrice;
}
else {
return 0;
}
}
function _setCollectionFloorPrice(uint newFloorPrice) external {
require(msg.sender == admin, "only admin");
uint oldFloorPrice = collectionFloorPrice;
collectionFloorPrice = newFloorPrice;
emit NewCollectionFloorPrice(oldFloorPrice, newFloorPrice);
}
}
contract PriceOracleV0_2 is PriceOracleV0_1 {
event NewIndividualPrice(uint256 tokenID, uint oldPrice, uint newPrice);
mapping (uint256 => uint256) individualPrices;
constructor(address _admin, TestNFT _glassesContract, IERC721 _collectionContract) PriceOracleV0_1(_admin, _glassesContract, _collectionContract) public {
}
function getUnderlyingPrice(address underlyingToken, uint256 tokenID) public view returns (uint) {
if (underlyingToken == address(uint160(-1))) {
return 1.0e18;
}
else if (underlyingToken == address(glassesContract)) {
return glassesContract.price();
}
else if (underlyingToken == address(collectionContract)) {
uint collection = collectionFloorPrice;
uint individual = individualPrices[tokenID];
return (individual > collection ? individual : collection);
}
else {
return 0;
}
}
function _setIndividualPrice(uint256 tokenID, uint newPrice) external {
require(msg.sender == admin, "only admin");
uint oldPrice = individualPrices[tokenID];
if (newPrice != oldPrice) {
individualPrices[tokenID] = newPrice;
emit NewIndividualPrice(tokenID, oldPrice, newPrice);
}
}
}
文件 24 的 25:TokenAuction.sol
pragma solidity ^0.5.16;
import "./MtrollerInterface.sol";
import "./MTokenInterfaces.sol";
import "./MTokenStorage.sol";
import "./ErrorReporter.sol";
import "./compound/Exponential.sol";
import "./open-zeppelin/token/ERC721/IERC721.sol";
contract TokenAuction is Exponential, TokenErrorReporter {
event NewAuctionOffer(uint240 tokenID, address offeror, uint256 totalOfferAmount);
event AuctionOfferCancelled(uint240 tokenID, address offeror, uint256 cancelledOfferAmount);
event HighestOfferAccepted(uint240 tokenID, address offeror, uint256 acceptedOfferAmount, uint256 auctioneerTokens, uint256 oldOwnerTokens);
event AuctionRefund(address beneficiary, uint256 amount);
struct Bidding {
mapping (address => uint256) offers;
mapping (address => uint256) offerIndex;
uint256 nextOffer;
mapping (uint256 => mapping (uint256 => address)) maxOfferor;
}
bool internal _notEntered;
MEtherUserInterface public paymentToken;
MtrollerUserInterface public mtroller;
mapping (uint240 => Bidding) public biddings;
mapping (address => uint256) public refunds;
constructor(MtrollerUserInterface _mtroller, MEtherUserInterface _mEtherPaymentToken) public
{
mtroller = _mtroller;
paymentToken = _mEtherPaymentToken;
_notEntered = true;
}
function addOfferETH(
uint240 _mToken,
address _bidder,
address payable _oldOwner,
bool _directSale
)
external
nonReentrant
payable
returns (uint256)
{
require (msg.value > 0, "No payment sent");
( , , address _tokenAddress) = mtroller.parseToken(_mToken);
require(msg.sender == _tokenAddress, "Only token contract");
uint256 _oldOffer = biddings[_mToken].offers[_bidder];
uint256 _newOffer = _oldOffer + msg.value;
uint240 _anchorToken = mtroller.getAnchorToken(_tokenAddress);
if (_mToken == _anchorToken) {
mtroller.collateralFactorMantissa(_mToken);
}
else {
require(mtroller.auctionAllowed(_mToken, _bidder) == uint(Error.NO_ERROR), "Auction not allowed");
if (_directSale) {
if (_oldOffer > 0) {
require(cancelOfferInternal(_mToken, _bidder) == _oldOffer, "Could not cancel offer");
}
( , uint256 oldOwnerTokens) = processPaymentInternal(_oldOwner, _newOffer, _oldOwner, 0);
redeemFromAndTransfer(_mToken, _tokenAddress, _bidder);
emit HighestOfferAccepted(_mToken, _bidder, _newOffer, 0, oldOwnerTokens);
return _newOffer;
}
}
if (_oldOffer == 0) {
uint256 _nextIndex = biddings[_mToken].nextOffer;
biddings[_mToken].offerIndex[_bidder] = _nextIndex;
biddings[_mToken].nextOffer = _nextIndex + 1;
}
_updateOffer(_mToken, biddings[_mToken].offerIndex[_bidder], _bidder, _newOffer);
emit NewAuctionOffer(_mToken, _bidder, _newOffer);
return 0;
}
function cancelOffer(
uint240 _mToken
)
public
nonReentrant
{
uint256 _oldOffer = cancelOfferInternal(_mToken, msg.sender);
refunds[msg.sender] += _oldOffer;
emit AuctionOfferCancelled(_mToken, msg.sender, _oldOffer);
}
function acceptHighestOffer(
uint240 _mToken,
address payable _oldOwner,
address payable _auctioneer,
uint256 _auctioneerFeeMantissa,
uint256 _minimumPrice,
address _favoriteBidder
)
external
nonReentrant
returns (address _maxOfferor, uint256 _maxOffer, uint256 auctioneerTokens, uint256 oldOwnerTokens)
{
require(mtroller.auctionAllowed(_mToken, _auctioneer) == uint(Error.NO_ERROR), "Auction not allowed");
( , , address _tokenAddress) = mtroller.parseToken(_mToken);
require(msg.sender == _tokenAddress, "Only token contract");
if (_favoriteBidder == address(0)) {
uint256 _maxAllOffers = getMaxOffer(_mToken);
require(_maxAllOffers > 0, "No valid offer found");
uint240 _anchorToken = mtroller.getAnchorToken(_tokenAddress);
if (_maxAllOffers > getMaxOffer(_anchorToken)) {
_maxOfferor = getMaxOfferor(_mToken);
_maxOffer = cancelOfferInternal(_mToken, _maxOfferor);
}
else {
_maxOfferor = getMaxOfferor(_anchorToken);
_maxOffer = cancelOfferInternal(_anchorToken, _maxOfferor);
}
}
else {
_maxOfferor = _favoriteBidder;
uint240 _anchorToken = mtroller.getAnchorToken(_tokenAddress);
if (getOffer(_anchorToken, _maxOfferor) > getOffer(_mToken, _maxOfferor))
{
_maxOffer = cancelOfferInternal(_anchorToken, _maxOfferor);
}
else {
_maxOffer = cancelOfferInternal(_mToken, _maxOfferor);
}
}
require(_maxOffer >= _minimumPrice, "Best offer too low");
(auctioneerTokens, oldOwnerTokens) = processPaymentInternal(_oldOwner, _maxOffer, _auctioneer, _auctioneerFeeMantissa);
redeemFromAndTransfer(_mToken, _tokenAddress, _maxOfferor);
emit HighestOfferAccepted(_mToken, _maxOfferor, _maxOffer, auctioneerTokens, oldOwnerTokens);
return (_maxOfferor, _maxOffer, auctioneerTokens, oldOwnerTokens);
}
function redeemFromAndTransfer(uint240 _mToken, address _tokenAddress, address _beneficiary) internal {
MERC721Interface _mTokenContract = MERC721Interface(_tokenAddress);
MTokenV1Storage _mTokenStorage = MTokenV1Storage(_tokenAddress);
uint256 _underlyingID = _mTokenStorage.underlyingIDs(_mToken);
_mTokenContract.safeTransferFrom(_mTokenContract.ownerOf(_mToken), address(this), _mToken);
require(_mTokenContract.redeem(_mToken) == uint(Error.NO_ERROR), "Redeem failed");
IERC721(_mTokenStorage.underlyingContract()).safeTransferFrom(address(this), _beneficiary, _underlyingID);
require(IERC721(_mTokenStorage.underlyingContract()).ownerOf(_underlyingID) == _beneficiary, "Transfer failed");
}
function payOut(address payable beneficiary, uint256 amount) internal returns (uint256 mintedMTokens) {
uint240 mToken = MTokenV1Storage(address(paymentToken)).thisFungibleMToken();
uint err = paymentToken.accrueInterest(mToken);
if (err != uint(Error.NO_ERROR)) {
mintedMTokens = paymentToken.mintTo.value(amount)(beneficiary);
return mintedMTokens;
}
uint256 borrowBalance = paymentToken.borrowBalanceStored(beneficiary, mToken);
if (borrowBalance > amount) {
borrowBalance = amount;
}
if (borrowBalance > 0) {
require(paymentToken.repayBorrowBehalf.value(borrowBalance)(beneficiary) == borrowBalance, "Borrow repayment failed");
}
if (amount > borrowBalance) {
uint256 shortfall;
(err, , shortfall) = MtrollerInterface(MTokenV1Storage(address(paymentToken)).mtroller()).getAccountLiquidity(beneficiary);
if (err == uint(Error.NO_ERROR) && shortfall == 0) {
(bool success, ) = beneficiary.call.value(amount - borrowBalance)("");
require(success, "ETH Transfer failed");
mintedMTokens = 0;
}
else {
mintedMTokens = paymentToken.mintTo.value(amount - borrowBalance)(beneficiary);
}
}
}
function processPaymentInternal(
address payable _oldOwner,
uint256 _price,
address payable _broker,
uint256 _brokerFeeMantissa
)
internal
returns (uint256 brokerTokens, uint256 oldOwnerTokens)
{
require(_oldOwner != address(0), "Invalid owner address");
require(_price > 0, "Invalid price");
uint256 _amountLeft = _price;
Exp memory _feeShare = Exp({mantissa: paymentToken.getProtocolAuctionFeeMantissa()});
(MathError _mathErr, uint256 _fee) = mulScalarTruncate(_feeShare, _price);
require(_mathErr == MathError.NO_ERROR, "Invalid protocol fee");
if (_fee > 0) {
(_mathErr, _amountLeft) = subUInt(_price, _fee);
require(_mathErr == MathError.NO_ERROR, "Invalid protocol fee");
paymentToken._addReserves.value(_fee)();
}
_feeShare = Exp({mantissa: _brokerFeeMantissa});
(_mathErr, _fee) = mulScalarTruncate(_feeShare, _price);
require(_mathErr == MathError.NO_ERROR, "Invalid broker fee");
if (_fee > 0) {
require(_broker != address(0), "Invalid broker address");
(_mathErr, _amountLeft) = subUInt(_amountLeft, _fee);
require(_mathErr == MathError.NO_ERROR, "Invalid broker fee");
brokerTokens = payOut(_broker, _fee);
}
if (_amountLeft > 0) {
oldOwnerTokens = payOut(_oldOwner, _amountLeft);
}
}
function cancelOfferInternal(
uint240 _mToken,
address _offeror
)
internal
returns (uint256 _oldOffer)
{
_oldOffer = biddings[_mToken].offers[_offeror];
require (_oldOffer > 0, "No active offer found");
uint256 _thisIndex = biddings[_mToken].offerIndex[_offeror];
uint256 _nextIndex = biddings[_mToken].nextOffer;
assert (_nextIndex > 0);
_nextIndex--;
if (_thisIndex != _nextIndex) {
address _swappedOfferor = biddings[_mToken].maxOfferor[0][_nextIndex];
biddings[_mToken].offerIndex[_swappedOfferor] = _thisIndex;
uint256 _newOffer = biddings[_mToken].offers[_swappedOfferor];
_updateOffer(_mToken, _thisIndex, _swappedOfferor, _newOffer);
}
_updateOffer(_mToken, _nextIndex, address(0), 0);
delete biddings[_mToken].offers[_offeror];
delete biddings[_mToken].offerIndex[_offeror];
biddings[_mToken].nextOffer = _nextIndex;
return _oldOffer;
}
function withdrawAuctionRefund()
public
nonReentrant
{
require(refunds[msg.sender] > 0, "No outstanding refunds found");
uint256 _refundAmount = refunds[msg.sender];
refunds[msg.sender] = 0;
msg.sender.transfer(_refundAmount);
emit AuctionRefund(msg.sender, _refundAmount);
}
function cancelOfferAndWithdrawRefund(
uint240 _mToken
)
external
{
cancelOffer(_mToken);
withdrawAuctionRefund();
}
uint256 constant private clusterSize = (2**4);
function _updateOffer(
uint240 _mToken,
uint256 _offerIndex,
address _newOfferor,
uint256 _newOffer
)
internal
{
assert (biddings[_mToken].nextOffer > 0);
assert (biddings[_mToken].offers[address(0)] == 0);
uint256 _n = 0;
address _origOfferor = _newOfferor;
uint256 _origOffer = biddings[_mToken].offers[_newOfferor];
if (_newOffer != _origOffer) {
biddings[_mToken].offers[_newOfferor] = _newOffer;
}
for (uint256 tmp = biddings[_mToken].nextOffer * clusterSize; tmp > 0; tmp = tmp / clusterSize) {
uint256 _oldOffer;
address _oldOfferor = biddings[_mToken].maxOfferor[_n][_offerIndex];
if (_oldOfferor != _newOfferor) {
biddings[_mToken].maxOfferor[_n][_offerIndex] = _newOfferor;
}
_offerIndex = _offerIndex / clusterSize;
address _maxOfferor = biddings[_mToken].maxOfferor[_n + 1][_offerIndex];
if (tmp < clusterSize) {
if (_maxOfferor != address(0)) {
biddings[_mToken].maxOfferor[_n + 1][_offerIndex] = address(0);
}
return;
}
if (_maxOfferor != address(0)) {
if (_oldOfferor == _origOfferor) {
_oldOffer = _origOffer;
}
else {
_oldOffer = biddings[_mToken].offers[_oldOfferor];
}
if ((_oldOfferor != _maxOfferor) && (_newOffer <= _oldOffer)) {
return;
}
if ((_oldOfferor == _maxOfferor) && (_newOffer > _oldOffer)) {
_n++;
continue;
}
}
uint256 _i = _offerIndex * clusterSize;
_newOfferor = biddings[_mToken].maxOfferor[_n][_i];
_newOffer = biddings[_mToken].offers[_newOfferor];
_i++;
while ((_i % clusterSize) != 0) {
address _tmpOfferor = biddings[_mToken].maxOfferor[_n][_i];
if (biddings[_mToken].offers[_tmpOfferor] > _newOffer) {
_newOfferor = _tmpOfferor;
_newOffer = biddings[_mToken].offers[_tmpOfferor];
}
_i++;
}
_n++;
}
}
function getMaxOffer(
uint240 _mToken
)
public
view
returns (uint256)
{
uint256 _maxCollectionOffer = 0;
( , , address _tokenAddress) = mtroller.parseToken(_mToken);
uint240 _anchorToken = mtroller.getAnchorToken(_tokenAddress);
if (_mToken != _anchorToken && biddings[_anchorToken].nextOffer != 0) {
_maxCollectionOffer = biddings[_anchorToken].offers[getMaxOfferor(_anchorToken)];
}
if (biddings[_mToken].nextOffer == 0) {
return _maxCollectionOffer;
}
uint256 _maxSpecificOffer = biddings[_mToken].offers[getMaxOfferor(_mToken)];
return (_maxCollectionOffer > _maxSpecificOffer ? _maxCollectionOffer : _maxSpecificOffer);
}
function getMaxOfferor(
uint240 _mToken
)
public
view
returns (address)
{
uint256 _n = 0;
for (uint256 tmp = biddings[_mToken].nextOffer * clusterSize; tmp > 0; tmp = tmp / clusterSize) {
_n++;
}
require (_n > 0, "No valid offer found");
_n--;
return biddings[_mToken].maxOfferor[_n][0];
}
function getMaxOfferor(
uint240 _mToken,
uint256 _level,
uint256 _offset
)
public
view
returns (address[10] memory _offerors)
{
for (uint256 _i = 0; _i < 10; _i++) {
_offerors[_i] = biddings[_mToken].maxOfferor[_level][_offset + _i];
}
return _offerors;
}
function getOffer(
uint240 _mToken,
address _account
)
public
view
returns (uint256)
{
return biddings[_mToken].offers[_account];
}
function getOfferIndex(
uint240 _mToken
)
public
view
returns (uint256)
{
require (biddings[_mToken].offers[msg.sender] > 0, "No active offer");
return biddings[_mToken].offerIndex[msg.sender];
}
function getCurrentOfferCount(
uint240 _mToken
)
external
view
returns (uint256)
{
return(biddings[_mToken].nextOffer);
}
function getOfferAtIndex(
uint240 _mToken,
uint256 _offerIndex
)
external
view
returns (address offeror, uint256 offer)
{
require(biddings[_mToken].nextOffer > 0, "No valid offer");
require(_offerIndex < biddings[_mToken].nextOffer, "Offer index out of range");
offeror = biddings[_mToken].maxOfferor[0][_offerIndex];
offer = biddings[_mToken].offers[offeror];
}
function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data) public view returns (bytes4) {
from;
tokenId;
data;
if (operator == address(this)) {
return this.onERC721Received.selector;
}
else if (MERC721Interface(operator).getTokenType() == MTokenIdentifier.MTokenType.ERC721_MTOKEN) {
return this.onERC721Received.selector;
}
else {
revert("Cannot accept token");
}
}
function _sweepERC721(address _tokenContract, uint256 _tokenID) external nonReentrant {
require(msg.sender == mtroller.getAdmin(), "Only mtroller admin can do that");
IERC721(_tokenContract).safeTransferFrom(address(this), msg.sender, _tokenID);
}
modifier nonReentrant() {
require(_notEntered, "Reentrance not allowed");
_notEntered = false;
_;
_notEntered = true;
}
}
文件 25 的 25:ZSafeMath.sol
pragma solidity ^0.5.0;
library ZSafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
return c;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
{
"compilationTarget": {
"project:/contracts/MDelegator.sol": "MERC721Token"
},
"evmVersion": "istanbul",
"libraries": {},
"optimizer": {
"enabled": true,
"runs": 500
},
"remappings": []
}
[{"inputs":[{"internalType":"contract MERC721UserInterface","name":"userImpl","type":"address"},{"internalType":"contract MERC721AdminInterface","name":"adminImpl","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":false,"inputs":[],"name":"_disableFurtherImplementationUpdates","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"},{"internalType":"bool","name":"supported","type":"bool"}],"name":"_setAdminSelectorSupported","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_newUserImplementation","type":"address"},{"internalType":"address","name":"_newAdminImplementation","type":"address"}],"name":"_setImplementation","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_newAdmin","type":"address"}],"name":"_setMDelegatorAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"mDelegatorAdmin","outputs":[{"internalType":"address","name":"admin","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"mDelegatorAdminImplementation","outputs":[{"internalType":"address","name":"implementation","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"mDelegatorAdminImplementationSelectorSupported","outputs":[{"internalType":"bool","name":"supported","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"mDelegatorImplementationUpdateEnabled","outputs":[{"internalType":"bool","name":"enabled","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"mDelegatorUserImplementation","outputs":[{"internalType":"address","name":"implementation","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}]