Strategies
Security Considerations

Security Considerations

Security Considerations

Reentrancy

Reentrancy attacks are a well known method of hacking smart contracts. \ The Quadratic Funding contract uses openzeppelin's ReentrancyGuard (opens in a new tab) to prevent such attacks

function vote(bytes[] calldata encodedVotes, address voterAddress) external override payable nonReentrant isRoundContract {

Encoding Votes

The vote method requires voting information to be encoded. Your vote method will need to decode the information in the body.

 for (uint256 i = 0; i < encodedVotes.length; i++) {
      /// @dev decode encoded vote
      (
        address _token,
        uint256 _amount,
        address _grantAddress,
        bytes32 _projectId,
        uint256 _applicationIndex
      ) = abi.decode(encodedVotes[i], (
        address,
        uint256,
        address,
        bytes32,
        uint256
      ));

Checking the Token

There should be a check to ensure that the token being sent is a valid token. This prevents attacks by users minting new tokens or trying to vote with unaccepted tokens. Some voting strategies will allow voting with multiple tokens, which will need to be handled in the code logic.

The OpenZeppelin Address (opens in a new tab) and SafeERC20Upgradeable (opens in a new tab) contracts provide safe transfer methods for native tokens and ERC20 tokens.

Round Address Checks

The vote method should only be callable by the round address that was set when the contract was initialized. The voting strategy interface includes a modifier isRoundContract that can be used to enforce this.

function vote(bytes[] calldata encodedVotes, address voterAddress) external override payable isRoundContract {