In the _screeningVote function of StandardFunding.sol contract, specifically in the line where the votes parameter is converted to a uint128 using the SafeCast.toUint128 function. The issue is that the votes_ parameter is not limited to 128 bits, which can result in an integer overflow. If an attacker can successfully exploit this vulnerability, they could potentially gain control over the proposal, which could allow them to influence the outcome of the vote and potentially steal funds.
The SafeCast.toUint128() function is used to convert the votes_ parameter into a uint128 data type. The issue is that the votes_ parameter is not limited to 128 bits, which can result in an integer overflow.
For Example:
Alice creates a new proposal and sets the votesReceived value to the maximum possible value for a uint128 data type, which is 2^128 - 1.
Alice would call the _screeningVote function with the appropriate parameters, passing in her own address, the proposal object she created, and a votes_ parameter set to 2^129. Here is an example of the code she might use:
Note that proposalId should be the identifier for the proposal that Alice created earlier, and proposals should be the mapping that stores all the proposals.
Alice then calls the screeningVote function with a votes parameter that is larger than the maximum value that can be represented by a uint128 data type. Let's say Alice sets the votes_ parameter to 2^129.
Because of the integer overflow vulnerability in the SafeCast.toUint128 function used in the _screeningVote function, the votesReceived value will wrap around and start over from zero instead of throwing an error due to the overflow. The new value of votesReceived will be 2^129 - 1, which is smaller than the original value of 2^128 - 1 set by Alice.
Now that the votesReceived value has been manipulated by Alice, she effectively has full control over the proposal with a vote count of zero. She can manipulate the proposal in any way she wants, including changing the proposal's status or even stealing funds associated with the proposal.
Tools Used
vscode
Recommended Mitigation Steps
Replace the SafeCast.toUint128() function with a function that limits the votes_ parameter to 128 bits before conversion. Alternatively, convert the votes_ parameter to a larger data type before conversion to a uint128 data type to avoid integer overflow.
Lines of code
https://github.com/code-423n4/2023-05-ajna/blob/276942bc2f97488d07b887c8edceaaab7a5c3964/ajna-grants/src/grants/base/StandardFunding.sol#L711-L712
Vulnerability details
Impact
In the
_screeningVote
function of StandardFunding.sol contract, specifically in the line where the votes parameter is converted to a uint128 using theSafeCast.toUint128
function. The issue is that thevotes_
parameter is not limited to 128 bits, which can result in an integer overflow. If an attacker can successfully exploit this vulnerability, they could potentially gain control over the proposal, which could allow them to influence the outcome of the vote and potentially steal funds.Proof of Concept
#L711-L712
The
SafeCast.toUint128()
function is used to convert thevotes_
parameter into auint128
data type. The issue is that thevotes_
parameter is not limited to 128 bits, which can result in an integer overflow.For Example:
votesReceived
value to the maximum possible value for auint128
data type, which is 2^128 - 1.Alice would call the
_screeningVote
function with the appropriate parameters, passing in her own address, the proposal object she created, and avotes_
parameter set to 2^129. Here is an example of the code she might use:Note that
proposalId
should be the identifier for the proposal that Alice created earlier, andproposals
should be the mapping that stores all the proposals.Alice then calls the
screeningVote
function with a votes parameter that is larger than the maximum value that can be represented by a uint128 data type. Let's say Alice sets thevotes_
parameter to 2^129.Because of the integer overflow vulnerability in the
SafeCast.toUint128
function used in the_screeningVote
function, thevotesReceived
value will wrap around and start over from zero instead of throwing an error due to the overflow. The new value ofvotesReceived
will be 2^129 - 1, which is smaller than the original value of 2^128 - 1 set by Alice.Now that the votesReceived value has been manipulated by Alice, she effectively has full control over the proposal with a vote count of zero. She can manipulate the proposal in any way she wants, including changing the proposal's status or even stealing funds associated with the proposal.
Tools Used
vscode
Recommended Mitigation Steps
Replace the
SafeCast.toUint128()
function with a function that limits thevotes_
parameter to 128 bits before conversion. Alternatively, convert thevotes_
parameter to a larger data type before conversion to auint128
data type to avoid integer overflow.Assessed type
Under/Overflow