How to write a Private Beefy Vault | RAILGUN | John Meurer Jr. | ETHDam 2023
CryptoCanal·Mon, Oct 9, 2023, 12:00 AM
John Meurer Jr. https://twitter.com/therealjmj RAILGUN https://railgun.org/ https://docs.railgun.org/developer-guide ETHDam is a Hackathon & Conference that gathered over 500 DeFi and Privacy builders on the 20th and 21st of May 2023 in Amsterdam. Privacy is normal. Following the arrest of Alex Pertsev, a Tornado Cash developer in the Netherlands, ETHDam 2023 is determined to counter the chilling effects of the lawsuit and bridge worlds to discuss the future of privacy and encourage to build on the shoulders of cypherpunk giants. ETHDam is powered by CryptoCanal, - a blockchain education and events platform growing in Amsterdam, spreading its roots to Rotterdam and Zurich. ETHDam 2024 is on the map already! Keep up with us to see updates: CryptoCanal https://www.cryptocanal.org/ CryptoCanal Twitter https://twitter.com/CryptoCanal Join CryptoCanal Community https://t.me/CryptoCanalCommunity We would like to thank our partners and sponsors that made this event possible. 🌷 Our BFF 1inch https://1inch.io/ Our Frens: Sismo https://www.sismo.io/ Aleph Zero https://alephzero.org/ Scroll https://scroll.io/ RAILGUN https://railgun.org/#/ And our Sisters: oasis.app https://oasis.app/#earn Maven11 https://www.maven11.com/ bitvavo https://bitvavo.com/en Lido https://lido.fi/ Spankchain https://spankchain.com/ API3 https://api3.org/ Gelato https://www.gelato.network/ VanEck https://www.vaneck.com/nl/en/crypto-etn Marlin Protocol https://www.marlin.org/ Silent Protocol https://www.silentprotocol.org/ Cyber Capital https://cyber.capital/ … and Proto https://twitter.com/protolambda 🍍
Transcript
Uh, so today we're going to be talking through a new product that we just actually released last week. It's called the Railgun Cookbook. And the purpose of the cookbook is to um uh, give developers a pretty easy way to structure smart contract calls so that they can fit within the sort of the Railgun system uh, and allow you to transact privately with any smart contract call. Uh, and so we're we're calling these recipes uh, sort of you know, simple um, uh, kind of housing for these calls. Uh, for example, you could do things with your private balance where uh, you're staking tokens uh, into vaults.
It's something we're going to demo today. Uh, you could actually provide liquidity on Uniswap. Uh, you could uh, do it any variety of things. Mint NFTs. You can do all of this stuff anonymously on Ethereum through Railgun.
Uh, and and Arbitrum, Polygon, etc. And so uh, I know the title of the talk was about GMX uh, and we built a recipe for this well 80% of the way over the last few days. Uh, it's it's a bit difficult and I'll I'll uh, kind of go into that at the end of the talk. Uh, we will have this recipe uh, publicly available in the next week but uh, we ran into some uh, some challenges getting that out. So I'm going to demo something called Beefy which is uh, another vault mechanism.
Uh, it's a way to store you know, vaults are essentially storing tokens um, depositing tokens into a vault. You receive a vault token back uh, which is a uh, ERC-4626. Uh, typically with with Beefy it's a little bit different but um, essentially that token can be redeemed for uh, your original tokens that you deposited plus like interest. And so you you sort of earn um, kind of a high-interest savings account for your ERC-20 tokens is what the purpose of a vault is. Uh, a lot of people, you know, deposit tokens into a vault and they'll wait, you know, they'll maybe redeem it after a year or something like that.
They gain 5, 6% uh, yield on the the tokens that they deposit. And through Railgun you can do that entire process anonymously. So, uh, this appeals to like larger funds that might want to diversify their assets and and uh, gain interest on those, uh, you know, the assets they've accumulated. Uh, but they might not want to share those strategies with the wider community. They want they might want to keep that close to home.
They had put a lot of, uh, money into research and all this kind of stuff. They don't want to share their alpha necessarily. Uh, and so that's where, uh, Railgun becomes, uh, essential. So, there was a few other things I wanted to go over up front uh, before we talk about like the exact code, uh, for the cookbook. Uh, so the way that, um, the Railgun private balances work, uh, is through a zero-knowledge system.
Uh, so it's sort of, uh, well, it's a system of smart contracts that lives on Ethereum, for example. Uh, you deposit tokens into that smart contract. We call that shielding. Uh, and then you can withdraw them at any time. We call that unshielding.
And so that kind of process of going into the smart contract, it pulls all the tokens together, but you have account-level ownership of, uh, like your balance within this system. So, rather than, um, you know, like a traditional mixer style, uh, with sort of what we think of what I think of it as like IOUs from the system, uh, that you can kind of cash in. Um, it's it's actually like more like, um, uh, traditional bank like checking account model where you actually have an account. It has a full history. Uh, you know, you have account-level ownership.
You can share a viewing key to all of your balances and historical, um, kind of transactions. You could share that with an auditor, your CPA, or something. Um and, you know, so it's account level ownership. When you go to make a private transaction, so you know, facilitating one of these recipe calls, a smart contract call to deposit in a vault, for example, it happens in three stages. So, the recipe and the cookbook was was really created to make this process very easy, where you really only have to worry about the second step, like the stuff that happens, the cross contract call.
And you don't really have to worry about like the housing and and how it how it's facilitated within Railgun. What's actually happening behind the scenes is that you take your private balance and it will be unshielded into like an intermediary contract. We call that the relay adapt contract. From there, something happens, right? You deposit into a vault or you can do a series of steps.
You can mint an NFT and assign it as an owner and do all this stuff that I'll describe for GMX later. It's a series of six or seven steps. Uh so it's a unshield, you know, do a bunch of stuff, and then it takes whatever balance is left over after this series of steps, and it reshields it into your private balance. This all happens without touching your like public 0x account on Ethereum. And so it's not This is how it's anonymized.
It doesn't actually touch your balances. You won't see your like account on Etherscan or one of the other block scanning sites. You're sort of out of the picture and it's facilitated through smart contract logic. Uh so, oh, my screen died. Um and so uh what the cookbook does when you write a recipe, uh it's a series of steps that are kind of broken down, kind of bite-size um uh steps.
Uh one for example could be like an ERC-20 approval step. Something that you usually do in a UI, right? You approve the token and then you can swap on Uniswap or something. Uh this can happen as a step, approve, and then for example, that swap would be another step, right? And so, those two steps become a two-step recipe.
And that's facilitated. You don't have to worry about the unshield and shield, but that's how it will work on chain. Um so, for Beefy, there's a few things to create a new like recipe from scratch. So, first off, you can you can follow along uh uh from uh Railgun community/cookbook. Uh I'm not sure.
Oh, there's the URL up there. Um this is just published last week. Our team's been hard at work getting this going. Um so, cookbook is going to show you know, it's sort of how you create new steps and recipes. We call something combo meal, which is multiple recipes kind of strung together.
Um which we kind we kind of find amusing. There's a integration test um suite which I'll demo as well. Um it's a little bit hard in this demo to like write the full code for a step and recipe. It doesn't take all that long. It's just in a 30-minute condensed presentation.
It's going to be a little bit of a challenge. And so, I'm going to kind of just walk you through kind of the the steps or the steps to creating steps to creating a recipe and running that against an integration like fork tests. Uh so, the first thing would be uh for each of these new cross-contract calls, um smart contract calls, the interfaces are called ABIs. People are probably familiar with those. When you deploy a contract, uh, to, uh, the Ethereum blockchain, uh, the ABI is sort of the skeleton of the calls and of the events that happen, uh, that are that are available through the smart contract interface.
And so, the first thing you do here would be to add an ABI. Is this hard to see? I might I might bump it up. Here, how about that? Um, so we've got Beefy here.
We added the ABI. This came directly from, um, Etherscan. So, if you're finding one of the ABIs, you go to their contract, you can find their addresses through, um, Beefy has decent documentation for this stuff. Uh, you can find their, um, their contracts over here. Go to Etherscan in the contracts tab, you can find the ABI.
You just basically copy and paste that. It's a structured, um, array, uh, JSON. Uh, put that into a new file, uh, and then we can, um, go to create a Beefy like wrapper contract. Uh, where do we go? Contract.
So, the vault contract, let me get rid of these. The vault contract, uh, is very, uh, like a thin wrapper for the ABI. We generate types through something called TypeChain. This can take an ABI and generate TypeScript types for it. Uh, so, we're using Ethers V5.
There's a V6, which which has nicer types like big int. Um, but for example, I created a wrapper, um, for these functions, uh, the functions we're going to use from the Beefy vaults are deposit all uh, and withdraw all, uh, which is going to be for, um, uh, for example, for, uh, the uh, they have like a curve convex vault and they give you a curve convex vault token uh, to represent that position. Uh, you can, uh, find the the of the Beefy vaults for Curve Convex. Um construct, you know, new Beefy vault contracts here uh along with the address for this specific vault. They have hundreds of different vaults that they have access to and they have a a sort of wrapper contract um that facilitates that shares the ABI between all these vaults.
Uh and you can call um deposit all to deposit your Curve Convex tokens from one account uh into the vault and they will return you an appropriate amount uh of the vault tokens based on the current rate. So, to know um you know, the the addresses of all the vaults, which vaults are available, uh Beefy does have an API. Uh their API is um it doesn't really have filters. Uh here's an example call. I just like a get call to this uh address will will bring up a list of all the vaults.
Um we wrote a uh quick wrapper around these things, so we have Beefy API um just to find filtered Beefy vaults, so I can pass in to this function a list of tokens and then pull that, you know, get request of 400 vaults and filter them by the tokens that I might have in my wallet. Uh and so this returns the Beefy vault data. We have the ID, uh the vault name, uh which which token address we're going to deposit, the token the vault token address that we get back, uh the vault rate, uh which is kind of constantly changing depending on uh how many people are depositing or redeeming from the vault, um sort of like um LP. Uh there there are fees on some of these. I I think it's pretty rare, um but these are these are pretty essential in calculating like what a user should expect, how many vault tokens they're going to get, which is pretty nice to see in a UI when you're building out these things.
Um and uh they have an APY uh request as well. Uh and the vault contract address right here. This is the uh piece I was talking about. So, when we create a new Beefy vault contract uh that has the structured ABI uh can access those functions, we're going to pass into the constructor, we're going to pass in the Beefy vault address that we got from their API. So, this is really like the data request layer and this is like how do we format a smart contract call on Ethereum or Arbitrum, Polygon, they all work.
All EVMs kind of have this structure. Uh we can create a new uh vault contract uh through these uh functions. We can generate uh like two from or or it's two data and value fields, which is called a populated transaction. And this is kind of the format of any smart contract call. Uh they have this, you know, uh byte code um uh bytes of data to to actually facilitate that call.
Uh and and so, we'll move to the next step. So, this is really we have our data, that's the API part. We have the structure of the call and we have the contract to like generate one of these calls with a certain token. Uh so, we have like the basis right now. So, the next part would be creating a step.
Uh I should say as well, this um all of this code exists uh open source uh as I showed on GitHub. Uh it's also available as an NPM. So, you don't necessarily have to like create a branch and like add code to the repo itself. You could download the NPM, create your own steps like offline. Uh and and, you know, facilitate against uh something called Railgun quick start, uh which will package those into calls against your private balance.
So, Beefy, I'm uh I'm going to show here the Beefy deposit step. We have uh abstract classes for steps and recipes. If you were to create a new fresh step, delete the code in here, it'll tell you you're going to need a few you're going to need a config and you're going to need a um a function called get step output which translates sort of the input values to this step into kind of filters what we expect the input to have. So, um show right here. Get valid input ERC-20 amount.
So, we expect to have the token we're depositing in our balance at this point in the recipe, right? If we don't have the token we're trying to deposit in the vault, we're going to get an error when we call the contract. And so, the cookbook kind of makes it easy and it and it validates the actual inputs and outputs of each step along the way. Make sure we have the tokens we expect. Um of course, we don't actually know what the tokens will be if if there's a logical error in the smart contract until we run it like on the actual contract which is why we have integration tests which I'll demo in a second.
So, we get the vault data from the vault ID. Um we have the token we're expecting to deposit. We make sure to get the in from our list of inputs. We make sure that our deposit amount is there and we it it will have a field called expected balance. Um from there, we create the new vault contract.
This is what I was talking about earlier. With the vault contract address. And we call create deposit all. That is that is the whole transaction that we're doing right here. The vault contract address is the important part cuz that'll tell us what is the token we're depositing, right?
There's a different as I said different address for Curve Convex or all the other vaults. Um I have a wrapper util right here that kind of calculates fees and different things. So, this is just kind of the math that's involved for estimating what the the return amount would be based on the vault rate and the fees associated to it. And So, this part is, you know, for a given step, I said it has inputs and we kind of translate those into outputs. Those outputs are going to be automatically verified which makes or validated by the recipe mechanics of the recipe which makes it like safe for users.
When you're creating one of these recipes, it's harder to make bugs. You'll get error messages throughout the process. So, for example, when we return the data from the step, there are these certain outputs that each step has in the recipe. A list of transactions, that's really important. That's what's actually getting called against the the blockchain.
Then we have a list of spent amounts, right? For example, we're going to spend the deposit amount and we're going to gain the vault token. So, we spend and we have the output which is the vault token and associated fees, the deposit fee for example if there is one. These are the outputs from this step. And we have just kind of basic tests to make sure that when you create one of these steps and pass in certain inputs that the outputs are, you know, valid for this step.
Once you have a a few steps, for example, with the deposit step, when we create a recipe, we're also going to need like the ERC-20 approval step. It's the same kind of thing you would do. You approve the token before you swap. You have to do the same thing when you deposit into a vault. Uh the ERC-20 approval step is already created in the cookbook.
Uh part of the impetus for for uh making the cookbook in this kind of recipe step style format is that a lot of these steps are repeated. Uh an approval will always have like a spender, like the contract that you're approving for, it always has a token, uh and it could have an amount or not. Uh if you're you know, it's safer to approve with an amount, uh but you can approve the the sort of max amount, which is which is pretty typical. Um and this this step can be used in conjunction with any other like new steps that you create for a recipe. And so so you won't have to like uh recreate the wheel here.
Uh when we look at the BEE fee deposit recipe, the really interesting thing about sort of the format of this repo is that the steps have all that complicated math and you know, the validation logic and all this like more complex stuff, but when you get to the recipe, the more abstract um uh like uh part of the the cookbook, um recipes are actually much simpler in code uh because they sort of use these complex steps and wire them together. The validation happens underneath. And so you can see actually uh the recipe is a lot less code. It's 45 lines total. Uh it basically takes a vault ID.
It's going to pull information about the vault, uh make sure that uh the network is supported. Uh this is a required um implementation uh within this class, uh and then get internal steps. So remember where I I talked about kind of the three three uh part process for a for a private call. There's the unshield and then there's like the stuff and then there's um the shield. So, internal steps is the stuff here.
This is number two, part two. You don't have to worry about the unshield, you don't have to worry about the shield part, you just kind of name what the steps are. With with the Beefy deposit recipe, we construct this with just a vault ID. So, we do need a list of those from like the Beefy API ahead of time. For internal steps, we're going to pull the vault info, which is an API call with the vault ID.
We're going to pull out the spender contract, which is which we're going to need for the approval step. We construct the from the token address that the vault um requires for for the deposit and the the amount of decimals, we construct kind of this info object about the deposit token. And then we return the two steps, right? We have an approval step for the spender and the the deposit token. And then we create a a Beefy deposit with, you know, the vault's data.
And so the the cool thing about this style again is like nobody's well, in if you were to publish one of these recipes that, you know, has tests and and all that folks can download the code for that recipe. And when they're actually facilitating one of these pretty complicated private transactions the code to initialize the recipe and pass in inputs is extremely simple. And it will tell them what the outputs are to expect. It'll have all the fees calculate pre-calculated. They won't have to do very much the like end developers.
Railgun is really like an infrastructure system. We're not necessarily going to be the ones that build the end products that were people are actually um know the wallets and this kind of stuff where people are like facilitating the private transactions. We're building a infrastructure so that it's possible to to more readily build applications with with ZK privacy at the core. So I'm going to demo quick two. Uh We have a special kind of test here that's for integrations integration tests which uses a system called Anvil by Foundry up Paradigm product.
Anvil is similar to hardhat or ganache. You run an Anvil server locally and it acts as like a virtual RPC. Uh so it puts a RPC up on your localhost and you can actually fork the current state of ethereum or arbitrum. Uh and have that state sort of like delivered via your localhost. So it's really nice product to be able to test what is going to happen on ethereum without actually paying gas to to do all of those requests.
Um so we have specific tests for for fork mode. Uh Just to look through this quickly. Uh this test is for running the Beefy deposit recipe I was just talking through. Uh for the recipe we we create or we pull the details for a vault. I have a specific vault which I think is yeah the curve convex vault on ethereum.
I have a specific vault ID I have in mind already. I know the vault token addresses so we have that's the information we're starting with. We're going to be on the ethereum network. We have the the ID already. Um we create uh or we pull the the information from the vault.
Um make sure that the expected information we get from the API is is the same. Uh we're going to we create the deposit recipe. This is the part I said, sort of the end product that adds like a like Beefy Vault mechanic through this cookbook recipe. Uh this code is is pretty simple here. Uh we pull in the deposit recipe.
These are the inputs uh that are going to be originally unshielded from your private balance, right? When somebody goes into your UI, let's say as a wallet developer, and they want to um deposit a thousand die into one of these vaults, they select a thousand die, and that's what gets passed into this uh recipe input. Uh so for example, token address die, decimals would be 18. Uh and the amount would be um uh a thousand or whatever it is. Um let's see.
So this is setting up an uh initial values uh so that we can later expect uh that they've changed against uh against the initial value. Um and this is it. Uh recipe output, deposit recipe.get recipe output, and we put in here's the uh the expected input values. Recipe output is going to have a list of populated transactions.
Uh these are what are passed into a function in uh something called Railgun Quickstart, which is our wallet SDK. Uh and this is how you actually um call this recipe against the private balance. These populated transactions will will contain all the data that's required. Uh there is a wrapper here to actually run the recipe steps, like run the populated transaction against Quickstart, and do all the stuff. It's in the It's in this wrapper here.
Uh and then there's some expectations uh at the end of this at the end of this integration test. We want to expect that the private vault token balance has increased by the amount we expect. We want we we in this recipe we unshield convex curve. We deposit it into a vault. We receive convex curve vault tokens and then we shield those back in our private balance.
So at the very end of the test we want to expect that that private balance has increased by this amount. I'll actually demo quick. We'll run this test. It takes a second to run cuz it has to run against the fork. I'm going to Oh, we're on Arbitrum.
Let's do scripts run anvil Ethereum and I'm going to put in pocket Put in a public Ethereum address RPC address for our fork. Uh Yeah, let's say. Run anvil. Of course. Oh.
So this is going to Anvil runs a lot faster than hardhat if you're familiar with that or Ganache. Anvil I think is written with Rust. It is when we switched over to it it got a lot more performant. Uh now I'm going to run yarn test fork. Actually, I might need I can't remember we changed this.
Network name is Ethereum. And this is going to run fork tests. We're going to see a little bit of an output here which kind of describes what's happening behind the scenes. So fork tests Uh, we can't guarantee that there is a balance in any Railgun account, especially one that we're going to put um, the seed phrase in in integration test for. Uh, and so for this we're using the like test test test junk seed phrase.
Um, which is a pretty common test test keys for a wallet. It's going to load up the fork from Ethereum. It shields a bunch of initial tokens into this fork. The cool thing with Anvil is you can set it to precede your test account with like 10,000 ETH so you're never going to run out of gas. Right now it's it's shielding tokens into my Railgun balance on Ethereum through this fork.
And it's pulling for the balances. So we can see the balances are found and it's running this fork for the Beefy Vault recipes. Um, that is going to run the code we just went through to create the new recipe to add in some inputs. Those are the tokens that are already shielded through this fork. The inputs are going to be validated against the expected output.
It's going to actually run the call against the private balance. It's going to do all the stuff. It's going to deposit into the Beefy Vault on this fork. Some error, great. During the demo of course.
The values are off by a small amount. They must Oh, they're off by literally Do you see what it is? One one way? Some precision error somewhere. Yeah, there are some difficulties.
For example, the swap recipe. So we we use the 0x DEX aggregator um, as you know, which pulls in prices from, uh, I think Uniswap and 1inch and all these different, um, uh, different DEXes. Uh, and prices are constantly changing. And so, one thing, there are a few limitations to, like, when you're building a recipe. Uh, we certain steps are designated as, like, non-deterministic.
We don't know exactly what the amount will come out of it. Uh, but with, I think every every recipe we've written so far, we limit you to having one non-deterministic step. Because otherwise, the calculations blow up and get crazy. Um, but you'll have an expected balance and a minimum balance as the outputs of every step. Uh, and so, you know, with slippage or something, uh, if your slippage is set to 1% on Uniswap, your expected balance could, uh, could be 100 and and the minimum balance will be 99.
Um, and if you wire a few of those together, again, it gets crazy, so, uh, it's a little hard to to test, especially with these kind of precision errors, um, but uh, you know, I think when you build it as, like, certain steps and write unit tests for those and then make a recipe and write unit tests for those, by the time you get to the integration tests, you've kind of ironed out most of those. Um, the original uh, the code for these, like, what I'm demoing, the Beefy deposits, it's Kai, our protocol architect over there, and myself, uh, we wrote this over about 12 hours last week, uh, in a single day. So, it can be done. This stuff is, like, once you get, like, in the flow of it, the whole purpose of this, again, is to make it easier than doing it from scratch. Uh, you it's much easier as well having these, um, existing steps and recipes as templates that you could copy-paste and kind of fill in the own you know your details of your protocol.
But it makes it easy easier to to facilitate all this. Um Time is it? I've got another 10 minutes. So any questions from y'all? I want to know what what people want want to know about.
I know I talked for a while here. Good. Oh, yeah. Yeah, I would agree with that. So the question was you know what what were some of the technical difficulties with GMX?
I can actually show you there's a few to-dos in this recipe. But let me see GMX stake mint GLP recipe. I won't go into the steps right now cuz those are again very complicated. The recipe looks a little simpler. Um but whereas the Beefy Vault recipe was two steps approve and then deposit the GMX one is a bit more difficult.
When we stake um the when we stake GLP token without necessarily having it they they have a contract called to like mint GLP and stake it. So you could provide die for example. They mint you an equivalent amount of GLP based on the current price and then they automatically stake that and you earn yield on on that stake position. The difficulty is that the owning account of that stake position is whoever called that function. In our example, that would be the relay adapt contract.
And we can't designate that as like a private owner. And so we've uh uh designed actually a new system along with the folks at Gnosis Safe uh where you can own a safe via an NFT. So you create a new safe or actually we have a um an uh uh like you could you could do it in a variety of ways, but uh generate a new safe, assign it uh so that the owner of the safe is an NFT, and the safe itself acts as an account. So you can call the stake from the NFT owned safe, and then you can deposit, you can shield the NFT into a private balance. The NFT owns the safe which holds the tokens, but nobody knows who is the owner of the NFT.
So that's what makes the whole thing private end to end. So it's you can see how it gets a little bit complicated. Um for for this so you can see the the stages of this, right? Uh we call it an access card, the NFT. This is kind of a nomenclature for, you know, swiping your access card and you get get access to the the safe.
Uh so we mint an NFT, uh we create the NFT owner, this would be the safe, and then we assign um the safe uh we assign the NFT as its owner. Uh we transfer the DAI to the safe because that's where it's going to actually stake from. Uh it needs to be approved from the safe to spend against the GMX contract, and then we call GMX mint and stake from the from the NFT owned safe. After that, the NFT is sitting in the um Relay Adapt contract, and it gets shielded into your private balance. Uh so you'll hold an NFT that has ownership over these assets um instead of actually holding those assets inside the relay and contract.
Um this is why this this one would have been harder to demo kind of the the whole creating steps and things. It got a little out of control while we were writing this over the past couple days. What what's the Oh, one second. So, what's the problem that's that's solving? What is What's the reason that the relay the relay adapter can't stake?
Well, the relay adapt we certainly could call the stake from relay adapt, but then anybody at all could redeem it. Because it's owned by this sort of public utility. The relay adapt is is what we think of as like a public utility. What makes it anonymous and private is that everybody's using it, right? Okay, so there are some applications where you could do a kind of like atomic swap or something something could be owned by the relay contract and other applications like this stake where there'd be no way to do it cuz there's nothing that's being stopped swapped.
Yeah, so staking is an example of something that typically has like an owner address. Uh and whoever called it, like if you look at the solidity code on the smart contract, whoever called it, they just go, "Hey, take the address of that and like increment that value." They have a higher stake for that address. And so, you can imagine if three separate people did it for the relay adapt contract, it would get incremented, it would get incremented, and then somebody would unstake all of it. Do you know what I'm saying?
Uh and anybody would have access to do that cuz you can call anything from the relay adapt contract. Uh it's sort of open-ended. So, like every stake position is basically non-fungible cuz the world rewards accrue. Is is that why So, I'm just thinking like uh um for instance like an LSD for instance, you can stake ETH but it's just in wrapped in an ERC-20. So, that's more fungible.
Yeah, so could that maybe like also get around that? Um So, the difference I guess to to clear it up, the difference with Beefy and why that one is much simpler is because when you um stake or when you deposit into the Beefy vault uh they issue you a token back. And some stake positions like don't like give you a token back and some of them don't, right? They give you a representation of that stake which you can privatize, which you can shield into your balance. But if they don't give you anything back, like like is the case for GMX they just kind of increment something on their smart contract and say, "Oh yeah, they they've got something here."
and they store it. Yeah. Um that's a situation where you need to store that somewhere. And you know, we're getting around that through the NFT safe module. I got Um I got a question about the anonymity because so as a depositor let's say I want to do a swap on on Uniswap.
Mhm. Um I deposit funds on the relay adapter. So, that will mean there is a trace of my wallet going to the relay adapter, right? Then I do the swap. Let's say that I swap like one ETH back to 1,800 USDC.
Yeah. At some point that 1,800 USDC will leave the relay adapter back to my wallet. So, I mean, is it correct what I'm saying? Yeah, absolutely. And so the whole thing is not end-to-end private in one of these relay adapt what we call cross contract calls.
Uh but it's it's fully anonymous. So full privacy would mean that the details of the transaction, the token amounts, etc. would be uh invisible. Uh but you're right, because we're talking to another smart contract, liquidity pools on Uniswap, etc. those token values have to be known, right?
You have you have you have to swap something and somebody's earning those tokens and that happens publicly. Uh but it is anonymous. What happens in Railgun uh with your shielded balance, you um sign or you you generate a zero-knowledge proof that validates that you have spend capabilities of a certain account within the system. Right? That's what the zero where the zero-knowledge comes in.
From there, that that actually facilitates the unshield step that comes out from uh the Railgun core pool. Um you know, before it does relay adapt stuff and that does happen publicly. You know the amount that came out of the Railgun pool, you know what swapped, you know what was deposited back in the pool. Uh but because of zero knowledge, you don't know who uh the origin is, right? Or whose balance it came from within the Railgun contract.
So let's say there's a million dollars in the Railgun contract, a you see a thousand come out into relay adapt and swap for wrapped ETH and go back into the Railgun balance, it was somebody that had a a die balance, but you don't necessarily know who. And the fact that you can kind of swap in and out uh means that it could be like it wasn't necessarily somebody that shielded it in. Uh the other thing that's interesting is private transfers within the Railgun system are completely invisible, right? You won't see the value because it doesn't leave the system. It just sort of reassigns the owner within the system.
Uh which is interesting and in the future uh we will have capabilities to build like an atomic swap. Uh like liquidity within within the Railgun system meaning that we could do swaps completely invisibly. I sort of So So that would mean that um let's say that I deposit with wallet A, I could take it out with wallet B. Yeah, certainly. So it's very similar to Tornado Cash.
Are there like Yeah, I would imagine there would be some problems at some point. Yeah, and we're doing a lot in terms of like uh compliance mechanisms. Um you know, kind of a non-KYC uh zero like a zero-knowledge way to prove that uh you are a good actor within the system. You can prove where the origin that the origin of the funds that you have unshielded to Binance or whatever um came from a legitimate source and wasn't a sanctioned address or something else. Um so we're working on those those kind of proofs right now that will will hopefully make it more secure and safe for everybody to to use these systems.
Okay, thank you. Last question before lunch. Anything? Yeah. Okay, um Thank you very much, John.
All right, Great talk. Thanks all.
Automatic transcript — names and jargon may be misspelled.