Smart contracts

WAR Token

The WAR token contract is an ERC20 allowing the MINTER Role to mint tokens (Role given to the Minter contract) and the BURNER Role to burn tokens (Role given to the Redeemer contract)

User methods :

Basic ERC20 methods :

function approve(address spender, uint256 amount) public virtual returns (bool)
function transfer(address to, uint256 amount) public virtual returns (bool)
function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual returns (bool)
function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual

Minter

The Minter contracts allows to send CVX and/or AURA tokens (and later, any new other token listed in Warlord) to mint WAR tokens. The tokens received by the Minter are directly sent to the Lockers to be locked into vlTokens.

User methods :

mint

   /**
   * @notice Mints WAR token based of the amount of token deposited
   * @param vlToken Address of the token to deposit
   * @param amount Amount to deposit
   */
  function mint(address vlToken, uint256 amount) external

mintMultiple

   /**
   * @notice Mints WAR token based of the amount of token deposited, mints for the given receiver
   * @param vlToken Address of the token to deposit
   * @param amount Amount to deposit
   * @param receiver Address to receive the minted WAR
   */
  function mint(address vlToken, uint256 amount, address receiver) external

Ratios

The Ratios contract handle the calculations between WAR and the underlying token (currently CVX & AURA). Ratios are defined when listing an asset, allowing to calculate how many WAR to mint for a given amount of tokens, or how many tokens to return when burning WAR.

The current ratios are:

  • CVX 1:1 WAR

  • AURA 2:1 WAR

User methods :

getTokenRatio

   /**
   * @notice Returns the ratio for a given token
   * @param token Address of the token
   */
  function getTokenRatio(address token) external view returns (uint256)

getMintAmount

   /**
   * @notice Returns the amount of WAR to mint for a given amount of token
   * @param token Address of the token
   * @param amount Amount of token received
   * @return mintAmount (uint256) : Amount to mint
   */
  function getMintAmount(address token, uint256 amount) external view returns (uint256 mintAmount)

getBurnAmount

   /**
   * @notice Returns the amount of token to redeem for a given amount of WAR burned
   * @param token Address of the token
   * @param burnAmount Amount of WAR to burn
   * @return redeemAmount (uint256) : Redeem amount
   */
  function getBurnAmount(address token, uint256 burnAmount) external view returns (uint256 redeemAmount)

Zap

The Zap contract allows users to mint WAR using CVX and/or AURA, and directly stake them into stkWAR in one transaction.

User methods :

zap

   /**
   * @notice Zaps a given amount of tokens to mint WAR and stake it
   * @param token Address of the token to deposit
   * @param amount Amount to deposit
   * @param receiver Address to stake for
   * @return uint256 : Amount of WAR staked
   */
  function zap(address token, uint256 amount, address receiver) external returns (uint256)

zapMultiple

   /**
   * @notice Zaps given amounts of tokens to mint WAR and stake it
   * @param vlTokens List of token addresses to deposit
   * @param amounts Amounts to deposit for each token
   * @param receiver Address to stake for
   * @return uint256 : Amount of WAR staked
   */
  function zapMultiple(address[] calldata vlTokens, uint256[] calldata amounts, address receiver)
    external
    returns (uint256)

Lockers

The lockers contract receive tokens allowed in to Warlord (ex: CVX, AURA) and lock them into their vlToken (vlCVX, vlAURA) when received from the Minter.

All yield generated by those vlTokens are harvest and sent to the Controller to be process and distributed.

The Lockers delegate their voting power to be used to received maximized Gauge vote incentives (currently delegating to the Paladin Delegation address), and all the incentives received are also send to the Controller to be processed and distributed.

External methods :

getCurrentLockedTokens

   /**
   * @notice Returns the current total amount of locked tokens for this Locker
   */
  function getCurrentLockedTokens() external view override returns (uint256)

processUnlocks

(Sends the unlocked token to the Redeemer if needed, otherwise re-locks them)

   /**
   * @notice Processes the unlock of tokens
   */
  function processUnlock() external

harvest

(Sends all harvested rewards to the Controller)

   /**
   * @notice Harvest rewards
   */
  function harvest() external

Farmers

The Farmers contracts are set for some specific tokens received as rewards from the Lockers : cvxCRV and auraBAL, to be staked inot their specific staking contract, so it can farm more rewards while not claimed by stkWAR stakers.

When the cvxCRV or auraBAL are claimed by stkWAR stakers, their are directly unstaked and sent to the claimer.

All rewards farmed by the Farmers are harvested and sent to the Controller to be process and distributed.

External methods :

getCurrentIndex

   /**
   * @notice Returns the current reward index for the Staker distribution
   * @return uint256 : current index
   */
  function getCurrentIndex() external view returns (uint256)

harvest

(Sends all harvested rewards to the Controller)

   /**
   * @notice Harvests rewards from the staking contract
   */
  function harvest() external

Controller

The Controller contracts receives rewards from different sources from the Warlord system:

  • Lockers (vlToken rewards & vote incentives)

  • Farmers

  • Redeemer fees

All rewards received are then processed, following the logic:

  • CVX & AURA are sent to the Minter to mint more WAR, and the WAR is distributed to the Stakers

  • auraBAL & cvxCRV are sent to the Farmers. An index is updated allowing to track the rewards stkWAR stakers have accrued in those tokens

  • WAR & PAL are directly sent to the Staker to be distributed as is

  • All the other rewards are set available for the Swapper to pull, swap into WETH and distribute the WETH via the Staker contract

External methods :

harvest

   /**
   * @notice Harvests rewards from a given Harvestable contract
   * @param target Address of the contract to harvest from
   */
  function harvest(address target) external

harvestMultiple

   /**
   * @notice Harvests rewards from Harvestable contracts
   * @param targets List of contracts to harvest from
   */
  function harvestMultiple(address[] calldata targets) external

harvestAll

   /**
   * @notice Harvest from all listed Harvestable contracts (Locker & Farmers)
   */
  function harvestAll() external

process

   /**
   * @notice Processes a token held in this contract
   * @param token Address of the token to process
   */
  function process(address token) external

processMultiple

   /**
   * @notice Processes tokens held in this contract
   * @param tokens List of tokens to process
   */
  function processMultiple(address[] calldata tokens) external

harvestAndProcess

   /**
   * @notice Harvests rewards from a given Harvestable contract & process the received rewards
   * @param target Address of the contract to harvest from
   */
  function harvestAndProcess(address target) external

harvestAllAndProcessAll

   /**
   * @notice Harvest from all listed Harvestable contracts (Locker & Farmers) & process the received rewards
   */
  function harvestAllAndProcessAll() external

Redeemer

The Redeemer contract allows WAR holders to burn their WAR tokens to redeem CVX & AURA. The weights of CVX and AURA redeemed depend on the current holding in the Lockers at the time of the redeem, and the state of the redeem queues for each token.

When redeeming, Redeem Tickets are created for the user, indicating when the user will be able to execute the tickets and receive the CVX and AURA tokens. Tickets are organized as a queue, summing up the amount of CVX and AURA needed to be unlocked from the Lockers. Each period, when the Lockers are able to unlocks tokens, they are sent to the Redeemer (based on the needed amount in the Redeem queues), allowing the 1st tickets in the queue to be executed and the tokens to be received by the user.

User methods :

queuedForWithdrawal

   /**
   * @notice Returns the amount queued for withdrawal for a given token
   * @param token Address of the token
   * @return uint256 : amount queued
   */
  function queuedForWithdrawal(address token) public view returns (uint256)

getUserRedeemTickets

   /**
   * @notice Returns an user Redeem tickets
   * @param user Address of the user
   * @return RedeemTicket[] : user Redeem tickets
   */
  function getUserRedeemTickets(address user) external view returns (RedeemTicket[] memory)

getUserActiveRedeemTickets

   /**
   * @notice Returns an user active Redeem tickets
   * @param user Address of the user
   * @return RedeemTicket[] : user active Redeem tickets
   */
  function getUserActiveRedeemTickets(address user) external view returns (RedeemTicket[] memory)

getTokenWeights

   /**
   * @notice Returns the current weights of all listed tokens for redeeming
   * @return TokenWeight[] : weights and address for each token
   */
  function getTokenWeights() external view returns (TokenWeight[] memory)

joinQueue

   /**
   * @notice Joins the redeem queue for each token & burns the given amount of WAR token
   * @param amount Amount of WAR to burn
   */
  function joinQueue(uint256 amount) external

redeem

   /**
   * @notice Redeems tickets to receive the tokens
   * @param tickets List of tickets to redeem
   * @param receiver Address to receive the tokens
   */
  function redeem(uint256[] calldata tickets, address receiver) external

Staker

The Staker is a contract allowing users to stake WAR token to receive stkWAR shares. the stkWAR shares are receiving the rewards generated from the Warlord protocol (rewards from Lockers, Farmers, Gauge vote incentives & Reddem fees).

All the rewards (expect from the Farmers) are distributed over a 1 week period.

Users can unstake their WAR token with no cooldown.

User methods :

getRewardTokens

   /**
   * @notice Get the list of all reward tokens
   * @return address[] : List of reward tokens
   */
  function getRewardTokens() external view returns (address[] memory)

getUserRewardState

   /**
   * @notice Get the current reward state of an user for a given reward token
   * @param reward Address of the reward token
   * @param user Address of the user
   * @return UserRewardState : User reward state
   */
  function getUserRewardState(address reward, address user) external view returns (UserRewardState memory)

getUserAccruedRewards

   /**
   * @notice Get the current amount of rewards accrued by an user for a given reward token
   * @param reward Address of the reward token
   * @param user Address of the user
   * @return uint256 : amount of rewards accrued
   */
  function getUserAccruedRewards(address reward, address user) external view returns (uint256)

getUserTotalClaimableRewards

   /**
   * @notice Get all current claimable amount of rewards for all reward tokens for a given user
   * @param user Address of the user
   * @return UserClaimableRewards[] : Amounts of rewards claimable by reward token
   */
  function getUserTotalClaimableRewards(address user) external view returns (UserClaimableRewards[] memory)

stake

  // Can give MAX_UINT256 to stake full balance
  /**
   * @notice Stake WAR tokens
   * @param amount Amount to stake
   * @param receiver Address of the address to stake for
   * @return uint256 : scaled amount for the deposit
   */
  function stake(uint256 amount, address receiver) external returns (uint256)

unstake

  // Can give MAX_UINT256 to unstake full balance
  /**
   * @notice Unstake WAR tokens
   * @param amount Amount to unstake
   * @param receiver Address to receive the tokens
   * @return uint256 : amount unstaked
   */
  function unstake(uint256 amount, address receiver) external returns (uint256)

claimRewards

   /**
   * @notice Claim the accrued rewards for a given reward token
   * @param reward Address of the reward token
   * @param receiver Address to receive the rewards
   * @return uint256 : Amount of rewards claimed
   */
  function claimRewards(address reward, address receiver) external returns (uint256)

claimAllRewards

   /**
   * @notice Claim all accrued rewards for all reward tokens
   * @param receiver Address to receive the rewards
   * @return UserClaimedRewards[] : Amounts of reward claimed
   */
  function claimAllRewards(address receiver) external nonReentrant whenNotPaused returns (UserClaimedRewards[] memory)

updateRewardState

   /**
   * @notice Update the reward state for a given reward token
   * @param reward Address of the reward token
   */
  function updateRewardState(address reward) external

updateAllRewardStates

   /**
   * @notice Update the reward state for all reward tokens
   */
  function updateAllRewardStates() external

Audit :

At the current stage, Warlord has not undergone a formal security audit. However, the contracts have undergone extensive internal testing & external reviews, giving confidence in the existing security measures implemented. We acknowledge the importance of security audits and will consider conducting them as the project evolves. We strongly advise users to conduct their own research and make informed decisions based on their individual risk tolerance.

Last updated