// SPDX-License-Identifier: MIT
pragma solidity >=0.8.4 <0.9.0;
import '../Keep3rAccountance.sol';
import '../Keep3rParameters.sol';
import '../../../interfaces/peripherals/IKeep3rKeepers.sol';
import '../../../interfaces/external/IKeep3rV1.sol';
import '../../../interfaces/external/IKeep3rV1Proxy.sol';
import '@openzeppelin/contracts/security/ReentrancyGuard.sol';
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';
abstract contract Keep3rKeeperFundable is IKeep3rKeeperFundable, ReentrancyGuard, Keep3rParameters {
using EnumerableSet for EnumerableSet.AddressSet;
using SafeERC20 for IERC20;
/// @inheritdoc IKeep3rKeeperFundable
function bond(address _bonding, uint256 _amount) external override nonReentrant {
if (disputes[msg.sender]) revert Disputed();
if (_jobs.contains(msg.sender)) revert AlreadyAJob();
canActivateAfter[msg.sender][_bonding] = block.timestamp + bondTime;
uint256 _before = IERC20(_bonding).balanceOf(address(this));
IERC20(_bonding).safeTransferFrom(msg.sender, address(this), _amount);
_amount = IERC20(_bonding).balanceOf(address(this)) - _before;
hasBonded[msg.sender] = true;
pendingBonds[msg.sender][_bonding] += _amount;
emit Bonding(msg.sender, _bonding, _amount);
}
/// @inheritdoc IKeep3rKeeperFundable
function activate(address _bonding) external override {
if (disputes[msg.sender]) revert Disputed();
if (canActivateAfter[msg.sender][_bonding] == 0) revert BondsUnexistent();
if (canActivateAfter[msg.sender][_bonding] >= block.timestamp) revert BondsLocked();
_activate(msg.sender, _bonding);
}
/// @inheritdoc IKeep3rKeeperFundable
function unbond(address _bonding, uint256 _amount) external override {
canWithdrawAfter[msg.sender][_bonding] = block.timestamp + unbondTime;
bonds[msg.sender][_bonding] -= _amount;
pendingUnbonds[msg.sender][_bonding] += _amount;
emit Unbonding(msg.sender, _bonding, _amount);
}
/// @inheritdoc IKeep3rKeeperFundable
function withdraw(address _bonding) external override nonReentrant {
if (canWithdrawAfter[msg.sender][_bonding] == 0) revert UnbondsUnexistent();
if (canWithdrawAfter[msg.sender][_bonding] >= block.timestamp) revert UnbondsLocked();
if (disputes[msg.sender]) revert Disputed();
uint256 _amount = pendingUnbonds[msg.sender][_bonding];
if (_bonding == keep3rV1) {
IKeep3rV1Proxy(keep3rV1Proxy).mint(_amount);
}
pendingUnbonds[msg.sender][_bonding] = 0;
IERC20(_bonding).safeTransfer(msg.sender, _amount);
emit Withdrawal(msg.sender, _bonding, _amount);
}
function _bond(
address _bonding,
address _from,
uint256 _amount
) internal virtual {
bonds[_from][_bonding] += _amount;
if (_bonding == keep3rV1) {
IKeep3rV1(keep3rV1).burn(_amount);
}
}
function _activate(address _keeper, address _bonding) internal {
if (firstSeen[_keeper] == 0) {
firstSeen[_keeper] = block.timestamp;
}
_keepers.add(_keeper);
uint256 _amount = pendingBonds[_keeper][_bonding];
pendingBonds[_keeper][_bonding] = 0;
_bond(_bonding, _keeper, _amount);
emit Activation(_keeper, _bonding, _amount);
}
}
|