contract Issuable is RocketBase, Authorized, PausableRedemption {
    using SafeMath for uint256;

    event AssetsUpdated(address indexed depository, uint256 amount);
    event CertificationUpdated(address indexed auditor, uint256 amount);

    // Get assetsOnDeposit
    function assetsOnDeposit() public view returns (uint256) {
        return rocketStorage.getUint(keccak256("issuable.assetsOnDeposit"));
    }

    // Get assetsCertified
    function assetsCertified() public view returns (uint256) {
        return rocketStorage.getUint(keccak256("issuable.assetsCertified"));
    }

    /******* For paused redemption *******/

    // Set assetsOnDeposit
    function setAssetsOnDeposit(uint256 _total) public onlyDepository whenRedemptionPaused {
        uint256 totalSupply_ = rocketStorage.getUint(keccak256("token.totalSupply"));
        require(_total >= totalSupply_);
        rocketStorage.setUint(keccak256("issuable.assetsOnDeposit"), _total);
        emit AssetsUpdated(msg.sender, _total);
    }

    // Set assetsCertified
    function setAssetsCertified(uint256 _total) public onlyAuditor whenRedemptionPaused {
        uint256 totalSupply_ = rocketStorage.getUint(keccak256("token.totalSupply"));
        require(_total >= totalSupply_);
        rocketStorage.setUint(keccak256("issuable.assetsCertified"), _total);
        emit CertificationUpdated(msg.sender, _total);
    }

    /******* For during both paused and non-paused redemption *******/

    // Depository can receive assets (increasing)
    function receiveAssets(uint256 _units) public onlyDepository {
        uint256 total_ = assetsOnDeposit().add(_units);
        rocketStorage.setUint(keccak256("issuable.assetsOnDeposit"), total_);
        emit AssetsUpdated(msg.sender, total_);
    }

    // Depository can release assets (decreasing), but never to less than the totalSupply
    function releaseAssets(uint256 _units) public onlyDepository {
        uint256 totalSupply_ = rocketStorage.getUint(keccak256("token.totalSupply"));
        uint256 total_ = assetsOnDeposit().sub(_units);
        require(total_ >= totalSupply_);
        rocketStorage.setUint(keccak256("issuable.assetsOnDeposit"), total_);
        emit AssetsUpdated(msg.sender, total_);
    }

    // Auditor can increase certified assets
    function increaseAssetsCertified(uint256 _units) public onlyAuditor {
        uint256 total_ = assetsCertified().add(_units);
        rocketStorage.setUint(keccak256("issuable.assetsCertified"), total_);
        emit CertificationUpdated(msg.sender, total_);
    }

    // Auditor can decrease certified assets
    function decreaseAssetsCertified(uint256 _units) public onlyAuditor {
        uint256 totalSupply_ = rocketStorage.getUint(keccak256("token.totalSupply"));
        uint256 total_ = assetsCertified().sub(_units);
        require(total_ >= totalSupply_);
        rocketStorage.setUint(keccak256("issuable.assetsCertified"), total_);
        emit CertificationUpdated(msg.sender, total_);
    }

}
function setAssetsOnDeposit(uint256 _total) public onlyDepository whenRedemptionPaused {
    uint256 totalSupply_ = rocketStorage.getUint(keccak256("token.totalSupply"));
    require(_total >= totalSupply_);
    rocketStorage.setUint(keccak256("issuable.assetsOnDeposit"), _total);
    emit AssetsUpdated(msg.sender, _total);
}

// Set assetsOnDeposit