This contract's source code is verified! Compiler
0.5.15+commit.6a57276f
File 1 of 13: Address.sol
File 2 of 13: Context.sol
File 4 of 13: ERC20Detailed.sol
File 5 of 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 ) ;
}File 7 of 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;
}
}
File 8 of 13: ReentrancyGuard.sol
File 9 of 13: SafeERC20.sol
File 10 of 13: SafeMath.sol
File 11 of 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 ;
}
}File 12 of 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);
}
}File 13 of 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"}]