> For the complete documentation index, see [llms.txt](https://reports.immunefi.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://reports.immunefi.com/alchemix/31566-sc-medium-checkpoints-wont-update-block-number-in-point-b....md).

# 31566 - \[SC - Medium] Checkpoints wont update block number in point b...

Submitted on May 21st 2024 at 12:27:19 UTC by @copperscrewer for [Boost | Alchemix](https://immunefi.com/bounty/alchemix-boost/)

Report ID: #31566

Report type: Smart Contract

Report severity: Medium

Target: <https://github.com/alchemix-finance/alchemix-v2-dao/blob/main/src/VotingEscrow.sol>

Impacts:

* Contract fails to deliver promised returns, but doesn't lose value

## Description

## Brief/Intro

Voting Escrow Checkpoints won't update block number in point because of a Rounding issue, currently the block time in Ethereum is around \~ 12 seconds, There is an attempt to calculate block slope by the difference of the block number multiplied by a MULTIPLIER and then divided by the difference in block.timestamp.

There is an issue because of the precision of the division.

## Vulnerability Details

In \_checkpoint of VotingEscrow there is a line

`blockSlope = (MULTIPLIER * (block.number - lastPoint.blk)) / (block.timestamp - lastPoint.ts);`

Here blockSlope will always be zero as for each block.number the difference in block.timestamp is around \~ 12 seconds. The MULTIPLIER : 2 is too low to cover that and as a result it becomes zero as the numerator is lesser than the denominator

`lastPoint.blk = initialLastPoint.blk + (blockSlope * (_time - initialLastPoint.ts)) / MULTIPLIER;` as a result will be stagnant and never be updated.

## Impact Details

The Point objects used in \_checkpoint never have their block value updated. This will affect any off-calculation/computation that relies on the block number for points to make a transaction

## Remediation

Increase MULTIPLIER to a much higher value \~ 10000

## Proof of Concept

Run `forge test --match-test testRounding --fork-url https://eth-mainnet.alchemyapi.io/v2/[API_KETY] -vvv`

after pasting this function in VotingEscrow\.t.sol

```solidity
function testRounding() external
    {        

        VotingEscrowTest.Point memory lastPoint;
        (int256 a, int256 b, uint256 c, uint256 d) = veALCX.pointHistory(veALCX.epoch());
        lastPoint = Point(a,b,c,d);

        hevm.warp(block.timestamp + 12);
        hevm.roll(block.number + 1);
        
        console.log("block.timestamp : ", block.timestamp, "\tBlock.number : ", block.number);
        uint256 blockSlope = (MULTIPLIER * (block.number - lastPoint.blk)) / (block.timestamp - lastPoint.ts);
        console.log("blockSlope is ", blockSlope);

        veALCX.checkpoint();
        hevm.warp(block.timestamp + 12);
        hevm.roll(block.number + 1);

        ( a,  b,  c,  d) = veALCX.pointHistory(veALCX.epoch());
        lastPoint = Point(a,b,c,d);

        console.log("block.timestamp : ", block.timestamp, "\tBlock.number : ", block.number);
        blockSlope = (MULTIPLIER * (block.number - lastPoint.blk)) / (block.timestamp - lastPoint.ts);
        console.log("blockSlope is ", blockSlope);

        veALCX.checkpoint();

        hevm.warp(block.timestamp + 12*10);
        hevm.roll(block.number + 1*10);

        ( a,  b,  c,  d) = veALCX.pointHistory(veALCX.epoch());
        lastPoint = Point(a,b,c,d);
        
        console.log("block.timestamp : ", block.timestamp, "\tBlock.number : ", block.number);
        blockSlope = (MULTIPLIER * (block.number - lastPoint.blk)) / (block.timestamp - lastPoint.ts);
        console.log("blockSlope is ", blockSlope);

        veALCX.checkpoint();

    }
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://reports.immunefi.com/alchemix/31566-sc-medium-checkpoints-wont-update-block-number-in-point-b....md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
