Contract Name:
VaultBoardroom
Contract Source Code:
<i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IERC20} from '@openzeppelin/contracts/contracts/token/ERC20/IERC20.sol';
import {IVault} from '../../interfaces/IVault.sol';
import {SafeMath} from '@openzeppelin/contracts/contracts/math/SafeMath.sol';
import {ContractGuard} from '../../utils/ContractGuard.sol';
import {BaseBoardroom} from './BaseBoardroom.sol';
// import 'hardhat/console.sol';
contract VaultBoardroom is ContractGuard, BaseBoardroom {
using SafeMath for uint256;
// The vault which has state of the stakes.
IVault public vault;
uint256 public currentEpoch = 1;
mapping(address => mapping(uint256 => BondingSnapshot))
public bondingHistory;
mapping(address => mapping(uint256 => uint256)) directorBalanceForEpoch;
mapping(address => uint256) balanceCurrentEpoch;
mapping(address => uint256) balanceLastEpoch;
mapping(address => uint256) balanceBeforeLaunch;
modifier directorExists {
require(
vault.balanceOf(msg.sender) > 0,
'Boardroom: The director does not exist'
);
_;
}
modifier onlyVault {
require(msg.sender == address(vault), 'Boardroom: not vault');
_;
}
constructor(
IERC20 token_,
IVault vault_,
address owner,
address operator
) BaseBoardroom(token_) {
vault = vault_;
BoardSnapshot memory genesisSnapshot =
BoardSnapshot({
number: block.number,
time: 0,
rewardReceived: 0,
rewardPerShare: 0
});
boardHistory.push(genesisSnapshot);
transferOperator(operator);
transferOwnership(owner);
}
function getBoardhistory(uint256 i)
public
view
returns (BoardSnapshot memory)
{
return boardHistory[i];
}
function getBondingHistory(address who, uint256 epoch)
public
view
returns (BondingSnapshot memory)
{
return bondingHistory[who][epoch];
}
// returns the balance as per the last epoch; if the user deposits/withdraws
// in the current epoch, this value will not change unless another epoch passes
function getBalanceFromLastEpoch(address who)
public
view
returns (uint256)
{
// console.log('getBalanceFromLastEpoch who %s', who);
// console.log('getBalanceFromLastEpoch currentEpoch %s', currentEpoch);
if (currentEpoch == 1) return 0;
// console.log(
// 'getBalanceFromLastEpoch balanceLastEpoch[who] %s',
// balanceLastEpoch[who]
// );
// console.log(
// 'getBalanceFromLastEpoch balanceCurrentEpoch[who] %s',
// balanceCurrentEpoch[who]
// );
if (balanceCurrentEpoch[who] == 0) {
// console.log(
// 'getBalanceFromLastEpoch balanceOf(who) %s',
// balanceOf(who)
// );
return balanceOf(who);
}
uint256 currentBalance =
getBondingHistory(who, balanceCurrentEpoch[who]).balance;
if (balanceCurrentEpoch[who] == currentEpoch) {
// if boardroom was disconnected before then just return the old balance
if (balanceLastEpoch[who] == 0) return balanceBeforeLaunch[who];
return getBondingHistory(who, balanceLastEpoch[who]).balance;
}
if (balanceCurrentEpoch[who] < currentEpoch) {
return currentBalance;
}
return 0;
}
function claimAndReinvestReward(IVault _vault) external virtual {
uint256 reward = _claimReward(msg.sender);
_vault.bondFor(msg.sender, reward);
}
function rewardPerShare() public view override returns (uint256) {
return getLatestSnapshot().rewardPerShare;
}
function balanceOf(address who) public view returns (uint256) {
uint256 unbondingAmount = vault.getStakedAmount(who);
return vault.balanceOf(who).sub(unbondingAmount);
}
function earned(address director)
public
view
virtual
override
returns (uint256)
{
uint256 latestRPS = getLatestSnapshot().rewardPerShare;
uint256 storedRPS = getLastSnapshotOf(director).rewardPerShare;
return
getBalanceFromLastEpoch(director)
.mul(latestRPS.sub(storedRPS))
.div(1e18)
.add(directors[director].rewardEarnedCurrEpoch);
}
function claimReward()
public
virtual
override
directorExists
returns (uint256)
{
return _claimReward(msg.sender);
}
function allocateSeigniorage(uint256 amount)
external
override
onlyOneBlock
onlyOperator
{
require(amount > 0, 'Boardroom: Cannot allocate 0');
uint256 totalSupply = vault.totalBondedSupply();
// 'Boardroom: Cannot allocate when totalSupply is 0'
if (totalSupply == 0) return;
// Create & add new snapshot
uint256 prevRPS = getLatestSnapshot().rewardPerShare;
uint256 nextRPS = prevRPS.add(amount.mul(1e18).div(totalSupply));
BoardSnapshot memory snap =
BoardSnapshot({
number: block.number,
time: block.timestamp,
rewardReceived: amount,
rewardPerShare: nextRPS
});
boardHistory.push(snap);
// console.log('allocateSeigniorage totalSupply: %s', totalSupply);
// console.log('allocateSeigniorage time: %s', block.timestamp);
// console.log('allocateSeigniorage rewardReceived: %s', amount);
// console.log('allocateSeigniorage rewardPerShare: %s', nextRPS);
token.transferFrom(msg.sender, address(this), amount);
currentEpoch = currentEpoch.add(1);
emit RewardAdded(msg.sender, amount);
}
function updateReward(address director)
external
virtual
override
onlyVault
{
_updateBalance(director);
}
function _claimReward(address who) internal returns (uint256) {
_updateReward(who);
uint256 reward = directors[who].rewardEarnedCurrEpoch;
if (reward > 0) {
directors[who].rewardEarnedCurrEpoch = 0;
token.transfer(who, reward);
emit RewardPaid(who, reward);
if (balanceLastEpoch[who] == 0) {
balanceBeforeLaunch[who] = balanceOf(who);
}
}
return reward;
}
function setVault(IVault _vault) external onlyOwner {
vault = _vault;
}
function _updateReward(address director) internal {
Boardseat memory seat = directors[director];
seat.rewardEarnedCurrEpoch = earned(director);
seat.lastSnapshotIndex = latestSnapshotIndex();
directors[director] = seat;
}
function _updateBalance(address who) internal {
// console.log('updating balance for director at epoch: %s', currentEpoch);
BondingSnapshot memory snap =
BondingSnapshot({
epoch: currentEpoch,
when: block.timestamp,
balance: balanceOf(who)
});
bondingHistory[who][currentEpoch] = snap;
// update epoch counters if they need updating
if (balanceCurrentEpoch[who] != currentEpoch) {
balanceLastEpoch[who] = balanceCurrentEpoch[who];
balanceCurrentEpoch[who] = currentEpoch;
}
// if (balanceLastEpoch[who] == 0) {
// require(
// earned(who) == 0,
// 'Claim rewards once before depositing again'
// );
// }
if (balanceLastEpoch[who] == 0) {
balanceLastEpoch[who] = 1;
}
_updateReward(who);
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IVault {
function totalSupply() external view returns (uint256);
function balanceOf(address who) external view returns (uint256);
function totalBondedSupply() external view returns (uint256);
function balanceWithoutBonded(address who) external view returns (uint256);
function bond(uint256 amount) external;
function bondFor(address who, uint256 amount) external;
function unbond(uint256 amount) external;
function withdraw() external;
function getStakedAmount(address who) external view returns (uint256);
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Wrappers over Solidity's arithmetic operations.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the substraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator.
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract ContractGuard {
mapping(uint256 => mapping(address => bool)) private _status;
function checkSameOriginReentranted() internal view returns (bool) {
return _status[block.number][tx.origin];
}
function checkSameSenderReentranted() internal view returns (bool) {
return _status[block.number][msg.sender];
}
modifier onlyOneBlock() {
require(
!checkSameOriginReentranted(),
'ContractGuard: one block, one function'
);
require(
!checkSameSenderReentranted(),
'ContractGuard: one block, one function'
);
_;
_status[block.number][tx.origin] = true;
_status[block.number][msg.sender] = true;
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IERC20} from '@openzeppelin/contracts/contracts/token/ERC20/IERC20.sol';
import {IVault} from '../../interfaces/IVault.sol';
import {SafeMath} from '@openzeppelin/contracts/contracts/math/SafeMath.sol';
import {Safe112} from '../../lib/Safe112.sol';
import {ContractGuard} from '../../utils/ContractGuard.sol';
import {Operator} from '../../owner/Operator.sol';
import {IBoardroom} from '../../interfaces/IBoardroom.sol';
import {IBasisAsset} from '../../interfaces/IBasisAsset.sol';
import {IVaultBoardroom} from '../../interfaces/IVaultBoardroom.sol';
abstract contract BaseBoardroom is Operator, IBoardroom {
using Safe112 for uint112;
using SafeMath for uint256;
IERC20 public token;
BoardSnapshot[] public boardHistory;
mapping(address => Boardseat) public directors;
event RewardPaid(address indexed user, uint256 reward);
event RewardAdded(address indexed user, uint256 reward);
constructor(IERC20 token_) {
token = token_;
}
function getDirector(address who)
external
view
override
returns (Boardseat memory)
{
return directors[who];
}
function getLastSnapshotIndexOf(address director)
external
view
override
returns (uint256)
{
return directors[director].lastSnapshotIndex;
}
function getLastSnapshotOf(address director)
public
view
returns (BoardSnapshot memory)
{
return boardHistory[directors[director].lastSnapshotIndex];
}
function latestSnapshotIndex() public view returns (uint256) {
return boardHistory.length.sub(1);
}
function getLatestSnapshot() public view returns (BoardSnapshot memory) {
return boardHistory[latestSnapshotIndex()];
}
function rewardPerShare() public view virtual returns (uint256) {
return getLatestSnapshot().rewardPerShare;
}
function refundReward() external onlyOwner {
token.transfer(msg.sender, token.balanceOf(address(this)));
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
library Safe112 {
function add(uint112 a, uint112 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, 'Safe112: addition overflow');
return c;
}
function sub(uint112 a, uint112 b) internal pure returns (uint256) {
return sub(a, b, 'Safe112: subtraction overflow');
}
function sub(
uint112 a,
uint112 b,
string memory errorMessage
) internal pure returns (uint112) {
require(b <= a, errorMessage);
uint112 c = a - b;
return c;
}
function mul(uint112 a, uint112 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, 'Safe112: multiplication overflow');
return c;
}
function div(uint112 a, uint112 b) internal pure returns (uint256) {
return div(a, b, 'Safe112: division by zero');
}
function div(
uint112 a,
uint112 b,
string memory errorMessage
) internal pure returns (uint112) {
// Solidity only automatically asserts when dividing by 0
require(b > 0, errorMessage);
uint112 c = a / b;
return c;
}
function mod(uint112 a, uint112 b) internal pure returns (uint256) {
return mod(a, b, 'Safe112: modulo by zero');
}
function mod(
uint112 a,
uint112 b,
string memory errorMessage
) internal pure returns (uint112) {
require(b != 0, errorMessage);
return a % b;
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import '@openzeppelin/contracts/contracts/GSN/Context.sol';
import '@openzeppelin/contracts/contracts/access/Ownable.sol';
import {IOperator} from '../interfaces/IOperator.sol';
abstract contract Operator is Context, Ownable, IOperator {
address private _operator;
event OperatorTransferred(
address indexed previousOperator,
address indexed newOperator
);
constructor() {
_operator = _msgSender();
emit OperatorTransferred(address(0), _operator);
}
function operator() public view override returns (address) {
return _operator;
}
modifier onlyOperator() {
require(
_operator == msg.sender,
'operator: caller is not the operator'
);
_;
}
function isOperator() public view override returns (bool) {
return _msgSender() == _operator;
}
function transferOperator(address newOperator_) public override onlyOwner {
_transferOperator(newOperator_);
}
function _transferOperator(address newOperator_) internal {
require(
newOperator_ != address(0),
'operator: zero address given for new operator'
);
emit OperatorTransferred(address(0), newOperator_);
_operator = newOperator_;
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IOperator} from './IOperator.sol';
interface IBoardroom is IOperator {
struct Boardseat {
uint256 rewardClaimed;
uint256 lastRPS;
uint256 firstRPS;
uint256 lastBoardSnapshotIndex;
// // Pending reward from the previous epochs.
// uint256 rewardPending;
// Total reward earned in this epoch.
uint256 rewardEarnedCurrEpoch;
// Last time reward was claimed(not bound by current epoch).
uint256 lastClaimedOn;
// // The reward claimed in vesting period of this epoch.
// uint256 rewardClaimedCurrEpoch;
// // Snapshot of boardroom state when last epoch claimed.
uint256 lastSnapshotIndex;
// // Rewards claimable now in the current/next claim.
// uint256 rewardClaimableNow;
// // keep track of the current rps
// uint256 claimedRPS;
bool isFirstVaultActivityBeforeFirstEpoch;
uint256 firstEpochWhenDoingVaultActivity;
}
struct BoardSnapshot {
// Block number when recording a snapshot.
uint256 number;
// Block timestamp when recording a snapshot.
uint256 time;
// Amount of funds received.
uint256 rewardReceived;
// Equivalent amount per share staked.
uint256 rewardPerShare;
}
struct BondingSnapshot {
uint256 epoch;
// Time when first bonding was made.
uint256 when;
// The snapshot index of when first bonded.
uint256 balance;
}
// function updateReward(address director) external;
function allocateSeigniorage(uint256 amount) external;
function getDirector(address who) external view returns (Boardseat memory);
function getLastSnapshotIndexOf(address director)
external
view
returns (uint256);
function earned(address director) external view returns (uint256);
function claimReward() external returns (uint256);
function updateReward(address director) external;
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IERC20} from '@openzeppelin/contracts/contracts/token/ERC20/IERC20.sol';
interface IBasisAsset is IERC20 {
function mint(address recipient, uint256 amount) external returns (bool);
function burn(uint256 amount) external;
function burnFrom(address from, uint256 amount) external;
function isOperator() external returns (bool);
function operator() external view returns (address);
function transferOperator(address newOperator_) external;
function transferOwnership(address newOwner) external;
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IBoardroom} from './IBoardroom.sol';
interface IVaultBoardroom is IBoardroom {
function bondingHistory(address who, uint256 epoch)
external
view
returns (BondingSnapshot memory);
function directors(address who) external view returns (Boardseat memory);
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/Context.sol";
<i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor () {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IEpoch} from './IEpoch.sol';
interface IOperator {
function operator() external view returns (address);
function isOperator() external view returns (bool);
function transferOperator(address newOperator_) external;
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with GSN meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IEpoch {
function callable() external view returns (bool);
function getLastEpoch() external view returns (uint256);
function getCurrentEpoch() external view returns (uint256);
function getNextEpoch() external view returns (uint256);
function nextEpochPoint() external view returns (uint256);
function getPeriod() external view returns (uint256);
function getStartTime() external view returns (uint256);
function setPeriod(uint256 _period) external;
}