编译器
0.5.15+commit.6a57276f
文件 4 的 13:ERC20Detailed.sol
文件 5 的 13:IController.sol
pragma solidity 0.5.15;
interface IController {
function vaults(address) external view returns (address);
function withdraw(address, uint) external;
function balanceOf(address) external view returns (uint);
function underlyingBalanceOf(address) external view returns (uint);
function earn(address, uint) external;
function rewards() external view returns (address);
function belRewards() external view returns (address);
function paused() external view returns (bool);
}
文件 7 的 13:Ownable.sol
pragma solidity 0.5.15;
contract Ownable {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor(address initalOwner) internal {
_owner = initalOwner;
emit OwnershipTransferred(address(0), _owner);
}
function owner() public view returns (address) {
return _owner;
}
modifier onlyOwner() {
require(isOwner(), "Only owner can call");
_;
}
function isOwner() public view returns (bool) {
return msg.sender == _owner;
}
function renounceOwnership() public onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
function transferOwnership(address newOwner) public onlyOwner {
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal {
require(newOwner != address(0), "Owner should not be 0 address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
文件 8 的 13:ReentrancyGuard.sol
文件 11 的 13:WhiteList.sol
pragma solidity ^0.5.15;
import "./Ownable.sol";
contract WhiteList is Ownable {
mapping (address => bool) public inWhiteList;
constructor(address governance) public Ownable(governance) {}
function add(address toAdd) external onlyOwner {
inWhiteList[toAdd] = true;
}
function remove(address toRemove) external onlyOwner {
inWhiteList[toRemove] = false;
}
}
文件 12 的 13:WhiteListChecker.sol
pragma solidity ^0.5.15;
import "./WhiteList.sol";
contract WhiteListChecker {
WhiteList public whiteList;
modifier onlyWhiteListed() {
require((tx.origin == msg.sender) || whiteList.inWhiteList(msg.sender), "not in white list");
_;
}
constructor(address whiteListAddress) public {
whiteList = WhiteList(whiteListAddress);
}
}
文件 13 的 13:bVault.sol
pragma solidity 0.5.15;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20Detailed.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "../interfaces/IController.sol";
import "../libraries/WhiteListChecker.sol";
contract bVault is ERC20, ERC20Detailed, WhiteListChecker, ReentrancyGuard {
using SafeERC20 for IERC20;
using Address for address;
using SafeMath for uint256;
IERC20 public token;
uint public min = 9000;
uint public constant max = 10000;
uint public withdrawalFee = 25;
uint constant public withdrawalMax = 10000;
address public governance;
address public controller;
bool public paused = false;
mapping(address => bool) public pauseRoles;
modifier notPaused() {
require(!IController(controller).paused(), "Global paused!");
require(!paused, "Local paused!");
_;
}
constructor (address _token, address _controller, address whiteList) public ERC20Detailed(
string(abi.encodePacked("bella ", ERC20Detailed(_token).name())),
string(abi.encodePacked("b", ERC20Detailed(_token).symbol())),
ERC20Detailed(_token).decimals()
) WhiteListChecker(whiteList) {
token = IERC20(_token);
governance = msg.sender;
controller = _controller;
}
function setPauseRole(address admin) external {
require(msg.sender == governance, "!governance");
pauseRoles[admin] = true;
}
function unSetPauseRole(address admin) external {
require(msg.sender == governance, "!governance");
pauseRoles[admin] = false;
}
function pause() external {
require(pauseRoles[msg.sender], "no right to pause!");
paused = true;
}
function unpause() external {
require(pauseRoles[msg.sender], "no right to pause!");
paused = false;
}
function balance() public view returns (uint) {
return token.balanceOf(address(this))
.add(IController(controller).balanceOf(address(token)));
}
function underlyingBalance() public view returns (uint) {
return token.balanceOf(address(this))
.add(IController(controller).underlyingBalanceOf(address(token)));
}
function setMin(uint _min) external {
require(msg.sender == governance, "!governance");
require(_min <= max, "invalid min!");
min = _min;
}
function setWithdrawalFee(uint _withdrawalFee) external {
require(msg.sender == governance, "!governance");
require(_withdrawalFee <= withdrawalMax, "invalid withdrawal fee");
withdrawalFee = _withdrawalFee;
}
function setGovernance(address _governance) public {
require(msg.sender == governance, "!governance");
governance = _governance;
}
function setController(address _controller) public {
require(msg.sender == governance, "!governance");
controller = _controller;
}
function available() public view returns (uint) {
return balance().mul(min).div(max).sub(IController(controller).balanceOf(address(token)));
}
function rebalance() public onlyWhiteListed notPaused {
uint256 amount = IController(controller).balanceOf(address(token)).sub(balance().mul(min).div(max));
IController(controller).withdraw(address(token), amount);
}
function earn() public onlyWhiteListed notPaused {
require(msg.sender == tx.origin ,"!contract");
uint _bal = available();
token.safeTransfer(controller, _bal);
IController(controller).earn(address(token), _bal);
}
function deposit(uint _amount) external onlyWhiteListed notPaused nonReentrant {
uint _pool = balance();
uint _before = token.balanceOf(address(this));
token.safeTransferFrom(msg.sender, address(this), _amount);
uint _after = token.balanceOf(address(this));
_amount = _after.sub(_before);
uint shares = 0;
if (totalSupply() == 0) {
shares = _amount;
} else {
shares = (_amount.mul(totalSupply())).div(_pool);
}
_mint(msg.sender, shares);
}
function withdraw(uint _shares) external notPaused nonReentrant {
_withdraw(msg.sender, _shares);
}
function withdrawAll() external notPaused nonReentrant {
_withdraw(msg.sender, balanceOf(msg.sender));
}
function getPricePerFullShare() public view returns (uint) {
return balance().mul(1e18).div(totalSupply());
}
function _withdraw(address user, uint _shares) private {
uint r = (underlyingBalance().mul(_shares)).div(totalSupply());
_burn(user, _shares);
uint b = token.balanceOf(address(this));
if (b < r) {
uint w = r.sub(b);
IController(controller).withdraw(address(token), w);
uint _after = token.balanceOf(address(this));
uint _diff = _after.sub(b);
if (_diff < w) {
r = b.add(_diff);
}
}
uint _fee = r.mul(withdrawalFee).div(withdrawalMax);
token.safeTransfer(IController(controller).rewards(), _fee);
token.safeTransfer(user, r.sub(_fee));
}
}
{
"compilationTarget": {
"contracts/vault/bVault.sol": "bVault"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":@openzeppelin/=/home/ubuntu/flex-saving/node_modules/@openzeppelin/"
]
}
[{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_controller","type":"address"},{"internalType":"address","name":"whiteList","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"available","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"balance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"controller","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"earn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getPricePerFullShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"max","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"min","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"pauseRoles","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"rebalance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_controller","type":"address"}],"name":"setController","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_governance","type":"address"}],"name":"setGovernance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_min","type":"uint256"}],"name":"setMin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"setPauseRole","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_withdrawalFee","type":"uint256"}],"name":"setWithdrawalFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"unSetPauseRole","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"underlyingBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"whiteList","outputs":[{"internalType":"contract WhiteList","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"withdrawAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"withdrawalFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"withdrawalMax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]