# Security

### Audits

{% file src="/files/raKFXQ5DjnOZk3iETupB" %}
Jan 17th, 2022
{% endfile %}

{% file src="/files/jHzPCxRapQdNIJE6vrie" %}
April 25th, 2022
{% endfile %}

{% file src="/files/WU2hafm8UMNitNRJdYPT" %}
Jan 29th 2024
{% endfile %}

{% file src="/files/qvWDUNRwzAonlyiF6srv" %}
March 14th 2024
{% endfile %}

{% file src="/files/SWfXSFJsCUHgLZ9xZ8r3" %}
June 11th 2024
{% endfile %}

{% file src="/files/VB41RX3x7ccrg7exgKC1" %}
September 14th 2024
{% endfile %}

### Security Architecture

Security is a top priority for Arrow. Our smart contract architecture is stratified. Our hybrid architecutre avoids a P2Pool model which are the primary targets for DeFi attacks. However, we have a dedicated contract (`UserFundsManager`) which acts as a *middleman* that facilities options transaction for buys and sell, transferring the funds from the buyer to the seller on purchase.  There are multiple layers of redundancy ensuring the `FundsManager` is secure.&#x20;

**Arrow contracts do not hold any user funds at any moment throughout any transaction**.\
User must approve a set amount of funds for the `UserFundsManager` to be able to move the funds, which are then transferred directly between users and market makers.&#x20;

**It is important to never give unlimited approval to any contract including ours and only approve an amount you are willing to risk if the approval fund is not immediately used.**

### Attack attempts

#### October 14th 2024:

**Background:** Our `FundsManager` contract uses a proxy-delegate structure for upgradeability, specifically the OpenZeppelin UUPS pattern. This means a shell "proxy" contract is deployed at an address that stays fixed for the lifecycle of the contract suite, and an implementation or "delegate" contract is deployed at a separate address that the proxy contract points to. Upgrades work by deploying a new delegate and updating the pointer address in the proxy. When an upgrade happens, an initialize function has to be called to set the contract router and other state variables. Initialize is only called once, and a boolean is set to `True` to enforce that.&#x20;

**What Happened:** During our last upgrade, we included new state variables, inadvertently moving the slot for the initialize boolean. The resulting slot had a value of 0. This allowed an attacker to call the initialize function and insert a malicious contract address in place of our Router. Subsequently, they were able to get around access modifiers in the `FundsManager` by supplying their own `Registry` contract address using their malicious `Router` address. Finally, with this access, they deployed a malicious delegate contract and gained access to any funds that had been approved to the `FundsManager` proxy, which was 277 USDC. We discovered this almost immediately and shut down the app and notified the affected parties.

**Fix:** We have deployed new `FundsManager` proxies and implementations and rewired the frontend and `Registry`\` contracts accordingly. We have shored up our upgrade protocol to include a series of automated checks so the upgrade will fail if any state variables change location.  We have also added access modifiers to the initialize functions. Drained funds were returned.&#x20;

**Diagnosis:** This is not a weakness of the architecture per-se, but rather a weakness in our upgrade protocols which have now been shored up. We've had multiple audits and work closely with our auditor on an ongoing basis. Because of the modularized components and because it is p2p/p2MM rather than p2pool, Arrow's architecture is much harder to hack than conventional DeFi applications.


---

# 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.arrow.markets/arrow-markets/arrow/security.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.
