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

Feat/restituton2.0 #1

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion contracts/RemBadger.sol
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ import "../interfaces/setth/IGac.sol";
* RemBadger Version
* Allows for one time dilution of ppfs by minting extra shares (briked after)
* DepositBricked to track when deposits can no longer be done (irreversible)

V1.Rem2.0
* Introduces function to enable deposits after they have been bricked
* Removes the governance only modifier from the _depositFor function
* Intended to allow for a single deposit from a single user, enforced via Guestlist (BIP 103 - Amendment 3)
* Reference: https://forum.badger.finance/t/bip-103-restitution-amendments/6184/5
*/

contract RemBadger is ERC20Upgradeable, SettAccessControlDefended, PausableUpgradeable {
Expand Down Expand Up @@ -71,6 +77,7 @@ contract RemBadger is ERC20Upgradeable, SettAccessControlDefended, PausableUpgra
event FullPricePerShareUpdated(uint256 value, uint256 indexed timestamp, uint256 indexed blockNumber);

event DepositBricked(uint256 indexed timestamp);
event DepositEnabled(uint256 indexed timestamp);

modifier whenNotPaused() override {
require(!paused(), "Pausable: paused");
Expand Down Expand Up @@ -117,6 +124,14 @@ contract RemBadger is ERC20Upgradeable, SettAccessControlDefended, PausableUpgra
emit DepositBricked(block.timestamp);
}

/// @dev Sets `depositsEnded` to false, enabling deposits
function enableDeposits() public {
_onlyGovernance();
depositsEnded = false;

emit DepositEnabled(block.timestamp);
}

/// @dev Mint more shares, diluting the ppfs
/// @notice This bricks deposit to avoid griefing, can only call once!!
function mintExtra(uint256 amount) external {
Expand Down Expand Up @@ -342,7 +357,6 @@ contract RemBadger is ERC20Upgradeable, SettAccessControlDefended, PausableUpgra

function _depositFor(address recipient, uint256 _amount) internal virtual {
require(!depositsEnded, "No longer accepting Deposits");
_onlyGovernance();
uint256 _pool = balance();
uint256 _before = token.balanceOf(address(this));
token.safeTransferFrom(msg.sender, address(this), _amount);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.0 <0.7.0;
pragma solidity 0.6.12;
pragma experimental ABIEncoderV2;

import "../../deps/@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol";
import "../../deps/@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "../../deps/@openzeppelin/contracts-upgradeable/cryptography/MerkleProofUpgradeable.sol";
import "interfaces/yearn/GuestlistApi.sol";
import "interfaces/yearn/BadgerWrapperApi.sol";

import "../../interfaces/yearn/BadgerGuestlistApi.sol";
import "../../interfaces/badger/ISett.sol";

/**
* @notice A basic guest list contract for testing.
Expand All @@ -22,21 +23,25 @@ import "interfaces/yearn/BadgerWrapperApi.sol";
* A variant of the yearn AffiliateToken that supports guest list control of deposits
* A guest list that gates access by merkle root and a TVL cap
*/
contract VipCappedGuestListWrapperUpgradeable is OwnableUpgradeable {
contract VipCappedGuestListBbtcUpgradeable is OwnableUpgradeable {
using SafeMathUpgradeable for uint256;

address public wrapper;

bytes32 public guestRoot;
uint256 public userDepositCap;
uint256 public totalDepositCap;
uint256 public constant BASE = 1e18;

mapping(address => bool) public guests;

address public geyser;

event ProveInvitation(address indexed account, bytes32 indexed guestRoot);
event SetGuestRoot(bytes32 indexed guestRoot);
event SetUserDepositCap(uint256 cap);
event SetTotalDepositCap(uint256 cap);
event SetGeyser(address geyser);

/**
* @notice Create the test guest list, setting the message sender as
Expand All @@ -48,48 +53,37 @@ contract VipCappedGuestListWrapperUpgradeable is OwnableUpgradeable {
__Ownable_init();
wrapper = wrapper_;
}

function setWrapper(address wrapper_) public onlyOwner {
wrapper = wrapper_;
}

/**
* @notice Invite guests or kick them from the party.
* @param _guests The guests to add or update.
* @param _invited A flag for each guest at the matching index, inviting or
* uninviting the guest.
*/
function setGuests(address[] calldata _guests, bool[] calldata _invited)
external
onlyOwner
{
function setGuests(address[] calldata _guests, bool[] calldata _invited) external onlyOwner {
_setGuests(_guests, _invited);
}

function vaultBalance(address account) public view returns (uint256) {
return BadgerWrapperAPI(wrapper).totalVaultBalance(account);
}

function wrapperBalance(address user) public view returns (uint256) {
return BadgerWrapperAPI(wrapper).totalWrapperBalance(user);
}

function remainingTotalDepositAllowed() public view returns (uint256) {
return totalDepositCap.sub(vaultBalance(wrapper));
uint256 totalDeposited = ISett(wrapper).totalSupply().mul(ISett(wrapper).getPricePerFullShare()).div(BASE);
return totalDepositCap.sub(totalDeposited);
}

function remainingUserDepositAllowed(address user)
public
view
returns (uint256)
{
return userDepositCap.sub(wrapperBalance(user));
function remainingUserDepositAllowed(address user) public view returns (uint256) {
uint256 deposited = ISett(wrapper).balanceOf(user).mul(ISett(wrapper).getPricePerFullShare()).div(BASE);
return userDepositCap.sub(deposited);
sajanrajdev marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* @notice Permissionly prove an address is included in the current merkle root, thereby granting access
* @notice Note that the list is designed to ONLY EXPAND in future instances
* @notice The admin does retain the ability to ban individual addresses
*/
function proveInvitation(address account, bytes32[] calldata merkleProof)
public
{
function proveInvitation(address account, bytes32[] calldata merkleProof) public {
// Verify Merkle Proof
require(_verifyInvitationProof(account, merkleProof));

Expand Down Expand Up @@ -134,11 +128,7 @@ contract VipCappedGuestListWrapperUpgradeable is OwnableUpgradeable {
* from the wrapper tests' perspective this is a pass/fail call anyway.
* @param _guest The guest's address to check.
*/
function authorized(
address _guest,
uint256 _amount,
bytes32[] calldata _merkleProof
) external view returns (bool) {
function authorized(address _guest, uint256 _amount, bytes32[] calldata _merkleProof) external view returns (bool) {
// Yes: If the user is on the list, and under the cap
// Yes: If the user is not on the list, supplies a valid proof (thereby being added to the list), and is under the cap
// No: If the user is not on the list, does not supply a valid proof, or is over the cap
Expand All @@ -156,20 +146,14 @@ contract VipCappedGuestListWrapperUpgradeable is OwnableUpgradeable {
}

// If the user was previously invited, or proved invitiation via list, verify if the amount to deposit keeps them under the cap
if (
invited &&
remainingUserDepositAllowed(_guest) >= _amount &&
remainingTotalDepositAllowed() >= _amount
) {
if (invited && remainingUserDepositAllowed(_guest) >= _amount && remainingTotalDepositAllowed() >= _amount) {
return true;
} else {
return false;
}
}

function _setGuests(address[] memory _guests, bool[] memory _invited)
internal
{
function _setGuests(address[] memory _guests, bool[] memory _invited) internal {
require(_guests.length == _invited.length);
for (uint256 i = 0; i < _guests.length; i++) {
if (_guests[i] == address(0)) {
Expand All @@ -179,11 +163,8 @@ contract VipCappedGuestListWrapperUpgradeable is OwnableUpgradeable {
}
}

function _verifyInvitationProof(
address account,
bytes32[] calldata merkleProof
) internal view returns (bool) {
function _verifyInvitationProof(address account, bytes32[] calldata merkleProof) internal view returns (bool) {
bytes32 node = keccak256(abi.encodePacked(account));
return MerkleProofUpgradeable.verify(merkleProof, guestRoot, node);
}
}
}
7 changes: 7 additions & 0 deletions interfaces/badger/IProxyAdmin.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.11;

interface IProxyAdmin {
function upgrade(address, address) external;
}
Loading