xanoutas/solidity-security-findings huggingface dataset:
user supplied owner address which is meant to be token owner is never the token owner.  
Audit: 2024-10-coded-estate-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-10-coded-estate/blob/97efb35fd3734676f33598e6dff70119e41c7032/contracts/codedestate/src/execute.rs#L293


# Vulnerability details

## Impact
in the function `mint()`, owner is a parameter which is accepted by the function and is meant to be set into the `TokenInfo` struct's owner field during the mint. But the issue is that the `TokenInfo` struct sets the `owner` to be the` info.sender`. And this is wrong because `info.sender`, which is the function caller is not always the  `owner` arg. This means the mint logic is defective, the user supplied value for owner will never be the owner of the newly minted token. 

## Proof Of Concept 
https://github.com/code-423n4/2024-10-coded-estate/blob/97efb35fd3734676f33598e6dff70119e41c7032/contracts/codedestate/src/execute.rs#L249-L257
```rust
    pub fn mint(
        &self,
        deps: DepsMut,
        info: MessageInfo,
        token_id: String,
        owner: String,
        token_uri: Option<String>,
        extension: T,
    ) -> Result<Response<C>, ContractError> {
```
above we can see the mint function's name and parameters, the owner parameter is a required parameter meant to be provided by the caller of the function. 

But this `owner` parameter is not used in the `token:TokenInfo struct`. `owner` is set to be the function caller instead of the user supplied owner value. 

https://github.com/code-423n4/2024-10-coded-estate/blob/97efb35fd3734676f33598e6dff70119e41c7032/contracts/codedestate/src/execute.rs#L293
```rust
        let token = TokenInfo {
            owner: info.sender.clone(), //@audit owner is provided as arg, function caller is set as owner instead. 
            approvals: vec![],
            rentals:vec![],
            bids:vec![],
            longterm_rental,
            shortterm_rental,
            sell,
            token_uri,
            extension,
        };
```

This will mean that a case where user A wants to mint token1 for user B will not work because even though user A is the function caller and has specified that user B shoiuld be the owner of token1, user A will still be set as the token owner. 

## Recommened Mitigation 
set user supplied owner value as owner in the token struct. 
```rust
        let token = TokenInfo {
            owner: owner,
            approvals: vec![],
            rentals:vec![],
            bids:vec![],
            longterm_rental,
            shortterm_rental,
            sell,
            token_uri, 
            extension,
        };
```


## Assessed type

Context
Blacklisted user can burn tokens during WHITELIST_ENABLED state
Audit: 2024-11-ethena-labs-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-11-ethena-labs/blob/e93ee09b10f900bd3be385f392c80920898bf53e/contracts/ustb/UStb.sol#L199


# Vulnerability details

## Finding description and impact

Blacklisted user can burn tokens during WHITELIST_ENABLED state. This breaks the main invariant from the [README](https://github.com/code-423n4/2024-11-ethena-labs/tree/main#main-invariants). This could become an issue when the admin tries to redistribute the blacklisted user's UStb balance using redistributeLockedAmount() but the blacklisted user frontruns it with a burn.

## Proof of Concept

According to the comment [here](https://github.com/code-423n4/2024-11-ethena-labs/blob/e93ee09b10f900bd3be385f392c80920898bf53e/contracts/ustb/UStb.sol#L209), it is possible for an address to be whitelisted and blacklisted at the same. 

During the WHITELIST_ENABLED state, the code block below is checked when burning tokens to ensure only whitelisted addresses can burn their tokens. But since blacklisted users also have the whitelisted role as per the comment above, the condition evaluates to true and allows the blacklisted address to burn tokens. 
```solidity
File: UStb.sol
208:             } else if (hasRole(WHITELISTED_ROLE, msg.sender) && hasRole(WHITELISTED_ROLE, from) && to == address(0)) {
209:                 // whitelisted user can burn

```

## Recommended mitigation steps
Add the conditions `!hasRole(BLACKLISTED_ROLE, msg.sender)` and `!hasRole(BLACKLISTED_ROLE, from)` to the check.
UStb can be minted to non-whitelisted users during WHITELIST_ENABLED state
Audit: 2024-11-ethena-labs-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-11-ethena-labs/blob/e93ee09b10f900bd3be385f392c80920898bf53e/contracts/ustb/UStb.sol#L191


# Vulnerability details

## Finding description and impact

UStb can be minted to non-whitelisted users even when whitelist mode has been enabled on UStb contract. This breaks the main invariant mentioned in the [README](https://github.com/code-423n4/2024-11-ethena-labs/tree/main#additional-context).

## Proof of Concept

The below code block is from the _beforeTokenTransfer() function(), which is called at the beginning of the ERC20 _mint() internal function. When the transferState is WHITELIST_ENABLED, it should only UStb to be minted to whitelisted users as mentioned under the main invariants in the [README](https://github.com/code-423n4/2024-11-ethena-labs/tree/main#additional-context). But since the `to` address is not checked to have the `WHITELISTED_ROLE` as well, the call goes through.
```solidity
```solidity
File: UStb.sol
198:             } else if (hasRole(MINTER_CONTRACT, msg.sender) && from == address(0) && !hasRole(BLACKLISTED_ROLE, to)) {
199:                 // minting

```

A coded proof of concept is recommended for high severity findings.

## Recommended mitigation steps
Add `hasRole(WHITELISTED_ROLE, to) ` in the check.
Non-whitelisted users can burn UStb and redeem collateral during WHITELIST_ENABLED state
Audit: 2024-11-ethena-labs-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-11-ethena-labs/blob/e93ee09b10f900bd3be385f392c80920898bf53e/contracts/ustb/UStb.sol#L189


# Vulnerability details

## Finding description and impact

Non-whitelisted users can redeem collateral tokens and burn their UStb even when whitelist mode has been enabled on UStb contract. This breaks the main invariant mentioned in the [README](https://github.com/code-423n4/2024-11-ethena-labs/tree/main#additional-context).

## Proof of Concept

The below code block is from the _beforeTokenTransfer() function(), which is called at the beginning of the ERC20 _burn() internal function. When the transferState is WHITELIST_ENABLED, it should only allow whitelisted users to burn their UStb as mentioned under the main invariants in the [README](https://github.com/code-423n4/2024-11-ethena-labs/tree/main#additional-context). But since the `from` address is not checked to have the `WHITELISTED_ROLE` as well, the call goes through.
```solidity
File: UStb.sol
193:         } else if (transferState == TransferState.WHITELIST_ENABLED) {
194:            
195:             if (hasRole(MINTER_CONTRACT, msg.sender) && !hasRole(BLACKLISTED_ROLE, from) && to == address(0)) {
```

## Recommended mitigation steps
Add `hasRole(WHITELISTED_ROLE, from) ` in the check.
Lack of Functionality for Signer to Revoke Delegation
Audit: 2024-11-ethena-labs-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-11-ethena-labs/blob/main/contracts/ustb/UStbMinting.sol#L311
https://github.com/code-423n4/2024-11-ethena-labs/blob/main/contracts/ustb/UStbMinting.sol#L317
https://github.com/code-423n4/2024-11-ethena-labs/blob/main/contracts/ustb/UStbMinting.sol#L326


# Vulnerability details

## Impact

- **Insufficient Control for Signers**: Once a delegation is confirmed, the signer has no method to revoke their delegation. This lack of control can lead to prolonged exposure to potential risks if the signer no longer trusts the benefactor or if circumstances change.
- **Security and Trust Issues**: Without the ability to revoke delegation, the security model is weakened, as the signer remains perpetually linked to the benefactor until the benefactor decides to revoke the delegation.
- **Operational and Governance Risks**: This limitation could deter signers from delegating in the first place, impacting the contract’s utility and trustworthiness. Users might be wary of delegating if they have no straightforward way to retract that delegation.

## **Proof of Concept**

**Root Cause**:
The `UStbMinting` contract implements a system for delegating signing rights through the `delegatedSigner` mapping. This system enables smart contracts to delegate signing to other address (signer) and allows signer to accept. However, there is no mechanism for the original signer to revoke or reject a delegation once he has accepted.

**Relevant Code**:

```solidity
// Mapping to track delegated signer status
mapping(address => mapping(address => DelegatedSignerStatus)) public delegatedSigner;

// Existing functions
function setDelegatedSigner(address _delegateTo) external {
    delegatedSigner[_delegateTo][msg.sender] = DelegatedSignerStatus.PENDING;
    emit DelegatedSignerInitiated(_delegateTo, msg.sender);
}

function confirmDelegatedSigner(address _delegatedBy) external {
    if (delegatedSigner[msg.sender][_delegatedBy] != DelegatedSignerStatus.PENDING) {
        revert DelegationNotInitiated();
    }
    delegatedSigner[msg.sender][_delegatedBy] = DelegatedSignerStatus.ACCEPTED;
    emit DelegatedSignerAdded(msg.sender, _delegatedBy);
}

function removeDelegatedSigner(address _removedSigner) external {
    delegatedSigner[_removedSigner][msg.sender] = DelegatedSignerStatus.REJECTED;
    emit DelegatedSignerRemoved(_removedSigner, msg.sender);
}
```

**Problem Analysis**:

- The `removeDelegatedSigner` function only allows the benefactor to revoke the delegation, but the original signer has no equivalent function to do so.
- **Scenario**:
  - EOA (`address A`) sets delegate `address B`(signer) for signing.
  - `address B` confirms the delegation.
  - `address B` decides to remove signing rights for `address A`, but there is no function available for `address B` to revoke this delegation independently.


## Recommended Mitigation Steps

**Introduce a Function for Signer-Driven Revocation**:
Add a function that allows the o
Missing Whitelist Check in `setApprovedBeneficiary`
Audit: 2024-11-ethena-labs-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-11-ethena-labs/blob/main/contracts/ustb/UStbMinting.sol#L411-L425


# Vulnerability details

## Impact

- **Unauthorized Access**: This vulnerability allows any user to modify the approved beneficiaries list, potentially granting unauthorized access to minting or redemption functions tied to these beneficiaries.
- **Loss of Trust**: This breach in access control may erode trust in the contract and lead to unexpected and unauthorized modifications, weakening the overall security posture of the system.

## **Proof of Concept**

**Root Cause**:
The `setApprovedBeneficiary` function lacks a check to ensure that the caller (`msg.sender`) is part of the `_whitelistedBenefactors` set. This missing verification allows any address to call `setApprovedBeneficiary`, thereby adding or removing a beneficiary without being a whitelisted benefactor. This oversight undermines the intended restriction on who can manage beneficiaries, posing a significant security risk.

1. **Issue in the Code**:
   The `setApprovedBeneficiary` function currently does not have a `require` statement to check if `msg.sender` is in the `_whitelistedBenefactors` set.

   ```solidity
   function setApprovedBeneficiary(address beneficiary, bool status) public {
       if (status) {
           if (!_approvedBeneficiariesPerBenefactor[msg.sender].add(beneficiary)) {
               revert InvalidBeneficiaryAddress();
           } else {
               emit BeneficiaryAdded(msg.sender, beneficiary);
           }
       } else {
           if (!_approvedBeneficiariesPerBenefactor[msg.sender].remove(beneficiary)) {
               revert InvalidBeneficiaryAddress();
           } else {
               emit BeneficiaryRemoved(msg.sender, beneficiary);
           }
       }
   }
   ```

2. **Proof of Unauthorized Call**:
   Any unprivileged user can successfully execute the `setApprovedBeneficiary` function, altering the beneficiary list without restriction.

3. **Impact Illustration**:
   - **Example Attack Scenario**: An attacker calls `setApprovedBeneficiary` from an unauthorized address to add a fraudulent beneficiary. This newly added beneficiary could be used for unauthorized minting or fund transfers, potentially causing financial loss or system manipulation.

## Recommended Mitigation Steps

**Add a Whitelist Check**:
To mitigate this issue, add a `require` statement at the beginning of `setApprovedBeneficiary` to verify that the caller is in `_whitelistedBenefactors`:

```solidity
function setApprovedBeneficiary(address beneficiary, bool status) public {
    require(_whitelistedBenefactors.contains(msg.sender), "Caller is not a whitelisted benefactor");

    if (status) {
        if (!_approvedBeneficiariesPerBenefactor[msg.sender].add(beneficiary)) {
            revert InvalidBeneficiaryAddress();
        } else {
            emit BeneficiaryAdded(msg.sender, beneficiary);
        }
    } else {
        if (!_approvedBeneficiariesPerBe
Potential zero transfer issue in `UStbMinting` contract's `_transferCollateral` function due to small `amountToTransfer` calculation
Audit: 2024-11-ethena-labs-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-11-ethena-labs/blob/main/contracts/ustb/UStbMinting.sol#L612


# Vulnerability details

## Impact

1. **Incorrect Distribution:** Small collateral amounts may result in zero transfers to some addresses in `route.addresses`, leaving only the last address with the full collateral.

2. **Operational Imbalance:** Custody wallets expecting specific collateral shares may receive nothing, creating operational inconsistencies.

3. **Trust and Compliance Risks:** Unbalanced collateral routing could lead to trust issues and potential regulatory or contractual concerns, particularly for users relying on predictable distribution.

## Proof of Concept

1. **Setup and Conditions:**

   - Assume the `amount` to transfer is smaller than `ROUTE_REQUIRED_RATIO` (10,000).
   - Ratios are provided to divide the `amount` among several addresses, but because `amount` is small, each calculated `amountToTransfer` will be zero due to integer division.

2. **Example Scenario:**

   - `amount = 5,000`
   - `ratios = [1, 1, 1, 9_997]` (for 4 addresses)
   - `ROUTE_REQUIRED_RATIO = 10,000`
   - `amountToTransfer` for each address:
     amountToTransfer[i] = 5_000 \* 1 / 10,000 = 0
   - This results in zero transfer to the first three addresses, with the entire `amount` going only to the last address.

3. **Demonstration Code:**

   ```solidity
   uint128 amount = 5000;
   uint128[] memory ratios = new uint128[](4);
   ratios[0] = 1;
   ratios[1] = 1;
   ratios[2] = 1;
   ratios[3] = 9997;

   address[] memory addresses = new address[](4);
   addresses[0] = 0xAddress1;
   addresses[1] = 0xAddress2;
   addresses[2] = 0xAddress3;
   addresses[3] = 0xAddress4;

   for (uint128 i = 0; i < addresses.length; i++) {
       uint128 amountToTransfer = (amount * ratios[i]) / ROUTE_REQUIRED_RATIO;
       // Each amountToTransfer is 0, except for the last address
       console.log("Amount to transfer to address", i, amountToTransfer);
   }
   ```

4. **Expected Outcome:**
   - The first three addresses receive zero, and only the fourth address receives `5,000`.
   - This demonstrates how integer division causes an imbalance, contradicting the expected proportional distribution.


## Recommended Mitigation Steps

**Minimum Transfer Check:** Ensure `amountToTransfer` is > 0 before transferring; if zero, redistribute or adjust to ensure all addresses receive a non-zero share.
Denial of Service when Delegated Address Wants to Reject a Previously Confirmed Delegation.
Audit: 2024-11-ethena-labs-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-11-ethena-labs/blob/main/contracts/ustb/UStbMinting.sol#L468
https://github.com/code-423n4/2024-11-ethena-labs/blob/main/contracts/ustb/UStbMinting.sol#L321


# Vulnerability details

## Finding impact
Denial of Service when Delegated address wants to reject a previously confirmed delegation which would allow delegation execution that delegate is not willing to carry out for the delegator as noted in [Order verification](https://github.com/code-423n4/2024-11-ethena-labs/blob/main/contracts/ustb/UStbMinting.sol#L468) in the UStbMinting contract
## Description and Proof of Concept
```
    /// @notice assert validity of signed order
    function verifyOrder(
        Order calldata order,
        Signature calldata signature
    ) public view override returns (bytes32 taker_order_hash) {
        taker_order_hash = hashOrder(order);
        if (signature.signature_type == SignatureType.EIP712) {
            address signer = ECDSA.recover(taker_order_hash, signature.signature_bytes);
            if (
                !(signer == order.benefactor ||
>>>                   delegatedSigner[signer][order.benefactor] == DelegatedSignerStatus.ACCEPTED)
            ) {
                revert InvalidEIP712Signature();
            }  This report wants to bring to attention of protocol that
...
```
The code above shows how Order is verified in the UStbMinting contract, as noted in the pointer above, verification would go through if DelegatedSignerStatus is accepted. It can be noted in contract implementation that when delegated Signer is being set it takes the agreement of both the delegator and delegate in a two step process for the delegated Signer to be set in setDelegatedSigner(…) and confirmDelegatedSigner(…) function by the delegator and delegate respectively, however when delegated signer is to be removed only one party (the delegator) has the power to reverse delegation which would cause denial of service to a delegate who wants to also remove delegation.
```solidity
    /// @notice The delegated address to confirm delegation
    function confirmDelegatedSigner(address _delegatedBy) external {
        if (delegatedSigner[msg.sender][_delegatedBy] != DelegatedSignerStatus.PENDING) {
            revert DelegationNotInitiated();
        }
>>>        delegatedSigner[msg.sender][_delegatedBy] = DelegatedSignerStatus.ACCEPTED;
        emit DelegatedSignerAdded(msg.sender, _delegatedBy);
    }
```
The code above shows how a Delegated address accepts delegation smart contracts following a two step process by both delegator and delegate from pending status to confirmation status. Then in the situation of undelegating, it can be noted at [L326](https://github.com/code-423n4/2024-11-ethena-labs/blob/main/contracts/ustb/UStbMinting.sol#L326) that a smart contract can undelegated an address for signing. However there is no implementation in situation when a delegate wants to undelegate a contracts when it does not wan
Blacklisted user can burn tokens in one case
Audit: 2024-11-ethena-labs-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-11-ethena-labs/blob/main/contracts/ustb/UStb.sol#L199


# Vulnerability details

## Finding description and impact

When the USTB token operates in `WHITELIST_ENABLED` mode, users who hold both `WHITELISTED` and `BLACKLISTED` roles can still burn tokens, which violates expected behavior.

## Proof of Concept

```solidity
       } else if (transferState == TransferState.WHITELIST_ENABLED) {
            if (hasRole(MINTER_CONTRACT, msg.sender) && !hasRole(BLACKLISTED_ROLE, from) && to == address(0)) {
                // redeeming
            } else if (hasRole(MINTER_CONTRACT, msg.sender) && from == address(0) && !hasRole(BLACKLISTED_ROLE, to)) {
                // minting
            } else if (hasRole(DEFAULT_ADMIN_ROLE, msg.sender) && hasRole(BLACKLISTED_ROLE, from) && to == address(0)) {
                // redistributing - burn
            } else if (
                hasRole(DEFAULT_ADMIN_ROLE, msg.sender) && from == address(0) && !hasRole(BLACKLISTED_ROLE, to)
            ) {
                // redistributing - mint
>>          } else if (hasRole(WHITELISTED_ROLE, msg.sender) && hasRole(WHITELISTED_ROLE, from) && to == address(0)) {
                // whitelisted user can burn
            } else if (
                hasRole(WHITELISTED_ROLE, msg.sender) &&
                hasRole(WHITELISTED_ROLE, from) &&
                hasRole(WHITELISTED_ROLE, to) &&
                !hasRole(BLACKLISTED_ROLE, msg.sender) &&
                !hasRole(BLACKLISTED_ROLE, from) &&
                !hasRole(BLACKLISTED_ROLE, to)
            ) {
                // n.b. an address can be whitelisted and blacklisted at the same time
                // normal case
```
As seen above, the check allows a whitelisted user to burn tokens even if they are also blacklisted. Since the `normal case` branch acknowledges that an account can hold both `WHITELISTED` and `BLACKLISTED` roles, such users still have burning privileges, conflicting with one of the stated [USTB invariants](https://github.com/code-423n4/2024-11-ethena-labs/tree/main?tab=readme-ov-file#main-invariants):

> Blacklisted users cannot send/receive/mint/burn UStb tokens in any case.
 
## Recommended mitigation steps
```diff
-           } else if (hasRole(WHITELISTED_ROLE, msg.sender) && hasRole(WHITELISTED_ROLE, from) && to == address(0)) {
+           } else if (
+               hasRole(WHITELISTED_ROLE, msg.sender) && 
+               hasRole(WHITELISTED_ROLE, from) && 
+               to == address(0) && 
+               !hasRole(BLACKLISTED_ROLE, msg.sender) && 
+               !hasRole(BLACKLISTED_ROLE, from)
+           ) {

```
Upgraded Q -> 3 from #883 [1682591277339]
Audit: 2023-03-asymmetry-findings
Severity: HIGH

Judge has assessed an item in Issue #883 as 3 risk. The relevant finding follows:

 As such, if deposit() or withdraw() reverts for any derivative, stake() and unstake() will fail.

This could cause stake() and unstake() to permanently revert for an prolonged period of time, as it is possible for deposit() and withdraw() to revert due to unchecked external conditions:

Reth
The rocket pool DAO can disable deposits.
Withdrawals will fail if rocket pool does not have sufficient ETH.
WstETH
stETH has a daily staking limit, which could cause deposits to fail.
If any of the external conditions above occurs, their respecitve function will be DOSed.

Although an owner can prevent this by setting the affected derivative's weight to 0, this is not a sufficient mitigation as:

This affects the ETH distribution for each derivative, potentially making it unbalanced.
If the DOS is over a short period of time but occurs repeatedly, such as stETH's staking limit, the owner will have to keep adjusting the affected derivative's weight.