-
Notifications
You must be signed in to change notification settings - Fork 78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Investigate "found pools that don't correspond to any known Balancer pool factory " #343
Comments
The code should be setup in a way where you can have multiple factories for similar things (see |
@nlordell is right. We may sometimes deploy new factories for pools of the same type. In this case, Note that the previous one can't be "shut down", so people can still deploy pools with it. But due to the known issues we'll disincentivize its use to the extent possible (eg no new pools deployed by the old factory should be expected to be added to the Balancer UI). |
@markusbkoch - do you know why the previous one was deprecated and what were the issues? |
Numerical issues when one of the token depegs. The invariant calculation computation wouldn't converge and the pool would get stuck. Didn't happen to any of ours, but it did to one on Beethoven. |
I'm wondering if the math we have implemented for the v1 stable pools still holds for v2. Since you're mentioning the invariant computation which I also see referenced in in our code here it probably does not. Also relevant for our Quasimodo solver. (Not really directed at anyone, just thinking out loud for reference. Also CC @bh2smith because you did most of the balancer implementation and we talked about this issue on Slack. Feel free to ignore the ping since you're not working on the backend atm.) |
Good point, we'll look into it and get back to you soon. |
It is the same algorithm: in that sense the "math" didn't change. We did change some details of the implementation to exactly match Curve's code (and also the Vyper compiler). These changes make it converge over a wider range, and should avoid any issues like we saw on Beethoven after the UST de-peg. In particular, we calculate a D_P value (formerly P_D) that has higher initial precision, and then adjust the quotient below to use it. Also, we dropped the directional rounding, as Vyper just does truncation. The latest code (same deployed for v2) is at: https://github.com/balancer-labs/balancer-v2-monorepo/blob/9eb7e44a4e9ebbadfe3c6242a086118298cadc9f/pkg/pool-stable-phantom/contracts/StableMath.sol#L57 |
So, we have implemented stable math here: services/crates/shared/src/sources/balancer_v2/swap/stable_math.rs Lines 19 to 84 in f7e53c3
It appears that |
Ok, so I am looking at the DIFF between the new an old contract implementations and I am seeing the following weird difference: You have changed However, I also see that both For reference I am looking at the DIFF of I am also unable to tell why |
Yes; that was a stale comment (already fixed in repo by #1488. Thanks!
…On Thu, Jul 14, 2022 at 4:24 AM Benjamin Smith ***@***.***> wrote:
Ok, so I am looking at the DIFF between the new an old contract
implementations and I am seeing the following *weird* difference:
You have changed calculateInvariant so that it always rounds down (cf
https://github.com/balancer-labs/balancer-v2-monorepo/blob/9eb7e44a4e9ebbadfe3c6242a086118298cadc9f/pkg/pool-stable-phantom/contracts/StableMath.sol#L71
)
However, I also see that both _calcOutGivenIn and _calcInGivenOut (cf here
<https://github.com/balancer-labs/balancer-v2-monorepo/blob/9eb7e44a4e9ebbadfe3c6242a086118298cadc9f/pkg/pool-stable-phantom/contracts/StableMath.sol#L124-L132>
and here
<https://github.com/balancer-labs/balancer-v2-monorepo/blob/9eb7e44a4e9ebbadfe3c6242a086118298cadc9f/pkg/pool-stable-phantom/contracts/StableMath.sol#L165-L173>)have
this new comment "// The invariant should be rounded up." and the invariant
is now being passed into the methods. If the calculateInvariantmethod has
been changed to only support rounding down, how can we ever expect to pass
in an invariant which is expected to be rounded up? It seems contradictory.
For reference I am looking at the DIFF of
/// OLD:
https://raw.githubusercontent.com/balancer-labs/balancer-v2-monorepo/ad1442113b26ec22081c2047e2ec95355a7f12ba/pkg/pool-stable/contracts/StableMath.sol
/// NEW:
https://raw.githubusercontent.com/balancer-labs/balancer-v2-monorepo/9eb7e44a4e9ebbadfe3c6242a086118298cadc9f/pkg/pool-stable-phantom/contracts/StableMath.sol
—
Reply to this email directly, view it on GitHub
<#343 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AALW2VQQTFDLHOJUBUTXTJ3VT7FCXANCNFSM52ZKQCHQ>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
So which comment was fixed, could you link to the actual change so I can see? Have there been any new unit tests introduced upon making these changes? Is there a specific PR I could look at that shows exactly what changed from one version of the contract to the other? Generally I find that these balancer contract projects change the entire directory structure every time you change a contract. Makes tracking the diff and keeping up pretty challenging. Update: Here is the change - https://github.com/balancer-labs/balancer-v2-monorepo/pull/1488/files and here is the relevant PR containing updated unit tests I have been asking about: |
There's a whole year between the initial and current StablePool
deployments, so the codebase did change significantly in that time. (In
particular, one big and fairly recent reorganization that touched almost
every file was the introduction of /interfaces to prevent circular
dependencies PR #1285.) It won't be very helpful to directly diff deployed
code over that kind of time range, unless you pull the function of interest
out and compare just that code in isolation.
It's best to look at file changes within recent PRs. PR #1488 (
https://github.com/balancer-labs/balancer-v2-monorepo/pull/1488/files)
simply removed the two lines with misleading comments.
PR #1330 (
https://github.com/balancer-labs/balancer-v2-monorepo/pull/1330/files) was
the one that changed StableMath to extend the convergence range (and
removed the directional rounding)
…On Sat, Jul 16, 2022 at 2:03 AM Benjamin Smith ***@***.***> wrote:
Yes; that was a stale comment (already fixed in repo by #1488. Thanks!
So which comment was fixed, could you link to the actual change so I can
see?
Have there been any new unit tests introduced upon making these changes?
Is there a specific PR I could look at that shows exactly what changed from
one version of the contract to the other? Generally I find that these
balancer contract projects change the entire directory structure every time
you change a contract. Makes tracking the diff pretty challenging.
—
Reply to this email directly, view it on GitHub
<#343 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AALW2VTIRGUGD5BX7WLPJJDVUJGBJANCNFSM52ZKQCHQ>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
Thanks @EndymionJkb - I have made the analogous changes to our implementation of At the moment only one of our unit tests is failing (something that was not expected to converge before, that is converging now) - which aligns with the purpose of the change, to "extend the convergence range". My only question now is whether we now need to support both implementations (one for all new stable pools and one for all old stable pools) or have the old pools been upgraded to refer to the new implementation? |
Yes, I also changed that test. It now says "still converges at extreme
values":
https://github.com/balancer-labs/balancer-v2-monorepo/blob/133359ac8b6f2cf2e19a123d10313fb02f92cb7d/pkg/pool-stable-phantom/test/StableMath.test.ts#L65
When the final stable release comes, there will be only one kind of Stable
pool: the StablePhantomPool (probably renamed to be less spooky), with the
capabilities of regular Stable pools (e.g., multi-token joins/exits) merged
into PhantomStable. There are no further changes to the math.
The V1 stable pool (from '21) is deprecated, and new pools should
use/migrate to the latest, when it's released. The 20220609 regular
StablePool release (V2) was a stopgap until the full Phantom merge is
completed, but has the updated math and all vulnerabilities addressed, so
it is perfectly fine to use, if you don't need the Phantom functionality.
Some new projects deployed using that version of plain Stable, so it should
be supported.
The blockchain is forever, so people might continue using the originally
deployed Stable pools (20210624), but they're officially deprecated. Note
their presence in the deprecated folder in /deployments:
https://github.com/balancer-labs/balancer-v2-monorepo/tree/master/pkg/deployments/tasks/deprecated
.
…On Sun, Jul 17, 2022 at 2:30 PM Benjamin Smith ***@***.***> wrote:
Thanks @EndymionJkb <https://github.com/EndymionJkb> - I have made the
analogous changes to our implementation of calculate_invariant
#368 <#368>
At the moment only one of our unit tests is failing (something that was
not expected to converge before, that is converging now) - which aligns
with the purpose of the change, to "extend the convergence range".
My only question now is whether we now need to support both
implementations (one for all new stable pools and one for all old stable
pools) or have the old pools been upgraded to refer to the new
implementation?
—
Reply to this email directly, view it on GitHub
<#343 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AALW2VWR4HOYAFXK6WDCYWTVURGLVANCNFSM52ZKQCHQ>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
This is all fantastic news. It sounds a bit like our backend services will still need to support the possibility that older versions of the pool are being used. Since this is the case, then we would need some way of identifying which stable pool uses what invariant calculation. Is this something we can determine automatically from the pool itself, or something we would have to hardcode in our project? I can imagine something like a boolean flag on the pool's attributes like All stable pools from the
Is this a legit statement? If so, can you confirm that these are the Stable Pool Factories?
|
I don't have full context here, but I'm not sure why you'd need to know
which deployment it is. The invariant calculation is an internal library
function and doesn't change anything in the pool interface. (Though the
internal interface to the library function did drop the rounding flag.)
All "versions" will produce the same value. Nothing changed in the
algorithm or calculation itself: the later versions just do the same
calculation in a slightly different way that has higher precision in the
initial steps, so that it converges over a wider range. If the "old"
version converges, it will give the exact same numerical value as the
current code: it's just that the original deployment might fail to converge
under some extreme conditions. So if you're just calculating the invariant
and want the same value as the pool, you can just use the current code.
Still, there is a way to check which deployment a pool is from. Off-chain,
you can enumerate them from the subgraph. On-chain, you can ask the
factory: call `isPoolFromFactory` with the pool address on each
StablePoolFactory deployment.
…On Mon, Jul 18, 2022 at 2:09 AM Benjamin Smith ***@***.***> wrote:
This is all fantastic news. It sounds a bit like our back end services
will still need to support the possibility that older versions of the pool
are being used. Since this is the case, then we would need some way of
identifying which stable pool uses what invariant calculation. Is this
something we can determine automatically from the pool itself, or something
we would have to hardcode in our project? I can imagine something like a
boolean flag on the pool's attributes like uses_deprecated_arithmetic,
just wondering if the pool contract itself has some indication which
invariant it is using?
—
Reply to this email directly, view it on GitHub
<#343 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AALW2VS5WFPMAL4F3TITAEDVUTYIXANCNFSM52ZKQCHQ>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
The reason is that we index the events emitted by the factory contracts (namely
which means we can simply update the invariant calculation and start indexing pools from the newly deployed factory. FYI, I did notice, however, that the new contract factory has a new event being emitted. Namely Thanks for these clarifications. Will make everything much easier now. |
Glad that cleared it up!
Yes, the new event is a universal "kill switch", which lets us deprecate
factories. It's unrelated to the other changes, but was a feature
introduced in the last release. Every factory deployment from now on will
have this.
We've gone from releasing things once a month in the early days to
deploying something like once a week now (albeit smaller things), so this
has become important, and will make version management easier in the
future. I also mentioned the /deprecated folder in the repo, which is where
you can see all the officially deprecated deployments. (Of course, those
that predate the kill switch could theoretically still be used.)
Only governance can disable a factory, after which no new pools can be
created from that factory. You'll still have legacy pools, but can at least
be certain there won't be any new ones. (This action is irreversible.)
…On Mon, Jul 18, 2022 at 3:51 PM Benjamin Smith ***@***.***> wrote:
The reason is that we index the events emitted by the factory contracts
(namely PoolCreated) in order to have a complete set Balancer Pools. We
also emulate the contract methods calc_out_given_in and calc_in_given_out.
I was worried that with the upgrade in StablePool contract that we may
have to continue to support both implementations of these methods, but am
very happy to hear that
All "versions" will produce the same value
which means we can simply update the invariant calculation and start
indexing pools from the newly deployed factory.
FYI, I did notice, however, that the new contract factory has a new event
being emitted. Namely FactoryDisabled which is emitted with no additional
parameters.
Thanks for these clarifications. Will make everything much easier now.
—
Reply to this email directly, view it on GitHub
<#343 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AALW2VXVYUGSLNABHEP4LQ3VUWYSJANCNFSM52ZKQCHQ>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
The PRs related to this issue have been merged and will soon be available in our staging environment. So, within the next few minutes, we should be able to
Note that one of those pools involves a BPT (aka LP token) which is not a likely candidate to select as a tradable token. However, we may find that since there exists a pool for it, it does become tradable. I suspect this will not be the case however, since the pool containing this BP token does not also contain one of our "base-tokens" In any case, these pools should now be entered into the ring for competitive prices. I will try and force a trade using one. |
We are currently logging this warning:
This looks weird to me because the pool type is Stable but the factory address is not the one we have in the repository. It seems like someone else created a new StablePoolFactory. This does not match how we model balancer in our code where we expect only one StablePoolFactory.
Found a reference to this here balancer/balancer-subgraph-v2@e23515e.
The text was updated successfully, but these errors were encountered: