Skip to content
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

Feat: add capability to overwrite balances of the proxy-based tokens #504

Open
3 tasks
KirillDogadin-std opened this issue Oct 19, 2022 · 2 comments
Open
3 tasks

Comments

@KirillDogadin-std
Copy link
Contributor

KirillDogadin-std commented Oct 19, 2022

Goal

Be able to find and overwrite balance of the token that is based on the proxy contract.

Context

Some tokens such as RENBTC or GUSd use the proxy to store information but all the logic is extracted into another contract. In general proxy-contract redirects the function calls to the logic-contract but stores relevant information itself. We should be able to detect the slot of the balance of such token and overwrite it.

Assets

Overview issue #501

Tasks

  • Research and report what's different about handling the proxy contract vs the conventional contract (e.g. vs ETH-A)
  • Propose the solution
  • Implement
@KirillDogadin-std
Copy link
Contributor Author

KirillDogadin-std commented Oct 20, 2022

https://eips.ethereum.org/EIPS/eip-1967 declares how community should work with proxy contracts. Hence we know the method of proxy-based token detection.

so as mentioned in the standard specification, if the contract is of proxy type,

  • it should store the reference to the logic contract in bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1) address/slot.
  • If logic value is empty, then we fallback to beacon contract: bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1) and call implementation function there to receive the logic contract address.

general plan on how to handle this:

  • extract the address of the contract with logic,
  • initialize the ethers.js contract instance with the extracted address
  • use attach to change the address that is being called to the address of the proxy-based token contract.

aka something like

const proxyContract = getContractByAddress(tokenAddress)
const implementationContractAddress = getImplementationContract(proxyContract)
const implementationContract = getContractByAddress(implementationContractAddress)
return implementationContract.attach(proxyContract)

My quick experiment to draft the solution did not result into success (attaching the contract does not allow to read the balance successfully). I would advise to be more cautions during time estimations on how long this one will take. There's a risk factor apparently of it not being so simple/straightforward

@KirillDogadin-std
Copy link
Contributor Author

Currently i have an opinion that it is not trivial to come up with a uniform way to handle all the proxy tokens.

  1. Trying the detectProxyTarget as expected did not work. overwriting slots both in the proxy and implementation contrats does not help. The information is stored in an unusual way.
  2. GUSD has apparentaly a separate storage contract that keeps the track of the balance. The chain of reference is proxy(token) => logic contract => storage contract
  3. i did not find a trail of such structure (with storage contract deployed separately) for the renbtc case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant