EthereumEthereum
0x80...dc0e
bella USD Coin

bella USD Coin

bUSDC

Token
Market Cap
$1.00
 
Price
2%
This contract's source code is verified!
Contract Metadata
Compiler
0.5.15+commit.6a57276f
Language
Solidity
Contract Source Code
File 1 of 13: Address.sol
Contract Source Code
File 2 of 13: Context.sol
Contract Source Code
File 3 of 13: ERC20.sol
Contract Source Code
File 4 of 13: ERC20Detailed.sol
Contract Source Code
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);
}
Contract Source Code
File 6 of 13: IERC20.sol
Contract Source Code
File 7 of 13: Ownable.sol
pragma solidity 0.5.15;

/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Ownable {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev The Ownable constructor sets the original `owner` of the contract to the a
     * specified account.
     * @param initalOwner The address of the inital owner.
     */
    constructor(address initalOwner) internal {
        _owner = initalOwner;
        emit OwnershipTransferred(address(0), _owner);
    }

    /**
     * @return the address of the owner.
     */
    function owner() public view returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(isOwner(), "Only owner can call");
        _;
    }

    /**
     * @return true if `msg.sender` is the owner of the contract.
     */
    function isOwner() public view returns (bool) {
        return msg.sender == _owner;
    }

    /**
     * @dev Allows the current owner to relinquish control of the contract.
     * It will not be possible to call the functions with the `onlyOwner`
     * modifier anymore.
     * @notice Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Allows the current owner to transfer control of the contract to a newOwner.
     * @param newOwner The address to transfer ownership to.
     */
    function transferOwnership(address newOwner) public onlyOwner {
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers control of the contract to a newOwner.
     * @param newOwner The address to transfer ownership to.
     */
    function _transferOwnership(address newOwner) internal {
        require(newOwner != address(0), "Owner should not be 0 address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}
Contract Source Code
File 8 of 13: ReentrancyGuard.sol
Contract Source Code
File 9 of 13: SafeERC20.sol
Contract Source Code
File 10 of 13: SafeMath.sol
Contract Source Code
File 11 of 13: WhiteList.sol
pragma solidity ^0.5.15;

import "./Ownable.sol";

/**
* @title WhiteList
* @dev A Whitelist maintaned by the governance
*/
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;
    }  

}
Contract Source Code
File 12 of 13: WhiteListChecker.sol
pragma solidity ^0.5.15;

import "./WhiteList.sol";

/**
* @title WhiteListChecker
* @dev Inherit this contract to check if a contract is whitelisted
*/
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);
    }
}
Contract Source Code
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";

/**
 * @title bVault
 * @dev btoken vault, a typical mining aggregator's vault
 */
contract bVault is ERC20, ERC20Detailed, WhiteListChecker, ReentrancyGuard {
    using SafeERC20 for IERC20;
    using Address for address;
    using SafeMath for uint256;

    IERC20 public token;
  
    // buffer size 10%
    uint public min = 9000;
    uint public constant max = 10000;

    uint public withdrawalFee = 25; // 0.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;
    }
    
    /**
     * @dev View function to check how much the vault allows to invest (due to buffer)
     */
    function available() public view returns (uint) {
        return balance().mul(min).div(max).sub(IController(controller).balanceOf(address(token)));
    }

    /**
     * @dev Rebalance the buffer to make withdraw cheaper
     */
    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); // Additional check for deflationary tokens
        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);

        // Check balance
        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));
    }
}
Settings
{
  "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/"
  ]
}
ABI
[{"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"}]