文件 1 的 8:Address.sol
pragma solidity ^0.7.5;
library Address {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly { size := extcodesize(account) }
return size > 0;
}
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");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return _functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{ value: weiValue }(data);
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
function addressToString(address _address) internal pure returns(string memory) {
bytes32 _bytes = bytes32(uint256(_address));
bytes memory HEX = "0123456789abcdef";
bytes memory _addr = new bytes(42);
_addr[0] = '0';
_addr[1] = 'x';
for(uint256 i = 0; i < 20; i++) {
_addr[2+i*2] = HEX[uint8(_bytes[i + 12] >> 4)];
_addr[3+i*2] = HEX[uint8(_bytes[i + 12] & 0x0f)];
}
return string(_addr);
}
}
文件 2 的 8:FixedPoint.sol
pragma solidity ^0.7.5;
import "./FullMath.sol";
library Babylonian {
function sqrt(uint256 x) internal pure returns (uint256) {
if (x == 0) return 0;
uint256 xx = x;
uint256 r = 1;
if (xx >= 0x100000000000000000000000000000000) {
xx >>= 128;
r <<= 64;
}
if (xx >= 0x10000000000000000) {
xx >>= 64;
r <<= 32;
}
if (xx >= 0x100000000) {
xx >>= 32;
r <<= 16;
}
if (xx >= 0x10000) {
xx >>= 16;
r <<= 8;
}
if (xx >= 0x100) {
xx >>= 8;
r <<= 4;
}
if (xx >= 0x10) {
xx >>= 4;
r <<= 2;
}
if (xx >= 0x8) {
r <<= 1;
}
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
uint256 r1 = x / r;
return (r < r1 ? r : r1);
}
}
library BitMath {
function mostSignificantBit(uint256 x) internal pure returns (uint8 r) {
require(x > 0, 'BitMath::mostSignificantBit: zero');
if (x >= 0x100000000000000000000000000000000) {
x >>= 128;
r += 128;
}
if (x >= 0x10000000000000000) {
x >>= 64;
r += 64;
}
if (x >= 0x100000000) {
x >>= 32;
r += 32;
}
if (x >= 0x10000) {
x >>= 16;
r += 16;
}
if (x >= 0x100) {
x >>= 8;
r += 8;
}
if (x >= 0x10) {
x >>= 4;
r += 4;
}
if (x >= 0x4) {
x >>= 2;
r += 2;
}
if (x >= 0x2) r += 1;
}
}
library FixedPoint {
struct uq112x112 {
uint224 _x;
}
struct uq144x112 {
uint256 _x;
}
uint8 private constant RESOLUTION = 112;
uint256 private constant Q112 = 0x10000000000000000000000000000;
uint256 private constant Q224 = 0x100000000000000000000000000000000000000000000000000000000;
uint256 private constant LOWER_MASK = 0xffffffffffffffffffffffffffff;
function decode(uq112x112 memory self) internal pure returns (uint112) {
return uint112(self._x >> RESOLUTION);
}
function decode112with18(uq112x112 memory self) internal pure returns (uint) {
return uint(self._x) / 5192296858534827;
}
function fraction(uint256 numerator, uint256 denominator) internal pure returns (uq112x112 memory) {
require(denominator > 0, 'FixedPoint::fraction: division by zero');
if (numerator == 0) return FixedPoint.uq112x112(0);
if (numerator <= uint144(-1)) {
uint256 result = (numerator << RESOLUTION) / denominator;
require(result <= uint224(-1), 'FixedPoint::fraction: overflow');
return uq112x112(uint224(result));
} else {
uint256 result = FullMath.mulDiv(numerator, Q112, denominator);
require(result <= uint224(-1), 'FixedPoint::fraction: overflow');
return uq112x112(uint224(result));
}
}
function sqrt(uq112x112 memory self) internal pure returns (uq112x112 memory) {
if (self._x <= uint144(-1)) {
return uq112x112(uint224(Babylonian.sqrt(uint256(self._x) << 112)));
}
uint8 safeShiftBits = 255 - BitMath.mostSignificantBit(self._x);
safeShiftBits -= safeShiftBits % 2;
return uq112x112(uint224(Babylonian.sqrt(uint256(self._x) << safeShiftBits) << ((112 - safeShiftBits) / 2)));
}
}
文件 3 的 8:FullMath.sol
pragma solidity ^0.7.5;
library FullMath {
function fullMul(uint256 x, uint256 y) private pure returns (uint256 l, uint256 h) {
uint256 mm = mulmod(x, y, uint256(-1));
l = x * y;
h = mm - l;
if (mm < l) h -= 1;
}
function fullDiv(
uint256 l,
uint256 h,
uint256 d
) private pure returns (uint256) {
uint256 pow2 = d & -d;
d /= pow2;
l /= pow2;
l += h * ((-pow2) / pow2 + 1);
uint256 r = 1;
r *= 2 - d * r;
r *= 2 - d * r;
r *= 2 - d * r;
r *= 2 - d * r;
r *= 2 - d * r;
r *= 2 - d * r;
r *= 2 - d * r;
r *= 2 - d * r;
return l * r;
}
function mulDiv(
uint256 x,
uint256 y,
uint256 d
) internal pure returns (uint256) {
(uint256 l, uint256 h) = fullMul(x, y);
uint256 mm = mulmod(x, y, d);
if (mm > l) h -= 1;
l -= mm;
if (h == 0) return l / d;
require(h < d, 'FullMath: FULLDIV_OVERFLOW');
return fullDiv(l, h, d);
}
}
文件 4 的 8:IERC20.sol
pragma solidity >=0.7.5;
interface IERC20 {
function decimals() external view returns (uint8);
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);
}
文件 5 的 8:ITreasury.sol
pragma solidity >=0.7.5;
interface ITreasury {
function mint(address _to, uint256 _amount) external;
function valueOfToken( address _token, uint _amount ) external view returns ( uint value_ );
function VEC() external view returns (address);
function vETH() external view returns (address);
function LP() external view returns (address);
function excessReserves() external view returns (uint256);
function RESERVE_BACKING() external view returns (uint256);
}
文件 6 的 8:SafeERC20.sol
pragma solidity >=0.7.5;
import {IERC20} from "../interface/IERC20.sol";
library SafeERC20 {
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 amount
) internal {
(bool success, bytes memory data) = address(token).call(
abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, amount)
);
require(success && (data.length == 0 || abi.decode(data, (bool))), "TRANSFER_FROM_FAILED");
}
function safeTransfer(
IERC20 token,
address to,
uint256 amount
) internal {
(bool success, bytes memory data) = address(token).call(
abi.encodeWithSelector(IERC20.transfer.selector, to, amount)
);
require(success && (data.length == 0 || abi.decode(data, (bool))), "TRANSFER_FAILED");
}
function safeApprove(
IERC20 token,
address to,
uint256 amount
) internal {
(bool success, bytes memory data) = address(token).call(
abi.encodeWithSelector(IERC20.approve.selector, to, amount)
);
require(success && (data.length == 0 || abi.decode(data, (bool))), "APPROVE_FAILED");
}
function safeTransferETH(address to, uint256 amount) internal {
(bool success, ) = to.call{value: amount}(new bytes(0));
require(success, "ETH_TRANSFER_FAILED");
}
}
文件 7 的 8:SafeMath.sol
pragma solidity ^0.7.5;
library SafeMath {
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;
assert(a == b * c + a % b);
return c;
}
function sqrrt(uint256 a) internal pure returns (uint c) {
if (a > 3) {
c = a;
uint b = add( div( a, 2), 1 );
while (b < c) {
c = b;
b = div( add( div( a, b ), b), 2 );
}
} else if (a != 0) {
c = 1;
}
}
}
文件 8 的 8:VectorBonding.sol
import "../libraries/SafeMath.sol";
import "../libraries/FixedPoint.sol";
import "../libraries/Address.sol";
import "../libraries/SafeERC20.sol";
import "../interface/ITreasury.sol";
interface IUniswapV2Router02 {
function addLiquidity(
address tokenA,
address tokenB,
uint256 amountADesired,
uint256 amountBDesired,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline
) external returns (uint256 amountA, uint256 amountB, uint256 liquidity);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external;
function WETH() external pure returns (address);
}
interface IvETH {
function deposit(
address _restakedLST,
address _to,
uint256 _amount
) external;
}
pragma solidity 0.7.5;
contract VectorBonding {
using FixedPoint for *;
using SafeERC20 for IERC20;
using SafeMath for uint256;
enum PARAMETER {
VESTING,
PAYOUT,
DEBT
}
enum BondType {
TAKEINPRINCIPAL,
WETHTOVETH,
WETHTOLP
}
modifier onlyOwner() {
require(owner == msg.sender, "Ownable: caller is not the owner");
_;
}
event BondCreated(uint256 deposit, uint256 payout, uint256 expires);
event BondRedeemed(address recipient, uint256 payout, uint256 remaining);
event BondPriceChanged(uint256 internalPrice, uint256 debtRatio);
event ControlVariableAdjustment(
uint256 initialBCV,
uint256 newBCV,
uint256 adjustment,
bool addition
);
uint256 public constant FEE_DENOM = 1_000_000;
address public owner;
IERC20 public immutable VEC;
IERC20 public immutable principalToken;
ITreasury public immutable treasury;
IUniswapV2Router02 public immutable uniswapV2Router;
address public LP;
address public feeTo;
address public immutable vETH;
uint256 public feePercent;
uint256 public totalPrincipalBonded;
uint256 public totalPayoutGiven;
uint256 public totalDebt;
uint256 public lastDecay;
Terms public terms;
Adjust public adjustment;
bool public immutable feeInVEC;
BondType public bondType;
mapping(address => Bond) public bondInfo;
struct Terms {
uint256 controlVariable;
uint256 vestingTerm;
uint256 minimumPrice;
uint256 maxPayout;
uint256 maxDebt;
}
struct Bond {
uint256 payout;
uint256 vesting;
uint256 lastBlockTimestamp;
uint256 truePricePaid;
}
struct Adjust {
bool add;
uint256 rate;
uint256 target;
uint256 buffer;
uint256 lastBlockTimestamp;
}
constructor(
address _treasury,
address _vETH,
address _principalToken,
bool _feeInVEC
) {
treasury = ITreasury(_treasury);
VEC = IERC20(ITreasury(_treasury).VEC());
principalToken = IERC20(_principalToken);
owner = msg.sender;
feeInVEC = _feeInVEC;
vETH = _vETH;
IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(
0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
);
uniswapV2Router = _uniswapV2Router;
}
function initializeBond(
uint256 _controlVariable,
uint256 _vestingTerm,
uint256 _minimumPrice,
uint256 _maxPayout,
uint256 _maxDebt,
uint256 _initialDebt,
BondType _bondType
) external onlyOwner {
require(currentDebt() == 0, "Debt must be 0 for initialization");
bondType = _bondType;
if (_bondType == BondType.WETHTOVETH) {
require(address(principalToken) == uniswapV2Router.WETH(), "Principal must be WETH");
principalToken.approve(vETH, type(uint256).max);
} else if (_bondType == BondType.WETHTOLP) {
require(address(principalToken) == uniswapV2Router.WETH(), "Principal must be WETH");
LP = treasury.LP();
principalToken.approve(address(uniswapV2Router), type(uint256).max);
VEC.approve(address(uniswapV2Router), type(uint256).max);
}
terms = Terms({
controlVariable: _controlVariable,
vestingTerm: _vestingTerm,
minimumPrice: _minimumPrice,
maxPayout: _maxPayout,
maxDebt: _maxDebt
});
totalDebt = _initialDebt;
lastDecay = block.timestamp;
}
function withdrawStuckToken(
address _token,
address _to,
uint256 _amount
) external onlyOwner {
require(_token != address(0), "_token address cannot be 0");
require(_token != address(VEC), "Can not withdraw VEC");
IERC20(_token).safeTransfer(_to, _amount);
}
function setFeeAndFeeTo(
address _feeTo,
uint256 _feePercent
) external onlyOwner {
require(_feePercent <= FEE_DENOM, "Fee > FEE_DENOM");
feeTo = _feeTo;
feePercent = _feePercent;
}
function transferOwnership(address newOwner) external onlyOwner {
require(
newOwner != address(0),
"Ownable: new owner is the zero address"
);
owner = newOwner;
}
function setBondTerms(
PARAMETER _parameter,
uint256 _input
) external onlyOwner {
if (_parameter == PARAMETER.VESTING) {
require(_input >= 129600, "Vesting must be longer than 36 hours");
terms.vestingTerm = _input;
} else if (_parameter == PARAMETER.PAYOUT) {
require(_input <= 100000, "Cannot be greater than 100% of supply");
terms.maxPayout = _input;
} else if (_parameter == PARAMETER.DEBT) {
terms.maxDebt = _input;
}
}
function setAdjustment(
bool _addition,
uint256 _increment,
uint256 _target,
uint256 _buffer
) external onlyOwner {
require(
_increment <= terms.controlVariable.mul(30).div(1000),
"Increment too large"
);
adjustment = Adjust({
add: _addition,
rate: _increment,
target: _target,
buffer: _buffer,
lastBlockTimestamp: block.timestamp
});
}
function deposit(
uint256 _amount,
uint256 _maxPrice
) external returns (uint256) {
require(
IERC20(principalToken).balanceOf(msg.sender) >= _amount,
"Balance too low"
);
decayDebt();
uint256 nativePrice = bondPrice();
require(
_maxPrice >= nativePrice,
"Slippage limit: more than max price"
);
uint256 value;
uint256 payout;
uint256 fee;
(payout, fee, value) = payoutFor(_amount);
if (!feeInVEC) _amount = _amount.sub(fee);
require(payout >= 10 ** VEC.decimals() / 100, "Bond too small");
require(payout <= maxPayout(), "Bond too large");
totalDebt = totalDebt.add(value);
require(totalDebt <= terms.maxDebt, "Max capacity reached");
bondInfo[msg.sender] = Bond({
payout: bondInfo[msg.sender].payout.add(payout),
vesting: terms.vestingTerm,
lastBlockTimestamp: block.timestamp,
truePricePaid: bondPrice()
});
totalPrincipalBonded = totalPrincipalBonded.add(_amount);
totalPayoutGiven = totalPayoutGiven.add(payout);
treasury.mint(address(this), payout);
if (bondType == BondType.TAKEINPRINCIPAL) {
principalToken.safeTransferFrom(
msg.sender,
address(treasury),
_amount
);
} else if (bondType == BondType.WETHTOVETH) {
principalToken.safeTransferFrom(msg.sender, address(this), _amount);
IvETH(vETH).deposit(address(principalToken), address(treasury), _amount);
} else {
principalToken.safeTransferFrom(msg.sender, address(this), _amount);
uint256 vecBefore = VEC.balanceOf(address(this));
swapETHForTokens(_amount / 2);
addLiquidity(
VEC.balanceOf(address(this)) - vecBefore,
principalToken.balanceOf(address(this))
);
}
if (fee != 0) {
if (feeInVEC) {
treasury.mint(feeTo, fee);
} else {
principalToken.safeTransferFrom(msg.sender, feeTo, fee);
}
}
emit BondCreated(
_amount,
payout,
block.timestamp.add(terms.vestingTerm)
);
emit BondPriceChanged(_bondPrice(), debtRatio());
adjust();
return payout;
}
function redeem(address _depositor) external returns (uint256) {
Bond memory info = bondInfo[_depositor];
uint256 percentVested = percentVestedFor(_depositor);
if (percentVested >= 10000) {
delete bondInfo[_depositor];
emit BondRedeemed(_depositor, info.payout, 0);
VEC.safeTransfer(_depositor, info.payout);
return info.payout;
} else {
uint256 payout = info.payout.mul(percentVested).div(10000);
bondInfo[_depositor] = Bond({
payout: info.payout.sub(payout),
vesting: info.vesting.sub(
block.timestamp.sub(info.lastBlockTimestamp)
),
lastBlockTimestamp: block.timestamp,
truePricePaid: info.truePricePaid
});
emit BondRedeemed(_depositor, payout, bondInfo[_depositor].payout);
VEC.safeTransfer(_depositor, payout);
return payout;
}
}
function swapETHForTokens(uint256 ethAmount) internal {
address[] memory path = new address[](2);
path[0] = uniswapV2Router.WETH();
path[1] = address(VEC);
uniswapV2Router.swapExactTokensForTokensSupportingFeeOnTransferTokens(
ethAmount,
0,
path,
address(this),
block.timestamp
);
}
function addLiquidity(uint256 tokenAmount, uint256 ethAmount) internal {
uniswapV2Router.addLiquidity(
address(VEC),
address(principalToken),
tokenAmount,
ethAmount,
0,
0,
address(treasury),
block.timestamp
);
}
function adjust() internal {
uint256 timestampCanAdjust = adjustment.lastBlockTimestamp.add(
adjustment.buffer
);
if (adjustment.rate != 0 && block.timestamp >= timestampCanAdjust) {
uint256 initial = terms.controlVariable;
if (adjustment.add) {
terms.controlVariable = terms.controlVariable.add(
adjustment.rate
);
if (terms.controlVariable >= adjustment.target) {
adjustment.rate = 0;
}
} else {
terms.controlVariable = terms.controlVariable.sub(
adjustment.rate
);
if (terms.controlVariable <= adjustment.target) {
adjustment.rate = 0;
}
}
adjustment.lastBlockTimestamp = block.timestamp;
emit ControlVariableAdjustment(
initial,
terms.controlVariable,
adjustment.rate,
adjustment.add
);
}
}
function decayDebt() internal {
totalDebt = totalDebt.sub(debtDecay());
lastDecay = block.timestamp;
}
function _bondPrice() internal returns (uint256 price_) {
price_ = terms.controlVariable.mul(debtRatio()).div(1e2);
if (price_ < terms.minimumPrice) {
price_ = terms.minimumPrice;
} else if (terms.minimumPrice != 0) {
terms.minimumPrice = 0;
}
}
function bondPrice() public view returns (uint256 price_) {
price_ = terms.controlVariable.mul(debtRatio()).div(1e2);
if (price_ < terms.minimumPrice) {
price_ = terms.minimumPrice;
}
}
function maxPayout() public view returns (uint256) {
return VEC.totalSupply().mul(terms.maxPayout).div(100000);
}
function payoutFor(
uint256 _amount
) public view returns (uint256 _payout, uint256 _fee, uint256 _value) {
if (!feeInVEC) {
_fee = _amount.mul(feePercent).div(FEE_DENOM);
_value = treasury.valueOfToken(
address(principalToken),
_amount.sub(_fee)
);
_payout = FixedPoint
.fraction(_value, bondPrice())
.decode112with18();
} else {
_value = treasury.valueOfToken(address(principalToken), _amount);
uint256 total = FixedPoint
.fraction(_value, bondPrice())
.decode112with18();
_payout = total;
_fee = total.mul(feePercent).div(FEE_DENOM);
}
}
function debtRatio() public view returns (uint256 debtRatio_) {
debtRatio_ = FixedPoint
.fraction(
currentDebt().mul(10 ** VEC.decimals()),
VEC.totalSupply()
)
.decode112with18()
.div(1e9);
}
function currentDebt() public view returns (uint256) {
return totalDebt.sub(debtDecay());
}
function debtDecay() public view returns (uint256 decay_) {
uint256 timestampSinceLast = block.timestamp.sub(lastDecay);
decay_ = totalDebt.mul(timestampSinceLast).div(terms.vestingTerm);
if (decay_ > totalDebt) {
decay_ = totalDebt;
}
}
function percentVestedFor(
address _depositor
) public view returns (uint256 percentVested_) {
Bond memory bond = bondInfo[_depositor];
uint256 timestampSinceLast = block.timestamp.sub(
bond.lastBlockTimestamp
);
uint256 vesting = bond.vesting;
if (vesting > 0) {
percentVested_ = timestampSinceLast.mul(10000).div(vesting);
} else {
percentVested_ = 0;
}
}
function pendingPayoutFor(
address _depositor
) external view returns (uint256 pendingPayout_) {
uint256 percentVested = percentVestedFor(_depositor);
uint256 payout = bondInfo[_depositor].payout;
if (percentVested >= 10000) {
pendingPayout_ = payout;
} else {
pendingPayout_ = payout.mul(percentVested).div(10000);
}
}
}
{
"compilationTarget": {
"contracts/bonds/VectorBonding.sol": "VectorBonding"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 1000
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_treasury","type":"address"},{"internalType":"address","name":"_vETH","type":"address"},{"internalType":"address","name":"_principalToken","type":"address"},{"internalType":"bool","name":"_feeInVEC","type":"bool"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"deposit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"payout","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"expires","type":"uint256"}],"name":"BondCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"internalPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"debtRatio","type":"uint256"}],"name":"BondPriceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"payout","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"remaining","type":"uint256"}],"name":"BondRedeemed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"initialBCV","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBCV","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"adjustment","type":"uint256"},{"indexed":false,"internalType":"bool","name":"addition","type":"bool"}],"name":"ControlVariableAdjustment","type":"event"},{"inputs":[],"name":"FEE_DENOM","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LP","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VEC","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"adjustment","outputs":[{"internalType":"bool","name":"add","type":"bool"},{"internalType":"uint256","name":"rate","type":"uint256"},{"internalType":"uint256","name":"target","type":"uint256"},{"internalType":"uint256","name":"buffer","type":"uint256"},{"internalType":"uint256","name":"lastBlockTimestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"bondInfo","outputs":[{"internalType":"uint256","name":"payout","type":"uint256"},{"internalType":"uint256","name":"vesting","type":"uint256"},{"internalType":"uint256","name":"lastBlockTimestamp","type":"uint256"},{"internalType":"uint256","name":"truePricePaid","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bondPrice","outputs":[{"internalType":"uint256","name":"price_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bondType","outputs":[{"internalType":"enum VectorBonding.BondType","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"debtDecay","outputs":[{"internalType":"uint256","name":"decay_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"debtRatio","outputs":[{"internalType":"uint256","name":"debtRatio_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_maxPrice","type":"uint256"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeInVEC","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeTo","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_controlVariable","type":"uint256"},{"internalType":"uint256","name":"_vestingTerm","type":"uint256"},{"internalType":"uint256","name":"_minimumPrice","type":"uint256"},{"internalType":"uint256","name":"_maxPayout","type":"uint256"},{"internalType":"uint256","name":"_maxDebt","type":"uint256"},{"internalType":"uint256","name":"_initialDebt","type":"uint256"},{"internalType":"enum VectorBonding.BondType","name":"_bondType","type":"uint8"}],"name":"initializeBond","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lastDecay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPayout","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"payoutFor","outputs":[{"internalType":"uint256","name":"_payout","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"uint256","name":"_value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_depositor","type":"address"}],"name":"pendingPayoutFor","outputs":[{"internalType":"uint256","name":"pendingPayout_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_depositor","type":"address"}],"name":"percentVestedFor","outputs":[{"internalType":"uint256","name":"percentVested_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"principalToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_depositor","type":"address"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_addition","type":"bool"},{"internalType":"uint256","name":"_increment","type":"uint256"},{"internalType":"uint256","name":"_target","type":"uint256"},{"internalType":"uint256","name":"_buffer","type":"uint256"}],"name":"setAdjustment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum VectorBonding.PARAMETER","name":"_parameter","type":"uint8"},{"internalType":"uint256","name":"_input","type":"uint256"}],"name":"setBondTerms","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeTo","type":"address"},{"internalType":"uint256","name":"_feePercent","type":"uint256"}],"name":"setFeeAndFeeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"terms","outputs":[{"internalType":"uint256","name":"controlVariable","type":"uint256"},{"internalType":"uint256","name":"vestingTerm","type":"uint256"},{"internalType":"uint256","name":"minimumPrice","type":"uint256"},{"internalType":"uint256","name":"maxPayout","type":"uint256"},{"internalType":"uint256","name":"maxDebt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalPayoutGiven","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalPrincipalBonded","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"contract ITreasury","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uniswapV2Router","outputs":[{"internalType":"contract IUniswapV2Router02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawStuckToken","outputs":[],"stateMutability":"nonpayable","type":"function"}]