Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sett upgrades #59

Open
wants to merge 12 commits into
base: develop
Choose a base branch
from
18 changes: 18 additions & 0 deletions contracts/badger-remote/DefenderStorageless.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

import "interfaces/remote/IRemoteDefender.sol";

/*
DefenderStorageless is a no-storage required inheritable defender of unapproved contract access.
Contracts may safely inherit this w/o messing up their internal storage layout.
*/
contract DefenderStorageless {
// Defend against access by unapproved contracts (EOAs are allowed access).
modifier defend(address defender) {
require(IRemoteDefender(defender).approved(msg.sender) || msg.sender == tx.origin, "Access denied for caller");
require(!IRemoteDefender(defender).frozen(msg.sender), "Caller frozen");
_;
}
}
69 changes: 69 additions & 0 deletions contracts/badger-remote/PauseableStorageless.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

import "interfaces/remote/IRemotePauser.sol";

/*
PauseableStorageless is a no-storage required inheritable version of OZ's Pauseable contract.
Contracts may safely inherit this w/o messing up their internal storage layout.
*/
contract PauseableStorageless {
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);

/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);

/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPausedRemote(address pauser) {
require(!IRemotePauser(pauser).paused(), "Pausable: paused");
_;
}

/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPausedRemote(address pauser) {
require(IRemotePauser(pauser).paused(), "Pausable: not paused");
_;
}

/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause(address pauser) internal virtual {
IRemotePauser(pauser).pause();
emit Paused(msg.sender);
}

/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause(address pauser) internal virtual {
IRemotePauser(pauser).unpause();
emit Unpaused(msg.sender);
}
}
92 changes: 92 additions & 0 deletions contracts/badger-remote/RemoteDefenderUpgradeable.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

import "deps/@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

/*
RemoteDefenderUpgradeable defends against unapproved address access.
It handles the following protective functionality (of contract addresses and EOAs):
- approved for contract specific or global access
- frozen from global access
- paused specific contract or globally
*/
contract RemoteDefenderUpgradeable is OwnableUpgradeable {
// Is contract address approved for global access?
mapping(address => bool) private _approvedGlobal;
// Is contract address approved for targeted access to msg.sender?
mapping(address => mapping(address => bool)) private _approvedTargeted;

// Is account address frozen?
mapping(address => bool) private _frozen;

// Is contract address paused?
mapping(address => bool) private _paused;
// Is everything paused globally?
bool private _pausedGlobal;

function initialize() public initializer {
__Ownable_init();
}

// Access control functions.
function approved(address account) external view returns (bool) {
if (_approvedTargeted[account][msg.sender]) {
return true;
}
return _approvedGlobal[account];
}

function approve(address account) external onlyOwner {
_approvedGlobal[account] = true;
}

function revoke(address account) external onlyOwner {
_approvedGlobal[account] = false;
}

function approveFor(address account, address target) external onlyOwner {
_approvedTargeted[account][target] = true;
}

function revokeFor(address account, address target) external onlyOwner {
_approvedTargeted[account][target] = false;
}

// Freezer functions.
function frozen(address account) external view returns (bool) {
return _frozen[account];
}

function freeze(address account) external onlyOwner {
_frozen[account] = true;
}

function unfreeze(address account) external onlyOwner {
_frozen[account] = false;
}

// Pauser functions.
function paused() external view returns (bool) {
return _pausedGlobal || _paused[msg.sender];
}

function pauseGlobal() external onlyOwner {
_pausedGlobal = true;
}

function unpauseGlobal() external onlyOwner {
_pausedGlobal = false;
}

function pause() external {
_paused[msg.sender] = true;
}

function unpause() external {
_paused[msg.sender] = false;
}

// Reserve storage space for upgrades.
uint256[50] private __gap;
}
33 changes: 33 additions & 0 deletions contracts/badger-remote/test/ThirdPartyContractAccess.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

import "interfaces/badger/ISett.sol";

/*
ThirdPartyContractAccess is a test contract for simulating third party contract access to our API.
*/
contract ThirdPartyContractAccess {
address public sett;

constructor(address _sett) public {
sett = _sett;
}

// Test third party access paths for Sett methods (if authorized).
function depositAll() external {
ISett(sett).depositAll();
}

function withdrawAll() external {
ISett(sett).withdrawAll();
}

function deposit(uint256 _amount) external {
ISett(sett).deposit(_amount);
}

function withdraw(uint256 _amount) external {
ISett(sett).withdraw(_amount);
}
}
Loading