Open hats-bug-reporter[bot] opened 1 month ago
Intended design
I just want to make sure you realize that one of the consequences is that any account can make any transfer transaction revert if they are able to frontrun it.
I realize that "intended design" is that tokens are move easily through the trust graph. But doing some checks on msg.sender, as we suggest, does mitigate the problem, and does not not make any compromises wrt liquidity, I think.
We have had in a first implementation a stronger constraint, but this was relaxed. ie. we then checked for all flow vertices to have authorized the operator.
I have also hence considered reformulating it as an opt-in, so that for those opting-in, checking the operator would also have been required when included in the flow vertices.
I share your concern of front-running but it comes at a cost of allowing the network to fracture with operators limited in their reach, and in particular giving more power to high-centrality nodes to dictate which operators are allowed.
the other concern is that there are other ways in which one can front-run the operator that would not be covered by a stronger check. eg
I have proposed solutions for all three (1 is still possible later). There might be other ways to front-run though that I have not come up with, so overall the debate is:
So with regard to "closing the problem", it depends a bit on what you understand to be the problem. I see how it would be hard to exclude front-running altogether. But currently, your system seems completely defenseless. Frontrunning can be mitigated by maintaining a whitelist of operators that can "touch your coins", so that malicious actors can be excluded. Managing such a whitelist would be cumbersome, but you have a natural (kind-of) whitelist that consists of all addresses that are connected to you in your trust network (all addresses that trust coins that trust coins that ... that trust coins you trust). And in case such a "whitelisted" address becomes malicious and disrupts the network, you can "blacklist" it by untrusting your connections to it (or lobbying others to untrust) that address. This is a doable check, and it would not fracture the network, as far as I understand.
About incentives. So usually I would mention defi applications here (for example, liquidates may have financial incentives to keep you from paying of your debt), but in the circles case, a more plausable scenario, perhaps, is to think of a hostile government that does not like alternative currencies, that makes the local Circles network unusable by constantly re-arranging the coins in the network. One gnosis chain this would be affordable, I think.
just a quick note that 1. one of the primary design rules is that there is no governance, so maintaining a white or black list globally is already not possible; but then 2. defining it over the trust graph is not feasible, as it breaks the need of an operator to be able to act globally
eg. just for reference in a 2023 version it checked for all flow vertices that the operator is authorized (but this was with ERC20, not ERC1155, so there was a custom GraphOperator
concept) https://github.com/aboutcircles/circles-contracts-v2/blob/chiado-v0.1.0/src/graph/Graph.sol#L495-L509
and similarly untrust
had a delay enforced on it https://github.com/aboutcircles/circles-contracts-v2/blob/chiado-v0.1.0/src/graph/Graph.sol#L738-L741
(and sudden token movements out can still be mitigated over account abstraction and preferring to route tokens over vertices that have enabled a delay on sudden token movements)
So it is not that we don't know how to address this, it is that we have decided so far that the downsides of "fixing" it are worse than the upsides
Github username: -- Twitter username: -- Submission hash (on-chain): 0x1bcbde06a1402ab535edca78a66a69efcd6d007b0c688cd5e7e8ce294d225598 Severity: medium
Description: Description\ When making a transaction using
operateSignedFlowMatrix
with 0 net change, ie. Bob sends Carl 1 token and Carl sends Bob 1 token, no streams need to passed.As no streams are passed, all checks for msg.sender in the function are skipped, and this allows any address, to redistribute user's tokens within a trust network, making the user hold an equal amount but of different (and unexpected) tokens.
Attack Scenario\ First, this allows anyone to cause others to have different tokens than what they would expect and possibly desire. This is especially a problem if trust relations are not symmetric, and some user tokens may be more liquid (trusted by more users and so more easy to spend) than others.
Second, this could be used as a griefing attack. If user A front runs a transfer from B, and switches B's tokens with other tokens from B's trust network, the transaction from B will fail. This could allow an attack that blocks a user from making transactions.
Third, if this attack is used against groups, it could cause the tokens of the group to move to its vault, when this was not intended by the group nor by its trusted network.
Possible mitigation
Limit the initiation of transactions to users within the same trust network. This makes it, at least in theory, possible for users to exclude malicious actors from their trust network. This can be done by checking that each path passed in
operateSignedFlowMatrix
originates from msg.sender.Test scenario
Run with: