Skip to content

Commit cbbbe25

Browse files
authored
Merge pull request #47 from Basalt-Foundation/fix/audit-r2-storage
fix: remediate round 2 audit — storage layer (#32)
2 parents e3beeb8 + 5a06eb3 commit cbbbe25

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

src/api/Basalt.Api.Rest/RestApiEndpoints.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -679,14 +679,17 @@ public static void MapBasaltEndpoints(
679679
// If the contract storage format changes, this endpoint must be updated accordingly.
680680
app.MapGet("/v1/pools", () =>
681681
{
682+
// S2-03: Fork state for consistent multi-read snapshot
683+
var snapshot = stateDb.Fork();
684+
682685
var contractAddr = new Address(new byte[]
683686
{
684687
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
685688
0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0x05,
686689
});
687690

688691
// Read _nextPoolId (key "sp_next")
689-
var nextIdRaw = stateDb.GetStorage(contractAddr, Blake3Hasher.Hash(Encoding.UTF8.GetBytes("sp_next")));
692+
var nextIdRaw = snapshot.GetStorage(contractAddr, Blake3Hasher.Hash(Encoding.UTF8.GetBytes("sp_next")));
690693
ulong poolCount = 0;
691694
if (nextIdRaw is { Length: >= 9 } && nextIdRaw[0] == 0x01)
692695
poolCount = System.Buffers.Binary.BinaryPrimitives.ReadUInt64LittleEndian(nextIdRaw.AsSpan(1));
@@ -697,19 +700,19 @@ public static void MapBasaltEndpoints(
697700
var idStr = i.ToString();
698701

699702
// Operator (key "sp_ops:{id}", tag 0x07 = string)
700-
var opsRaw = stateDb.GetStorage(contractAddr, Blake3Hasher.Hash(Encoding.UTF8.GetBytes("sp_ops:" + idStr)));
703+
var opsRaw = snapshot.GetStorage(contractAddr, Blake3Hasher.Hash(Encoding.UTF8.GetBytes("sp_ops:" + idStr)));
701704
var operatorHex = opsRaw is { Length: > 1 } && opsRaw[0] == 0x07
702705
? Encoding.UTF8.GetString(opsRaw.AsSpan(1))
703706
: "";
704707

705708
// Total stake (key "sp_total:{id}", tag 0x0A = UInt256)
706-
var stakeRaw = stateDb.GetStorage(contractAddr, Blake3Hasher.Hash(Encoding.UTF8.GetBytes("sp_total:" + idStr)));
709+
var stakeRaw = snapshot.GetStorage(contractAddr, Blake3Hasher.Hash(Encoding.UTF8.GetBytes("sp_total:" + idStr)));
707710
var totalStake = stakeRaw is { Length: >= 33 } && stakeRaw[0] == 0x0A
708711
? new UInt256(stakeRaw.AsSpan(1, 32)).ToString()
709712
: "0";
710713

711714
// Total rewards (key "sp_rewards:{id}", tag 0x0A = UInt256)
712-
var rewardsRaw = stateDb.GetStorage(contractAddr, Blake3Hasher.Hash(Encoding.UTF8.GetBytes("sp_rewards:" + idStr)));
715+
var rewardsRaw = snapshot.GetStorage(contractAddr, Blake3Hasher.Hash(Encoding.UTF8.GetBytes("sp_rewards:" + idStr)));
713716
var totalRewards = rewardsRaw is { Length: >= 33 } && rewardsRaw[0] == 0x0A
714717
? new UInt256(rewardsRaw.AsSpan(1, 32)).ToString()
715718
: "0";

src/storage/Basalt.Storage/Trie/NibblePath.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,15 @@ public NibblePath(byte[] data, int offset, int length)
2424

2525
/// <summary>
2626
/// Get the nibble at the specified index.
27+
/// S2-05: Validates index is within bounds.
2728
/// </summary>
2829
public byte this[int index]
2930
{
3031
get
3132
{
33+
if ((uint)index >= (uint)_length)
34+
throw new ArgumentOutOfRangeException(nameof(index), index,
35+
$"Index must be in range [0, {_length}).");
3236
int absoluteIndex = _offset + index;
3337
int byteIndex = absoluteIndex / 2;
3438
return (absoluteIndex % 2 == 0)
@@ -39,17 +43,23 @@ public byte this[int index]
3943

4044
/// <summary>
4145
/// Create a sub-path starting from the given offset.
46+
/// S2-05: Validates start is within bounds.
4247
/// </summary>
4348
public NibblePath Slice(int start)
4449
{
50+
if (start < 0 || start > _length)
51+
throw new ArgumentOutOfRangeException(nameof(start));
4552
return new NibblePath(_data, _offset + start, _length - start);
4653
}
4754

4855
/// <summary>
4956
/// Create a sub-path with specified offset and length.
57+
/// S2-05: Validates start and length are within bounds.
5058
/// </summary>
5159
public NibblePath Slice(int start, int length)
5260
{
61+
if (start < 0 || length < 0 || start + length > _length)
62+
throw new ArgumentOutOfRangeException(nameof(start));
5363
return new NibblePath(_data, _offset + start, length);
5464
}
5565

0 commit comments

Comments
 (0)