Security Analysis of Using Hedgey for Proposal Payment Vesting

Abstract

OpenZeppelin, as the Security Member of the ARDC, was asked to review a draft proposal for WakeUp Labs building a front-end interface to force transaction inclusion during sequencer downtime. This proposal is effectively a grant request for front-end work to allow users to submit transactions directly to L1 when the Arbitrum Sequencer experiences downtime. The proposal makes use of Hedgey’s BatchPlanner contract to distribute the payment through a vesting plan. We were asked to review the on-chain proposal to be executed and share any security concerns we had.

Summary

The proposal is made up of three different calls to be made from the L2 Treasury Timelock:

  1. It transfers $ARB 42,500 out of the DAO treasury to itself
  2. It then approves Hedgey’s BatchPlanner contract for the same amount
  3. Finally, it calls Hedgey’s BatchPlanner contract which transfers the tokens to itself and then finally to a “locker” contract which stores and administers the vesting plan.

Our simulation of this proposal was successful (i.e. did not revert) and our review of the contracts and their simulated behavior showed that the proposal provides two key features critical for the proposal’s success:

  1. the proposer had access to funds which vested according to the specified schedule
  2. the security council had the ability at all times to revoke any unvested tokens

Overall, we believe the proposal will execute successfully and meets the security expectations of the proposer and delegates.

Prepatory Calls

The first two calls of the proposal entirely involve Arbitrum contracts that should be well known to the community and have done these sort of transactions before. We did not focus our attention on the logic of these contracts.

Address Name Upgradeable? Description
0xF3FC178157fb3c87548bAA86F9d24BA38E649B58 TransparentUpgradeableProxy Yes DAO Treasury
0x912CE59144191C1204E64559FE8253a0e49E6548 TransparentUpgradeableProxy Yes $ARB Token
0xbFc1FECa8B09A5c5D3EFfE7429eBE24b9c09EF58 TransparentUpgradeableProxy Yes L2 Treasury Timelock

Hedgey Contracts And Behaviors

The third call relies on two contracts developed by Hedgey. These contracts were included in an audit performed by Consensys in June of 2023 and were deployed to the chain in August of 2023. We reviewed these contracts ourselves and deeply investigated the portions that related to the two key behaviors mentioned above.

Address Name Upgradeable? Deployed Description
0x3466EB008EDD8d5052446293D1a7D212cb65C646 BatchPlanner No 8 Aug 2023 Passes the vesting schedule through to VotingTokenVestingPlans
0x1bb64AF7FE05fc69c740609267d2AbE3e119Ef82 VotingTokenVestingPlans No 8 Aug 2023 Administers the vesting schedule

The first important note here is that a different Hedgey contract has recently suffered a security breach. The compromised contract is not used by the contracts in this proposal and does not interact with the proposal contracts in any way. The issue it exhibited was giving approval privileges to an unsanitized address. This specific issue is not present in the proposal contracts.

The first contract, BatchPlanner, is used simply as an entry point for creating the vesting schedule. It performs some sanitation checks on the data, transfers the entire grant amount to itself, approves the other Hedgey contract (VotingTokenVestingPlans) to later take those tokens, and then calls the other contract’s createPlan method with the vesting schedule data.

The second contract, VotingTokenVestingPlans, is the real work-horse of the vesting schedule and is referred to as the “locker” contract. It takes the grant tokens and starting from 1 Apr 2024 @ 12am UTC will vest $ARB 0.00323 per second (or roughly $ARB 1956.16 per week) until the final grant amount is entirely vested on 31 Aug 2024 @ 2am UTC. There is an initial cliff on 1 May 2024 @ 12am UTC where not tokens will be officially vest before then, but afterward all of the accrued, vesting tokens will become available. Below is a chart to show the total vested amount over time. Note that the on-chain vesting amounts don’t exactly match the numbers in the description of the proposal. These discrepancies are due to the authors rounding numbers to make the description more readable for the audience. They are, however, generally accurate.

With the grant transferred to the “locker” contract, some new functionality becomes available. It exposes a redeemPlans method which the proposer’s multi-sig can call to transfer vested grant tokens. It also exposes methods revokePlans and futureRevokePlans which the Arbitrum 7 of 12 Security Council contract can call to end the vesting schedule at either the time of call or a future, specified time and receive the tokens that will no longer vest. The Security Council contract can also call the transferFrom method to replace the proposer’s multi-sig as the owner of the grant. This is intended to be used in case the grant proposers lose access to their own multi-sig.

Interestingly, while the tokens themselves are not able to be transferred out of the locker except as scheduled, the locker does allow the proposer’s multi-sig to immediately gain the ability to delegate the entire grant’s voting power to another contract using its delegate* methods. In this way, the proposal will grant voting power to the proposers more than their actual ownership entails.

Conclusion

We looked for all sorts of ways in which the expected behaviors could fail or be frustrated. We simulated behaviors on chain to confirm their efficacy and we anticipate no issues at this time for this proposal.

For more information on OpenZeppelin’s role as Security Member of ARDC, please visit our Notion homepage.

6 Likes