Skip to content

[wip] Add exploratory xGNANA contracts#3

Open
DeFiFoFum wants to merge 1 commit into
mainfrom
feat/xGNANA
Open

[wip] Add exploratory xGNANA contracts#3
DeFiFoFum wants to merge 1 commit into
mainfrom
feat/xGNANA

Conversation

@DeFiFoFum

@DeFiFoFum DeFiFoFum commented Dec 16, 2022

Copy link
Copy Markdown
Contributor

xGNANA Prototype

I believe this could be a valid prototype for xGNANA to provide the features and modularity we desire.

The important concept in this design is the ability to have external contracts that could be delegated to, and if voting power is adjusted, they could be called to account for changes.

  • The vision is a bribe factory which deploys bribe contracts and gives out rewards to accounts which delegate to it.

Considerations

  • this is longer term thinking, but it begs the question, how would xGNANA work with revenue sharing from other tokens?

TODO (If this prototype is considered for merge)

  • Take some more time to consider naming. (This was just started on the fly for a poc)
  • Add some form of cumulative price feature so that the contract can be used as a TWAP. Oracle. (Could be good to get some inspiration from UniV3 https://docs.uniswap.org/concepts/protocol/oracle)
    Factory
  • Create an implementation of a Bribe contract
  • Create a xGNANABribeFactory with whitelist capabilities for deployment of non-upgradable xGNANABribe contracts which xGNANA holders can delegate votes to
  • ...

Comment thread contracts/xGNANA.sol
}

function exchangeRate() public view returns (uint256) {
return gnanaBalance() * 1e18 / totalSupply();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if totalSupply() == 0, which it is in the beginning, will keep the exchange rate at 0 (or just error even actually).
A simple check on this returning 1 should fix it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch! Definitely need to update that.

Comment thread contracts/xGNANA.sol
return gnanaBalance() * 1e18 / totalSupply();
}

function redeem(uint256 xGnanaAmount) external {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think redeem is more fitting but withdraw is used in a lot of places so just worth a mention

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sushi and SpookySwap use enter and leave instead of deposit and redeem/withdraw.
I think I prefer deposit and redeem but maybe worth a little vote.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy to explore this more.


function syncDelegateVotingPower(address delegator, address delegatee, bool withRevert) public {
bool synced = _syncDelegateVotingPower(delegator, delegatee);
if(withRevert && !synced) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably turn this internal and provide a public function which automatically reverts if the delegatee is not registered.

* where a protocol can fill up with tokens and distribute tokens to xGNANA holders who
* delegate their voting power.
*/
interface IxTokenWithBribes {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe IxTokenDelegatorCallback is more generic and "bribes" would still fall under this, but of course the idea is to be extensible and allow many other options.


function _syncDelegateVotingPower(address delegator, address delegatee) internal returns (bool){
if(_registeredCallbackDelegatees.contains(delegatee)) {
IERC20VotesDelegatee(delegatee).syncDelegatePower(delegator);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tricky part is that an external contract could cause a denial of service if they revert inside this function.

The whitelist is important for that, but may not catch the edge cases. Paladin strongly recommended against using a try/catch as there is a way to purposely throw it which could allow users to unstake xGNANA and still have bribe rewards on another contract.

The nice thing is that worst case we can de-whitelist a delagatee contract and it would allow xGNANA to be redeemed again.

@DeFiFoFum DeFiFoFum changed the title Add exploratory xGNANA contracts [wip] Add exploratory xGNANA contracts Mar 20, 2023
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

Successfully merging this pull request may close these issues.

2 participants