Skip to content

Commit

Permalink
Merge branch 'main' into jade/de-prize-join
Browse files Browse the repository at this point in the history
  • Loading branch information
jaderiverstokes committed Dec 16, 2024
2 parents 5359d15 + f721efd commit 5bb5484
Show file tree
Hide file tree
Showing 87 changed files with 3,806 additions and 835 deletions.
5 changes: 4 additions & 1 deletion contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ yarn install
cp .env.sample .env

# Install Vyper
pip install vyper==0.2.4
pip install vyper==0.3.1

# Add vyper to path
export PATH="$PATH:$HOME/Library/Python/3.9/bin"

# Install Git submodules
forge install
Expand Down
4 changes: 4 additions & 0 deletions contracts/deployments/base-sepolia.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"MOONEYToken": "0x3B3024e49261866a420F2444Fa1f248902C8D143",
"vMOONEYToken": "0xa83aceC4e6784a0c9C4Ba6fa414665Ba15F6F3b6"
}
4 changes: 4 additions & 0 deletions contracts/deployments/base.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"MOONEYToken": "0x6585a54A98fADA893904EB8A9E9CDFb927bddf39",
"vMOONEYToken": "0x7f8f1B45c3FD6Be4F467520Fc1Cf030d5CaBAcF5"
}
10 changes: 9 additions & 1 deletion contracts/foundry.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
[default]
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
evm_version = "berlin"

#[profile.default.compiler]
#version = "0.8.10"

# Vyper compiler settings
[profile.default.vyper]
vyper_version = "0.3.1"
60 changes: 35 additions & 25 deletions contracts/scripts/dev-deploy.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,33 @@
import { wallet, dec, save } from "./helpers";
import { ethers, BigNumber, Contract } from "ethers";
import { formatUnits } from "@ethersproject/units"
import { formatUnits } from "@ethersproject/units";

import MyToken from '../out/MyToken.sol/MyToken.json';
import VotingEscrow from '../out/VotingEscrow.vy/VotingEscrow.json';
import MerkleDistributorV2 from '../out/MerkleDistributorV2.sol/MerkleDistributorV2.json';
import MyToken from "../out/MyToken.sol/MyToken.json";
import VotingEscrow from "../out/VotingEscrow.vy/VotingEscrow.json";

const getContractFactory = (artifact: any) => {
return new ethers.ContractFactory(artifact.abi, artifact.bytecode.object, wallet);
}

const deployContract = async ({ name, deployer, factory, args }: { name: string, deployer: ethers.Wallet, factory: ethers.ContractFactory, args: Array<any>}) => {
console.log(`Deploying ${name}..`)
const contract = await factory.connect(deployer).deploy(...args);
};

const deployContract = async ({
name,
deployer,
factory,
args,
}: {
name: string;
deployer: ethers.Wallet;
factory: ethers.ContractFactory;
args: Array<any>;
}) => {
console.log(`Deploying ${name}..`);
const contract = await factory.connect(deployer).deploy(...args, {
gasLimit: BigNumber.from(8000000),
});
await contract.deployed();
console.log(`Deployed ${name} to: ${contract.address}`)
console.log(`Deployed ${name} to: ${contract.address}`);
return contract;
}
};

const deployMOONEY = async () => {
const supply: BigNumber = BigNumber.from(process.env.MOONEY_SUPPLY ?? dec(42069, 18));
Expand All @@ -26,14 +37,14 @@ const deployMOONEY = async () => {
name: "MOONEY",
deployer: wallet,
factory: Factory,
args: []
args: ["Mooney", "MOONEY"],
});

await MOONEYToken.connect(wallet).mint(wallet.address, supply);
console.log(`Minted ${formatUnits(supply, 18)} tokens to deployer address`)
//await MOONEYToken.connect(wallet).mint(wallet.address, supply);
console.log(`Minted ${formatUnits(supply, 18)} tokens to deployer address`);

return MOONEYToken;
}
};

const deployVMOONEY = async (MOONEYToken: Contract) => {
const Factory = getContractFactory(VotingEscrow);
Expand All @@ -42,11 +53,11 @@ const deployVMOONEY = async (MOONEYToken: Contract) => {
name: "vMOONEY",
deployer: wallet,
factory: Factory,
args: [MOONEYToken.address, "Vote-escrowed MOONEY", "vMOONEY", "vMOONEY_1.0.0"]
})
args: [MOONEYToken.address, "Vote-escrowed MOONEY", "vMOONEY", "vMOONEY_1.0.0"],
});

return vMOONEY;
}
};

// const deployAirdropDistributor = async (MOONEYToken: Contract, root: string) => {
// const Factory = getContractFactory(MerkleDistributorV2);
Expand Down Expand Up @@ -119,7 +130,7 @@ const deployVMOONEY = async (MOONEYToken: Contract) => {
// factory: passportIssuerFactory,
// args: []
// })

// await passportToken.connect(wallet).transferControl(passportIssuer.address);
// // TODO: Set renderer

Expand All @@ -139,16 +150,15 @@ const main = async () => {
const vMOONEY = await deployVMOONEY(MOONEY);

const deployment = {
"MOONEYToken": MOONEY.address,
"vMOONEYToken": vMOONEY.address,
}
MOONEYToken: MOONEY.address,
vMOONEYToken: vMOONEY.address,
};

const manifestFile = "./deployments/local.json";
save(deployment, manifestFile);

console.log(`Deployment manifest saved to ${manifestFile}`)
}

console.log(`Deployment manifest saved to ${manifestFile}`);
};

main().catch((error) => {
console.error(error);
Expand Down
12 changes: 12 additions & 0 deletions contracts/src/governance/IVotingEscrow.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,16 @@ interface IVotingEscrow {
function locked(address) external view returns (LockedBalance memory);

function balanceOf(address) external view returns (uint256);
function deploy_for(address _addr, uint256 _value) external;
function commit_smart_wallet_checker(address) external;
function apply_smart_wallet_checker() external;

function admin() external view returns (address);
function create_lock(uint256 _value, uint256 _unlock_time) external;
function totalSupply() external view returns (uint256);
function checkpoint() external;
function user_point_history(address, uint256) external view returns (uint256, uint256);
function user_point_history__ts(address, uint256) external view returns (uint256);
function get_last_user_slope(address) external view returns (int128);

}
63 changes: 63 additions & 0 deletions contracts/src/governance/SmartWalletChecker.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

//import "@openzeppelin/contracts-4.2.0/access/Ownable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract SmartWalletChecker is Ownable {
bool public isWhitelistEnabled;
mapping(address => bool) public wallets;
address public checker;
address public future_checker;

event ApproveWallet(address);
event RevokeWallet(address);
event WhitelistEnabled(bool);

constructor(bool _isWhitelistEnabled) public Ownable() {
// Set state variables
setIsWhitelistEnabled(_isWhitelistEnabled);
}

function commitSetChecker(address _checker) external onlyOwner {
future_checker = _checker;
}

function applySetChecker() external onlyOwner {
checker = future_checker;
}

function approveWallet(address _wallet) external onlyOwner {
wallets[_wallet] = true;

emit ApproveWallet(_wallet);
}

function revokeWallet(address _wallet) external onlyOwner {
wallets[_wallet] = false;

emit RevokeWallet(_wallet);
}

function setIsWhitelistEnabled(bool _isWhitelistEnabled) public onlyOwner {
isWhitelistEnabled = _isWhitelistEnabled;

emit WhitelistEnabled(_isWhitelistEnabled);
}

function check(address _wallet) external view returns (bool) {
if (!isWhitelistEnabled) {
return true;
}

bool _check = wallets[_wallet];
if (_check) {
return _check;
} else {
if (checker != address(0)) {
return SmartWalletChecker(checker).check(_wallet);
}
}
return false;
}
}
65 changes: 65 additions & 0 deletions contracts/src/governance/VotingEscrowDepositor.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/access/Ownable.sol";

interface IERC20Interface {
function transfer(address recipient, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
function balanceOf(address account) external view returns (uint256);
}

interface IVotingEscrowInterface {
function deposit_for(address _addr, uint256 _value) external;
}

contract VotingEscrowDepositor is Ownable{
IERC20Interface public token;
IVotingEscrowInterface public escrowToken;
// map from address to amount availabe to withdraw
mapping(address => uint256) public availableToWithdraw;
address[] public withdrawAddresses;

constructor(address _tokenAddress, address _escrowTokenAddress){
token = IERC20Interface(_tokenAddress);
escrowToken = IVotingEscrowInterface(_escrowTokenAddress);
}

function increaseWithdrawAmounts(address[] memory addresses, uint256[] memory amounts) external onlyOwner{
require(addresses.length == amounts.length, "Arrays must be of equal length");
uint256 totalAmount = 0;
for (uint256 i = 0; i < addresses.length; i++) {
if (availableToWithdraw[addresses[i]] == 0) {
withdrawAddresses.push(addresses[i]);
}
availableToWithdraw[addresses[i]] += amounts[i];
totalAmount += amounts[i];
}
require(token.transferFrom(msg.sender, address(this), totalAmount), "Token transfer failed");
}

function clearWithdrawAmounts() external onlyOwner {
for (uint256 i = 0; i < withdrawAddresses.length; i++) {
availableToWithdraw[withdrawAddresses[i]] = 0;
}
delete withdrawAddresses;
}

function withdraw() external {
uint256 amount = availableToWithdraw[msg.sender];
require(amount > 0, "No amount available to withdraw");
availableToWithdraw[msg.sender] = 0;
require(token.transfer(msg.sender, amount), "Token transfer failed");
escrowToken.deposit_for(msg.sender, amount);
}

function returnTokens() external onlyOwner {
uint256 balance = token.balanceOf(address(this));
require(token.transfer(msg.sender, balance), "Token transfer failed");
}

function sendVotingEscrowTokens(address _addr, uint256 _value) external onlyOwner {
require(token.transfer(_addr, _value), "Token transfer failed");
escrowToken.deposit_for(_addr, _value);
}
}
65 changes: 65 additions & 0 deletions contracts/src/test/VotingEscrowDepositor.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "forge-std/Test.sol";
import "../governance/VotingEscrowDepositor.sol";
import "../governance/SmartWalletChecker.sol";
import "../governance/IVotingEscrow.sol";
import "../tokens/MyToken.sol";

contract VotingEscrowDepositorTest is Test {
VotingEscrowDepositor public depositor;
MyToken public token;
IVotingEscrow public escrowToken;
SmartWalletChecker public checker;

address public user = address(0x123);
uint256 public initialBalance = 126144000 * 2;
uint256 depositAmount = 126144000;

address public MOONEY = 0x5FbDB2315678afecb367f032d93F642f64180aa3;

address public vMOONEY = 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512;


function setUp() public {
token = MyToken(MOONEY);

escrowToken = IVotingEscrow(vMOONEY);
vm.prank(0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266);
depositor = new VotingEscrowDepositor(address(MOONEY), address(vMOONEY));
checker = new SmartWalletChecker(true);
checker.approveWallet(address(depositor));
// we don't seem to need this in prod, but required for tests
checker.approveWallet(address(user));
vm.prank(0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266);
escrowToken.commit_smart_wallet_checker(address(checker));
vm.prank(0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266);
escrowToken.apply_smart_wallet_checker();
//token.transfer(address(depositor), initialBalance);
address[] memory addresses = new address[](1);
addresses[0] = address(user);
uint256[] memory amounts = new uint256[](1);
amounts[0] = depositAmount;
vm.prank(0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266);
token.approve(address(depositor), depositAmount);
vm.prank(0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266);
depositor.increaseWithdrawAmounts(addresses, amounts);
vm.prank(0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266);
token.transfer(address(user), initialBalance);
vm.prank(user);
token.approve(address(escrowToken), initialBalance);
vm.prank(user);
escrowToken.create_lock(initialBalance, block.timestamp + 4*60 * 60 * 24 * 365);
vm.prank(user);
token.approve(address(escrowToken), depositAmount);
vm.prank(0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266);
depositor.sendVotingEscrowTokens(address(user), depositAmount);
}

function testTransferAndDepositFor() public {
vm.prank(user);
depositor.withdraw();
assertEq(escrowToken.balanceOf(user), depositAmount + initialBalance);
}
}
1 change: 1 addition & 0 deletions ui/.env.testnet
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
NEXT_PUBLIC_CHAIN=mumbai
NEXT_PUBLIC_VMOONEY_REQUIRED_STAKE=1
NEXT_PUBLIC_SNAPSHOT_API_KEY=placeholder
COORDINAPE_API_KEY=placeholder
Loading

0 comments on commit 5bb5484

Please sign in to comment.