Skip to content

Commit

Permalink
# This is a combination of 2 commits.
Browse files Browse the repository at this point in the history
# This is the 1st commit message:

CR changes + test them

# This is the commit message #2:

use shell array
  • Loading branch information
Tofel committed Aug 5, 2024
1 parent 77f4a3e commit cb083ee
Show file tree
Hide file tree
Showing 5 changed files with 669 additions and 4 deletions.
16 changes: 12 additions & 4 deletions .github/workflows/solidity-foundry.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ jobs:
- 'contracts/src/v0.8/l2ep/**/*.sol'
liquiditymanager:
- 'contracts/src/v0.8/liquiditymanager/**/*.sol'
ll-feeds:
llo-feeds:
- 'contracts/src/v0.8/llo-feeds/**/*.sol'
operatorforwarder:
- 'contracts/src/v0.8/operatorforwarder/**/*.sol'
Expand Down Expand Up @@ -248,14 +248,22 @@ jobs:
- name: Run Slither
shell: bash
run: |
CHANGED="${{ needs.changes.outputs.sol_modified_files }}"
CHANGED_ARRAY=$(echo "$CHANGED" | tr ' ' ',')
CHANGED_ARRAY="${{ needs.changes.outputs.sol_modified_files }}"
# modify remappings so that solc can find dependencies
./contracts/scripts/ci/modify_remappings.sh contracts contracts/remappings.txt
mv remappings_modified.txt remappings.txt
./contracts/scripts/ci/generate_slither_report.sh "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.sha }}/" contracts/.slither.config-pr.json "." "$CHANGED_ARRAY" "contracts/slither-reports" "--solc-remaps @=contracts/node_modules/@"
for FILE in $CHANGED_ARRAY; do
PRODUCT=$(echo "$FILE" | awk -F'src/[^/]*/' '{print $2}' | cut -d'/' -f1)
echo "Running Slither for $FILE in $PRODUCT"
SLITHER_CONFIG="contracts/configs/slither/.slither.config-$PRODUCT-pr.json"
if [ ! -f $SLITHER_CONFIG ]; then
echo "No Slither config found for $PRODUCT, using default"
SLITHER_CONFIG="contracts/configs/slither/.slither.config-default-pr.json"
./contracts/scripts/ci/generate_slither_report.sh "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.sha }}/" "$SLITHER_CONFIG" "." "$FILE" "contracts/slither-reports" "--solc-remaps @=contracts/node_modules/@"
fi
done
- name: Print Slither summary
shell: bash
Expand Down
4 changes: 4 additions & 0 deletions contracts/configs/slither/.slither.config-ccip-pr.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"filter_paths": "(openzeppelin|mocks/|test/|tests/|testhelpers)",
"detectors_to_exclude": "pragma,solc-version,naming-convention,assembly,reentrancy-events,timestamp,calls-loop,unused-return"
}
4 changes: 4 additions & 0 deletions contracts/configs/slither/.slither.config-default-pr.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"filter_paths": "(openzeppelin|mocks/|test/|tests/|testhelpers)",
"detectors_to_exclude": "pragma"
}
92 changes: 92 additions & 0 deletions contracts/src/v0.8/ccip/AggregateRateLimiterNew.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.24;

import {IPriceRegistry} from "./interfaces/IPriceRegistry.sol";

import {OwnerIsCreator} from "./../shared/access/OwnerIsCreator.sol";
import {Client} from "./libraries/Client.sol";
import {RateLimiter} from "./libraries/RateLimiter.sol";
import {USDPriceWith18Decimals} from "./libraries/USDPriceWith18Decimals.sol";

/// @notice The aggregate rate limiter is a wrapper of the token bucket rate limiter
/// which permits rate limiting based on the aggregate value of a group of
/// token transfers, using a price registry to convert to a numeraire asset (e.g. USD).
contract AggregateRateLimiter is OwnerIsCreator {
using RateLimiter for RateLimiter.TokenBucket;
using USDPriceWith18Decimals for uint224;

error PriceNotFoundForToken(address token);

event AdminSet(address newAdmin);

// The address of the token limit admin that has the same permissions as the owner.
address internal s_admin;

// The token bucket object that contains the bucket state.
RateLimiter.TokenBucket private s_rateLimiter;

/// @param config The RateLimiter.Config
constructor(RateLimiter.Config memory config) {
s_rateLimiter = RateLimiter.TokenBucket({
rate: config.rate,
capacity: config.capacity,
tokens: config.capacity,
lastUpdated: uint32(block.timestamp),
isEnabled: config.isEnabled
});
}

/// @notice Consumes value from the rate limiter bucket based on the token value given.
function _rateLimitValue(uint256 value) internal {
s_rateLimiter._consume(value, address(0));
}

function _getTokenValue(
Client.EVMTokenAmount memory tokenAmount,
IPriceRegistry priceRegistry
) internal view returns (uint256) {
// not fetching validated price, as price staleness is not important for value-based rate limiting
// we only need to verify the price is not 0
uint224 pricePerToken = priceRegistry.getTokenPrice(tokenAmount.token).value;
if (pricePerToken == 0) revert PriceNotFoundForToken(tokenAmount.token);
return pricePerToken._calcUSDValueFromTokenAmount(tokenAmount.amount);
}

/// @notice Gets the token bucket with its values for the block it was requested at.
/// @return The token bucket.
function currentRateLimiterState() external view returns (RateLimiter.TokenBucket memory) {
return s_rateLimiter._currentTokenBucketState();
}

/// @notice Sets the rate limited config.
/// @param config The new rate limiter config.
/// @dev should only be callable by the owner or token limit admin.
function setRateLimiterConfig(RateLimiter.Config memory config) external onlyAdminOrOwner {
s_rateLimiter._setTokenBucketConfig(config);
}

// ================================================================
// │ Access │
// ================================================================

/// @notice Gets the token limit admin address.
/// @return the token limit admin address.
function getTokenLimitAdmin() external view returns (address) {
return s_admin;
}

/// @notice Sets the token limit admin address.
/// @param newAdmin the address of the new admin.
/// @dev setting this to address(0) indicates there is no active admin.
function setAdmin(address newAdmin) external onlyAdminOrOwner {
s_admin = newAdmin;
emit AdminSet(newAdmin);
}

/// @notice a modifier that allows the owner or the s_tokenLimitAdmin call the functions
/// it is applied to.
modifier onlyAdminOrOwner() {
if (msg.sender != owner() && msg.sender != s_admin) revert RateLimiter.OnlyCallableByAdminOrOwner();
_;
}
}
Loading

0 comments on commit cb083ee

Please sign in to comment.