Files
smom-dbis-138/contracts/cw-settlement/CWStabilityFund.sol

67 lines
2.2 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
/**
* @title CWStabilityFund
* @notice Insurance / surplus buffer for bridge, oracle, and temporary depeg events.
*/
contract CWStabilityFund is AccessControl, ReentrancyGuard {
using SafeERC20 for IERC20;
bytes32 public constant EMERGENCY_ROLE = keccak256("EMERGENCY_ROLE");
bytes32 public constant DEPOSITOR_ROLE = keccak256("DEPOSITOR_ROLE");
mapping(address => bool) public supportedAsset;
event AssetSupported(address indexed asset, bool supported);
event Deposited(address indexed asset, address indexed from, uint256 amount);
event EmergencyWithdrawn(address indexed asset, address indexed to, uint256 amount, bytes32 reason);
error ZeroAddress();
error UnsupportedAsset();
constructor(address admin) {
if (admin == address(0)) {
revert ZeroAddress();
}
_grantRole(DEFAULT_ADMIN_ROLE, admin);
_grantRole(EMERGENCY_ROLE, admin);
_grantRole(DEPOSITOR_ROLE, admin);
}
function setSupportedAsset(address asset, bool supported) external onlyRole(DEFAULT_ADMIN_ROLE) {
supportedAsset[asset] = supported;
emit AssetSupported(asset, supported);
}
function deposit(address asset, uint256 amount) external onlyRole(DEPOSITOR_ROLE) nonReentrant {
if (!supportedAsset[asset]) {
revert UnsupportedAsset();
}
IERC20(asset).safeTransferFrom(msg.sender, address(this), amount);
emit Deposited(asset, msg.sender, amount);
}
function emergencyWithdraw(
address asset,
address to,
uint256 amount,
bytes32 reason
) external onlyRole(EMERGENCY_ROLE) nonReentrant {
if (to == address(0)) {
revert ZeroAddress();
}
IERC20(asset).safeTransfer(to, amount);
emit EmergencyWithdrawn(asset, to, amount, reason);
}
function balanceOf(address asset) external view returns (uint256) {
return IERC20(asset).balanceOf(address(this));
}
}