# RebasedStakedCelo

### RebasedStakedCelo.sol (wrap & unwrap) <a href="#hvx7byvo15x5" id="hvx7byvo15x5"></a>

This is a wrapper token (ticker: rstCELO) around stCELO that, instead of accruing value to each token as staking rewards accrue in the pool, rebases balances, such that an account's balance always represents the amount of CELO that could be withdrawn for the underlying stCELO. Thus, the value of one unit of rstCELO and one unit of CELO should be approximately equivalent.

* [Source Code](https://github.com/celo-org/staked-celo/blob/master/contracts/RebasedStakedCelo.sol)
* Mainnet Deployment: [`0xDc5762753043327d74e0a538199c1488FC1F44cf`](https://explorer.celo.org/address/0xDc5762753043327d74e0a538199c1488FC1F44cf/write-proxy)
* Alfajores Testnet Deployment: [`0xe26Ed019Aa0d780Ac49826604357B1319b12602F`](https://alfajores-blockscout.celo-testnet.org/address/0xe26Ed019Aa0d780Ac49826604357B1319b12602F/transactions)

#### Methods <a href="#lvstdohfegay" id="lvstdohfegay"></a>

**Initialize**

Replaces the constructor for proxy implementation.

```
function initialize(
        address _stakedCelo,
        address _account,
        address _owner
    ) external initializer {
        __ERC20_init("Rebased Staked CELO", "rstCELO");
        _transferOwnership(_owner);
        stakedCelo = IStakedCelo(_stakedCelo);
        account = IAccount(_account);
    }
```

**Deposit**

Deposit stCELO in return for rstCELO. Although rstCELO is never minted to any account, the rstCELO balance is calculated based on the account's deposited stCELO. See \`balanceOf()\` function below.

```
 function deposit(uint256 stCeloAmount) external {
        if (stCeloAmount == 0) {
            revert ZeroAmount();
        }

        totalDeposit += stCeloAmount;

        stakedCeloBalance[msg.sender] += stCeloAmount;

        emit StakedCeloDeposited(msg.sender, stCeloAmount);

        if (!stakedCelo.transferFrom(msg.sender, address(this), stCeloAmount)) {
            revert FailedDeposit(msg.sender, stCeloAmount);
        }
    }

```

**Withdraw**

Withdraws stCELO. This function transfers back some or all of the sender's. previously deposited stCELO.

```
function withdraw(uint256 stCeloAmount) external {
        if (stCeloAmount > stakedCeloBalance[msg.sender]) {
            revert InsufficientBalance(stCeloAmount);
        }

        totalDeposit -= stCeloAmount;

        unchecked {
            stakedCeloBalance[msg.sender] -= stCeloAmount;
        }
        emit StakedCeloWithdrawn(msg.sender, stCeloAmount);

        if (!stakedCelo.transfer(msg.sender, stCeloAmount)) {
            revert FailedWithdrawal(msg.sender, stCeloAmount);
        }
    }
```

**totalSupply**

Used to query the total supply of rstCELO. The calculated total supply of rstCELO.

```
 function totalSupply() public view virtual override returns (uint256) {
        return toRebasedStakedCelo(totalDeposit);
    }

```

**balanceOf**

Used to query the rstCELO balance of an address.

```
 function balanceOf(address _account) public view override returns (uint256) {
        return toRebasedStakedCelo(stakedCeloBalance[_account]);
    }
```

**toStakedCelo**

Computes the amount of stCELO that is represented by an amount of rstCELO.

```
 function toStakedCelo(uint256 rstCeloAmount) public view returns (uint256) {
        uint256 stCeloSupply = stakedCelo.totalSupply();
        uint256 celoBalance = account.getTotalCelo();

        if (stCeloSupply == 0 || celoBalance == 0) {
            return rstCeloAmount;
        }

        return (rstCeloAmount * stCeloSupply) / celoBalance;
    }
```

**toRebasedStakedCelo**

Computes the amount of rstCELO that is represented by an amount of stCELO.

```
function toRebasedStakedCelo(uint256 stCeloAmount) public view returns (uint256) {
        uint256 stCeloSupply = stakedCelo.totalSupply();
        uint256 celoBalance = account.getTotalCelo();

        if (stCeloSupply == 0 || celoBalance == 0) {
            return stCeloAmount;
        }

        return (stCeloAmount * celoBalance) / stCeloSupply;
    }

```

**\_transfer**

Moves \`amount\` of rstCELO from \`sender\` to \`recipient\`.

```
function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal override {
        if (from == address(0)) {
            revert NullAddress();
        }
        if (to == address(0)) {
            revert NullAddress();
        }

        uint256 fromBalance = stakedCeloBalance[from];
        uint256 equivalentStakedCeloAmount = toStakedCelo(amount);
        if (fromBalance < equivalentStakedCeloAmount) {
            revert InsufficientBalance(amount);
        }

        unchecked {
            stakedCeloBalance[from] = fromBalance - equivalentStakedCeloAmount;
        }
        stakedCeloBalance[to] += equivalentStakedCeloAmount;

        emit Transfer(from, to, amount);
    }
}
```

### &#x20;<a href="#knr8m611s79h" id="knr8m611s79h"></a>


---

# Agent Instructions: Querying This Documentation

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

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.stcelo.xyz/contracts/rebasedstakedcelo.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
