Skip to content

Commit

Permalink
Merge pull request #6 from decent-dao/develop
Browse files Browse the repository at this point in the history
Update main with existing deployments
  • Loading branch information
herbig authored Oct 21, 2022
2 parents 3303477 + 6da7583 commit b9bb9a6
Show file tree
Hide file tree
Showing 39 changed files with 7,763 additions and 747 deletions.
82 changes: 0 additions & 82 deletions contracts/CallbackGnosis.sol

This file was deleted.

8 changes: 4 additions & 4 deletions contracts/FractalModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,16 @@ contract FractalModule is IFractalModule, Module {
__Ownable_init();
(
address _owner, // Controlling DAO
address _avatar, // GSafe // Address(0) == msg.sender
address _target, // GSafe or Modifier // Address(0) == msg.sender
address _avatar,
address _target,
address[] memory _controllers // Authorized controllers
) = abi.decode(
initializeParams,
(address, address, address, address[])
);

setAvatar(_avatar == address(0) ? msg.sender : _avatar);
setTarget(_target == address(0) ? msg.sender : _target);
setAvatar(_avatar);
setTarget(_target);
addControllers(_controllers);
transferOwnership(_owner);
}
Expand Down
65 changes: 65 additions & 0 deletions contracts/TokenClaim.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;

import "./interfaces/ITokenClaim.sol";
import "./VotesToken.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

contract TokenClaim is FactoryFriendly, ITokenClaim {
using SafeERC20 for IERC20;

address public childToken;
address public parentToken;
uint256 public snapShotId;
uint256 public parentAllocation;
mapping(address => bool) public claimed;

/// @notice Initialize function, will be triggered when a new proxy is deployed
/// @param initializeParams Parameters of initialization encoded
function setUp(bytes memory initializeParams) public override initializer {
__Ownable_init();
(
address _childTokenFunder,
address _parentToken,
address _childToken,
uint256 _parentAllocation
) = abi.decode(initializeParams, (address, address, address, uint256));

childToken = _childToken;
parentToken = _parentToken;
parentAllocation = _parentAllocation;

snapShotId = VotesToken(_parentToken).captureSnapShot();

IERC20(_childToken).transferFrom(_childTokenFunder, address(this), _parentAllocation);

emit TokenClaimCreated(_parentToken, _childToken, _parentAllocation, snapShotId);
}

/// @notice This function allows pToken holders to claim cTokens
/// @param claimer Address which is being claimed for
function claimToken(address claimer) external {
uint256 amount = getClaimAmount(claimer); // Get user balance

if (amount == 0) revert NoAllocation();

claimed[claimer] = true;

IERC20(childToken).safeTransfer(claimer, amount); // transfer user balance

emit TokenClaimed(parentToken, childToken, claimer, amount);
}

/// @notice Gets a users child token claimable amount
/// @param claimer Address which is being claimed for
/// @return cTokenAllocation Users cToken allocation
function getClaimAmount(address claimer)
public
view
returns (uint256)
{
return claimed[claimer] ? 0 :
(VotesToken(parentToken).balanceOfAt(claimer, snapShotId) * parentAllocation) /
VotesToken(parentToken).totalSupplyAt(snapShotId);
}
}
131 changes: 29 additions & 102 deletions contracts/VetoERC20Voting.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,14 @@
pragma solidity ^0.8.0;

import "./interfaces/IVetoGuard.sol";
import "./interfaces/IVetoERC20Voting.sol";
import "./interfaces/IVetoVoting.sol";
import "./TransactionHasher.sol";
import "@gnosis.pm/safe-contracts/contracts/common/Enum.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@gnosis.pm/zodiac/contracts/factory/FactoryFriendly.sol";
import "@openzeppelin/contracts/governance/utils/IVotes.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

/// @notice A contract for casting veto votes with an ERC20 votes token
contract VetoERC20Voting is
IVetoERC20Voting,
TransactionHasher,
Initializable,
Ownable
{
contract VetoERC20Voting is IVetoVoting, TransactionHasher, FactoryFriendly {
uint256 public vetoVotesThreshold; // Number of votes required to veto a transaction
uint256 public freezeVotesThreshold; // Number of freeze votes required to activate a freeze
uint256 public freezeProposalCreatedBlock; // Block number the freeze proposal was created at
Expand All @@ -28,23 +22,23 @@ contract VetoERC20Voting is
mapping(address => mapping(bytes32 => bool)) public userHasVoted;
mapping(address => mapping(uint256 => bool)) public userHasFreezeVoted;

/// @notice Initializes the contract that can only be called once
/// @param _owner The owner address that can update configurable parameters
/// @param _vetoVotesThreshold The number of votes required to veto a transaction
/// @param _freezeVotesThreshold The number of votes required to freeze the DAO
/// @param _freezeProposalBlockDuration The number of blocks a freeze proposal has to succeed
/// @param _freezeBlockDuration The number of blocks a freeze last, from time of freeze proposal creation
/// @param _votesToken The address of the VotesToken contract
/// @param _vetoGuard The address of the VetoGuard contract
function initialize(
address _owner,
uint256 _vetoVotesThreshold,
uint256 _freezeVotesThreshold,
uint256 _freezeProposalBlockDuration,
uint256 _freezeBlockDuration,
address _votesToken,
address _vetoGuard
) external initializer {
/// @notice Initialize function, will be triggered when a new proxy is deployed
/// @param initializeParams Parameters of initialization encoded
function setUp(bytes memory initializeParams) public override initializer {
__Ownable_init();
(
address _owner,
uint256 _vetoVotesThreshold,
uint256 _freezeVotesThreshold,
uint256 _freezeProposalBlockDuration,
uint256 _freezeBlockDuration,
address _votesToken,
address _vetoGuard
) = abi.decode(
initializeParams,
(address, uint256, uint256, uint256, uint256, address, address)
);

_transferOwnership(_owner);
vetoVotesThreshold = _vetoVotesThreshold;
freezeVotesThreshold = _freezeVotesThreshold;
Expand Down Expand Up @@ -93,8 +87,7 @@ contract VetoERC20Voting is
emit VetoVoteCast(msg.sender, _transactionHash, vetoVotes, _freeze);
}

/// @notice Allows a user to cast a freeze vote if there is an active freeze proposal
/// @notice If there isn't an active freeze proposal, it is created and the user's votes are cast
/// @notice Allows user to cast a freeze vote, creating a freeze proposal if necessary
function castFreezeVote() public {
uint256 userVotes;

Expand Down Expand Up @@ -137,7 +130,6 @@ contract VetoERC20Voting is

/// @notice Unfreezes the DAO, only callable by the owner
function defrost() public onlyOwner {
require(isFrozen(), "DAO is not already frozen");
freezeProposalCreatedBlock = 0;
freezeProposalVoteCount = 0;
}
Expand Down Expand Up @@ -178,82 +170,17 @@ contract VetoERC20Voting is
}

/// @notice Returns whether the specified transaction has been vetoed
/// @param to Destination address.
/// @param value Ether value.
/// @param data Data payload.
/// @param operation Operation type.
/// @param safeTxGas Gas that should be used for the safe transaction.
/// @param baseGas Gas costs for that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)
/// @param gasPrice Maximum gas price that should be used for this transaction.
/// @param gasToken Token address (or 0 if ETH) that is used for the payment.
/// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).
/// @param _transactionHash The hash of the transaction data
/// @return bool True if the transaction is vetoed
function getIsVetoed(
address to,
uint256 value,
bytes memory data,
Enum.Operation operation,
uint256 safeTxGas,
uint256 baseGas,
uint256 gasPrice,
address gasToken,
address payable refundReceiver
) external view returns (bool) {
return
transactionVetoVotes[
getTransactionHash(
to,
value,
data,
operation,
safeTxGas,
baseGas,
gasPrice,
gasToken,
refundReceiver
)
] > vetoVotesThreshold;
}

/// @notice Returns the number of votes that have been cast to veto the specified transaction
/// @param to Destination address.
/// @param value Ether value.
/// @param data Data payload.
/// @param operation Operation type.
/// @param safeTxGas Gas that should be used for the safe transaction.
/// @param baseGas Gas costs for that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)
/// @param gasPrice Maximum gas price that should be used for this transaction.
/// @param gasToken Token address (or 0 if ETH) that is used for the payment.
/// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).
/// @return uint256 The number of veto votes that have been cast
function getVetoVotes(
address to,
uint256 value,
bytes memory data,
Enum.Operation operation,
uint256 safeTxGas,
uint256 baseGas,
uint256 gasPrice,
address gasToken,
address payable refundReceiver
) external view returns (uint256) {
return
transactionVetoVotes[
getTransactionHash(
to,
value,
data,
operation,
safeTxGas,
baseGas,
gasPrice,
gasToken,
refundReceiver
)
];
function getIsVetoed(bytes32 _transactionHash)
external
view
returns (bool)
{
return transactionVetoVotes[_transactionHash] > vetoVotesThreshold;
}

/// @notice Returns true if the DAO is currently frozen
/// @notice Returns true if the DAO is currently frozen, false otherwise
/// @return bool Indicates whether the DAO is currently frozen
function isFrozen() public view returns (bool) {
if (
Expand Down
Loading

0 comments on commit b9bb9a6

Please sign in to comment.