Skip to content

Commit

Permalink
feat: add fuzzing of the rebate program to overnight runs (#692)
Browse files Browse the repository at this point in the history
* chore: update tag

* feat: add hvmr methods and fuzzing
  • Loading branch information
cdummett authored Aug 20, 2024
1 parent cad5163 commit 23e0527
Show file tree
Hide file tree
Showing 7 changed files with 265 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
VEGA_SIM_VEGA_TAG=9b5afc95625be367f459feb9503a0d25749fc32a
VEGA_SIM_VEGA_TAG=0da1f2aba7fa15e8919727484ab728a46d6cf259
VEGA_SIM_CONSOLE_TAG=develop
VEGA_DEFAULT_KEY_NAME='Key 1'
VEGA_SIM_NETWORKS_INTERNAL_TAG=main
Expand Down
2 changes: 1 addition & 1 deletion Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pipeline {
disableConcurrentBuilds(abortPrevious: true)
}
parameters {
string( name: 'VEGA_VERSION', defaultValue: '9b5afc95625be367f459feb9503a0d25749fc32a',
string( name: 'VEGA_VERSION', defaultValue: '0da1f2aba7fa15e8919727484ab728a46d6cf259',
description: 'Git branch, tag or hash of the vegaprotocol/vega repository')
string( name: 'VEGACAPSULE_VERSION', defaultValue: 'main',
description: 'Git branch, tag or hash of the vegaprotocol/vegacapsule repository')
Expand Down
51 changes: 51 additions & 0 deletions vega_sim/api/governance.py
Original file line number Diff line number Diff line change
Expand Up @@ -1161,6 +1161,57 @@ def update_volume_discount_program(
).proposal.id


def update_volume_rebate_program(
key_name: str,
wallet: Wallet,
data_client: vac.VegaTradingDataClientV2,
benefit_tiers: Optional[list[dict]] = None,
end_of_program_timestamp: Optional[int] = None,
window_length: Optional[int] = None,
wallet_name: Optional[str] = None,
closing_time: Optional[int] = None,
enactment_time: Optional[int] = None,
time_forward_fn: Optional[Callable[[], None]] = None,
):
volume_rebate_program = vega_protos.governance.VolumeRebateProgramChanges(
end_of_program_timestamp=end_of_program_timestamp,
window_length=window_length,
)
if benefit_tiers is not None:
for benefit_tier in benefit_tiers:
volume_rebate_program.benefit_tiers.extend(
[
vega_protos.vega.VolumeRebateBenefitTier(
minimum_party_maker_volume_fraction=str(
benefit_tier["minimum_party_maker_volume_fraction"]
),
additional_maker_rebate=str(
benefit_tier["additional_maker_rebate"]
),
)
]
)

proposal = _build_generic_proposal(
pub_key=wallet.public_key(wallet_name=wallet_name, name=key_name),
data_client=data_client,
closing_time=closing_time,
enactment_time=enactment_time,
)
proposal.terms.update_volume_rebate_program.CopyFrom(
vega_protos.governance.UpdateVolumeRebateProgram(changes=volume_rebate_program)
)
print(proposal)
return _make_and_wait_for_proposal(
wallet_name=wallet_name,
wallet=wallet,
proposal=proposal,
data_client=data_client,
time_forward_fn=time_forward_fn,
key_name=key_name,
).proposal.id


def new_transfer(
asset_decimals: Dict[str, int],
data_client: vac.VegaTradingDataClientV2,
Expand Down
155 changes: 138 additions & 17 deletions vega_sim/scenario/fuzzed_markets/agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ def step(self, vega_state):
or midprice == 0
):
return
if self.random_state.rand() > self.step_bias:
if self.random_state.rand() < self.step_bias:
return

# If we have spare money in our general we need to increase our position
Expand Down Expand Up @@ -670,7 +670,7 @@ def step(self, vega_state):
self.commitment_amount = 0
return

if self.random_state.rand() > self.step_bias:
if self.random_state.rand() < self.step_bias:
return

if self.commitment_amount < self.commitment_factor * (total_balance):
Expand Down Expand Up @@ -1372,6 +1372,8 @@ class FuzzyReferralProgramManager(StateAgentWithWallet):
controlled frequency.
"""

NAME_BASE = "fuzzy_referral_program_manager"

def __init__(
self,
key_name: str,
Expand Down Expand Up @@ -1522,6 +1524,8 @@ class FuzzyVolumeDiscountProgramManager(StateAgentWithWallet):
controlled frequency.
"""

NAME_BASE = "fuzzy_volume_discount_program_manager"

def __init__(
self,
key_name: str,
Expand Down Expand Up @@ -1563,7 +1567,7 @@ def initialise(self, vega: VegaServiceNull, create_key: bool = True, mint_key=Tr
self._sensible_proposal()

def step(self, vega_state):
if self.random_state.rand() > self.step_bias:
if self.random_state.rand() < self.step_bias:
for i in range(self.attempts_per_step):
try:
self._fuzzed_proposal()
Expand Down Expand Up @@ -1594,21 +1598,21 @@ def _sensible_proposal(self):
benefit_tiers=[
{
"minimum_running_notional_taker_volume": 1000,
"infrastructure_discount_fee": 0.01,
"liquidity_discount_fee": 0.01,
"maker_discount_fee": 0.01,
"infrastructure_discount_factor": 0.01,
"liquidity_discount_factor": 0.01,
"maker_discount_factor": 0.01,
},
{
"minimum_running_notional_taker_volume": 2000,
"infrastructure_discount_fee": 0.01,
"liquidity_discount_fee": 0.01,
"maker_discount_fee": 0.01,
"infrastructure_discount_factor": 0.01,
"liquidity_discount_factor": 0.01,
"maker_discount_factor": 0.01,
},
{
"minimum_running_notional_taker_volume": 3000,
"infrastructure_discount_fee": 0.01,
"liquidity_discount_fee": 0.01,
"maker_discount_fee": 0.01,
"infrastructure_discount_factor": 0.01,
"liquidity_discount_factor": 0.01,
"maker_discount_factor": 0.01,
},
],
window_length=1,
Expand All @@ -1624,9 +1628,126 @@ def _fuzzed_proposal(self):
"minimum_running_notional_taker_volume": self.random_state.randint(
1, 1e6
),
"infrastructure_discount_fee": self.random_state.rand(),
"liquidity_discount_fee": self.random_state.rand(),
"maker_discount_fee": self.random_state.rand(),
"infrastructure_discount_factor": self.random_state.rand(),
"liquidity_discount_factor": self.random_state.rand(),
"maker_discount_factor": self.random_state.rand(),
}
for _ in range(self.random_state.randint(1, 5))
],
window_length=self.random_state.randint(1, 100),
end_of_program_timestamp=datetime.fromtimestamp(
self.vega.get_blockchain_time(in_seconds=True)
+ self.random_state.normal(
loc=600 * self.vega.seconds_per_block,
scale=300 * self.vega.seconds_per_block,
)
),
)


class FuzzyVolumeRebateProgramManager(StateAgentWithWallet):
"""Agent proposes sensible and fuzzed update volume rebate program
proposals at a controlled frequency.
"""

NAME_BASE = "fuzzy_volume_rebate_program_manager"

def __init__(
self,
key_name: str,
step_bias=0.5,
attempts_per_step=100,
stake_key: bool = False,
wallet_name: Optional[str] = None,
random_state: Optional[RandomState] = None,
tag: Optional[str] = None,
):
self.key_name = key_name
self.wallet_name = wallet_name
self.tag = tag
self.stake_key = stake_key

self.step_bias = step_bias
self.attempts_per_step = attempts_per_step

self.random_state = random_state if random_state is not None else RandomState()

def initialise(self, vega: VegaServiceNull, create_key: bool = True, mint_key=True):
super().initialise(vega, create_key)
self.vega.wait_for_total_catchup()
if mint_key:
self.vega.mint(
wallet_name=self.wallet_name,
asset=self.vega.find_asset_id(symbol="VOTE", enabled=True),
amount=1e4,
key_name=self.key_name,
)
self.vega.wait_for_total_catchup()
if self.stake_key:
self.vega.stake(
amount=1,
key_name=self.key_name,
wallet_name=self.wallet_name,
)
self.vega.wait_for_total_catchup()
self._sensible_proposal()

def step(self, vega_state):
if self.random_state.rand() < self.step_bias:
for i in range(self.attempts_per_step):
try:
self._fuzzed_proposal()
return
except (
HTTPError,
ProposalNotAcceptedError,
builders.exceptions.VegaProtoValueError,
):
continue
logging.info(
"All fuzzed UpdateVolumeRebate proposals failed, submitting sensible"
" proposal."
)
try:
# Updating program requires method to get the current blockchain time. Ensure
# datanode is synced before requesting the current blockchain time.
self.vega.wait_for_datanode_sync()
self._sensible_proposal()
except ProposalNotAcceptedError:
logging.warning("Sensible UpdateVolumeRebate proposal failed.")

def _sensible_proposal(self):
self.vega.update_volume_rebate_program(
forward_time_to_enactment=False,
proposal_key=self.key_name,
wallet_name=self.wallet_name,
benefit_tiers=[
{
"minimum_party_maker_volume_fraction": str(0.002),
"additional_maker_rebate": f"{0.0002/10:.9f}",
},
{
"minimum_party_maker_volume_fraction": str(0.020),
"additional_maker_rebate": f"{0.0002/5:.9f}",
},
{
"minimum_party_maker_volume_fraction": str(0.200),
"additional_maker_rebate": f"{0.0002/2:.9f}",
},
],
window_length=5,
)

def _fuzzed_proposal(self):
return
self.vega.update_volume_rebate_program(
forward_time_to_enactment=False,
proposal_key=self.key_name,
wallet_name=self.wallet_name,
benefit_tiers=[
{
"minimum_party_maker_volume_fraction": f"{self.random_state.rand():.9f}",
"additional_maker_rebate": f"{self.random_state.lognormal(-10, 0.5):.9f}",
}
for _ in range(self.random_state.randint(1, 5))
],
Expand Down Expand Up @@ -1695,7 +1816,7 @@ def initialise(
)

def step(self, vega_state):
if self.random_state.rand() > self.step_bias:
if self.random_state.rand() < self.step_bias:
return
for _ in range(self.attempts_per_step):
try:
Expand Down Expand Up @@ -1782,7 +1903,7 @@ def initialise(
)

def step(self, vega_state):
if self.random_state.rand() > self.step_bias:
if self.random_state.rand() < self.step_bias:
return
for _ in range(self.attempts_per_step):
try:
Expand Down
10 changes: 10 additions & 0 deletions vega_sim/scenario/fuzzing/scenario.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
FuzzyLiquidityProvider,
FuzzedAutomatedMarketMaker,
FuzzyReferralProgramManager,
FuzzyVolumeRebateProgramManager,
FuzzyVolumeDiscountProgramManager,
)

Expand Down Expand Up @@ -69,6 +70,15 @@ def configure_agents(
)
)
# Add a fuzzed referral program
extra_agents.append(
FuzzyVolumeRebateProgramManager(
wallet_name="FuzzyReferralProgramManager",
key_name=f"FuzzyReferralProgramManager",
step_bias=0.01,
attempts_per_step=10,
)
)
# Add a fuzzed referral program
extra_agents.append(
FuzzyReferralProgramManager(
wallet_name="FuzzyReferralProgramManager",
Expand Down
56 changes: 56 additions & 0 deletions vega_sim/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -3682,6 +3682,62 @@ def update_volume_discount_program(
self.wait_for_thread_catchup()
return proposal_id

def update_volume_rebate_program(
self,
proposal_key: str,
benefit_tiers: Optional[list[dict]] = None,
end_of_program_timestamp: Optional[int] = None,
window_length: Optional[int] = None,
wallet_name: Optional[str] = None,
vote_closing_time: Optional[int] = None,
vote_enactment_time: Optional[int] = None,
approve_proposal: bool = True,
forward_time_to_enactment: bool = True,
):
blockchain_time_seconds = self.get_blockchain_time(in_seconds=True)
closing_time = (
blockchain_time_seconds + self.seconds_per_block * 40
if vote_closing_time is None
else int(vote_closing_time.timestamp())
)
enactment_time = (
blockchain_time_seconds + self.seconds_per_block * 50
if vote_enactment_time is None
else int(vote_enactment_time.timestamp())
)
end_of_program_timestamp = (
enactment_time + self.seconds_per_block * 60 * 60 * 24 * 7 * 52
if end_of_program_timestamp is None
else int(end_of_program_timestamp.timestamp())
)
proposal_id = gov.update_volume_rebate_program(
key_name=proposal_key,
wallet=self.wallet,
data_client=self.trading_data_client_v2,
benefit_tiers=benefit_tiers,
end_of_program_timestamp=end_of_program_timestamp,
window_length=window_length,
wallet_name=wallet_name,
closing_time=closing_time,
enactment_time=enactment_time,
time_forward_fn=lambda: self.wait_fn(2),
)
if approve_proposal:
gov.approve_proposal(
proposal_id=proposal_id,
wallet=self.wallet,
wallet_name=wallet_name,
key_name=proposal_key,
)

if forward_time_to_enactment:
time_to_enactment = enactment_time - self.get_blockchain_time(
in_seconds=True
)
self.wait_fn(int(time_to_enactment / self.seconds_per_block) + 1)
self.wait_for_thread_catchup()
return proposal_id

def get_current_volume_discount_program(
self,
) -> data.VolumeDiscountProgram:
Expand Down
8 changes: 8 additions & 0 deletions vega_sim/vegahome/genesis.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,14 @@
"governance.proposal.VolumeDiscountProgram.minVoterBalance": "1",
"governance.proposal.VolumeDiscountProgram.requiredMajority": "0.5",
"governance.proposal.VolumeDiscountProgram.requiredParticipation": "0.00001",
"governance.proposal.VolumeRebateProgram.maxClose": "8760h0m0s",
"governance.proposal.VolumeRebateProgram.maxEnact": "8760h0m0s",
"governance.proposal.VolumeRebateProgram.minClose": "1s",
"governance.proposal.VolumeRebateProgram.minEnact": "1s",
"governance.proposal.VolumeRebateProgram.minProposerBalance": "1",
"governance.proposal.VolumeRebateProgram.minVoterBalance": "1",
"governance.proposal.VolumeRebateProgram.requiredMajority": "0.5",
"governance.proposal.VolumeRebateProgram.requiredParticipation": "0.00001",
"governance.proposal.transfer.maxClose": "8760h0m0s",
"governance.proposal.transfer.maxEnact": "8760h0m0s",
"governance.proposal.transfer.minClose": "1s",
Expand Down

0 comments on commit 23e0527

Please sign in to comment.