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

Implement v2 for Lockstake #16

Merged
merged 36 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
df6f710
Remove ds-test
sunbreak1211 Oct 25, 2023
0224caf
forge install: dss-test
sunbreak1211 Oct 25, 2023
0bf1da5
Changes for V2
sunbreak1211 Oct 26, 2023
782e613
Remove comments
sunbreak1211 Jan 8, 2024
a51f390
Minor changes
sunbreak1211 Feb 27, 2024
197106f
Fix copyright year
sunbreak1211 Feb 27, 2024
ba3c300
Add testConstructor
sunbreak1211 Feb 27, 2024
5f8c76f
Test Lock and Free events
sunbreak1211 Feb 27, 2024
3129ccb
Change comment
sunbreak1211 Feb 27, 2024
c98ed1c
Minor changes to lock and free
sunbreak1211 Feb 27, 2024
8fa3418
Minor changes to tests
sunbreak1211 Feb 27, 2024
39d9af1
More minor changes for tests
sunbreak1211 Feb 27, 2024
2aafc61
Add CreateVoteDelegate event back
sunbreak1211 Feb 28, 2024
2f53049
Remove return value of interface
sunbreak1211 Feb 28, 2024
4bd338a
Remove unused functions from interface
sunbreak1211 Feb 28, 2024
fdc2cbf
Put salt inline
sunbreak1211 Feb 28, 2024
b644f59
Set event right exactly as was before
sunbreak1211 Feb 28, 2024
ca3cb3b
Rename variable with a proper name
sunbreak1211 Feb 28, 2024
9cc80ec
Fix renaming
sunbreak1211 Feb 28, 2024
350f279
Minor changes to tests
sunbreak1211 Feb 28, 2024
bcef5e6
Add checks back to test
sunbreak1211 Feb 29, 2024
b59e5be
Add delegates getter to the factory to keep compatibility with prev v…
sunbreak1211 Feb 29, 2024
edf24ce
Change comment position
sunbreak1211 Feb 29, 2024
c01dda0
Reserve free window (aka hatch), then enforce cool-down (#18)
oldchili Apr 12, 2024
d2db093
Add uncommited change to VoteDelegate.t.sol
oldchili Apr 17, 2024
9519c82
Use solc 0.8.21 + upgrade dss-tests and fix warnings due to it (#19)
sunbreak1211 Apr 26, 2024
d6e563f
Add CS audit
sunbreak1211 May 20, 2024
63700ad
Post Cantina Audit Minor Changes (#20)
oldchili Jun 24, 2024
4484057
Add Cantina Report (#21)
oldchili Jul 3, 2024
67a7d64
Update CS Report (#22)
oldchili Aug 5, 2024
01e7b57
Use regular create in VoteDelegateFactory (#23)
oldchili Aug 15, 2024
64dfa96
Update CS audit report (#24)
sunbreak1211 Sep 9, 2024
3fba35c
Add Cantina updates audit report (#25)
sunbreak1211 Sep 9, 2024
efc415c
Add Sherlock Report (#26)
oldchili Sep 19, 2024
2a585d7
Add Certora specs + configure CI for tests and Certora (#27)
sunbreak1211 Oct 21, 2024
c8ab9cb
Certora: Minor change
sunbreak1211 Oct 22, 2024
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/out
/cache
6 changes: 3 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[submodule "lib/ds-test"]
path = lib/ds-test
url = https://github.com/dapphub/ds-test
[submodule "lib/dss-test"]
path = lib/dss-test
url = https://github.com/makerdao/dss-test
6 changes: 0 additions & 6 deletions Makefile

This file was deleted.

3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
VoteDelegate based on https://github.com/makerdao/vote-proxy

Kovan Deploy: [0x1740F3bD55b1900C816A0071F8972C201566e3a3](https://kovan.etherscan.io/address/0x1740F3bD55b1900C816A0071F8972C201566e3a3#code)
Mainnet Deploy: [0xD897F108670903D1d6070fcf818f9db3615AF272](https://etherscan.io/address/0xD897F108670903D1d6070fcf818f9db3615AF272#code)
Binary file removed audits/ABDK-MakerDAO-Vote Delegate.pdf
Binary file not shown.
10 changes: 10 additions & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
solc = '0.8.16'
# Enabling optimizations to improve gas usage.
optimizer = true

[rpc_endpoints]
mainnet = "${ETH_RPC_URL}"
1 change: 0 additions & 1 deletion lib/ds-test
Submodule ds-test deleted from 0a5da5
1 change: 1 addition & 0 deletions lib/dss-test
Submodule dss-test added at 28000a
92 changes: 44 additions & 48 deletions src/VoteDelegate.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// SPDX-FileCopyrightText: © 2021 Dai Foundation <www.daifoundation.org>
// SPDX-License-Identifier: AGPL-3.0-or-later

// Copyright (C) 2021 Dai Foundation

//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
Expand All @@ -15,104 +14,101 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

// VoteDelegate - delegate your vote
pragma solidity 0.6.12;
pragma solidity ^0.8.16;

interface TokenLike {
function approve(address, uint256) external returns (bool);
function pull(address, uint256) external;
function push(address, uint256) external;
interface GemLike {
oldchili marked this conversation as resolved.
Show resolved Hide resolved
function approve(address, uint256) external;
function transfer(address, uint256) external;
function transferFrom(address, address, uint256) external;
}

interface ChiefLike {
function GOV() external view returns (TokenLike);
function IOU() external view returns (TokenLike);
function GOV() external view returns (GemLike);
function IOU() external view returns (GemLike);
oldchili marked this conversation as resolved.
Show resolved Hide resolved
function lock(uint256) external;
function free(uint256) external;
function vote(address[] calldata) external returns (bytes32);
function vote(bytes32) external;
}

interface PollingLike {
function withdrawPoll(uint256) external;
function vote(uint256, uint256) external;
function withdrawPoll(uint256[] calldata) external;
function vote(uint256[] calldata, uint256[] calldata) external;
}

contract VoteDelegate {
// --- storage variables ---

mapping(address => uint256) public stake;
address public immutable delegate;
TokenLike public immutable gov;
TokenLike public immutable iou;
ChiefLike public immutable chief;
PollingLike public immutable polling;
uint256 public immutable expiration;

// --- immutables ---

address immutable public delegate;
GemLike immutable public gov;
ChiefLike immutable public chief;
PollingLike immutable public polling;

// --- events ---

event Lock(address indexed usr, uint256 wad);
event Free(address indexed usr, uint256 wad);

constructor(address _chief, address _polling, address _delegate) public {
chief = ChiefLike(_chief);
polling = PollingLike(_polling);
delegate = _delegate;
expiration = block.timestamp + 365 days;
// --- constructor ---

TokenLike _gov = gov = ChiefLike(_chief).GOV();
TokenLike _iou = iou = ChiefLike(_chief).IOU();
constructor(address chief_, address polling_, address delegate_) {
chief = ChiefLike(chief_);
polling = PollingLike(polling_);
delegate = delegate_;

_gov.approve(_chief, type(uint256).max);
_iou.approve(_chief, type(uint256).max);
}
gov = ChiefLike(chief_).GOV();

function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x + y) >= x, "VoteDelegate/add-overflow");
gov.approve(chief_, type(uint256).max);
ChiefLike(chief_).IOU().approve(chief_, type(uint256).max);
}

// --- modifiers ---

modifier delegate_auth() {
require(msg.sender == delegate, "VoteDelegate/sender-not-delegate");
_;
}

modifier live() {
require(block.timestamp < expiration, "VoteDelegate/delegation-contract-expired");
_;
}
// --- gov owner functions

function lock(uint256 wad) external live {
stake[msg.sender] = add(stake[msg.sender], wad);
gov.pull(msg.sender, wad);
function lock(uint256 wad) external {
gov.transferFrom(msg.sender, address(this), wad);
chief.lock(wad);
iou.push(msg.sender, wad);
stake[msg.sender] += wad;

emit Lock(msg.sender, wad);
}

function free(uint256 wad) external {
require(stake[msg.sender] >= wad, "VoteDelegate/insufficient-stake");

stake[msg.sender] -= wad;
iou.pull(msg.sender, wad);
unchecked { stake[msg.sender] -= wad; }
chief.free(wad);
gov.push(msg.sender, wad);
gov.transfer(msg.sender, wad);

emit Free(msg.sender, wad);
}

function vote(address[] memory yays) external delegate_auth live returns (bytes32 result) {
// --- delegate executive voting functions

function vote(address[] memory yays) external delegate_auth returns (bytes32 result) {
result = chief.vote(yays);
}

function vote(bytes32 slate) external delegate_auth live {
function vote(bytes32 slate) external delegate_auth {
chief.vote(slate);
}

// Polling vote
function votePoll(uint256 pollId, uint256 optionId) external delegate_auth live {
// --- delegate poll voting functions

function votePoll(uint256 pollId, uint256 optionId) external delegate_auth {
polling.vote(pollId, optionId);
}

function votePoll(uint256[] calldata pollIds, uint256[] calldata optionIds) external delegate_auth live {
function votePoll(uint256[] calldata pollIds, uint256[] calldata optionIds) external delegate_auth {
polling.vote(pollIds, optionIds);
}
}
Loading